补充3.7及以下版本的多皮肤功能

This commit is contained in:
ww-rm
2025-04-15 20:19:32 +08:00
parent 695d3c0735
commit 2a55fd9c36
4 changed files with 80 additions and 52 deletions

View File

@@ -14,7 +14,17 @@ namespace SpineViewer.Spine.Implementations.SpineObject
[SpineImplementation(SpineVersion.V21)] [SpineImplementation(SpineVersion.V21)]
internal class SpineObject21 : Spine.SpineObject internal class SpineObject21 : Spine.SpineObject
{ {
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0); //private static SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
//{
// return spineBlendMode switch
// {
// BlendMode.Normal => BlendMode.Normal,
// BlendMode.Additive => BlendMode.Additive,
// BlendMode.Multiply => BlendMode.Multiply,
// BlendMode.Screen => BlendMode.Screen,
// _ => throw new NotImplementedException($"{spineBlendMode}"),
// };
//}
private class TextureLoader : SpineRuntime21.TextureLoader private class TextureLoader : SpineRuntime21.TextureLoader
{ {
@@ -34,11 +44,13 @@ namespace SpineViewer.Spine.Implementations.SpineObject
((SFML.Graphics.Texture)texture).Dispose(); ((SFML.Graphics.Texture)texture).Dispose();
} }
} }
private static TextureLoader textureLoader = new();
private Atlas atlas; private readonly static TextureLoader textureLoader = new();
private SkeletonBinary? skeletonBinary; private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
private SkeletonJson? skeletonJson;
private readonly Atlas atlas;
private readonly SkeletonBinary? skeletonBinary;
private readonly SkeletonJson? skeletonJson;
private SkeletonData skeletonData; private SkeletonData skeletonData;
private AnimationStateData animationStateData; private AnimationStateData animationStateData;
@@ -80,7 +92,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
foreach (var anime in skeletonData.Animations) foreach (var anime in skeletonData.Animations)
animationNames.Add(anime.Name); animationNames.Add(anime.Name);
skeleton = new Skeleton(skeletonData); skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
animationStateData = new AnimationStateData(skeletonData); animationStateData = new AnimationStateData(skeletonData);
animationState = new AnimationState(animationStateData); animationState = new AnimationState(animationStateData);
} }
@@ -161,14 +173,18 @@ namespace SpineViewer.Spine.Implementations.SpineObject
protected override void addSkin(string name) protected override void addSkin(string name)
{ {
if (!skinNames.Contains(name)) return; if (skeletonData.FindSkin(name) is Skin sk)
skeleton.SetSkin(name); // XXX: 3.7 及以下不支持 AddSkin {
// XXX: 3.7 及以下不支持 AddSkin
foreach (var (k, v) in sk.Attachments)
skeleton.Skin.AddAttachment(k.Key, k.Value, v);
}
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }
protected override void clearSkin() protected override void clearSkin()
{ {
skeleton.SetSkin(skeletonData.DefaultSkin); skeleton.Skin.Attachments.Clear();
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }
@@ -243,18 +259,6 @@ namespace SpineViewer.Spine.Implementations.SpineObject
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
} }
//private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
//{
// return spineBlendMode switch
// {
// BlendMode.Normal => BlendMode.Normal,
// BlendMode.Additive => BlendMode.Additive,
// BlendMode.Multiply => BlendMode.Multiply,
// BlendMode.Screen => BlendMode.Screen,
// _ => throw new NotImplementedException($"{spineBlendMode}"),
// };
//}
protected override void draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states) protected override void draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
{ {
triangleVertices.Clear(); triangleVertices.Clear();

View File

@@ -14,7 +14,17 @@ namespace SpineViewer.Spine.Implementations.SpineObject
[SpineImplementation(SpineVersion.V36)] [SpineImplementation(SpineVersion.V36)]
internal class SpineObject36 : Spine.SpineObject internal class SpineObject36 : Spine.SpineObject
{ {
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0); private static SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
{
return spineBlendMode switch
{
BlendMode.Normal => SFMLBlendMode.NormalPma,
BlendMode.Additive => SFMLBlendMode.AdditivePma,
BlendMode.Multiply => SFMLBlendMode.MultiplyPma,
BlendMode.Screen => SFMLBlendMode.ScreenPma,
_ => throw new NotImplementedException($"{spineBlendMode}"),
};
}
private class TextureLoader : SpineRuntime36.TextureLoader private class TextureLoader : SpineRuntime36.TextureLoader
{ {
@@ -34,18 +44,20 @@ namespace SpineViewer.Spine.Implementations.SpineObject
((SFML.Graphics.Texture)texture).Dispose(); ((SFML.Graphics.Texture)texture).Dispose();
} }
} }
private static TextureLoader textureLoader = new();
private Atlas atlas; private static readonly TextureLoader textureLoader = new();
private SkeletonBinary? skeletonBinary; private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
private SkeletonJson? skeletonJson;
private readonly Atlas atlas;
private readonly SkeletonBinary? skeletonBinary;
private readonly SkeletonJson? skeletonJson;
private SkeletonData skeletonData; private SkeletonData skeletonData;
private AnimationStateData animationStateData; private AnimationStateData animationStateData;
private Skeleton skeleton; private Skeleton skeleton;
private AnimationState animationState; private AnimationState animationState;
private SkeletonClipping clipping = new(); private readonly SkeletonClipping clipping = new();
public SpineObject36(string skelPath, string atlasPath) : base(skelPath, atlasPath) public SpineObject36(string skelPath, string atlasPath) : base(skelPath, atlasPath)
{ {
@@ -79,7 +91,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
foreach (var anime in skeletonData.Animations) foreach (var anime in skeletonData.Animations)
animationNames.Add(anime.Name); animationNames.Add(anime.Name);
skeleton = new Skeleton(skeletonData); skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
animationStateData = new AnimationStateData(skeletonData); animationStateData = new AnimationStateData(skeletonData);
animationState = new AnimationState(animationStateData); animationState = new AnimationState(animationStateData);
} }
@@ -160,14 +172,18 @@ namespace SpineViewer.Spine.Implementations.SpineObject
protected override void addSkin(string name) protected override void addSkin(string name)
{ {
if (!skinNames.Contains(name)) return; if (skeletonData.FindSkin(name) is Skin sk)
skeleton.SetSkin(name); // XXX: 3.7 及以下不支持 AddSkin {
// XXX: 3.7 及以下不支持 AddSkin
foreach (var (k, v) in sk.Attachments)
skeleton.Skin.AddAttachment(k.slotIndex, k.name, v);
}
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }
protected override void clearSkin() protected override void clearSkin()
{ {
skeleton.SetSkin(skeletonData.DefaultSkin); skeleton.Skin.Attachments.Clear();
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }

View File

@@ -11,7 +11,17 @@ namespace SpineViewer.Spine.Implementations.SpineObject
[SpineImplementation(SpineVersion.V37)] [SpineImplementation(SpineVersion.V37)]
internal class SpineObject37 : Spine.SpineObject internal class SpineObject37 : Spine.SpineObject
{ {
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0); private static SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
{
return spineBlendMode switch
{
BlendMode.Normal => SFMLBlendMode.NormalPma,
BlendMode.Additive => SFMLBlendMode.AdditivePma,
BlendMode.Multiply => SFMLBlendMode.MultiplyPma,
BlendMode.Screen => SFMLBlendMode.ScreenPma,
_ => throw new NotImplementedException($"{spineBlendMode}"),
};
}
private class TextureLoader : SpineRuntime37.TextureLoader private class TextureLoader : SpineRuntime37.TextureLoader
{ {
@@ -32,18 +42,19 @@ namespace SpineViewer.Spine.Implementations.SpineObject
} }
} }
private static TextureLoader textureLoader = new(); private static readonly TextureLoader textureLoader = new();
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
private Atlas atlas; private readonly Atlas atlas;
private SkeletonBinary? skeletonBinary; private readonly SkeletonBinary? skeletonBinary;
private SkeletonJson? skeletonJson; private readonly SkeletonJson? skeletonJson;
private SkeletonData skeletonData; private readonly SkeletonData skeletonData;
private AnimationStateData animationStateData; private readonly AnimationStateData animationStateData;
private Skeleton skeleton; private readonly Skeleton skeleton;
private AnimationState animationState; private readonly AnimationState animationState;
private SkeletonClipping clipping = new(); private readonly SkeletonClipping clipping = new();
public SpineObject37(string skelPath, string atlasPath) : base(skelPath, atlasPath) public SpineObject37(string skelPath, string atlasPath) : base(skelPath, atlasPath)
{ {
@@ -77,7 +88,7 @@ namespace SpineViewer.Spine.Implementations.SpineObject
foreach (var anime in skeletonData.Animations) foreach (var anime in skeletonData.Animations)
animationNames.Add(anime.Name); animationNames.Add(anime.Name);
skeleton = new Skeleton(skeletonData); skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
animationStateData = new AnimationStateData(skeletonData); animationStateData = new AnimationStateData(skeletonData);
animationState = new AnimationState(animationStateData); animationState = new AnimationState(animationStateData);
} }
@@ -132,14 +143,18 @@ namespace SpineViewer.Spine.Implementations.SpineObject
protected override void addSkin(string name) protected override void addSkin(string name)
{ {
if (!skinNames.Contains(name)) return; if (skeletonData.FindSkin(name) is Skin sk)
skeleton.SetSkin(name); // XXX: 3.7 及以下不支持 AddSkin {
// XXX: 3.7 及以下不支持 AddSkin
foreach (var (k, v) in sk.Attachments)
skeleton.Skin.AddAttachment(k.slotIndex, k.name, v);
}
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }
protected override void clearSkin() protected override void clearSkin()
{ {
skeleton.SetSkin(skeletonData.DefaultSkin); skeleton.Skin.Attachments.Clear();
skeleton.SetSlotsToSetupPose(); skeleton.SetSlotsToSetupPose();
} }

View File

@@ -52,7 +52,6 @@ namespace SpineViewer.Spine
/// 日志器 /// 日志器
/// </summary> /// </summary>
protected readonly Logger logger = LogManager.GetCurrentClassLogger(); protected readonly Logger logger = LogManager.GetCurrentClassLogger();
private bool skinLoggerWarned = false;
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
@@ -351,12 +350,6 @@ namespace SpineViewer.Spine
{ {
loadedSkins.Add(name); loadedSkins.Add(name);
reloadSkins(); reloadSkins();
if (!skinLoggerWarned && Version < SpineVersion.V38 && loadedSkins.Count > 1)
{
logger.Warn($"Multiplt skins not supported in SpineVersion {Version.GetName()}");
skinLoggerWarned = true;
}
} }
} }