Compare commits
214 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1677bda48 | ||
|
|
83d054382c | ||
|
|
608de7f2e8 | ||
|
|
6f2eb504ab | ||
|
|
2b53e0b60b | ||
|
|
e96db328fa | ||
|
|
874404e3d3 | ||
|
|
8e771fbaa4 | ||
|
|
fb319e09d8 | ||
|
|
849f1813be | ||
|
|
763d2e295e | ||
|
|
d6ca3cca92 | ||
|
|
32c826a3db | ||
|
|
b17f3bec79 | ||
|
|
246f70fd4d | ||
|
|
7eb140a030 | ||
|
|
c68a91fe3f | ||
|
|
dc2cb61219 | ||
|
|
decbb10fcb | ||
|
|
c538fd8960 | ||
|
|
cc884f7f5b | ||
|
|
dcfe48912b | ||
|
|
3c77365f60 | ||
|
|
baff9579e5 | ||
|
|
44f4367f3e | ||
|
|
5823d58dca | ||
|
|
7bb76d508e | ||
|
|
b4c7579d24 | ||
|
|
aafe487d96 | ||
|
|
dc2f6a2dad | ||
|
|
10b691d897 | ||
|
|
50219946ec | ||
|
|
659f6fb690 | ||
|
|
af5cb97f1a | ||
|
|
1be9e9e75f | ||
|
|
b0308db977 | ||
|
|
2dbcfe4ea7 | ||
|
|
9040e02025 | ||
|
|
b3ba073368 | ||
|
|
332019a667 | ||
|
|
add9cf157d | ||
|
|
8b0ea750d8 | ||
|
|
733739921d | ||
|
|
e0f46f521a | ||
|
|
aa4245ef2a | ||
|
|
a262538eba | ||
|
|
2e4a5a75c0 | ||
|
|
9331656431 | ||
|
|
64bc12db06 | ||
|
|
7a29fee641 | ||
|
|
49f95ddbb7 | ||
|
|
317ee71882 | ||
|
|
7780fbda28 | ||
|
|
b54c6a1777 | ||
|
|
617157044c | ||
|
|
29d7e8d9d8 | ||
|
|
701d1fcf90 | ||
|
|
df36d46528 | ||
|
|
3459f3af03 | ||
|
|
5498508700 | ||
|
|
a61bb43250 | ||
|
|
aace461ae0 | ||
|
|
c02cec9a18 | ||
|
|
31daed9e81 | ||
|
|
997d55350d | ||
|
|
cc6d1b6c00 | ||
|
|
e14c54c3a4 | ||
|
|
5eba515eac | ||
|
|
f878530184 | ||
|
|
81d9224658 | ||
|
|
9d9edb8bc4 | ||
|
|
d3b5814c6f | ||
|
|
aade44cffb | ||
|
|
c4956b9c16 | ||
|
|
7ca431b214 | ||
|
|
74538ddf74 | ||
|
|
779500ee8e | ||
|
|
ee7c9e9e54 | ||
|
|
d335645dc1 | ||
|
|
0893bd4b54 | ||
|
|
862926b43e | ||
|
|
0324ba7971 | ||
|
|
6a17ec0397 | ||
|
|
53a7700798 | ||
|
|
30608e05bc | ||
|
|
3dcd7b22ca | ||
|
|
dae5d0b7c7 | ||
|
|
f5d3f93cde | ||
|
|
dbd7c13c32 | ||
|
|
b662d8f68a | ||
|
|
02445d36e5 | ||
|
|
b178e48e84 | ||
|
|
c90713ffe7 | ||
|
|
dc472cf2a8 | ||
|
|
03c599264e | ||
|
|
8f7297bea5 | ||
|
|
e4d655012b | ||
|
|
4b23c779d3 | ||
|
|
f5684a50dc | ||
|
|
579ce9f944 | ||
|
|
7aa88089b8 | ||
|
|
be983f8407 | ||
|
|
249b930602 | ||
|
|
6472f378b7 | ||
|
|
8672f0571c | ||
|
|
e7a990c1bd | ||
|
|
6727fa8e8f | ||
|
|
66d8c489b5 | ||
|
|
1931c4713a | ||
|
|
f19f172e7c | ||
|
|
092fa76124 | ||
|
|
a0b7db0a70 | ||
|
|
6438b46ea0 | ||
|
|
2bf73db9d3 | ||
|
|
03c4974c9f | ||
|
|
760fa3a451 | ||
|
|
018d8f5330 | ||
|
|
c9730e1a11 | ||
|
|
1f6e19e544 | ||
|
|
a1a0777791 | ||
|
|
887e3f76d2 | ||
|
|
8b622050fa | ||
|
|
20369aaf43 | ||
|
|
07c0e84b7d | ||
|
|
6770acaffd | ||
|
|
6201ccc7d1 | ||
|
|
965d1c469e | ||
|
|
b448ca8cb0 | ||
|
|
2204eb6c75 | ||
|
|
0abe063899 | ||
|
|
6f9b357473 | ||
|
|
152d842043 | ||
|
|
d16f97d574 | ||
|
|
d28eabaca5 | ||
|
|
b730f677be | ||
|
|
8f8806417a | ||
|
|
06694c9e89 | ||
|
|
e9b0ce3db2 | ||
|
|
4c72608398 | ||
|
|
7e99882fbf | ||
|
|
0d72d8749a | ||
|
|
d5b7a74520 | ||
|
|
0202027edb | ||
|
|
d1d32b6292 | ||
|
|
b32485e122 | ||
|
|
36d578f4d4 | ||
|
|
42bd5c2830 | ||
|
|
44548618e8 | ||
|
|
681b1be360 | ||
|
|
30dee9978c | ||
|
|
47aafc7948 | ||
|
|
1d8e2efdff | ||
|
|
dd504d32ca | ||
|
|
267c7b81c3 | ||
|
|
c4a6fd9d86 | ||
|
|
6e46152e4c | ||
|
|
f2f296e494 | ||
|
|
34f9eeff2c | ||
|
|
1278fefea2 | ||
|
|
48d46afcff | ||
|
|
6742dacaf2 | ||
|
|
3337ecc03a | ||
|
|
b9eaacd1f7 | ||
|
|
a0ada51325 | ||
|
|
8e03911957 | ||
|
|
0b3db0fd0d | ||
|
|
bb2862ed4f | ||
|
|
8c3be98b54 | ||
|
|
b76224c010 | ||
|
|
bd9f8d714a | ||
|
|
6900968555 | ||
|
|
741d334a92 | ||
|
|
b583108afa | ||
|
|
f7ace4dfe9 | ||
|
|
7ce2bd5629 | ||
|
|
41716df7b2 | ||
|
|
fe9b9829e2 | ||
|
|
4365c2a008 | ||
|
|
7896e072e7 | ||
|
|
940397c673 | ||
|
|
d57ea781f0 | ||
|
|
b74f2811a7 | ||
|
|
66223f952b | ||
|
|
0443d5e3d5 | ||
|
|
0a0b6a08e9 | ||
|
|
63af4a19e6 | ||
|
|
51f0446c18 | ||
|
|
e965223284 | ||
|
|
dbc15952cc | ||
|
|
93b70509ec | ||
|
|
798883d4e0 | ||
|
|
3e88e65bbd | ||
|
|
0906817cd3 | ||
|
|
37235fa7d0 | ||
|
|
72935d8f2b | ||
|
|
8a4095dae1 | ||
|
|
b59f228f2e | ||
|
|
a28cb3f424 | ||
|
|
05bb797a91 | ||
|
|
eb0029a877 | ||
|
|
ef0bfa85aa | ||
|
|
b5721e30a0 | ||
|
|
2c3b076b58 | ||
|
|
01e12f4524 | ||
|
|
a814d3d99a | ||
|
|
6a4508dceb | ||
|
|
b7d7274a5a | ||
|
|
71359a4328 | ||
|
|
3a3691bcca | ||
|
|
3d649e36cc | ||
|
|
a24db3c447 | ||
|
|
699a055707 | ||
|
|
1f8ed1c31c | ||
|
|
e2fc27663c |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -15,4 +15,4 @@ assignees: ''
|
||||
如果有必要,提供报错时的有关截图。/If applicable, add screenshots to help explain your problem.
|
||||
|
||||
## 附件(可选)/Attachments (Optional)
|
||||
请将会**出现问题的文件**以及**日志文件**打包成一个 ZIP 后作为附件贴在 issue 内。/Please compress the problematic files and the log files into a single ZIP archive and attach it to this issue.
|
||||
请将会**出现问题的文件**以及**日志文件**打包成一个 ZIP 后作为附件贴在 issue 内,日志文件位于程序目录下的 `logs` 文件夹内。/Please compress the problematic files and the log files into a single ZIP archive and attach it to this issue. The log files are located in the `logs` folder under the program directory.
|
||||
|
||||
@@ -11,6 +11,10 @@ jobs:
|
||||
build-release:
|
||||
if: ${{ github.event.pull_request.merged == true }}
|
||||
runs-on: windows-latest
|
||||
outputs:
|
||||
version: ${{ steps.extract_version.outputs.version }}
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
|
||||
env:
|
||||
PROJECT_NAME: SpineViewer
|
||||
PROJ_CLI_NAME: SpineViewerCLI
|
||||
@@ -27,21 +31,15 @@ jobs:
|
||||
dotnet-version: "8.0.x"
|
||||
|
||||
- name: Extract version from csproj
|
||||
id: extract_version
|
||||
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".Trim()
|
||||
"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"
|
||||
echo "Version tag found: $VERSION_TAG"
|
||||
echo "version=$VERSION_TAG" >> $env:GITHUB_OUTPUT
|
||||
echo "VERSION=$VERSION_TAG" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Tag merge commit
|
||||
shell: pwsh
|
||||
@@ -63,19 +61,11 @@ jobs:
|
||||
dotnet publish "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj" -c Release -r win-x64 --sc true -o "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained"
|
||||
dotnet publish "$env:PROJ_CLI_NAME\$env:PROJ_CLI_NAME.csproj" -c Release -r win-x64 --sc true -o "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained"
|
||||
|
||||
- name: Create release directory
|
||||
- name: Compress Windows builds
|
||||
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
|
||||
|
||||
- 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
|
||||
|
||||
- name: Create GitHub Release
|
||||
@@ -89,7 +79,7 @@ jobs:
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload FrameworkDependent zip
|
||||
- name: Upload Windows FrameworkDependent zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -99,7 +89,7 @@ jobs:
|
||||
asset_name: ${{ env.PROJECT_NAME }}-${{ env.VERSION }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Upload SelfContained zip
|
||||
- name: Upload Windows SelfContained zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -108,3 +98,43 @@ jobs:
|
||||
asset_path: release/${{ env.PROJECT_NAME }}-${{ env.VERSION }}-SelfContained.zip
|
||||
asset_name: ${{ env.PROJECT_NAME }}-${{ env.VERSION }}-SelfContained.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
|
||||
build-release-linux:
|
||||
needs: build-release
|
||||
if: ${{ github.event.pull_request.merged == true }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PROJ_CLI_NAME: SpineViewerCLI
|
||||
VERSION: ${{ needs.build-release.outputs.version }}
|
||||
|
||||
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"
|
||||
|
||||
- name: Publish Linux SelfContained version
|
||||
run: |
|
||||
dotnet publish "$PROJ_CLI_NAME/$PROJ_CLI_NAME.csproj" -c Release -r linux-x64 --sc true -o "publish/${PROJ_CLI_NAME}-${VERSION}-Linux-SelfContained"
|
||||
|
||||
- name: Compress Linux build
|
||||
run: |
|
||||
mkdir -p release
|
||||
cd publish
|
||||
zip -r "../release/${PROJ_CLI_NAME}-${VERSION}-Linux-SelfContained.zip" "${PROJ_CLI_NAME}-${VERSION}-Linux-SelfContained"
|
||||
|
||||
- name: Upload Linux zip to GitHub Release
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.build-release.outputs.upload_url }}
|
||||
asset_path: release/${{ env.PROJ_CLI_NAME }}-${{ env.VERSION }}-Linux-SelfContained.zip
|
||||
asset_name: ${{ env.PROJ_CLI_NAME }}-${{ env.VERSION }}-Linux-SelfContained.zip
|
||||
asset_content_type: application/zip
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -396,3 +396,5 @@ FodyWeavers.xsd
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
launchSettings.json
|
||||
|
||||
107
CHANGELOG.md
107
CHANGELOG.md
@@ -1,5 +1,112 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.16.12
|
||||
|
||||
- 修复 label 控件文字显示问题
|
||||
- 增强报错日志输出
|
||||
- 增加实时帧率显示
|
||||
- 首选项增加预览画面和投影最大帧率设置,移除用户状态和工作区帧率记忆
|
||||
- 优化某些性能
|
||||
|
||||
## v0.16.11
|
||||
|
||||
- 增加 shift 切换缩放倍数
|
||||
- 改善后台性能
|
||||
- 修复字体显示颜色问题
|
||||
- 调整浏览目录参数保存至用户状态
|
||||
- 调整浏览面板至最后
|
||||
|
||||
## v0.16.10
|
||||
|
||||
- 增加 Linux 平台 CLI 工具构建
|
||||
|
||||
## v0.16.9
|
||||
|
||||
- 重构 CLI 工具
|
||||
|
||||
## v0.16.8
|
||||
|
||||
- 去除首次的最小化提示弹框
|
||||
- 窗口布局改变后实时保存
|
||||
- 增加侧边栏图标和折叠功能
|
||||
- 增加皮肤和插槽参数面板的全部启用/禁用菜单项
|
||||
- 修改窗口默认大小
|
||||
- 支持复制并应用单独的模型皮肤或插槽参数
|
||||
|
||||
## v0.16.7
|
||||
|
||||
- 修复空帧导致的包围盒计算错误
|
||||
- 修复重复启动程序无法唤出界面的问题
|
||||
|
||||
## v0.16.6
|
||||
|
||||
- 修复控件尺寸为0时导致的画面缩放错误
|
||||
|
||||
## v0.16.5
|
||||
|
||||
- 修复对于无 size 行的旧 atlas 格式读取错误
|
||||
- 修复托盘化之后无法联动显示窗口的问题
|
||||
|
||||
## v0.16.4
|
||||
|
||||
- 增加 apng 导出格式
|
||||
- 增加颜色拾取器面板
|
||||
- 增加程序皮肤(主题颜色)首选项
|
||||
- 优化部分使用体验
|
||||
|
||||
## v0.16.3
|
||||
|
||||
- 修复加载工作区时的顺序错误
|
||||
- 调整部分调试渲染的逻辑
|
||||
- 完善命中检测逻辑
|
||||
|
||||
## v0.16.2
|
||||
|
||||
- 修复批量添加时的添加顺序错误
|
||||
- 增加精确命中检测和插槽输出功能
|
||||
- 部分代码重构
|
||||
|
||||
## v0.16.1
|
||||
|
||||
- 修复 3.4 版本存在的附件残留问题
|
||||
|
||||
## v0.16.0
|
||||
|
||||
- 增加最小化至托盘图标功能
|
||||
- 调整部分参数项的顺序
|
||||
- 增加开机自启和自启文件设置
|
||||
- 切换桌面投影时自动设置预览分辨率为主屏幕分辨率
|
||||
- 修复 3.4 版本下可能存在的附件残留问题
|
||||
|
||||
## v0.15.19
|
||||
|
||||
- 模型重载后选中最后一个重载模型
|
||||
- 修复 3.4 版本可能的奇数顶点数组导致的越界崩溃问题
|
||||
- 移除参数自动记录中的背景图片路径
|
||||
- 增加测试性桌面投影功能
|
||||
|
||||
## v0.15.18
|
||||
|
||||
- 完善窗口日志颜色标记
|
||||
- 修复预览图背景颜色为透明
|
||||
- 修复面板高度首次还原错误
|
||||
- 增加托盘图标
|
||||
- 增加可选预览背景画面和填充模式
|
||||
- 增强支持的纹理格式(例如 webp)
|
||||
|
||||
## v0.15.17
|
||||
|
||||
- 修改图标配色
|
||||
|
||||
## v0.15.16
|
||||
|
||||
- 修改模型添加顺序, 每次向顶层添加
|
||||
- 添加模型后自动选中最近添加的模型S
|
||||
- 点击预览画面或者选中项发生变化时转移焦点至列表
|
||||
- 增加移除全部菜单项
|
||||
- 增加单例模式和命令行文件参数
|
||||
- 增加文件关联设置
|
||||
|
||||
## v0.15.15
|
||||
|
||||
- 增加报错信息
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.15.4</Version>
|
||||
<Version>0.16.0</Version>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,92 +1,53 @@
|
||||
//
|
||||
// Copyright (c) 2004-2011 Jaroslaw Kowalski <jaak@jkowalski.net>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of Jaroslaw Kowalski nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
using NLog;
|
||||
using NLog.Conditions;
|
||||
using NLog.Config;
|
||||
using NLog;
|
||||
using System.ComponentModel;
|
||||
using NLog.Layouts;
|
||||
using System.Windows;
|
||||
|
||||
namespace NLog.Windows.Wpf
|
||||
{
|
||||
[NLogConfigurationItem]
|
||||
public class RichTextBoxRowColoringRule
|
||||
{
|
||||
static RichTextBoxRowColoringRule()
|
||||
{
|
||||
Default = new RichTextBoxRowColoringRule();
|
||||
}
|
||||
|
||||
public RichTextBoxRowColoringRule()
|
||||
: this(null, "Empty", "Empty", FontStyles.Normal, FontWeights.Normal)
|
||||
{
|
||||
}
|
||||
|
||||
public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor, FontStyle fontStyle, FontWeight fontWeight)
|
||||
{
|
||||
Condition = condition;
|
||||
FontColor = fontColor;
|
||||
BackgroundColor = backColor;
|
||||
Style = fontStyle;
|
||||
Weight = fontWeight;
|
||||
}
|
||||
|
||||
public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor)
|
||||
{
|
||||
Condition = condition;
|
||||
FontColor = fontColor;
|
||||
BackgroundColor = backColor;
|
||||
Style = FontStyles.Normal;
|
||||
Weight = FontWeights.Normal;
|
||||
}
|
||||
|
||||
public static RichTextBoxRowColoringRule Default { get; private set; }
|
||||
|
||||
[RequiredParameter]
|
||||
public ConditionExpression Condition { get; set; }
|
||||
|
||||
[DefaultValue("Empty")]
|
||||
public string FontColor { get; set; }
|
||||
public Layout FontColor { get; set; }
|
||||
public Layout BackgroundColor { get; set; }
|
||||
|
||||
[DefaultValue("Empty")]
|
||||
public string BackgroundColor { get; set; }
|
||||
public FontStyle FontStyle { get; set; }
|
||||
public FontWeight FontWeight { get; set; }
|
||||
|
||||
public FontStyle Style { get; set; }
|
||||
static RichTextBoxRowColoringRule()
|
||||
{
|
||||
RichTextBoxRowColoringRule.Default = new RichTextBoxRowColoringRule();
|
||||
}
|
||||
|
||||
public FontWeight Weight { get; set; }
|
||||
public RichTextBoxRowColoringRule() : this(null, "Empty", "Empty", FontStyles.Normal, FontWeights.Normal) { }
|
||||
|
||||
public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor)
|
||||
{
|
||||
this.Condition = (ConditionExpression)condition;
|
||||
this.FontColor = Layout.FromString(fontColor);
|
||||
this.BackgroundColor = Layout.FromString(backColor);
|
||||
this.FontStyle = FontStyles.Normal;
|
||||
this.FontWeight = FontWeights.Normal;
|
||||
}
|
||||
|
||||
public RichTextBoxRowColoringRule(string condition, string fontColor, string backColor, FontStyle fontStyle, FontWeight fontWeight)
|
||||
{
|
||||
this.Condition = (ConditionExpression)condition;
|
||||
this.FontColor = Layout.FromString(fontColor);
|
||||
this.BackgroundColor = Layout.FromString(backColor);
|
||||
this.FontStyle = fontStyle;
|
||||
this.FontWeight = fontWeight;
|
||||
}
|
||||
|
||||
public bool CheckCondition(LogEventInfo logEvent)
|
||||
{
|
||||
return true.Equals(Condition.Evaluate(logEvent));
|
||||
return true.Equals(this.Condition.Evaluate(logEvent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,27 @@
|
||||
using NLog.Config;
|
||||
using NLog.Layouts;
|
||||
using NLog;
|
||||
using NLog.Common;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using System.Windows;
|
||||
|
||||
namespace NLog.Windows.Wpf
|
||||
{
|
||||
// TODO: 完善日志实现
|
||||
[Target("RichTextBox")]
|
||||
public sealed class RichTextBoxTarget : TargetWithLayout
|
||||
{
|
||||
private int lineCount;
|
||||
private int _width = 500;
|
||||
private int _height = 500;
|
||||
private static readonly TypeConverter colorConverter = new ColorConverter();
|
||||
public static ReadOnlyCollection<RichTextBoxRowColoringRule> DefaultRowColoringRules { get; } = CreateDefaultColoringRules();
|
||||
|
||||
static RichTextBoxTarget()
|
||||
private static ReadOnlyCollection<RichTextBoxRowColoringRule> CreateDefaultColoringRules()
|
||||
{
|
||||
var rules = new List<RichTextBoxRowColoringRule>()
|
||||
return new List<RichTextBoxRowColoringRule>()
|
||||
{
|
||||
new RichTextBoxRowColoringRule("level == LogLevel.Fatal", "White", "Red", FontStyles.Normal, FontWeights.Bold),
|
||||
new RichTextBoxRowColoringRule("level == LogLevel.Error", "Red", "Empty", FontStyles.Italic, FontWeights.Bold),
|
||||
@@ -36,220 +29,252 @@ namespace NLog.Windows.Wpf
|
||||
new RichTextBoxRowColoringRule("level == LogLevel.Info", "Black", "Empty"),
|
||||
new RichTextBoxRowColoringRule("level == LogLevel.Debug", "Gray", "Empty"),
|
||||
new RichTextBoxRowColoringRule("level == LogLevel.Trace", "DarkGray", "Empty", FontStyles.Italic, FontWeights.Normal),
|
||||
};
|
||||
|
||||
DefaultRowColoringRules = rules.AsReadOnly();
|
||||
}.AsReadOnly();
|
||||
}
|
||||
|
||||
public RichTextBoxTarget()
|
||||
{
|
||||
WordColoringRules = new List<RichTextBoxWordColoringRule>();
|
||||
RowColoringRules = new List<RichTextBoxRowColoringRule>();
|
||||
ToolWindow = true;
|
||||
}
|
||||
|
||||
private delegate void DelSendTheMessageToRichTextBox(string logMessage, RichTextBoxRowColoringRule rule);
|
||||
|
||||
private delegate void FormCloseDelegate();
|
||||
|
||||
public static ReadOnlyCollection<RichTextBoxRowColoringRule> DefaultRowColoringRules { get; private set; }
|
||||
public RichTextBoxTarget() { }
|
||||
|
||||
public string ControlName { get; set; }
|
||||
|
||||
public string FormName { get; set; }
|
||||
public string WindowName { get; set; }
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool UseDefaultRowColoringRules { get; set; }
|
||||
|
||||
[ArrayParameter(typeof(RichTextBoxRowColoringRule), "row-coloring")]
|
||||
public IList<RichTextBoxRowColoringRule> RowColoringRules { get; private set; }
|
||||
|
||||
[ArrayParameter(typeof(RichTextBoxWordColoringRule), "word-coloring")]
|
||||
public IList<RichTextBoxWordColoringRule> WordColoringRules { get; private set; }
|
||||
|
||||
[DefaultValue(true)]
|
||||
public bool ToolWindow { get; set; }
|
||||
|
||||
public bool ShowMinimized { get; set; }
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return _width; }
|
||||
set { _width = value; }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return _height; }
|
||||
set { _height = value; }
|
||||
}
|
||||
|
||||
public bool AutoScroll { get; set; }
|
||||
|
||||
public int MaxLines { get; set; }
|
||||
|
||||
internal Window TargetForm { get; set; }
|
||||
[ArrayParameter(typeof(RichTextBoxRowColoringRule), "row-coloring")]
|
||||
public IList<RichTextBoxRowColoringRule> RowColoringRules { get; } = new List<RichTextBoxRowColoringRule>();
|
||||
|
||||
internal RichTextBox TargetRichTextBox { get; set; }
|
||||
[ArrayParameter(typeof(RichTextBoxWordColoringRule), "word-coloring")]
|
||||
public IList<RichTextBoxWordColoringRule> WordColoringRules { get; } = new List<RichTextBoxWordColoringRule>();
|
||||
|
||||
internal bool CreatedForm { get; set; }
|
||||
[NLogConfigurationIgnoreProperty]
|
||||
public Window TargetWindow { get; set; }
|
||||
|
||||
[NLogConfigurationIgnoreProperty]
|
||||
public RichTextBox TargetRichTextBox { get; set; }
|
||||
|
||||
protected override void InitializeTarget()
|
||||
{
|
||||
TargetRichTextBox = Application.Current.MainWindow.FindName(ControlName) as RichTextBox;
|
||||
base.InitializeTarget();
|
||||
if (TargetRichTextBox != null)
|
||||
return;
|
||||
|
||||
if (TargetRichTextBox != null) return;
|
||||
//this.TargetForm = FormHelper.CreateForm(this.FormName, this.Width, this.Height, false, this.ShowMinimized, this.ToolWindow);
|
||||
//this.CreatedForm = true;
|
||||
|
||||
var openFormByName = Application.Current.Windows.Cast<Window>().FirstOrDefault(x => x.GetType().Name == FormName);
|
||||
if (openFormByName != null)
|
||||
if (WindowName == null)
|
||||
{
|
||||
TargetForm = openFormByName;
|
||||
HandleError("WindowName should be specified for {0}.{1}", GetType().Name, Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ControlName))
|
||||
{
|
||||
// throw new NLogConfigurationException("Rich text box control name must be specified for " + GetType().Name + ".");
|
||||
Trace.WriteLine("Rich text box control name must be specified for " + GetType().Name + ".");
|
||||
HandleError("Rich text box control name must be specified for {0}.{1}", GetType().Name, Name);
|
||||
return;
|
||||
}
|
||||
|
||||
CreatedForm = false;
|
||||
TargetRichTextBox = TargetForm.FindName(ControlName) as RichTextBox;
|
||||
|
||||
if (TargetRichTextBox == null)
|
||||
var targetWindow = Application.Current.Windows.OfType<Window>().FirstOrDefault(w => w.Name == WindowName);
|
||||
if (targetWindow == null)
|
||||
{
|
||||
// throw new NLogConfigurationException("Rich text box control '" + ControlName + "' cannot be found on form '" + FormName + "'.");
|
||||
Trace.WriteLine("Rich text box control '" + ControlName + "' cannot be found on form '" + FormName + "'.");
|
||||
}
|
||||
InternalLogger.Info("{0}: WindowName '{1}' not found", this, WindowName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TargetRichTextBox == null)
|
||||
var targetControl = targetWindow.FindName(ControlName) as RichTextBox;
|
||||
if (targetControl == null)
|
||||
{
|
||||
TargetForm = new Window
|
||||
{
|
||||
Name = FormName,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
WindowStyle = ToolWindow ? WindowStyle.ToolWindow : WindowStyle.None,
|
||||
WindowState = ShowMinimized ? WindowState.Minimized : WindowState.Normal,
|
||||
Title = "NLog Messages"
|
||||
};
|
||||
TargetForm.Show();
|
||||
|
||||
TargetRichTextBox = new RichTextBox { Name = ControlName };
|
||||
var style = new Style(typeof(Paragraph));
|
||||
TargetRichTextBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
|
||||
style.Setters.Add(new Setter(Block.MarginProperty, new Thickness(0, 0, 0, 0)));
|
||||
TargetRichTextBox.Resources.Add(typeof(Paragraph), style);
|
||||
TargetForm.Content = TargetRichTextBox;
|
||||
|
||||
CreatedForm = true;
|
||||
InternalLogger.Info("{0}: WIndowName '{1}' does not contain ControlName '{2}'", this, WindowName, ControlName);
|
||||
return;
|
||||
}
|
||||
|
||||
AttachToControl(targetWindow, targetControl);
|
||||
}
|
||||
|
||||
private static void HandleError(string message, params object[] args)
|
||||
{
|
||||
if (LogManager.ThrowExceptions)
|
||||
{
|
||||
throw new NLogConfigurationException(string.Format(message, args));
|
||||
}
|
||||
InternalLogger.Error(message, args);
|
||||
}
|
||||
|
||||
private void AttachToControl(Window window, RichTextBox textboxControl)
|
||||
{
|
||||
InternalLogger.Info("{0}: Attaching target to textbox {1}.{2}", this, window.Name, textboxControl.Name);
|
||||
DetachFromControl();
|
||||
TargetWindow = window;
|
||||
TargetRichTextBox = textboxControl;
|
||||
}
|
||||
|
||||
private void DetachFromControl()
|
||||
{
|
||||
TargetWindow = null;
|
||||
TargetRichTextBox = null;
|
||||
}
|
||||
|
||||
protected override void CloseTarget()
|
||||
{
|
||||
if (CreatedForm)
|
||||
{
|
||||
try
|
||||
{
|
||||
TargetForm.Dispatcher.Invoke(() =>
|
||||
{
|
||||
TargetForm.Close();
|
||||
TargetForm = null;
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
DetachFromControl();
|
||||
}
|
||||
|
||||
protected override void Write(LogEventInfo logEvent)
|
||||
{
|
||||
RichTextBoxRowColoringRule matchingRule = RowColoringRules.FirstOrDefault(rr => rr.CheckCondition(logEvent));
|
||||
|
||||
if (UseDefaultRowColoringRules && matchingRule == null)
|
||||
RichTextBox textbox = TargetRichTextBox;
|
||||
if (textbox == null || textbox.Dispatcher.HasShutdownStarted || textbox.Dispatcher.HasShutdownFinished)
|
||||
{
|
||||
foreach (var rr in DefaultRowColoringRules.Where(rr => rr.CheckCondition(logEvent)))
|
||||
{
|
||||
matchingRule = rr;
|
||||
break;
|
||||
}
|
||||
//no last logged textbox
|
||||
InternalLogger.Trace("{0}: Attached Textbox is {1}, skipping logging", this, textbox == null ? "null" : "disposed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (matchingRule == null)
|
||||
{
|
||||
matchingRule = RichTextBoxRowColoringRule.Default;
|
||||
string logMessage = RenderLogEvent(Layout, logEvent);
|
||||
RichTextBoxRowColoringRule matchingRule = FindMatchingRule(logEvent);
|
||||
_ = DoSendMessageToTextbox(logMessage, matchingRule, logEvent);
|
||||
}
|
||||
|
||||
var logMessage = Layout.Render(logEvent);
|
||||
|
||||
if (Application.Current == null) return;
|
||||
|
||||
private bool DoSendMessageToTextbox(string logMessage, RichTextBoxRowColoringRule rule, LogEventInfo logEvent)
|
||||
{
|
||||
RichTextBox textbox = TargetRichTextBox;
|
||||
try
|
||||
{
|
||||
if (Application.Current.Dispatcher.CheckAccess() == false)
|
||||
if (textbox != null && !textbox.Dispatcher.HasShutdownStarted && !textbox.Dispatcher.HasShutdownFinished)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() => SendTheMessageToRichTextBox(logMessage, matchingRule));
|
||||
if (!textbox.Dispatcher.CheckAccess())
|
||||
{
|
||||
textbox.Dispatcher.BeginInvoke(() => SendTheMessageToRichTextBox(textbox, logMessage, rule, logEvent));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendTheMessageToRichTextBox(logMessage, matchingRule);
|
||||
SendTheMessageToRichTextBox(textbox, logMessage, rule, logEvent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
InternalLogger.Warn(ex, "{0}: Failed to append RichTextBox", this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static Color GetColorFromString(string color, Brush defaultColor)
|
||||
if (LogManager.ThrowExceptions)
|
||||
{
|
||||
|
||||
if (color == "Empty")
|
||||
{
|
||||
return defaultColor is SolidColorBrush solidBrush ? solidBrush.Color : Colors.White;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Color)colorConverter.ConvertFromString(color);
|
||||
private RichTextBoxRowColoringRule FindMatchingRule(LogEventInfo logEvent)
|
||||
{
|
||||
//custom rules first
|
||||
if (RowColoringRules.Count > 0)
|
||||
{
|
||||
foreach (RichTextBoxRowColoringRule coloringRule in RowColoringRules)
|
||||
{
|
||||
if (coloringRule.CheckCondition(logEvent))
|
||||
{
|
||||
return coloringRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SendTheMessageToRichTextBox(string logMessage, RichTextBoxRowColoringRule rule)
|
||||
if (UseDefaultRowColoringRules && DefaultRowColoringRules != null)
|
||||
{
|
||||
RichTextBox rtbx = TargetRichTextBox;
|
||||
foreach (RichTextBoxRowColoringRule coloringRule in DefaultRowColoringRules)
|
||||
{
|
||||
if (coloringRule.CheckCondition(logEvent))
|
||||
{
|
||||
return coloringRule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RichTextBoxRowColoringRule.Default;
|
||||
}
|
||||
|
||||
private void SendTheMessageToRichTextBox(RichTextBox textBox, string logMessage, RichTextBoxRowColoringRule rule, LogEventInfo logEvent)
|
||||
{
|
||||
if (textBox == null) return;
|
||||
|
||||
var document = textBox.Document;
|
||||
|
||||
// 插入文本(带换行)
|
||||
var tr = new TextRange(document.ContentEnd, document.ContentEnd)
|
||||
{
|
||||
Text = logMessage + Environment.NewLine
|
||||
};
|
||||
|
||||
// 设置行级样式
|
||||
var fgColor = rule.FontColor?.Render(logEvent);
|
||||
var bgColor = rule.BackgroundColor?.Render(logEvent);
|
||||
|
||||
var tr = new TextRange(rtbx.Document.ContentEnd, rtbx.Document.ContentEnd);
|
||||
tr.Text = logMessage + "\n";
|
||||
tr.ApplyPropertyValue(TextElement.ForegroundProperty,
|
||||
new SolidColorBrush(GetColorFromString(rule.FontColor, (Brush)tr.GetPropertyValue(TextElement.ForegroundProperty)))
|
||||
);
|
||||
string.IsNullOrEmpty(fgColor) || fgColor == "Empty"
|
||||
? textBox.Foreground
|
||||
: new SolidColorBrush((Color)ColorConverter.ConvertFromString(fgColor)));
|
||||
|
||||
tr.ApplyPropertyValue(TextElement.BackgroundProperty,
|
||||
new SolidColorBrush(GetColorFromString(rule.BackgroundColor, (Brush)tr.GetPropertyValue(TextElement.BackgroundProperty)))
|
||||
);
|
||||
tr.ApplyPropertyValue(TextElement.FontStyleProperty, rule.Style);
|
||||
tr.ApplyPropertyValue(TextElement.FontWeightProperty, rule.Weight);
|
||||
string.IsNullOrEmpty(bgColor) || bgColor == "Empty"
|
||||
? Brushes.Transparent
|
||||
: new SolidColorBrush((Color)ColorConverter.ConvertFromString(bgColor)));
|
||||
|
||||
tr.ApplyPropertyValue(TextElement.FontStyleProperty, rule.FontStyle);
|
||||
tr.ApplyPropertyValue(TextElement.FontWeightProperty, rule.FontWeight);
|
||||
|
||||
// Word coloring(在刚插入的范围内做匹配)
|
||||
if (WordColoringRules.Count > 0)
|
||||
{
|
||||
foreach (var wordRule in WordColoringRules)
|
||||
{
|
||||
var pattern = wordRule.Regex?.Render(logEvent) ?? string.Empty;
|
||||
var text = wordRule.Text?.Render(logEvent) ?? string.Empty;
|
||||
var wholeWords = wordRule.WholeWords.RenderValue(logEvent);
|
||||
var ignoreCase = wordRule.IgnoreCase.RenderValue(logEvent);
|
||||
|
||||
var regex = wordRule.ResolveRegEx(pattern, text, wholeWords, ignoreCase);
|
||||
var matches = regex.Matches(tr.Text);
|
||||
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
// 匹配到的部分范围
|
||||
var start = tr.Start.GetPositionAtOffset(match.Index, LogicalDirection.Forward);
|
||||
var endPos = tr.Start.GetPositionAtOffset(match.Index + match.Length, LogicalDirection.Backward);
|
||||
if (start == null || endPos == null) continue;
|
||||
|
||||
var wordRange = new TextRange(start, endPos);
|
||||
|
||||
var wordFg = wordRule.FontColor?.Render(logEvent);
|
||||
var wordBg = wordRule.BackgroundColor?.Render(logEvent);
|
||||
|
||||
wordRange.ApplyPropertyValue(TextElement.ForegroundProperty,
|
||||
string.IsNullOrEmpty(wordFg) || wordFg == "Empty"
|
||||
? tr.GetPropertyValue(TextElement.ForegroundProperty)
|
||||
: new SolidColorBrush((Color)ColorConverter.ConvertFromString(wordFg)));
|
||||
|
||||
wordRange.ApplyPropertyValue(TextElement.BackgroundProperty,
|
||||
string.IsNullOrEmpty(wordBg) || wordBg == "Empty"
|
||||
? tr.GetPropertyValue(TextElement.BackgroundProperty)
|
||||
: new SolidColorBrush((Color)ColorConverter.ConvertFromString(wordBg)));
|
||||
|
||||
wordRange.ApplyPropertyValue(TextElement.FontStyleProperty, wordRule.FontStyle);
|
||||
wordRange.ApplyPropertyValue(TextElement.FontWeightProperty, wordRule.FontWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 限制最大行数
|
||||
if (MaxLines > 0)
|
||||
{
|
||||
lineCount++;
|
||||
if (lineCount > MaxLines)
|
||||
while (document.Blocks.Count > MaxLines)
|
||||
{
|
||||
tr = new TextRange(rtbx.Document.ContentStart, rtbx.Document.ContentEnd);
|
||||
tr.Text.Remove(0, tr.Text.IndexOf('\n'));
|
||||
lineCount--;
|
||||
document.Blocks.Remove(document.Blocks.FirstBlock);
|
||||
}
|
||||
}
|
||||
|
||||
// 自动滚动到最后
|
||||
if (AutoScroll)
|
||||
{
|
||||
rtbx.ScrollToEnd();
|
||||
textBox.ScrollToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 2004-2011 Jaroslaw Kowalski <jaak@jkowalski.net>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of Jaroslaw Kowalski nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
using NLog.Config;
|
||||
using NLog.Layouts;
|
||||
using System.ComponentModel;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using NLog.Config;
|
||||
|
||||
namespace NLog.Windows.Wpf
|
||||
{
|
||||
[NLogConfigurationItem]
|
||||
public class RichTextBoxWordColoringRule
|
||||
{
|
||||
private Regex compiledRegex;
|
||||
public Layout Regex { get; set; }
|
||||
public Layout Text { get; set; }
|
||||
public Layout<bool> WholeWords { get; set; }
|
||||
public Layout<bool> IgnoreCase { get; set; }
|
||||
|
||||
public RichTextBoxWordColoringRule()
|
||||
public Layout FontColor { get; set; }
|
||||
public Layout BackgroundColor { get; set; }
|
||||
|
||||
public FontStyle FontStyle { get; set; }
|
||||
public FontWeight FontWeight { get; set; }
|
||||
|
||||
internal Regex ResolveRegEx(string pattern, string text, bool wholeWords, bool ignoreCase)
|
||||
{
|
||||
FontColor = "Empty";
|
||||
BackgroundColor = "Empty";
|
||||
if (string.IsNullOrEmpty(pattern) && text != null)
|
||||
{
|
||||
pattern = System.Text.RegularExpressions.Regex.Escape(text);
|
||||
if (wholeWords)
|
||||
pattern = "\b" + pattern + "\b";
|
||||
}
|
||||
|
||||
RegexOptions options = RegexOptions.None;
|
||||
if (ignoreCase)
|
||||
options |= RegexOptions.IgnoreCase;
|
||||
|
||||
return new Regex(pattern, options); // RegEx-Cache
|
||||
}
|
||||
|
||||
public RichTextBoxWordColoringRule() : this(null, "Empty", "Empty", FontStyles.Normal, FontWeights.Normal) { }
|
||||
|
||||
public RichTextBoxWordColoringRule(string text, string fontColor, string backgroundColor)
|
||||
{
|
||||
Text = text;
|
||||
FontColor = fontColor;
|
||||
BackgroundColor = backgroundColor;
|
||||
Style = FontStyles.Normal;
|
||||
Weight = FontWeights.Normal;
|
||||
this.Text = text;
|
||||
this.FontColor = Layout.FromString(fontColor);
|
||||
this.BackgroundColor = Layout.FromString(backgroundColor);
|
||||
this.FontStyle = FontStyles.Normal;
|
||||
this.FontWeight = FontWeights.Normal;
|
||||
}
|
||||
|
||||
public RichTextBoxWordColoringRule(string text, string textColor, string backgroundColor, FontStyle fontStyle, FontWeight fontWeight)
|
||||
{
|
||||
Text = text;
|
||||
FontColor = textColor;
|
||||
BackgroundColor = backgroundColor;
|
||||
Style = fontStyle;
|
||||
Weight = fontWeight;
|
||||
}
|
||||
|
||||
public string Regex { get; set; }
|
||||
|
||||
public string Text { get; set; }
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool WholeWords { get; set; }
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool IgnoreCase { get; set; }
|
||||
|
||||
public FontStyle Style { get; set; }
|
||||
|
||||
public FontWeight Weight { get; set; }
|
||||
|
||||
public Regex CompiledRegex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (compiledRegex == null)
|
||||
{
|
||||
string regexpression = Regex;
|
||||
if (regexpression == null && Text != null)
|
||||
{
|
||||
regexpression = System.Text.RegularExpressions.Regex.Escape(Text);
|
||||
if (WholeWords)
|
||||
{
|
||||
regexpression = "\b" + regexpression + "\b";
|
||||
this.Text = text;
|
||||
this.FontColor = Layout.FromString(textColor);
|
||||
this.BackgroundColor = Layout.FromString(backgroundColor);
|
||||
this.FontStyle = fontStyle;
|
||||
this.FontWeight = fontWeight;
|
||||
}
|
||||
}
|
||||
|
||||
RegexOptions regexOptions = RegexOptions.Compiled;
|
||||
if (IgnoreCase)
|
||||
{
|
||||
regexOptions |= RegexOptions.IgnoreCase;
|
||||
}
|
||||
|
||||
compiledRegex = new Regex(regexpression, regexOptions);
|
||||
}
|
||||
|
||||
return compiledRegex;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue("Empty")]
|
||||
public string FontColor { get; set; }
|
||||
|
||||
[DefaultValue("Empty")]
|
||||
public string BackgroundColor { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
277
README.en.md
277
README.en.md
@@ -1,138 +1,167 @@
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-release.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||

|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
A simple and user-friendly Spine file viewer and exporter with multi-language support (Chinese/English/Japanese).
|
||||
Spine file viewer & exporter, also a dynamic wallpaper program supporting Spine animations.
|
||||
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Supports multiple versions of Spine files.
|
||||
* Batch open files via drag-and-drop or copy-paste.
|
||||
* Batch preview functionality.
|
||||
* List-based multi-skeleton viewing and render order management.
|
||||
* Batch adjustment of skeleton parameters using multi-selection.
|
||||
* Multi-track animation settings.
|
||||
* Skin and custom slot attachment settings.
|
||||
* Custom slot visibility settings.
|
||||
* Debug rendering support.
|
||||
* View/model/track time scale adjustment.
|
||||
* Track alpha blending parameter settings.
|
||||
* Fullscreen preview mode.
|
||||
* Export to single frame/image sequence/animated GIF/video formats.
|
||||
* Automatic resolution batch export.
|
||||
* FFmpeg custom export support.
|
||||
* Program parameter saving.
|
||||
* ...
|
||||
|
||||
### Supported Spine Versions
|
||||
|
||||
| Version | View & Export |
|
||||
| :-----: | :------------------: |
|
||||
| `2.1.x` | :white\_check\_mark: |
|
||||
| `3.4.x` | :white\_check\_mark: |
|
||||
| `3.5.x` | :white\_check\_mark: |
|
||||
| `3.6.x` | :white\_check\_mark: |
|
||||
| `3.7.x` | :white\_check\_mark: |
|
||||
| `3.8.x` | :white\_check\_mark: |
|
||||
| `4.0.x` | :white\_check\_mark: |
|
||||
| `4.1.x` | :white\_check\_mark: |
|
||||
| `4.2.x` | :white\_check\_mark: |
|
||||
| `4.3.x` | |
|
||||
|
||||
More versions under development \:rocket: \:rocket: \:rocket:
|
||||
|
||||
### Supported Export Formats
|
||||
|
||||
| Format | Use Case |
|
||||
| -------------- | ----------------------------------------------------------------------------- |
|
||||
| Single Frame | Generate high-resolution images of models; manually adjust the desired frame. |
|
||||
| Frame Sequence | Supports PNG format with transparency and lossless compression. |
|
||||
| GIF/Video | Export preview animations or common video formats. |
|
||||
| Custom Export | Supports arbitrary FFmpeg parameters for custom, complex export needs. |
|
||||
|
||||
## Installation
|
||||
|
||||
Download the compressed package from the [Release](https://github.com/ww-rm/SpineViewer/releases) page.
|
||||
|
||||
The software requires the [.NET Desktop Runtime 8.0.x](https://dotnet.microsoft.com/download/dotnet/8.0) to run.
|
||||
|
||||
Alternatively, download the package with the `SelfContained` suffix for standalone execution.
|
||||
|
||||
For exporting GIF/MP4 and other animation/video formats, FFmpeg must be installed and added to the system environment variables. Visit the [FFmpeg Windows download page](https://ffmpeg.org/download.html#build-windows) or download the latest version directly: [ffmpeg-release-full.7z](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z).
|
||||
|
||||
## Usage
|
||||
|
||||
### How to Change the Display Language
|
||||
|
||||
In the menu, go to "File" -> "Preferences..." -> "Language," select your desired language, and confirm the change.
|
||||
|
||||
### Basic Overview
|
||||
|
||||
The program is organized into a left-right layout:
|
||||
|
||||
* **Left Panel:** Functionality panel.
|
||||
* **Right Panel:** Preview display.
|
||||
|
||||
The left panel includes three sub-panels:
|
||||
|
||||
* **Browse:** Preview the content of a specified folder without importing files into the program. This panel allows generating `.webp` previews for models or importing selected models.
|
||||
* **Model:** Lists imported models for rendering. Parameters and rendering order can be adjusted here, along with other model-related functionalities.
|
||||
* **Display:** Adjust parameters for the right-side preview display.
|
||||
|
||||
Hover your mouse over buttons, labels, or input fields to see help text for most UI elements.
|
||||
|
||||
### Skeleton Import
|
||||
|
||||
Drag-and-drop or paste skeleton files/directories into the Model panel.
|
||||
|
||||
Alternatively, use the right-click menu in the Browse panel to import selected items.
|
||||
|
||||
### Content Adjustment
|
||||
|
||||
The Model panel supports right-click menus, some shortcuts, and batch adjustments of model parameters through multi-selection.
|
||||
|
||||
For preview display adjustments:
|
||||
|
||||
* **Left-click:** Select and drag models. Hold `Ctrl` for multi-selection, synchronized with the left-side list.
|
||||
* **Right-click:** Drag the entire display.
|
||||
* **Scroll wheel:** Zoom in/out. Hold `Ctrl` to scale selected models.
|
||||
* **Render selected-only mode:** In this mode, the preview only shows selected models, and selection status can only be changed via the left-side list.
|
||||
|
||||
The buttons below the preview display allow time adjustments, serving as a simple playback control.
|
||||
|
||||
### Content Export
|
||||
|
||||
Export follows the **WYSIWYG (What You See Is What You Get)** principle, meaning the preview display reflects the exported output.
|
||||
|
||||
Use the right-click menu in the Model panel to export selected items.
|
||||
|
||||
Key export parameters include:
|
||||
|
||||
* **Output folder:** Optional. When not specified, output is saved to the respective model folder; otherwise, all output is saved to the provided folder.
|
||||
* **Export single:** By default, each model is exported independently. Selecting "Export single" renders all selected models in a single frame, producing a unified output.
|
||||
* **Auto resolution:** Ignores the preview resolution and viewport parameters, exporting output at the actual size of the content. For animations/videos, the output matches the size required for full visibility.
|
||||
|
||||
### More Information
|
||||
|
||||
For detailed usage and documentation, see the [Wiki](https://github.com/ww-rm/SpineViewer/wiki). For usage questions or bug reports, submit an [Issue](https://github.com/ww-rm/SpineViewer/issues).
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
* [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
* [SFML.Net](https://github.com/SFML/SFML.Net)
|
||||
* [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
* [HandyControl](https://github.com/HandyOrg/HandyControl)
|
||||
* [NLog](https://github.com/NLog/NLog)
|
||||
* [SkiaSharp](https://github.com/mono/SkiaSharp)
|
||||
[https://github.com/user-attachments/assets/37b6b730-088a-4352-827a-c338127a16f0](https://github.com/user-attachments/assets/37b6b730-088a-4352-827a-c338127a16f0)
|
||||
|
||||
---
|
||||
|
||||
*If you find this project helpful, please give it a \:star: and share it with others! :)*
|
||||
## Features
|
||||
|
||||
- Supports multiple Spine file versions (`2.1.x; 3.4.x - 4.2.-`)
|
||||
- List-based multi-skeleton view with rendering order management
|
||||
- Supports multi-track animations
|
||||
- Supports skin/slot/attachment settings
|
||||
- Debug rendering support
|
||||
- Frame rate / model / track time scale adjustment
|
||||
- Track alpha blending control
|
||||
- Export single frame / GIF / video
|
||||
- Custom export via FFmpeg
|
||||
- Supports non-PNG texture formats
|
||||
- Desktop dynamic wallpaper with auto-start support
|
||||
- ......
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Download the compressed package from the [Releases](https://github.com/ww-rm/SpineViewer/releases) page.
|
||||
|
||||
The program requires the [.NET Desktop Runtime 8.0.x](https://dotnet.microsoft.com/download/dotnet/8.0) to be installed.
|
||||
|
||||
You can also download packages with the `SelfContained` suffix, which can run independently without additional installations.
|
||||
|
||||
Exporting GIF/MP4 or other animated/video formats requires **ffmpeg** installed locally and added to the system PATH. Download [FFmpeg for Windows](https://ffmpeg.org/download.html#build-windows) or the latest full build [ffmpeg-release-full.7z](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z).
|
||||
|
||||
---
|
||||
|
||||
## Changing Display Language
|
||||
|
||||
Currently, the program supports the following interface languages:
|
||||
|
||||
- `ZH` (Chinese)
|
||||
- `EN` (English)
|
||||
- `JA` (Japanese)
|
||||
|
||||
Change the language via the menu: **File → Preferences… → Language**, then confirm.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### Overview
|
||||
|
||||
The program uses a left-right layout: the left panel contains controls, the right panel displays the preview.
|
||||
|
||||
The left panel contains three sub-panels:
|
||||
|
||||
- **Models**: Lists imported and rendered models. Set model parameters, rendering order, and other model-related functions here.
|
||||
- **Browser**: Preview files in a folder without actually importing them. Generate WebP previews or import selected models.
|
||||
- **Canvas**: Set parameters for the right-side preview display.
|
||||
|
||||
Most buttons, labels, or input fields show help text on hover.
|
||||
|
||||
---
|
||||
|
||||
### Importing Skeletons
|
||||
|
||||
Drag-and-drop or paste skeleton files/folders directly into the **Models** panel.
|
||||
|
||||
Alternatively, use the right-click menu in the **Browser** panel to import selected items.
|
||||
|
||||
---
|
||||
|
||||
### Adjusting Content
|
||||
|
||||
The **Models** panel supports right-click menus, some hotkeys, and batch editing via multi-selection.
|
||||
|
||||
Mouse interactions in the preview panel:
|
||||
|
||||
- **Left click**: select and drag models. Hold `Ctrl` for multi-selection (synchronized with the model list).
|
||||
- **Right click**: drag the entire canvas.
|
||||
- **Mouse wheel**: zoom in/out. Hold `Ctrl` to scale selected models together, use `Shift` to switch zoom factor.
|
||||
- **Render selected only**: preview only the selected models, selection can only be changed via the left panel.
|
||||
|
||||
Playback controls below the preview allow time adjustment, acting as a simple player.
|
||||
|
||||
---
|
||||
|
||||
### Exporting Content
|
||||
|
||||
Right-click on models in the list to access export options.
|
||||
|
||||
Key export parameters:
|
||||
|
||||
- **Output folder**: Optional. If not provided, outputs go to each model’s folder. Otherwise, all outputs go to the specified folder.
|
||||
- **Single export**: Default exports each model separately. If enabled, all selected models are rendered together in one output.
|
||||
- **Auto resolution**: Ignores preview canvas resolution; exported resolution matches the actual size of content. For animations or videos, ensures full display of the animation.
|
||||
|
||||
---
|
||||
|
||||
### Dynamic Wallpaper
|
||||
|
||||
The dynamic wallpaper projects the current preview content to the desktop in real time.
|
||||
|
||||
Enable or disable via program preferences or the tray icon menu. Save workspace files to preserve model and canvas settings.
|
||||
|
||||
Auto-start with Windows can also be enabled, along with loading a specific workspace on startup.
|
||||
|
||||
---
|
||||
|
||||
### Command-line Tool
|
||||
|
||||
The project includes a CLI tool `SpineViewerCLI` for simple operations on a single model (querying parameters, exporting, etc.). Windows and Linux binaries are provided in Releases.
|
||||
|
||||
```bash
|
||||
$ SpineViewerCLI -h
|
||||
Description:
|
||||
Root Command
|
||||
|
||||
Usage:
|
||||
SpineViewerCLI [command] [options]
|
||||
|
||||
Options:
|
||||
-q, --quiet Suppress console logging (quiet mode).
|
||||
-?, -h, --help Show help and usage information
|
||||
--version Show version information
|
||||
|
||||
Commands:
|
||||
query <skel> Query information of single model
|
||||
preview <skel> Preview a model
|
||||
export <skel> Export single model
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### More
|
||||
|
||||
Detailed instructions and usage guides can be found in the [Wiki](https://github.com/ww-rm/SpineViewer/wiki).
|
||||
Report issues or bugs via [GitHub Issues](https://github.com/ww-rm/SpineViewer/issues).
|
||||
|
||||
---
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
- [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
- [SFML.Net](https://github.com/SFML/SFML.Net)
|
||||
- [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
- [HandyControl](https://github.com/HandyOrg/HandyControl)
|
||||
- [NLog](https://github.com/NLog/NLog)
|
||||
- [SkiaSharp](https://github.com/mono/SkiaSharp)
|
||||
- [Spectre.Console](https://github.com/spectreconsole/spectre.console)
|
||||
|
||||
---
|
||||
|
||||
*If you like this project, please give it a :star: and share it with others! :\)*
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
107
README.md
107
README.md
@@ -1,61 +1,34 @@
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-release.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||

|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
一个简单好用的 Spine 文件查看&导出程序, 支持中/英/日多语言界面.
|
||||
Spine 文件查看&导出程序, 同时也是支持 Spine 的动态壁纸程序.
|
||||
|
||||

|
||||

|
||||
|
||||
https://github.com/user-attachments/assets/37b6b730-088a-4352-827a-c338127a16f0
|
||||
|
||||
## 功能
|
||||
|
||||
- 支持多版本 spine 文件
|
||||
- 支持拖拽/复制粘贴批量打开文件
|
||||
- 支持批量预览
|
||||
- 支持多版本 spine 文件 (`2.1.x; 3.4.x - 4.2.x`)
|
||||
- 支持列表式多骨骼查看和渲染层级管理
|
||||
- 支持列表多选批量设置骨骼参数
|
||||
- 支持多轨道动画设置
|
||||
- 支持皮肤/自定义插槽附件设置
|
||||
- 支持自定义插槽可见性
|
||||
- 支持多轨道动画
|
||||
- 支持皮肤/插槽/附件设置
|
||||
- 支持调试渲染
|
||||
- 支持画面/模型/轨道时间倍速设置
|
||||
- 支持设置轨道 Alpha 混合参数
|
||||
- 支持全屏预览
|
||||
- 支持单帧/动图/视频文件导出
|
||||
- 支持自动分辨率批量导出
|
||||
- 支持 FFmpeg 自定义导出
|
||||
- 支持程序参数保存
|
||||
- 支持非 PNG 格式的纹理图片格式
|
||||
- 支持开机自启常驻动态壁纸
|
||||
- ......
|
||||
|
||||
### Spine 版本支持
|
||||
|
||||
| 版本 | 查看&导出 |
|
||||
| :---: | :---: |
|
||||
| `2.1.x` | :white_check_mark: |
|
||||
| `3.4.x` | :white_check_mark: |
|
||||
| `3.5.x` | :white_check_mark: |
|
||||
| `3.6.x` | :white_check_mark: |
|
||||
| `3.7.x` | :white_check_mark: |
|
||||
| `3.8.x` | :white_check_mark: |
|
||||
| `4.0.x` | :white_check_mark: |
|
||||
| `4.1.x` | :white_check_mark: |
|
||||
| `4.2.x` | :white_check_mark: |
|
||||
| `4.3.x` | |
|
||||
|
||||
更多版本正在施工 :rocket: :rocket: :rocket:
|
||||
|
||||
### 导出格式支持
|
||||
|
||||
| 导出格式 | 适用场景 |
|
||||
| --- | --- |
|
||||
| 单帧画面 | 支持生成高清模型画面图像, 可手动调节需要的一帧. |
|
||||
| 帧序列 | 支持 PNG 格式帧序列, 可保留透明通道且无损压缩. |
|
||||
| 动图/视频 | 可以生成预览动图或者常见格式视频. |
|
||||
| 自定义导出 | 除上述预设方案, 支持提供任意 FFmpeg 参数进行导出, 满足自定义复杂需求. |
|
||||
|
||||
## 安装
|
||||
|
||||
前往 [Release](https://github.com/ww-rm/SpineViewer/releases) 界面下载压缩包.
|
||||
@@ -66,20 +39,26 @@
|
||||
|
||||
导出 GIF/MP4 等动图/视频格式需要在本地安装 ffmpeg 命令行, 并且添加至环境变量, [点击前往 FFmpeg-Windows 下载页面](https://ffmpeg.org/download.html#build-windows), 也可以点这个下载最新版本 [ffmpeg-release-full.7z](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z).
|
||||
|
||||
## 修改显示语言
|
||||
|
||||
本项目目前支持以下界面显示语言:
|
||||
|
||||
- `ZH` (中文)
|
||||
- `EN` (English)
|
||||
- `JA` (日本語)
|
||||
|
||||
可以通过窗口菜单的 "文件" -> "首选项..." -> "语言", 选择你需要的语言并确认修改.
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 如何修改显示语言
|
||||
|
||||
窗口菜单的 "文件" -> "首选项..." -> "语言", 选择你需要的语言并确认修改.
|
||||
|
||||
### 基本介绍
|
||||
|
||||
程序大致是左右布局, 左侧是功能面板, 右侧是画面.
|
||||
|
||||
左侧有三个子面板, 分别是:
|
||||
|
||||
- **浏览**. 该面板用于预览指定文件夹的内容, 并没有真正导入文件到程序. 在该面板可以为模型生成 webp 格式的预览图, 或者导入选中的模型.
|
||||
- **模型**. 该面板记录导入并进行渲染的模型列表, 可以在这个面板设置与模型渲染相关的参数和渲染顺序, 以及一些与模型有关的功能.
|
||||
- **浏览**. 该面板用于预览指定文件夹的内容, 并没有真正导入文件到程序. 在该面板可以为模型生成 webp 格式的预览图, 或者导入选中的模型.
|
||||
- **画面**. 该面板用于设置右侧预览画面的参数.
|
||||
|
||||
绝大部分按钮或者标签或者输入框都可以通过鼠标指针悬停来获取帮助文本.
|
||||
@@ -98,16 +77,14 @@
|
||||
|
||||
- 左键可以选择和拖拽模型, 按下 `Ctrl` 键可以实现多选, 与左侧列表选择是联动的.
|
||||
- 右键对整体画面进行拖动.
|
||||
- 滚轮进行画面缩放, 按住 `Ctrl` 可以对选中的模型进行批量缩放.
|
||||
- 滚轮进行画面缩放, 按住 `Ctrl` 可以对选中的模型进行批量缩放, `Shift` 可以切换缩放倍数.
|
||||
- 仅渲染选中模式, 在该模式下, 预览画面仅包含被选中的模型, 并且只能通过左侧列表改变选中状态.
|
||||
|
||||
预览画面下方按钮支持对画面时间进行调整, 可以当作一个简易的播放器.
|
||||
|
||||
### 内容导出
|
||||
|
||||
导出遵循 "所见即所得" 原则, 即实时预览的画面就是你导出的画面.
|
||||
|
||||
在模型面板里, 右键菜单可以对选中项进行导出操作.
|
||||
在模型列表里, 右键单击选中的模型, 弹出菜单里可以对选中项执行导出操作.
|
||||
|
||||
导出有以下几个关键参数:
|
||||
|
||||
@@ -115,6 +92,37 @@
|
||||
- 导出单个. 默认是每个模型独立导出, 即对模型列表进行批量操作, 如果选择仅导出单个, 那么被导出的所有模型将在同一个画面上被渲染, 输出产物只有一份.
|
||||
- 自动分辨率. 该模式会忽略预览画面的分辨率和视区参数, 导出产物的分辨率与被导出内容的实际大小一致, 如果是动图或者视频则会与完整显示动画的必需大小一致.
|
||||
|
||||
### 动态壁纸
|
||||
|
||||
动态壁纸通过桌面投影实现, 可以将当前预览画面上的内容实时投影至桌面.
|
||||
|
||||
在程序首选项或者托盘图标右键菜单中可以进行桌面投影的启用与否, 模型和画面参数调整完成后, 可以将当前参数保存为工作区文件, 方便之后恢复该配置.
|
||||
|
||||
如果希望开机自启常驻壁纸, 也可以在首选项中启用开机自启, 并且设置启动后需要加载的工作区文件.
|
||||
|
||||
### 命令行工具
|
||||
|
||||
项目附带一个纯命令行工具 `SpineViewerCLI`, 目前支持对单个模型执行一些简单操作, 例如参数值查询以及导出等, 并且 Release 界面提供 Windows 和 Linux 多平台二进制文件.
|
||||
|
||||
```bash
|
||||
$ SpineViewerCLI -h
|
||||
Description:
|
||||
Root Command
|
||||
|
||||
Usage:
|
||||
SpineViewerCLI [command] [options]
|
||||
|
||||
Options:
|
||||
-q, --quiet Suppress console logging (quiet mode).
|
||||
-?, -h, --help Show help and usage information
|
||||
--version Show version information
|
||||
|
||||
Commands:
|
||||
query <skel> Query information of single model
|
||||
preview <skel> Preview a model
|
||||
export <skel> Export single model
|
||||
```
|
||||
|
||||
### 更多
|
||||
|
||||
更为详细的使用方法和说明见 [Wiki](https://github.com/ww-rm/SpineViewer/wiki), 有使用上的问题或者 BUG 可以提个 [Issue](https://github.com/ww-rm/SpineViewer/issues).
|
||||
@@ -127,9 +135,10 @@
|
||||
- [HandyControl](https://github.com/HandyOrg/HandyControl)
|
||||
- [NLog](https://github.com/NLog/NLog)
|
||||
- [SkiaSharp](https://github.com/mono/SkiaSharp)
|
||||
- [Spectre.Console](https://github.com/spectreconsole/spectre.console)
|
||||
|
||||
---
|
||||
|
||||
*如果你觉得这个项目不错请给个 :star:, 并分享给更多人知道! :)*
|
||||
*如果你觉得这个项目不错请给个 :star:, 并分享给更多人知道! :\)*
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
@@ -64,10 +64,10 @@ namespace SFMLRenderer
|
||||
hs?.Dispose();
|
||||
}
|
||||
|
||||
private nint HwndMessageHook(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled)
|
||||
private IntPtr HwndMessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
_renderWindow?.DispatchEvents();
|
||||
return nint.Zero;
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +240,8 @@ namespace SFMLRenderer
|
||||
if (RenderWindow is null) return;
|
||||
float parentW = (float)sizeInfo.NewSize.Width;
|
||||
float parentH = (float)sizeInfo.NewSize.Height;
|
||||
float renderW = (float)_hwndHost.ActualWidth;
|
||||
float renderH = (float)_hwndHost.ActualHeight;
|
||||
float renderW = _resolution.X;
|
||||
float renderH = _resolution.Y;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
180
SFMLRenderer/SFMLRenderWindow.cs
Normal file
180
SFMLRenderer/SFMLRenderWindow.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using SFML.Graphics;
|
||||
using SFML.System;
|
||||
using SFML.Window;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SFMLRenderer
|
||||
{
|
||||
public class SFMLRenderWindow : RenderWindow, ISFMLRenderer
|
||||
{
|
||||
private readonly DispatcherTimer _timer = new() { Interval = TimeSpan.FromMilliseconds(10) };
|
||||
|
||||
public SFMLRenderWindow(VideoMode mode, string title, Styles style) : base(mode, title, style)
|
||||
{
|
||||
SetActive(false);
|
||||
_timer.Tick += (s, e) => DispatchEvents();
|
||||
_timer.Start();
|
||||
|
||||
SetVisible(false);
|
||||
|
||||
var handle = SystemHandle;
|
||||
var exStyle = User32.GetWindowLong(handle, User32.GWL_EXSTYLE) | User32.WS_EX_LAYERED;
|
||||
User32.SetWindowLong(handle, User32.GWL_EXSTYLE, exStyle);
|
||||
User32.SetLayeredWindowAttributes(handle, 0, byte.MaxValue, User32.LWA_ALPHA);
|
||||
|
||||
RendererCreated?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler? RendererCreated;
|
||||
|
||||
public event EventHandler? RendererDisposing
|
||||
{
|
||||
add => throw new NotImplementedException();
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public event EventHandler<MouseMoveEventArgs>? CanvasMouseMove
|
||||
{
|
||||
add { MouseMoved += value; }
|
||||
remove { MouseMoved -= value; }
|
||||
}
|
||||
|
||||
public event EventHandler<MouseButtonEventArgs>? CanvasMouseButtonPressed
|
||||
{
|
||||
add { MouseButtonPressed += value; }
|
||||
remove { MouseButtonPressed -= value; }
|
||||
}
|
||||
|
||||
public event EventHandler<MouseButtonEventArgs>? CanvasMouseButtonReleased
|
||||
{
|
||||
add { MouseButtonReleased += value; }
|
||||
remove { MouseButtonReleased -= value; }
|
||||
}
|
||||
|
||||
public event EventHandler<MouseWheelScrollEventArgs>? CanvasMouseWheelScrolled
|
||||
{
|
||||
add { MouseWheelScrolled += value; }
|
||||
remove { MouseWheelScrolled -= value; }
|
||||
}
|
||||
|
||||
public Vector2u Resolution
|
||||
{
|
||||
get => Size;
|
||||
set => Size = value;
|
||||
}
|
||||
|
||||
public Vector2f Center
|
||||
{
|
||||
get
|
||||
{
|
||||
using var view = GetView();
|
||||
return view.Center;
|
||||
}
|
||||
set
|
||||
{
|
||||
using var view = GetView();
|
||||
view.Center = value;
|
||||
SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public float Zoom
|
||||
{
|
||||
get
|
||||
{
|
||||
using var view = GetView();
|
||||
return Math.Abs(Size.X / view.Size.X); // XXX: 仅使用宽度进行缩放计算
|
||||
}
|
||||
set
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
if (value <= 0) return;
|
||||
using var view = GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
var resolution = Size;
|
||||
view.Size = new(resolution.X / value * signX, resolution.Y / value * signY);
|
||||
SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public float Rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
using var view = GetView();
|
||||
return view.Rotation;
|
||||
}
|
||||
set
|
||||
{
|
||||
using var view = GetView();
|
||||
view.Rotation = value;
|
||||
SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FlipX
|
||||
{
|
||||
get
|
||||
{
|
||||
using var view = GetView();
|
||||
return view.Size.X < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
using var view = GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FlipY
|
||||
{
|
||||
get
|
||||
{
|
||||
using var view = GetView();
|
||||
return view.Size.Y < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
using var view = GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
public uint MaxFps
|
||||
{
|
||||
get => _maxFps;
|
||||
set
|
||||
{
|
||||
SetFramerateLimit(value);
|
||||
_maxFps = value;
|
||||
}
|
||||
}
|
||||
private uint _maxFps = 0;
|
||||
|
||||
public bool VerticalSync
|
||||
{
|
||||
get => _verticalSync;
|
||||
set
|
||||
{
|
||||
SetVerticalSyncEnabled(value);
|
||||
_verticalSync = value;
|
||||
}
|
||||
}
|
||||
private bool _verticalSync = false;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,11 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.15.4</Version>
|
||||
<Version>0.16.6</Version>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -19,4 +20,8 @@
|
||||
<PackageReference Include="SFML.Net" Version="2.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Win32Natives\Win32Natives.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Error("Failed to export {0} {1}, {2}", _format, output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
using SFML.Graphics;
|
||||
using SFML.System;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
namespace Spine.Exporters
|
||||
{
|
||||
public static class SFMLExtension
|
||||
public static class Extension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
@@ -59,25 +55,5 @@ namespace SpineViewer.Extensions
|
||||
self.Size.Y
|
||||
);
|
||||
}
|
||||
|
||||
public static FloatRect ToFloatRect(this Rect self)
|
||||
{
|
||||
return new((float)self.X, (float)self.Y, (float)self.Width, (float)self.Height);
|
||||
}
|
||||
|
||||
public static Vector2f ToVector2f(this Size self)
|
||||
{
|
||||
return new((float)self.Width, (float)self.Height);
|
||||
}
|
||||
|
||||
public static Vector2u ToVector2u(this Size self)
|
||||
{
|
||||
return new((uint)self.Width, (uint)self.Height);
|
||||
}
|
||||
|
||||
public static Vector2i ToVector2i(this Size self)
|
||||
{
|
||||
return new((int)self.Width, (int)self.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,12 +28,40 @@ namespace Spine.Exporters
|
||||
{
|
||||
Gif,
|
||||
Webp,
|
||||
Apng,
|
||||
Mp4,
|
||||
Webm,
|
||||
Mkv,
|
||||
Mov,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apng 格式预测器算法
|
||||
/// </summary>
|
||||
public enum ApngPredMethod
|
||||
{
|
||||
None = 0,
|
||||
Sub = 1,
|
||||
Up = 2,
|
||||
Avg = 3,
|
||||
Paeth = 4,
|
||||
Mixed = 5,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mov prores_ks 编码器 profile 参数
|
||||
/// </summary>
|
||||
public enum MovProfile
|
||||
{
|
||||
Auto = -1,
|
||||
Proxy = 0,
|
||||
Light = 1,
|
||||
Standard = 2,
|
||||
High = 3,
|
||||
Yuv4444 = 4,
|
||||
Yuv4444Extreme = 5,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视频格式
|
||||
/// </summary>
|
||||
@@ -41,34 +69,40 @@ namespace Spine.Exporters
|
||||
private VideoFormat _format = VideoFormat.Mp4;
|
||||
|
||||
/// <summary>
|
||||
/// 动图是否循环 [Gif/Webp]
|
||||
/// [Gif/Webp/Apng] 动图是否循环
|
||||
/// </summary>
|
||||
public bool Loop { get => _loop; set => _loop = value; }
|
||||
private bool _loop = true;
|
||||
|
||||
/// <summary>
|
||||
/// 质量 [Webp]
|
||||
/// [Webp] 质量
|
||||
/// </summary>
|
||||
public int Quality { get => _quality; set => _quality = Math.Clamp(value, 0, 100); }
|
||||
private int _quality = 75;
|
||||
|
||||
/// <summary>
|
||||
/// 无损压缩 [Webp]
|
||||
/// [Webp] 无损压缩
|
||||
/// </summary>
|
||||
public bool Lossless { get => _lossless; set => _lossless = value; }
|
||||
private bool _lossless = false;
|
||||
|
||||
/// <summary>
|
||||
/// CRF [Mp4/Webm/Mkv]
|
||||
/// [Apng] 预测器算法
|
||||
/// </summary>
|
||||
public ApngPredMethod PredMethod { get => _predMethod; set => _predMethod = value; }
|
||||
private ApngPredMethod _predMethod = ApngPredMethod.Mixed;
|
||||
|
||||
/// <summary>
|
||||
/// [Mp4/Webm/Mkv] CRF
|
||||
/// </summary>
|
||||
public int Crf { get => _crf; set => _crf = Math.Clamp(value, 0, 63); }
|
||||
private int _crf = 23;
|
||||
|
||||
/// <summary>
|
||||
/// prores_ks 编码器的配置等级, -1 是自动, 越高质量越好, 只有 4 及以上才有透明通道 [Mov]
|
||||
/// [Mov] prores_ks 编码器的配置等级, 越高质量越好, 只有 <see cref="MovProfile.Yuv4444"> 及以上才有透明通道
|
||||
/// </summary>
|
||||
public int Profile { get => _profile; set => _profile = Math.Clamp(value, -1, 5); }
|
||||
private int _profile = 5;
|
||||
public MovProfile Profile { get => _profile; set => _profile = value; }
|
||||
private MovProfile _profile = MovProfile.Yuv4444Extreme;
|
||||
|
||||
/// <summary>
|
||||
/// 获取的一帧, 结果是预乘的
|
||||
@@ -93,6 +127,7 @@ namespace Spine.Exporters
|
||||
{
|
||||
VideoFormat.Gif => SetGifOptions,
|
||||
VideoFormat.Webp => SetWebpOptions,
|
||||
VideoFormat.Apng => SetApngOptions,
|
||||
VideoFormat.Mp4 => SetMp4Options,
|
||||
VideoFormat.Webm => SetWebmOptions,
|
||||
VideoFormat.Mkv => SetMkvOptions,
|
||||
@@ -109,7 +144,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Error("Failed to export {0} {1}, {2}", _format, output, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -132,6 +167,13 @@ namespace Spine.Exporters
|
||||
.WithCustomArgument(customArgs);
|
||||
}
|
||||
|
||||
private void SetApngOptions(FFMpegArgumentOptions options)
|
||||
{
|
||||
var customArgs = $"-vf unpremultiply=inplace=1 -plays {(_loop ? 0 : 1)} -pred {(int)_predMethod}";
|
||||
options.ForceFormat("apng").WithVideoCodec("apng").ForcePixelFormat("rgba")
|
||||
.WithCustomArgument(customArgs);
|
||||
}
|
||||
|
||||
private void SetMp4Options(FFMpegArgumentOptions options)
|
||||
{
|
||||
// XXX: windows 默认播放器在播放 MP4 格式时对于 libx264 编码器只支持 yuv420p 的像素格式
|
||||
@@ -164,7 +206,7 @@ namespace Spine.Exporters
|
||||
var customArgs = "-vf unpremultiply=inplace=1";
|
||||
options.ForceFormat("mov").WithVideoCodec("prores_ks").ForcePixelFormat("yuva444p10le")
|
||||
.WithFastStart()
|
||||
.WithCustomArgument($"-profile {_profile}")
|
||||
.WithCustomArgument($"-profile {(int)_profile}")
|
||||
.WithCustomArgument(customArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,27 @@ namespace Spine.Exporters
|
||||
public FrameExporter(uint width = 100, uint height = 100) : base(width, height) { }
|
||||
public FrameExporter(Vector2u resolution) : base(resolution) { }
|
||||
|
||||
public SKEncodedImageFormat Format { get => _format; set => _format = value; }
|
||||
public SKEncodedImageFormat Format
|
||||
{
|
||||
get => _format;
|
||||
set {
|
||||
switch (value)
|
||||
{
|
||||
case SKEncodedImageFormat.Jpeg:
|
||||
case SKEncodedImageFormat.Png:
|
||||
case SKEncodedImageFormat.Webp:
|
||||
_format = value;
|
||||
break;
|
||||
default:
|
||||
_logger.Warn("Omit unsupported exporter format: {0}", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected SKEncodedImageFormat _format = SKEncodedImageFormat.Png;
|
||||
|
||||
public int Quality { get => _quality; set => _quality = Math.Clamp(value, 0, 100); }
|
||||
protected int _quality = 80;
|
||||
protected int _quality = 100;
|
||||
|
||||
public override void Export(string output, params SpineObject[] spines)
|
||||
{
|
||||
@@ -33,5 +49,15 @@ namespace Spine.Exporters
|
||||
using var stream = File.OpenWrite(output);
|
||||
data.SaveTo(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取帧图像, 结果是预乘的
|
||||
/// </summary>
|
||||
public SKImage ExportMemoryImage(params SpineObject[] spines)
|
||||
{
|
||||
using var frame = GetFrame(spines);
|
||||
var info = new SKImageInfo(frame.Width, frame.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
return SKImage.FromPixelCopy(info, frame.Image.Pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Spine.Exporters
|
||||
int frameCount = GetFrameCount();
|
||||
int frameIdx = 0;
|
||||
|
||||
_progressReporter?.Invoke(frameCount, 0, $"[{frameIdx}/{frameCount}] {output}");
|
||||
_progressReporter?.Invoke(frameCount, 0, $"[0/{frameCount}] {output}"); // 导出帧序列单独在此处调用进度报告
|
||||
foreach (var frame in GetFrames(spines))
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
@@ -37,7 +37,7 @@ namespace Spine.Exporters
|
||||
var savePath = Path.Combine(output, $"frame_{_fps}_{frameIdx:d6}.png");
|
||||
var info = new SKImageInfo(frame.Width, frame.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
|
||||
_progressReporter?.Invoke(frameCount, frameIdx, $"[{frameIdx + 1}/{frameCount}] {savePath}");
|
||||
_progressReporter?.Invoke(frameCount, frameIdx + 1, $"[{frameIdx + 1}/{frameCount}] {savePath}");
|
||||
try
|
||||
{
|
||||
using var skImage = SKImage.FromPixelCopy(info, frame.Image.Pixels);
|
||||
@@ -47,7 +47,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Error("Failed to save frame {0}, {1}", savePath, ex.Message);
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成帧序列
|
||||
/// 生成帧序列, 用于导出帧序列
|
||||
/// </summary>
|
||||
protected IEnumerable<SFMLImageVideoFrame> GetFrames(SpineObject[] spines)
|
||||
{
|
||||
@@ -121,14 +121,14 @@ namespace Spine.Exporters
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成帧序列, 支持中途取消和进度输出
|
||||
/// 生成帧序列, 支持中途取消和进度输出, 用于动图视频等单个文件输出
|
||||
/// </summary>
|
||||
protected IEnumerable<SFMLImageVideoFrame> GetFrames(SpineObject[] spines, string output, CancellationToken ct)
|
||||
{
|
||||
int frameCount = GetFrameCount();
|
||||
int frameIdx = 0;
|
||||
|
||||
_progressReporter?.Invoke(frameCount, 0, $"[{frameIdx}/{frameCount}] {output}");
|
||||
_progressReporter?.Invoke(frameCount, 0, $"[0/{frameCount}] {output}");
|
||||
foreach (var frame in GetFrames(spines))
|
||||
{
|
||||
if (ct.IsCancellationRequested)
|
||||
@@ -138,7 +138,7 @@ namespace Spine.Exporters
|
||||
break;
|
||||
}
|
||||
|
||||
_progressReporter?.Invoke(frameCount, frameIdx, $"[{frameIdx + 1}/{frameCount}] {output}");
|
||||
_progressReporter?.Invoke(frameCount, frameIdx + 1, $"[{frameIdx + 1}/{frameCount}] {output}");
|
||||
yield return frame;
|
||||
frameIdx++;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using SFML.Graphics;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
namespace Spine.Implementations
|
||||
{
|
||||
/// <summary>
|
||||
/// 实现不同版本的 TextureLoader
|
||||
@@ -20,6 +23,8 @@ namespace Spine.SpineWrappers
|
||||
SpineRuntime41.TextureLoader,
|
||||
SpineRuntime42.TextureLoader
|
||||
{
|
||||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 默认的全局纹理加载器
|
||||
/// </summary>
|
||||
@@ -40,38 +45,39 @@ namespace Spine.SpineWrappers
|
||||
/// </summary>
|
||||
public bool ForceMipmap { get; set; }
|
||||
|
||||
private SFML.Graphics.Texture ReadTexture(string path)
|
||||
private Texture ReadTexture(string path)
|
||||
{
|
||||
if (ForcePremul)
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
using var image = new SFML.Graphics.Image(path);
|
||||
var width = image.Size.X;
|
||||
var height = image.Size.Y;
|
||||
var pixels = image.Pixels;
|
||||
var size = width * height * 4;
|
||||
for (int i = 0; i < size; i += 4)
|
||||
{
|
||||
byte a = pixels[i + 3];
|
||||
if (a == 0)
|
||||
{
|
||||
pixels[i + 0] = 0;
|
||||
pixels[i + 1] = 0;
|
||||
pixels[i + 2] = 0;
|
||||
_logger.Error($"Texture file not found, {path}");
|
||||
throw new FileNotFoundException("Texture file not found", path);
|
||||
}
|
||||
else if (a != 255)
|
||||
|
||||
using var codec = SKCodec.Create(path, out var result);
|
||||
if (codec is null || result != SKCodecResult.Success)
|
||||
{
|
||||
float f = a / 255f;
|
||||
pixels[i + 0] = (byte)(pixels[i + 0] * f);
|
||||
pixels[i + 1] = (byte)(pixels[i + 1] * f);
|
||||
pixels[i + 2] = (byte)(pixels[i + 2] * f);
|
||||
_logger.Error($"Failed to create codec '{path}', {result}");
|
||||
throw new InvalidOperationException($"Failed to create codec '{path}', {result}");
|
||||
}
|
||||
|
||||
var width = codec.Info.Width;
|
||||
var height = codec.Info.Height;
|
||||
|
||||
// 判断是否需要强制预乘
|
||||
var alphaType = ForcePremul ? SKAlphaType.Premul : SKAlphaType.Unpremul;
|
||||
var info = new SKImageInfo(width, height, SKColorType.Rgba8888, alphaType);
|
||||
|
||||
result = codec.GetPixels(info, out var pixels);
|
||||
if (result != SKCodecResult.Success)
|
||||
{
|
||||
_logger.Error($"Failed to decode image '{path}', {result}");
|
||||
throw new InvalidOperationException($"Failed to decode image '{path}', {result}");
|
||||
}
|
||||
var tex = new SFML.Graphics.Texture(width, height);
|
||||
|
||||
Texture tex = new((uint)width, (uint)height);
|
||||
tex.Update(pixels);
|
||||
return tex;
|
||||
}
|
||||
return new(path);
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime21.AtlasPage page, string path)
|
||||
{
|
||||
@@ -106,6 +112,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime34.AtlasPage page, string path)
|
||||
@@ -141,6 +155,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime35.AtlasPage page, string path)
|
||||
@@ -176,6 +198,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime36.AtlasPage page, string path)
|
||||
@@ -211,6 +241,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime37.AtlasPage page, string path)
|
||||
@@ -246,6 +284,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime38.AtlasPage page, string path)
|
||||
@@ -282,9 +328,13 @@ namespace Spine.SpineWrappers
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 似乎是不需要设置的, 因为存在某些 png 和 atlas 大小不同的情况, 一般是有一些缩放, 如果设置了反而渲染异常
|
||||
// page.width = (int)texture.Size.X;
|
||||
// page.height = (int)texture.Size.Y;
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime40.AtlasPage page, string path)
|
||||
@@ -320,6 +370,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime41.AtlasPage page, string path)
|
||||
@@ -355,6 +413,14 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load(SpineRuntime42.AtlasPage page, string path)
|
||||
@@ -390,11 +456,19 @@ namespace Spine.SpineWrappers
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 有些旧的 atlas 会省略 size 行, 这时需要在读取纹理时赋值
|
||||
if (page.width <= 0 || page.height <= 0)
|
||||
{
|
||||
var texSize = texture.Size;
|
||||
page.width = (int)texSize.X;
|
||||
page.height = (int)texSize.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
((Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime21;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class Animation21(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class AnimationState21(AnimationState innerObject, SpineObjectData21 data) : IAnimationState
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -64,7 +64,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -93,7 +93,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
namespace Spine.Implementations.V21.Attachments
|
||||
{
|
||||
internal abstract class Attachment21(Attachment innerObject) : IAttachment
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V21;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
namespace Spine.Implementations.V21.Attachments
|
||||
{
|
||||
internal sealed class BoundingBoxAttachment21(BoundingBoxAttachment innerObject) :
|
||||
Attachment21(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
|
||||
public override BoundingBoxAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot21 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V21;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
namespace Spine.Implementations.V21.Attachments
|
||||
{
|
||||
internal sealed class MeshAttachment21(MeshAttachment innerObject) :
|
||||
Attachment21(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
|
||||
public override MeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot21 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V21;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
namespace Spine.Implementations.V21.Attachments
|
||||
{
|
||||
internal sealed class RegionAttachment21(RegionAttachment innerObject) :
|
||||
Attachment21(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
|
||||
public override RegionAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot21 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V21;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
namespace Spine.Implementations.V21.Attachments
|
||||
{
|
||||
internal sealed class SkinnedMeshAttachment21(SkinnedMeshAttachment innerObject) :
|
||||
Attachment21(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V21.Attachments
|
||||
|
||||
public override SkinnedMeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot21 st)
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class Bone21(Bone innerObject, Bone21? parent = null) : IBone
|
||||
{
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime21;
|
||||
using Spine.Interfaces;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class Skeleton21 : ISkeleton
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
|
||||
public Skeleton InnerObject => _o;
|
||||
|
||||
public string Name => _o.Data.Name;
|
||||
public float R { get => _o.R; set => _o.R = value; }
|
||||
public float G { get => _o.G; set => _o.G = value; }
|
||||
public float B { get => _o.B; set => _o.B = value; }
|
||||
@@ -95,11 +96,6 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
public void SetSlotsToSetupPose() => _o.SetSlotsToSetupPose();
|
||||
public void Update(float delta) => _o.Update(delta);
|
||||
|
||||
public void GetBounds(out float x, out float y, out float w, out float h)
|
||||
{
|
||||
_o.GetBounds(out x, out y, out w, out h);
|
||||
}
|
||||
|
||||
public override string ToString() => _o.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using Spine.Utils;
|
||||
using SpineRuntime21;
|
||||
using System;
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class SkeletonClipping21 : ISkeletonClipping
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class Skin21 : ISkin
|
||||
{
|
||||
@@ -5,10 +5,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime21;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class Slot21 : ISlot
|
||||
{
|
||||
@@ -39,7 +40,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
public float A { get => _o.A; set => _o.A = value; }
|
||||
public IBone Bone => _bone;
|
||||
|
||||
public Spine.SpineWrappers.Attachments.IAttachment? Attachment
|
||||
public IAttachment? Attachment
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -6,12 +6,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using SpineRuntime21;
|
||||
using Spine.Implementations.SpineWrappers.V21.Attachments;
|
||||
using Spine.Implementations.V21.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
[SpineImplementation(2, 1)]
|
||||
internal sealed class SpineObjectData21 : SpineObjectData
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
private readonly ImmutableArray<IAnimation> _animations;
|
||||
private readonly FrozenDictionary<string, IAnimation> _animationsByName;
|
||||
|
||||
public SpineObjectData21(string skelPath, string atlasPath, Spine.SpineWrappers.TextureLoader textureLoader)
|
||||
public SpineObjectData21(string skelPath, string atlasPath, TextureLoader textureLoader)
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime21;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V21
|
||||
namespace Spine.Implementations.V21
|
||||
{
|
||||
internal sealed class TrackEntry21(TrackEntry innerObject, AnimationState21 animationState, SpineObjectData21 data): ITrackEntry
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -63,7 +63,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -92,7 +92,7 @@ namespace Spine.Implementations.SpineWrappers.V21
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime34;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class Animation34(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class AnimationState34(AnimationState innerObject, SpineObjectData34 data) : IAnimationState
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -65,7 +65,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -94,7 +94,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
namespace Spine.Implementations.V34.Attachments
|
||||
{
|
||||
internal abstract class Attachment34(Attachment innerObject) : IAttachment
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V34;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
namespace Spine.Implementations.V34.Attachments
|
||||
{
|
||||
internal sealed class BoundingBoxAttachment34(BoundingBoxAttachment innerObject) :
|
||||
Attachment34(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
|
||||
public override BoundingBoxAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot34 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V34;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
namespace Spine.Implementations.V34.Attachments
|
||||
{
|
||||
internal sealed class MeshAttachment34(MeshAttachment innerObject) :
|
||||
Attachment34(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
|
||||
public override MeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot34 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V34;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
namespace Spine.Implementations.V34.Attachments
|
||||
{
|
||||
internal sealed class PathAttachment34(PathAttachment innerObject) :
|
||||
Attachment34(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
|
||||
public override PathAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot34 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V34;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
namespace Spine.Implementations.V34.Attachments
|
||||
{
|
||||
internal sealed class RegionAttachment34(RegionAttachment innerObject) :
|
||||
Attachment34(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V34.Attachments
|
||||
|
||||
public override RegionAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot34 st)
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class Bone34(Bone innerObject, Bone34? parent = null) : IBone
|
||||
{
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime34;
|
||||
using Spine.Interfaces;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class Skeleton34 : ISkeleton
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
|
||||
public Skeleton InnerObject => _o;
|
||||
|
||||
public string Name => _o.Data.Name;
|
||||
public float R { get => _o.R; set => _o.R = value; }
|
||||
public float G { get => _o.G; set => _o.G = value; }
|
||||
public float B { get => _o.B; set => _o.B = value; }
|
||||
@@ -95,12 +96,6 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
public void SetSlotsToSetupPose() => _o.SetSlotsToSetupPose();
|
||||
public void Update(float delta) => _o.Update(delta);
|
||||
|
||||
public void GetBounds(out float x, out float y, out float w, out float h)
|
||||
{
|
||||
float[] _ = [];
|
||||
_o.GetBounds(out x, out y, out w, out h);
|
||||
}
|
||||
|
||||
public override string ToString() => _o.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using Spine.Utils;
|
||||
using SpineRuntime34;
|
||||
using System;
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class SkeletonClipping34 : ISkeletonClipping
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime34;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class Skin34 : ISkin
|
||||
{
|
||||
@@ -5,10 +5,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime34;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class Slot34 : ISlot
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
public float A { get => _o.A; set => _o.A = value; }
|
||||
public IBone Bone => _bone;
|
||||
|
||||
public Spine.SpineWrappers.Attachments.IAttachment? Attachment
|
||||
public IAttachment? Attachment
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -6,12 +6,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using SpineRuntime34;
|
||||
using Spine.Implementations.SpineWrappers.V34.Attachments;
|
||||
using Spine.Implementations.V34.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
[SpineImplementation(3, 4)]
|
||||
internal sealed class SpineObjectData34 : SpineObjectData
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
private readonly ImmutableArray<IAnimation> _animations;
|
||||
private readonly FrozenDictionary<string, IAnimation> _animationsByName;
|
||||
|
||||
public SpineObjectData34(string skelPath, string atlasPath, Spine.SpineWrappers.TextureLoader textureLoader)
|
||||
public SpineObjectData34(string skelPath, string atlasPath, TextureLoader textureLoader)
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime34;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V34
|
||||
namespace Spine.Implementations.V34
|
||||
{
|
||||
internal sealed class TrackEntry34(TrackEntry innerObject, AnimationState34 animationState, SpineObjectData34 data): ITrackEntry
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -63,7 +63,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -92,7 +92,7 @@ namespace Spine.Implementations.SpineWrappers.V34
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime35;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class Animation35(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class AnimationState35(AnimationState innerObject, SpineObjectData35 data) : IAnimationState
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -56,7 +56,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -85,7 +85,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -114,7 +114,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -143,7 +143,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal abstract class Attachment35(Attachment innerObject) : IAttachment
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class BoundingBoxAttachment35(BoundingBoxAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override BoundingBoxAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class ClippingAttachment35(ClippingAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override ClippingAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class MeshAttachment35(MeshAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override MeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class PathAttachment35(PathAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override PathAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class PointAttachment35(PointAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override PointAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
namespace Spine.Implementations.V35.Attachments
|
||||
{
|
||||
internal sealed class RegionAttachment35(RegionAttachment innerObject) :
|
||||
Attachment35(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V35.Attachments
|
||||
|
||||
public override RegionAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot35 st)
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class Bone35(Bone innerObject, Bone35? parent = null) : IBone
|
||||
{
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime35;
|
||||
using Spine.Interfaces;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class Skeleton35 : ISkeleton
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
|
||||
public Skeleton InnerObject => _o;
|
||||
|
||||
public string Name => _o.Data.Name;
|
||||
public float R { get => _o.R; set => _o.R = value; }
|
||||
public float G { get => _o.G; set => _o.G = value; }
|
||||
public float B { get => _o.B; set => _o.B = value; }
|
||||
@@ -95,12 +96,6 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
public void SetSlotsToSetupPose() => _o.SetSlotsToSetupPose();
|
||||
public void Update(float delta) => _o.Update(delta);
|
||||
|
||||
public void GetBounds(out float x, out float y, out float w, out float h)
|
||||
{
|
||||
float[] _ = [];
|
||||
_o.GetBounds(out x, out y, out w, out h, ref _);
|
||||
}
|
||||
|
||||
public override string ToString() => _o.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using Spine.Utils;
|
||||
using SpineRuntime35;
|
||||
using System;
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class SkeletonClipping35 : ISkeletonClipping
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime35;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class Skin35 : ISkin
|
||||
{
|
||||
@@ -5,10 +5,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime35;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class Slot35 : ISlot
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
public float A { get => _o.A; set => _o.A = value; }
|
||||
public IBone Bone => _bone;
|
||||
|
||||
public Spine.SpineWrappers.Attachments.IAttachment? Attachment
|
||||
public IAttachment? Attachment
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -6,12 +6,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using SpineRuntime35;
|
||||
using Spine.Implementations.SpineWrappers.V35.Attachments;
|
||||
using Spine.Implementations.V35.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
[SpineImplementation(3, 5)]
|
||||
internal sealed class SpineObjectData35 : SpineObjectData
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
private readonly ImmutableArray<IAnimation> _animations;
|
||||
private readonly FrozenDictionary<string, IAnimation> _animationsByName;
|
||||
|
||||
public SpineObjectData35(string skelPath, string atlasPath, Spine.SpineWrappers.TextureLoader textureLoader)
|
||||
public SpineObjectData35(string skelPath, string atlasPath, TextureLoader textureLoader)
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime35;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V35
|
||||
namespace Spine.Implementations.V35
|
||||
{
|
||||
internal sealed class TrackEntry35(TrackEntry innerObject, AnimationState35 animationState, SpineObjectData35 data): ITrackEntry
|
||||
{
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -55,7 +55,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -84,7 +84,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -113,7 +113,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -142,7 +142,7 @@ namespace Spine.Implementations.SpineWrappers.V35
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime36;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class Animation36(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class AnimationState36(AnimationState innerObject, SpineObjectData36 data) : IAnimationState
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -56,7 +56,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -85,7 +85,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -114,7 +114,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -143,7 +143,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal abstract class Attachment36(Attachment innerObject) : IAttachment
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class BoundingBoxAttachment36(BoundingBoxAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override BoundingBoxAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class ClippingAttachment36(ClippingAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override ClippingAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class MeshAttachment36(MeshAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override MeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class PathAttachment36(PathAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override PathAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class PointAttachment36(PointAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override PointAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
namespace Spine.Implementations.V36.Attachments
|
||||
{
|
||||
internal sealed class RegionAttachment36(RegionAttachment innerObject) :
|
||||
Attachment36(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V36.Attachments
|
||||
|
||||
public override RegionAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot36 st)
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class Bone36(Bone innerObject, Bone36? parent = null) : IBone
|
||||
{
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime36;
|
||||
using Spine.Interfaces;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class Skeleton36 : ISkeleton
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
|
||||
public Skeleton InnerObject => _o;
|
||||
|
||||
public string Name => _o.Data.Name;
|
||||
public float R { get => _o.R; set => _o.R = value; }
|
||||
public float G { get => _o.G; set => _o.G = value; }
|
||||
public float B { get => _o.B; set => _o.B = value; }
|
||||
@@ -95,12 +96,6 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
public void SetSlotsToSetupPose() => _o.SetSlotsToSetupPose();
|
||||
public void Update(float delta) => _o.Update(delta);
|
||||
|
||||
public void GetBounds(out float x, out float y, out float w, out float h)
|
||||
{
|
||||
float[] _ = [];
|
||||
_o.GetBounds(out x, out y, out w, out h, ref _);
|
||||
}
|
||||
|
||||
public override string ToString() => _o.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using Spine.Utils;
|
||||
using SpineRuntime36;
|
||||
using System;
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class SkeletonClipping36 : ISkeletonClipping
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class Skin36 : ISkin
|
||||
{
|
||||
@@ -5,10 +5,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime36;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class Slot36 : ISlot
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
public float A { get => _o.A; set => _o.A = value; }
|
||||
public IBone Bone => _bone;
|
||||
|
||||
public Spine.SpineWrappers.Attachments.IAttachment? Attachment
|
||||
public IAttachment? Attachment
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -6,12 +6,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using SpineRuntime36;
|
||||
using Spine.Implementations.SpineWrappers.V36.Attachments;
|
||||
using Spine.Implementations.V36.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
[SpineImplementation(3, 6)]
|
||||
internal sealed class SpineObjectData36 : SpineObjectData
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
private readonly ImmutableArray<IAnimation> _animations;
|
||||
private readonly FrozenDictionary<string, IAnimation> _animationsByName;
|
||||
|
||||
public SpineObjectData36(string skelPath, string atlasPath, Spine.SpineWrappers.TextureLoader textureLoader)
|
||||
public SpineObjectData36(string skelPath, string atlasPath, TextureLoader textureLoader)
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime36;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V36
|
||||
namespace Spine.Implementations.V36
|
||||
{
|
||||
internal sealed class TrackEntry36(TrackEntry innerObject, AnimationState36 animationState, SpineObjectData36 data): ITrackEntry
|
||||
{
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -55,7 +55,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -84,7 +84,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -113,7 +113,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -142,7 +142,7 @@ namespace Spine.Implementations.SpineWrappers.V36
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime37;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class Animation37(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class AnimationState37(AnimationState innerObject, SpineObjectData37 data) : IAnimationState
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -56,7 +56,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -85,7 +85,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -114,7 +114,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -143,7 +143,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -3,11 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal abstract class Attachment37(Attachment innerObject) : IAttachment
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class BoundingBoxAttachment37(BoundingBoxAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override BoundingBoxAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class ClippingAttachment37(ClippingAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override ClippingAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class MeshAttachment37(MeshAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override MeshAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class PathAttachment37(PathAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override PathAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class PointAttachment37(PointAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override PointAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Implementations.V37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
namespace Spine.Implementations.V37.Attachments
|
||||
{
|
||||
internal sealed class RegionAttachment37(RegionAttachment innerObject) :
|
||||
Attachment37(innerObject),
|
||||
@@ -16,7 +18,7 @@ namespace Spine.Implementations.SpineWrappers.V37.Attachments
|
||||
|
||||
public override RegionAttachment InnerObject => _o;
|
||||
|
||||
public override int ComputeWorldVertices(Spine.SpineWrappers.ISlot slot, ref float[] worldVertices)
|
||||
public override int ComputeWorldVertices(ISlot slot, ref float[] worldVertices)
|
||||
{
|
||||
if (slot is Slot37 st)
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class Bone37(Bone innerObject, Bone37? parent = null) : IBone
|
||||
{
|
||||
@@ -5,10 +5,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Immutable;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime37;
|
||||
using Spine.Interfaces;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class Skeleton37 : ISkeleton
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
|
||||
public Skeleton InnerObject => _o;
|
||||
|
||||
public string Name => _o.Data.Name;
|
||||
public float R { get => _o.R; set => _o.R = value; }
|
||||
public float G { get => _o.G; set => _o.G = value; }
|
||||
public float B { get => _o.B; set => _o.B = value; }
|
||||
@@ -95,12 +96,6 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
public void SetSlotsToSetupPose() => _o.SetSlotsToSetupPose();
|
||||
public void Update(float delta) => _o.Update(delta);
|
||||
|
||||
public void GetBounds(out float x, out float y, out float w, out float h)
|
||||
{
|
||||
float[] _ = [];
|
||||
_o.GetBounds(out x, out y, out w, out h, ref _);
|
||||
}
|
||||
|
||||
public override string ToString() => _o.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using Spine.Utils;
|
||||
using SpineRuntime37;
|
||||
using System;
|
||||
@@ -8,7 +8,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class SkeletonClipping37 : ISkeletonClipping
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class Skin37 : ISkin
|
||||
{
|
||||
@@ -5,10 +5,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using SpineRuntime37;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class Slot37 : ISlot
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
public float A { get => _o.A; set => _o.A = value; }
|
||||
public IBone Bone => _bone;
|
||||
|
||||
public Spine.SpineWrappers.Attachments.IAttachment? Attachment
|
||||
public IAttachment? Attachment
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -6,12 +6,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.Utils;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using SpineRuntime37;
|
||||
using Spine.Implementations.SpineWrappers.V37.Attachments;
|
||||
using Spine.Implementations.V37.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
[SpineImplementation(3, 7)]
|
||||
internal sealed class SpineObjectData37 : SpineObjectData
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
private readonly ImmutableArray<IAnimation> _animations;
|
||||
private readonly FrozenDictionary<string, IAnimation> _animationsByName;
|
||||
|
||||
public SpineObjectData37(string skelPath, string atlasPath, Spine.SpineWrappers.TextureLoader textureLoader)
|
||||
public SpineObjectData37(string skelPath, string atlasPath, TextureLoader textureLoader)
|
||||
: base(skelPath, atlasPath, textureLoader)
|
||||
{
|
||||
// 加载 atlas
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Debug(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime37;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V37
|
||||
namespace Spine.Implementations.V37
|
||||
{
|
||||
internal sealed class TrackEntry37(TrackEntry innerObject, AnimationState37 animationState, SpineObjectData37 data): ITrackEntry
|
||||
{
|
||||
@@ -26,7 +26,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -55,7 +55,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -84,7 +84,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -113,7 +113,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -142,7 +142,7 @@ namespace Spine.Implementations.SpineWrappers.V37
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(_animationState.GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -1,4 +1,4 @@
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime38;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -6,7 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V38
|
||||
namespace Spine.Implementations.V38
|
||||
{
|
||||
internal sealed class Animation38(Animation innerObject) : IAnimation
|
||||
{
|
||||
@@ -3,10 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.Interfaces;
|
||||
using SpineRuntime38;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V38
|
||||
namespace Spine.Implementations.V38
|
||||
{
|
||||
internal sealed class AnimationState38(AnimationState innerObject, SpineObjectData38 data) : IAnimationState
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Start += f;
|
||||
@@ -56,7 +56,7 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Interrupt += f;
|
||||
@@ -85,7 +85,7 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.End += f;
|
||||
@@ -114,7 +114,7 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Complete += f;
|
||||
@@ -143,7 +143,7 @@ namespace Spine.Implementations.SpineWrappers.V38
|
||||
if (value is null) return;
|
||||
if (!_eventMapping.TryGetValue(value, out var f))
|
||||
{
|
||||
_eventMapping[value] = f = (TrackEntry t) => value(GetTrackEntry(t));
|
||||
_eventMapping[value] = f = (t) => value(GetTrackEntry(t));
|
||||
_eventCount[value] = 0;
|
||||
}
|
||||
_o.Dispose += f;
|
||||
@@ -3,12 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using Spine.Interfaces;
|
||||
using Spine.Interfaces.Attachments;
|
||||
using SpineRuntime38;
|
||||
using SpineRuntime38.Attachments;
|
||||
|
||||
namespace Spine.Implementations.SpineWrappers.V38.Attachments
|
||||
namespace Spine.Implementations.V38.Attachments
|
||||
{
|
||||
internal abstract class Attachment38(Attachment innerObject) : IAttachment
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user