Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c6e98f5e1 | ||
|
|
ef06073119 | ||
|
|
bca8b0ad85 | ||
|
|
4983b1fa88 | ||
|
|
f6b6d9f0e7 | ||
|
|
12a168df92 |
@@ -1,5 +1,13 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.12.12
|
||||
|
||||
- 修复 2.1 版本遗漏的 SkinnedMeshAttachment 附件渲染
|
||||
|
||||
## v0.12.11
|
||||
|
||||
- 修复可能的闪退错误
|
||||
|
||||
## v0.12.10
|
||||
|
||||
- 增加纹理全局加载选项
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject21(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -70,6 +71,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
@@ -258,7 +260,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
//int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
@@ -272,7 +274,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
||||
worldVerticesCount = 4;
|
||||
//worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
@@ -288,7 +290,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
//worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
@@ -297,6 +299,22 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)skinnedMeshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
//worldVerticesCount = skinnedMeshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = skinnedMeshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = skinnedMeshAttachment.Triangles.Length;
|
||||
uvs = skinnedMeshAttachment.UVs;
|
||||
tintR *= skinnedMeshAttachment.R;
|
||||
tintG *= skinnedMeshAttachment.G;
|
||||
tintB *= skinnedMeshAttachment.B;
|
||||
tintA *= skinnedMeshAttachment.A;
|
||||
}
|
||||
// 2.1.x 不支持剪裁
|
||||
//else if (attachment is ClippingAttachment clippingAttachment)
|
||||
//{
|
||||
@@ -430,6 +448,37 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var triangleIndices = skinnedMeshAttachment.Triangles;
|
||||
for (int i = 0; i < triangleIndices.Length; i += 3)
|
||||
{
|
||||
var idx0 = triangleIndices[i] * 2;
|
||||
var idx1 = triangleIndices[i + 1] * 2;
|
||||
var idx2 = triangleIndices[i + 2] * 2;
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx1];
|
||||
vt.Position.Y = worldVerticesBuffer[idx1 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx2];
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
@@ -452,6 +501,34 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
var hullLength = (meshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < hullLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var hullLength = (skinnedMeshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject36(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -69,6 +70,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject37(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -66,6 +67,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -92,7 +94,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject38(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -70,6 +71,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}", ex);
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject40(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -68,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject41(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -68,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
|
||||
public SpineObject42(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
@@ -68,6 +69,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.12.10</Version>
|
||||
<Version>0.12.12</Version>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
||||
|
||||
Reference in New Issue
Block a user