更换为wpf
This commit is contained in:
24
Spine/SpineWrappers/Attachments/IAttachment.cs
Normal file
24
Spine/SpineWrappers/Attachments/IAttachment.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IAttachment
|
||||
{
|
||||
/// <summary>
|
||||
/// 附件的唯一名字
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 计算世界顶点数组
|
||||
/// </summary>
|
||||
/// <param name="slot">装载的插槽</param>
|
||||
/// <param name="worldVertices">顶点缓冲数组, 如果大小不足会重分配到合适的大小, 实际长度需要通过返回值获取</param>
|
||||
/// <returns><paramref name="worldVertices"/> 的实际长度, 顶点数是长度除以 2</returns>
|
||||
public int ComputeWorldVertices(ISlot slot, ref float[] worldVertices);
|
||||
}
|
||||
}
|
||||
13
Spine/SpineWrappers/Attachments/IBoundingBoxAttachment.cs
Normal file
13
Spine/SpineWrappers/Attachments/IBoundingBoxAttachment.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IBoundingBoxAttachment : IAttachment
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
13
Spine/SpineWrappers/Attachments/IClippingAttachment.cs
Normal file
13
Spine/SpineWrappers/Attachments/IClippingAttachment.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IClippingAttachment : IAttachment
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
51
Spine/SpineWrappers/Attachments/IMeshAttachment.cs
Normal file
51
Spine/SpineWrappers/Attachments/IMeshAttachment.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IMeshAttachment : IAttachment
|
||||
{
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
public float R { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
public float G { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
public float B { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
public float A { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于渲染的纹理对象
|
||||
/// </summary>
|
||||
public SFML.Graphics.Texture RendererObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 顶点纹理坐标, 每个坐标有 u 和 v 两个数, 有效长度和 <see cref="IAttachment.ComputeWorldVertices(ISlot, ref float[])"/> 返回值一致
|
||||
/// </summary>
|
||||
public float[] UVs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 三角形索引顶点数组, 每 3 个为一组, 指向顶点的下标 (不是顶点坐标数组下标)
|
||||
/// </summary>
|
||||
public int[] Triangles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 边缘顶点数组长度
|
||||
/// </summary>
|
||||
public int HullLength { get; }
|
||||
}
|
||||
}
|
||||
13
Spine/SpineWrappers/Attachments/IPathAttachment.cs
Normal file
13
Spine/SpineWrappers/Attachments/IPathAttachment.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IPathAttachment : IAttachment
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
13
Spine/SpineWrappers/Attachments/IPointAttachment.cs
Normal file
13
Spine/SpineWrappers/Attachments/IPointAttachment.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IPointAttachment : IAttachment
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
51
Spine/SpineWrappers/Attachments/IRegionAttachment.cs
Normal file
51
Spine/SpineWrappers/Attachments/IRegionAttachment.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface IRegionAttachment : IAttachment
|
||||
{
|
||||
/// <summary>
|
||||
/// 总是将 Region 附件矩形区域切分成两个这样的三角形
|
||||
/// </summary>
|
||||
private static readonly int[] _trangles = [0, 1, 2, 2, 3, 0];
|
||||
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
public float R { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
public float G { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
public float B { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
public float A { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于渲染的纹理对象
|
||||
/// </summary>
|
||||
public SFML.Graphics.Texture RendererObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 顶点纹理坐标, 每个坐标有 u 和 v 两个数, 有效长度和 <see cref="IAttachment.ComputeWorldVertices(ISlot, ref float[])"/> 返回值一致
|
||||
/// </summary>
|
||||
public float[] UVs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 三角形索引顶点数组, 每 3 个为一组, 指向顶点的下标 (不是顶点坐标数组下标)
|
||||
/// </summary>
|
||||
public int[] Triangles => _trangles;
|
||||
}
|
||||
}
|
||||
51
Spine/SpineWrappers/Attachments/ISkinnedMeshAttachment.cs
Normal file
51
Spine/SpineWrappers/Attachments/ISkinnedMeshAttachment.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers.Attachments
|
||||
{
|
||||
public interface ISkinnedMeshAttachment : IAttachment
|
||||
{
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
public float R { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
public float G { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
public float B { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
public float A { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于渲染的纹理对象
|
||||
/// </summary>
|
||||
public SFML.Graphics.Texture RendererObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 顶点纹理坐标, 每个坐标有 u 和 v 两个数, 有效长度和 <see cref="IAttachment.ComputeWorldVertices(ISlot, ref float[])"/> 返回值一致
|
||||
/// </summary>
|
||||
public float[] UVs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 三角形索引顶点数组, 每 3 个为一组, 指向顶点的下标 (不是顶点坐标数组下标)
|
||||
/// </summary>
|
||||
public int[] Triangles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 边缘顶点数组长度
|
||||
/// </summary>
|
||||
public int HullLength { get; }
|
||||
}
|
||||
}
|
||||
21
Spine/SpineWrappers/IAnimation.cs
Normal file
21
Spine/SpineWrappers/IAnimation.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface IAnimation
|
||||
{
|
||||
/// <summary>
|
||||
/// 动画名称
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 动画时长
|
||||
/// </summary>
|
||||
public float Duration { get; }
|
||||
}
|
||||
}
|
||||
112
Spine/SpineWrappers/IAnimationState.cs
Normal file
112
Spine/SpineWrappers/IAnimationState.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface IAnimationState
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件方法签名
|
||||
/// </summary>
|
||||
/// <param name="trackEntry"></param>
|
||||
public delegate void TrackEntryDelegate(ITrackEntry trackEntry);
|
||||
|
||||
/// <summary>
|
||||
/// Start 事件
|
||||
/// </summary>
|
||||
public event TrackEntryDelegate? Start;
|
||||
|
||||
/// <summary>
|
||||
/// Interrupt 事件
|
||||
/// </summary>
|
||||
public event TrackEntryDelegate? Interrupt;
|
||||
|
||||
/// <summary>
|
||||
/// End 事件
|
||||
/// </summary>
|
||||
public event TrackEntryDelegate? End;
|
||||
|
||||
/// <summary>
|
||||
/// Complete 事件
|
||||
/// </summary>
|
||||
public event TrackEntryDelegate? Complete;
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 事件
|
||||
/// </summary>
|
||||
public event TrackEntryDelegate? Dispose;
|
||||
|
||||
/// <summary>
|
||||
/// 速度因子
|
||||
/// </summary>
|
||||
public float TimeScale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 遍历所有的轨道, 可能存在 null
|
||||
/// </summary>
|
||||
public IEnumerable<ITrackEntry?> IterTracks();
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public void Update(float delta);
|
||||
|
||||
/// <summary>
|
||||
/// 将动画应用到骨骼上
|
||||
/// </summary>
|
||||
public void Apply(ISkeleton skeleton);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定轨道当前播放条目, 可能返回 null
|
||||
/// </summary>
|
||||
public ITrackEntry? GetCurrent(int index);
|
||||
|
||||
/// <summary>
|
||||
/// 清除指定轨道
|
||||
/// </summary>
|
||||
public void ClearTrack(int index);
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有轨道
|
||||
/// </summary>
|
||||
public void ClearTracks();
|
||||
|
||||
/// <summary>
|
||||
/// 使用动画名设置轨道动画
|
||||
/// </summary>
|
||||
public ITrackEntry SetAnimation(int trackIndex, string animationName, bool loop);
|
||||
|
||||
/// <summary>
|
||||
/// 使用动画对象设置轨道动画
|
||||
/// </summary>
|
||||
public ITrackEntry SetAnimation(int trackIndex, IAnimation animation, bool loop);
|
||||
|
||||
/// <summary>
|
||||
/// 设置轨道空动画
|
||||
/// </summary>
|
||||
public ITrackEntry SetEmptyAnimation(int trackIndex, float mixDuration);
|
||||
|
||||
/// <summary>
|
||||
/// 设置所有轨道空动画
|
||||
/// </summary>
|
||||
public void SetEmptyAnimations(float mixDuration);
|
||||
|
||||
/// <summary>
|
||||
/// 在指定轨道后添加动画
|
||||
/// </summary>
|
||||
public ITrackEntry AddAnimation(int trackIndex, string animationName, bool loop, float delay);
|
||||
|
||||
/// <summary>
|
||||
/// 在指定轨道后添加动画
|
||||
/// </summary>
|
||||
public ITrackEntry AddAnimation(int trackIndex, IAnimation animation, bool loop, float delay);
|
||||
|
||||
/// <summary>
|
||||
/// 在指定轨道后添加空动画
|
||||
/// </summary>
|
||||
public ITrackEntry AddEmptyAnimation(int trackIndex, float mixDuration, float delay);
|
||||
}
|
||||
}
|
||||
66
Spine/SpineWrappers/IBone.cs
Normal file
66
Spine/SpineWrappers/IBone.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface IBone
|
||||
{
|
||||
/// <summary>
|
||||
/// 骨骼唯一名字
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 骨骼索引
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否激活
|
||||
/// </summary>
|
||||
public bool Active { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 父骨骼
|
||||
/// </summary>
|
||||
public IBone? Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 骨骼长度
|
||||
/// </summary>
|
||||
public float Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 世界坐标 X
|
||||
/// </summary>
|
||||
public float WorldX { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 世界坐标 Y
|
||||
/// </summary>
|
||||
public float WorldY { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>Cos(theta)</c>
|
||||
/// </summary>
|
||||
public float A { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>-Sin(theta)</c>
|
||||
/// </summary>
|
||||
public float B { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>Sin(theta)</c>
|
||||
/// </summary>
|
||||
public float C { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <c>Cos(theta)</c>
|
||||
/// </summary>
|
||||
public float D { get; }
|
||||
}
|
||||
}
|
||||
123
Spine/SpineWrappers/ISkeleton.cs
Normal file
123
Spine/SpineWrappers/ISkeleton.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface ISkeleton
|
||||
{
|
||||
/// <summary>
|
||||
/// 物理约束
|
||||
/// </summary>
|
||||
public enum Physics { None, Reset, Update, Pose }
|
||||
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
public float R { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
public float G { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
public float B { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
public float A { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 横坐标
|
||||
/// </summary>
|
||||
public float X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纵坐标
|
||||
/// </summary>
|
||||
public float Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 水平缩放, 负数时会翻转
|
||||
/// </summary>
|
||||
public float ScaleX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 垂直缩放, 负数时会翻转
|
||||
/// </summary>
|
||||
public float ScaleY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有骨骼按顺序
|
||||
/// </summary>
|
||||
public ImmutableArray<IBone> Bones { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有骨骼按名称
|
||||
/// </summary>
|
||||
public FrozenDictionary<string, IBone> BonesByName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有插槽按顺序
|
||||
/// </summary>
|
||||
public ImmutableArray<ISlot> Slots { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有插槽按名称
|
||||
/// </summary>
|
||||
public FrozenDictionary<string, ISlot> SlotsByName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 皮肤, 可以设置 null 值清除皮肤
|
||||
/// </summary>
|
||||
public ISkin? Skin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 遍历渲染时槽顺序
|
||||
/// </summary>
|
||||
public IEnumerable<ISlot> IterDrawOrder();
|
||||
|
||||
/// <summary>
|
||||
/// 更新附件约束等的缓存
|
||||
/// </summary>
|
||||
public void UpdateCache();
|
||||
|
||||
/// <summary>
|
||||
/// 更新变换
|
||||
/// </summary>
|
||||
public void UpdateWorldTransform(Physics physics);
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有参数至初始值
|
||||
/// </summary>
|
||||
public void SetToSetupPose();
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有骨骼参数至初始值
|
||||
/// </summary>
|
||||
public void SetBonesToSetupPose();
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有插槽参数至初始值
|
||||
/// </summary>
|
||||
public void SetSlotsToSetupPose();
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public void Update(float delta);
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前状态包围盒
|
||||
/// </summary>
|
||||
public void GetBounds(out float x, out float y, out float w, out float h);
|
||||
}
|
||||
}
|
||||
62
Spine/SpineWrappers/ISkeletonClipping.cs
Normal file
62
Spine/SpineWrappers/ISkeletonClipping.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface ISkeletonClipping
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正处于裁剪
|
||||
/// </summary>
|
||||
public bool IsClipping { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁剪后的顶点数组
|
||||
/// </summary>
|
||||
public float[] ClippedVertices { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁剪后的顶点数组 <see cref="ClippedVertices"/> 长度
|
||||
/// </summary>
|
||||
public int ClippedVerticesLength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁剪后的三角形索引数组
|
||||
/// </summary>
|
||||
public int[] ClippedTriangles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁剪后的三角形索引数组 <see cref="ClippedTriangles"/> 长度
|
||||
/// </summary>
|
||||
public int ClippedTrianglesLength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 裁剪后的 UV 数组
|
||||
/// </summary>
|
||||
public float[] ClippedUVs { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 进行裁剪, 裁剪后的结果通过属性获取
|
||||
/// </summary>
|
||||
public void ClipTriangles(float[] vertices, int verticesLength, int[] triangles, int trianglesLength, float[] uvs);
|
||||
|
||||
/// <summary>
|
||||
/// 开始裁剪
|
||||
/// </summary>
|
||||
public void ClipStart(ISlot slot, IClippingAttachment clippingAttachment);
|
||||
|
||||
/// <summary>
|
||||
/// 判断输入插槽是否需要结束裁剪并结束裁剪
|
||||
/// </summary>
|
||||
public void ClipEnd(ISlot slot);
|
||||
|
||||
/// <summary>
|
||||
/// 结束裁剪
|
||||
/// </summary>
|
||||
public void ClipEnd();
|
||||
}
|
||||
}
|
||||
26
Spine/SpineWrappers/ISkin.cs
Normal file
26
Spine/SpineWrappers/ISkin.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface ISkin
|
||||
{
|
||||
/// <summary>
|
||||
/// 皮肤名字
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加其他皮肤
|
||||
/// </summary>
|
||||
public void AddSkin(ISkin skin);
|
||||
|
||||
/// <summary>
|
||||
/// 清空皮肤内容
|
||||
/// </summary>
|
||||
public void Clear();
|
||||
}
|
||||
}
|
||||
57
Spine/SpineWrappers/ISlot.cs
Normal file
57
Spine/SpineWrappers/ISlot.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface ISlot
|
||||
{
|
||||
/// <summary>
|
||||
/// 插槽唯一名字
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 插槽唯一索引
|
||||
/// </summary>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 混合模式
|
||||
/// </summary>
|
||||
public SFML.Graphics.BlendMode Blend { get; }
|
||||
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
public float R { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
public float G { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
public float B { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
public float A { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所在骨骼
|
||||
/// </summary>
|
||||
public IBone Bone { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用的附件, 可以设置为 null 清空附件
|
||||
/// </summary>
|
||||
public IAttachment? Attachment { get; set; }
|
||||
}
|
||||
}
|
||||
52
Spine/SpineWrappers/ISpineObjectData.cs
Normal file
52
Spine/SpineWrappers/ISpineObjectData.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 对 SkeletonData 和 AnimationStateData 的访问封装
|
||||
/// </summary>
|
||||
public interface ISpineObjectData
|
||||
{
|
||||
/// <summary>
|
||||
/// skel 文件版本
|
||||
/// </summary>
|
||||
public string SkeletonVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有皮肤
|
||||
/// </summary>
|
||||
public ImmutableArray<ISkin> Skins { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有皮肤按名称
|
||||
/// </summary>
|
||||
public FrozenDictionary<string, ISkin> SkinsByName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有皮肤中所有插槽的可用附件集合, 并不保证所有插槽均在此处有键
|
||||
/// </summary>
|
||||
public FrozenDictionary<string, FrozenDictionary<string, IAttachment>> SlotAttachments { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有动画
|
||||
/// </summary>
|
||||
public ImmutableArray<IAnimation> Animations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有动画按名称
|
||||
/// </summary>
|
||||
public FrozenDictionary<string, IAnimation> AnimationsByName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认的动画过渡时长
|
||||
/// </summary>
|
||||
public float DefaultMix { get; set; }
|
||||
}
|
||||
}
|
||||
77
Spine/SpineWrappers/ITrackEntry.cs
Normal file
77
Spine/SpineWrappers/ITrackEntry.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
public interface ITrackEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Start 事件
|
||||
/// </summary>
|
||||
public event IAnimationState.TrackEntryDelegate? Start;
|
||||
|
||||
/// <summary>
|
||||
/// Interrupt 事件
|
||||
/// </summary>
|
||||
public event IAnimationState.TrackEntryDelegate? Interrupt;
|
||||
|
||||
/// <summary>
|
||||
/// End 事件
|
||||
/// </summary>
|
||||
public event IAnimationState.TrackEntryDelegate? End;
|
||||
|
||||
/// <summary>
|
||||
/// Complete 事件
|
||||
/// </summary>
|
||||
public event IAnimationState.TrackEntryDelegate? Complete;
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 事件
|
||||
/// </summary>
|
||||
public event IAnimationState.TrackEntryDelegate? Dispose;
|
||||
|
||||
/// <summary>
|
||||
/// 所在轨道序号
|
||||
/// </summary>
|
||||
public int TrackIndex { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 播放的动画
|
||||
/// </summary>
|
||||
public IAnimation Animation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 下一个条目, 形成播放链表
|
||||
/// </summary>
|
||||
public ITrackEntry? Next { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 动画是否循环
|
||||
/// </summary>
|
||||
public bool Loop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 轨道当前时间
|
||||
/// </summary>
|
||||
public float TrackTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 速度因子
|
||||
/// </summary>
|
||||
public float TimeScale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多轨道的 Alpha 混合
|
||||
/// </summary>
|
||||
public float Alpha { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过渡到下一个条目的时长
|
||||
/// </summary>
|
||||
public float MixDuration { get; set; }
|
||||
}
|
||||
}
|
||||
118
Spine/SpineWrappers/SpineObjectData.cs
Normal file
118
Spine/SpineWrappers/SpineObjectData.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Spine.SpineWrappers.Attachments;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 应当继承该类实现多版本, 子类需要提供签名为 <c><see cref="new(string, string)"/></c> 的构造函数
|
||||
/// </summary>
|
||||
public abstract class SpineObjectData :
|
||||
Utils.ImplementationResolver<SpineObjectData, Utils.SpineImplementationAttribute, string>,
|
||||
ISpineObjectData,
|
||||
IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 构建版本对象
|
||||
/// </summary>
|
||||
public static SpineObjectData New(SpineVersion version, string skelPath, string atlasPath) => CreateInstance(version.Tag, skelPath, atlasPath);
|
||||
|
||||
/// <summary>
|
||||
/// 纹理加载器, 可以设置一些预置参数
|
||||
/// </summary>
|
||||
public static TextureLoader TextureLoader => _textureLoader;
|
||||
protected static readonly TextureLoader _textureLoader = new();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数, 继承的子类应当实现一个相同签名的构造函数
|
||||
/// </summary>
|
||||
public SpineObjectData(string skelPath, string atlasPath) { }
|
||||
|
||||
public abstract string SkeletonVersion { get; }
|
||||
|
||||
public abstract ImmutableArray<ISkin> Skins { get; }
|
||||
|
||||
public abstract FrozenDictionary<string, ISkin> SkinsByName { get; }
|
||||
|
||||
public abstract FrozenDictionary<string, FrozenDictionary<string, IAttachment>> SlotAttachments { get; }
|
||||
|
||||
public abstract ImmutableArray<IAnimation> Animations { get; }
|
||||
|
||||
public abstract FrozenDictionary<string, IAnimation> AnimationsByName { get; }
|
||||
|
||||
public abstract float DefaultMix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 释放纹理资源
|
||||
/// </summary>
|
||||
protected abstract void DisposeAtlas();
|
||||
|
||||
/// <summary>
|
||||
/// 创建 skeleton
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract ISkeleton CreateSkeleton();
|
||||
|
||||
/// <summary>
|
||||
/// 创建 animationState
|
||||
/// </summary>
|
||||
public abstract IAnimationState CreateAnimationState();
|
||||
|
||||
/// <summary>
|
||||
/// 创建 skeletonClipping
|
||||
/// </summary>
|
||||
public abstract ISkeletonClipping CreateSkeletonClipping();
|
||||
|
||||
/// <summary>
|
||||
/// 创建空皮肤
|
||||
/// </summary>
|
||||
public abstract ISkin CreateSkin(string name);
|
||||
|
||||
#region IDispose 接口实现
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数, 初始为 1, 每调用一次 Dispose 会减 1, 由于可能被多个实例同时引用, 因此直到小于等于 0 才会真正释放资源
|
||||
/// </summary>
|
||||
private int _refCount = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数, 当使用同一份数据创建实例副本时, 调用方负责使用该方法增加引用计数, 并且使用 Dispose 或者 Finalize 减少引用计数, 初始为 1
|
||||
/// </summary>
|
||||
public void IncRef() => _refCount++;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_refCount <= 0) return;
|
||||
|
||||
_refCount--;
|
||||
if (_refCount <= 0)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
DisposeAtlas();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~SpineObjectData()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
if (_refCount <= 0)
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
290
Spine/SpineWrappers/TextureLoader.cs
Normal file
290
Spine/SpineWrappers/TextureLoader.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spine.SpineWrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 实现不同版本的 TextureLoader
|
||||
/// </summary>
|
||||
public class TextureLoader :
|
||||
SpineRuntime21.TextureLoader,
|
||||
SpineRuntime36.TextureLoader,
|
||||
SpineRuntime37.TextureLoader,
|
||||
SpineRuntime38.TextureLoader,
|
||||
SpineRuntime40.TextureLoader,
|
||||
SpineRuntime41.TextureLoader,
|
||||
SpineRuntime42.TextureLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// 强制启用 Smooth
|
||||
/// </summary>
|
||||
public bool ForceSmooth { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 强制启用 Repeated
|
||||
/// </summary>
|
||||
public bool ForceRepeated { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 强制启用 Mipmap
|
||||
/// </summary>
|
||||
public bool ForceMipmap { get; set; } = false;
|
||||
|
||||
public void Load(SpineRuntime21.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime21.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime21.TextureWrap.Repeat && page.vWrap == SpineRuntime21.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime21.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime21.TextureFilter.MipMap:
|
||||
case SpineRuntime21.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime21.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime21.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime21.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime36.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime36.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime36.TextureWrap.Repeat && page.vWrap == SpineRuntime36.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime36.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime36.TextureFilter.MipMap:
|
||||
case SpineRuntime36.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime36.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime36.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime36.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime37.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime37.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime37.TextureWrap.Repeat && page.vWrap == SpineRuntime37.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime37.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime37.TextureFilter.MipMap:
|
||||
case SpineRuntime37.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime37.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime37.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime37.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime38.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime38.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime38.TextureWrap.Repeat && page.vWrap == SpineRuntime38.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime38.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime38.TextureFilter.MipMap:
|
||||
case SpineRuntime38.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime38.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime38.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime38.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime40.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime40.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime40.TextureWrap.Repeat && page.vWrap == SpineRuntime40.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime40.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime40.TextureFilter.MipMap:
|
||||
case SpineRuntime40.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime40.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime40.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime40.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime41.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime41.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime41.TextureWrap.Repeat && page.vWrap == SpineRuntime41.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime41.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime41.TextureFilter.MipMap:
|
||||
case SpineRuntime41.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime41.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime41.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime41.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
}
|
||||
|
||||
public void Load(SpineRuntime42.AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == SpineRuntime42.TextureFilter.Linear)
|
||||
{
|
||||
texture.Smooth = true;
|
||||
}
|
||||
if (page.uWrap == SpineRuntime42.TextureWrap.Repeat && page.vWrap == SpineRuntime42.TextureWrap.Repeat)
|
||||
{
|
||||
texture.Repeated = true;
|
||||
}
|
||||
switch (page.minFilter)
|
||||
{
|
||||
case SpineRuntime42.TextureFilter.Linear:
|
||||
texture.Smooth = true;
|
||||
break;
|
||||
case SpineRuntime42.TextureFilter.MipMap:
|
||||
case SpineRuntime42.TextureFilter.MipMapNearestNearest:
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
case SpineRuntime42.TextureFilter.MipMapLinearNearest:
|
||||
case SpineRuntime42.TextureFilter.MipMapNearestLinear:
|
||||
case SpineRuntime42.TextureFilter.MipMapLinearLinear:
|
||||
texture.Smooth = true;
|
||||
texture.GenerateMipmap();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ForceSmooth) texture.Smooth = true;
|
||||
if (ForceRepeated) texture.Repeated = true;
|
||||
if (ForceMipmap) texture.GenerateMipmap();
|
||||
|
||||
page.rendererObject = texture;
|
||||
|
||||
// 似乎是不需要设置的, 因为存在某些 png 和 atlas 大小不同的情况, 一般是有一些缩放, 如果设置了反而渲染异常
|
||||
// page.width = (int)texture.Size.X;
|
||||
// page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user