diff --git a/SpineRuntimes/SpineRuntime21/Bone.cs b/SpineRuntimes/SpineRuntime21/Bone.cs index 286fd6a..52cdbeb 100644 --- a/SpineRuntimes/SpineRuntime21/Bone.cs +++ b/SpineRuntimes/SpineRuntime21/Bone.cs @@ -33,7 +33,7 @@ using System.Collections.Generic; namespace SpineRuntime21 { public class Bone{ - static public bool yDown; + static readonly public bool yDown = false; internal BoneData data; internal Skeleton skeleton; @@ -84,7 +84,8 @@ namespace SpineRuntime21 { /// Computes the world SRT using the parent bone and the local SRT. public void UpdateWorldTransform () { - Bone parent = this.parent; + float sx = skeleton.scaleX, sy = skeleton.scaleY; + Bone parent = this.parent; float x = this.x, y = this.y; if (parent != null) { worldX = x * parent.m00 + y * parent.m01 + parent.worldX; @@ -100,34 +101,22 @@ namespace SpineRuntime21 { worldFlipX = parent.worldFlipX != flipX; worldFlipY = parent.worldFlipY != flipY; } else { - Skeleton skeleton = this.skeleton; - bool skeletonFlipX = skeleton.flipX, skeletonFlipY = skeleton.flipY; - worldX = skeletonFlipX ? -x : x; - worldY = skeletonFlipY != yDown ? -y : y; + worldX = x * sx; + worldY = y * sy; worldScaleX = scaleX; worldScaleY = scaleY; worldRotation = rotationIK; - worldFlipX = skeletonFlipX != flipX; - worldFlipY = skeletonFlipY != flipY; + worldFlipX = (sx < 0) != flipX; + worldFlipY = (sy < 0) != flipY; } float radians = worldRotation * (float)Math.PI / 180; float cos = (float)Math.Cos(radians); float sin = (float)Math.Sin(radians); - if (worldFlipX) { - m00 = -cos * worldScaleX; - m01 = sin * worldScaleY; - } else { - m00 = cos * worldScaleX; - m01 = -sin * worldScaleY; - } - if (worldFlipY != yDown) { - m10 = -sin * worldScaleX; - m11 = -cos * worldScaleY; - } else { - m10 = sin * worldScaleX; - m11 = cos * worldScaleY; - } - } + m00 = cos * worldScaleX * sx; + m01 = -sin * worldScaleY * sx; + m10 = sin * worldScaleX * sy; + m11 = cos * worldScaleY * sy; + } public void SetToSetupPose () { BoneData data = this.data; diff --git a/SpineRuntimes/SpineRuntime21/Skeleton.cs b/SpineRuntimes/SpineRuntime21/Skeleton.cs index 53075b7..11d8763 100644 --- a/SpineRuntimes/SpineRuntime21/Skeleton.cs +++ b/SpineRuntimes/SpineRuntime21/Skeleton.cs @@ -42,8 +42,8 @@ namespace SpineRuntime21 { internal Skin skin; internal float r = 1, g = 1, b = 1, a = 1; internal float time; - internal bool flipX, flipY; - internal float x, y; + internal float scaleX = 1, scaleY = 1; + internal float x, y; public SkeletonData Data { get { return data; } } public List Bones { get { return bones; } } @@ -58,10 +58,16 @@ namespace SpineRuntime21 { public float Time { get { return time; } set { time = value; } } public float X { get { return x; } set { x = value; } } public float Y { get { return y; } set { y = value; } } - public bool FlipX { get { return flipX; } set { flipX = value; } } - public bool FlipY { get { return flipY; } set { flipY = value; } } + public float ScaleX { get { return scaleX; } set { scaleX = value; } } + public float ScaleY { get { return scaleY; } set { scaleY = value; } } - public Bone RootBone { + [Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")] + public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } } + + [Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")] + public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } } + + public Bone RootBone { get { return bones.Count == 0 ? null : bones[0]; } diff --git a/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs b/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs index a670bbf..4cd6dcb 100644 --- a/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs +++ b/SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs @@ -123,45 +123,11 @@ namespace SpineViewer.Spine.Implementations.SpineObject protected override float scale { - get - { - if (skeletonBinary is not null) - return skeletonBinary.Scale; - else if (skeletonJson is not null) - return skeletonJson.Scale; - else - return 1f; - } + get => Math.Abs(skeleton.ScaleX); set { - // 保存状态 - var pos = position; - var fX = flipX; - var fY = flipY; - var animations = animationState.Tracks.Where(te => te is not null).Select(te => te.Animation.Name).ToArray(); - - if (skeletonBinary is not null) - { - skeletonBinary.Scale = value; - skeletonData = skeletonBinary.ReadSkeletonData(SkelPath); - } - else if (skeletonJson is not null) - { - skeletonJson.Scale = value; - skeletonData = skeletonJson.ReadSkeletonData(SkelPath); - } - - // reload skel-dependent data - skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; - animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix }; - animationState = new AnimationState(animationStateData); - - // 恢复状态 - position = pos; - flipX = fX; - flipY = fY; - reloadSkins(); - for (int i = 0; i < animations.Length; i++) setAnimation(i, animations[i]); + skeleton.ScaleX = Math.Sign(skeleton.ScaleX) * value; + skeleton.ScaleY = Math.Sign(skeleton.ScaleY) * value; } } @@ -177,14 +143,22 @@ namespace SpineViewer.Spine.Implementations.SpineObject protected override bool flipX { - get => skeleton.FlipX; - set => skeleton.FlipX = value; + get => skeleton.ScaleX < 0; + set + { + if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value) + skeleton.ScaleX *= -1; + } } protected override bool flipY { - get => skeleton.FlipY; - set => skeleton.FlipY = value; + get => skeleton.ScaleY < 0; + set + { + if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value) + skeleton.ScaleY *= -1; + } } protected override string getSlotAttachment(string slot) => skeleton.FindSlot(slot)?.Attachment?.Name ?? EMPTY_ATTACHMENT; @@ -243,8 +217,8 @@ namespace SpineViewer.Spine.Implementations.SpineObject var maxDuration = 0f; var tmpSkeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; var tmpAnimationState = new AnimationState(animationStateData); - tmpSkeleton.FlipX = skeleton.FlipX; - tmpSkeleton.FlipY = skeleton.FlipY; + tmpSkeleton.ScaleX = skeleton.ScaleX; + tmpSkeleton.ScaleY = skeleton.ScaleY; tmpSkeleton.X = skeleton.X; tmpSkeleton.Y = skeleton.Y; foreach (var (name, _) in skinLoadStatus.Where(e => e.Value))