From 75a412d9d7d9b3135431dfe1d9c460559490a985 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 10 Apr 2025 16:59:09 +0200 Subject: [PATCH] [csharp] port of commit 52b7423: Brought back transform constraint offset. Some changes for alignment with reference implementation. --- spine-csharp/src/SkeletonBinary.cs | 49 +++++++++++++++------ spine-csharp/src/SkeletonJson.cs | 22 +++++++-- spine-csharp/src/TransformConstraintData.cs | 25 ++++++++--- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/spine-csharp/src/SkeletonBinary.cs b/spine-csharp/src/SkeletonBinary.cs index 0cf83cf65..fde73bbfd 100644 --- a/spine-csharp/src/SkeletonBinary.cs +++ b/spine-csharp/src/SkeletonBinary.cs @@ -271,12 +271,20 @@ namespace Spine { data.clamp = (flags & 16) != 0; FromProperty[] froms = data.properties.Resize(nn = flags >> 5).Items; for (int ii = 0, tn; ii < nn; ii++) { - float fromScale = 1.0f; + float fromScale = 1; FromProperty from; switch (input.ReadSByte()) { case 0: from = new FromRotate(); break; - case 1: from = new FromX(); fromScale = scale; break; - case 2: from = new FromY(); fromScale = scale; break; + case 1: { + from = new FromX(); + fromScale = scale; + break; + } + case 2: { + from = new FromY(); + fromScale = scale; + break; + } case 3: from = new FromScaleX(); break; case 4: from = new FromScaleY(); break; case 5: from = new FromShearY(); break; @@ -285,12 +293,20 @@ namespace Spine { from.offset = input.ReadFloat() * fromScale; ToProperty[] tos = from.to.Resize(tn = input.ReadSByte()).Items; for (int t = 0; t < tn; t++) { - float toScale = 1.0f; + float toScale = 1; ToProperty to; switch (input.ReadSByte()) { case 0: to = new ToRotate(); break; - case 1: to = new ToX(); toScale = scale; break; - case 2: to = new ToY(); toScale = scale; break; + case 1: { + to = new ToX(); + toScale = scale; + break; + } + case 2: { + to = new ToY(); + toScale = scale; + break; + } case 3: to = new ToScaleX(); break; case 4: to = new ToScaleY(); break; case 5: to = new ToShearY(); break; @@ -304,14 +320,19 @@ namespace Spine { froms[ii] = from; } flags = input.Read(); - if ((flags & 1) != 0) data.offsetX = input.ReadFloat() * scale; - if ((flags & 2) != 0) data.offsetY = input.ReadFloat() * scale; - if ((flags & 4) != 0) data.mixRotate = input.ReadFloat(); - if ((flags & 8) != 0) data.mixX = input.ReadFloat(); - if ((flags & 16) != 0) data.mixY = input.ReadFloat(); - if ((flags & 32) != 0) data.mixScaleX = input.ReadFloat(); - if ((flags & 64) != 0) data.mixScaleY = input.ReadFloat(); - if ((flags & 128) != 0) data.mixShearY = input.ReadFloat(); + if ((flags & 1) != 0) data.offsetRotation = input.ReadFloat(); + if ((flags & 2) != 0) data.offsetX = input.ReadFloat() * scale; + if ((flags & 4) != 0) data.offsetY = input.ReadFloat() * scale; + if ((flags & 8) != 0) data.offsetScaleX = input.ReadFloat(); + if ((flags & 16) != 0) data.offsetScaleY = input.ReadFloat(); + if ((flags & 32) != 0) data.offsetShearY = input.ReadFloat(); + flags = input.Read(); + if ((flags & 1) != 0) data.mixRotate = input.ReadFloat(); + if ((flags & 2) != 0) data.mixX = input.ReadFloat(); + if ((flags & 4) != 0) data.mixY = input.ReadFloat(); + if ((flags & 8) != 0) data.mixScaleX = input.ReadFloat(); + if ((flags & 16) != 0) data.mixScaleY = input.ReadFloat(); + if ((flags & 32) != 0) data.mixShearY = input.ReadFloat(); o[i] = data; } diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index 11eed6696..47e59da3c 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -240,6 +240,7 @@ namespace Spine { if (data.source == null) throw new Exception("Transform constraint source bone not found: " + sourceName); data.localSource = GetBoolean(constraintMap, "localSource", false); + data.localTarget = GetBoolean(constraintMap, "localTarget", false); data.additive = GetBoolean(constraintMap, "additive", false); data.clamp = GetBoolean(constraintMap, "clamp", false); @@ -249,12 +250,20 @@ namespace Spine { var fromEntry = (Dictionary)fromEntryObject.Value; string fromEntryName = fromEntryObject.Key; - float fromScale = 1.0f; + float fromScale = 1; FromProperty from; switch (fromEntryName) { case "rotate": from = new FromRotate(); break; - case "x": from = new FromX(); fromScale = scale; break; - case "y": from = new FromY(); fromScale = scale; break; + case "x": { + from = new FromX(); + fromScale = scale; + break; + } + case "y": { + from = new FromY(); + fromScale = scale; + break; + } case "scaleX": from = new FromScaleX(); break; case "scaleY": from = new FromScaleY(); break; case "shearY": from = new FromShearY(); break; @@ -267,7 +276,7 @@ namespace Spine { var toEntry = (Dictionary)toEntryObject.Value; string toEntryName = toEntryObject.Key; - float toScale = 1.0f; + float toScale = 1; ToProperty to; switch (toEntryName) { case "rotate": { @@ -314,8 +323,13 @@ namespace Spine { } } + data.offsetRotation = GetFloat(constraintMap, "rotation", 0); data.offsetX = GetFloat(constraintMap, "x", 0) * scale; data.offsetY = GetFloat(constraintMap, "y", 0) * scale; + data.offsetScaleX = GetFloat(constraintMap, "scaleX", 0); + data.offsetScaleY = GetFloat(constraintMap, "scaleY", 0); + data.offsetShearY = GetFloat(constraintMap, "shearY", 0); + if (rotate) data.mixRotate = GetFloat(constraintMap, "mixRotate", 1); if (x) data.mixX = GetFloat(constraintMap, "mixX", 1); if (y) data.mixY = GetFloat(constraintMap, "mixY", data.mixX); diff --git a/spine-csharp/src/TransformConstraintData.cs b/spine-csharp/src/TransformConstraintData.cs index 342c35c7d..f1bf1a8e3 100644 --- a/spine-csharp/src/TransformConstraintData.cs +++ b/spine-csharp/src/TransformConstraintData.cs @@ -33,7 +33,8 @@ namespace Spine { public class TransformConstraintData : ConstraintData { internal readonly ExposedList bones = new ExposedList(); internal BoneData source; - internal float offsetX, offsetY, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; + internal float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; + internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY; internal bool localSource, localTarget, additive, clamp; internal readonly ExposedList properties = new ExposedList(); @@ -68,10 +69,19 @@ namespace Spine { public float MixScaleY { get { return mixScaleY; } set { mixScaleY = value; } } /// A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. public float MixShearY { get { return mixShearY; } set { mixShearY = value; } } + /// An offset added to the constrained bone rotation. + public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } } /// An offset added to the constrained bone X translation. public float OffsetX { get { return offsetX; } set { offsetX = value; } } /// An offset added to the constrained bone Y translation. public float OffsetY { get { return offsetY; } set { offsetY = value; } } + /// An offset added to the constrained bone scaleX. + public float OffsetScaleX { get { return offsetScaleX; } set { offsetScaleX = value; } } + /// An offset added to the constrained bone scaleY. + public float OffsetScaleY { get { return offsetScaleY; } set { offsetScaleY = value; } } + /// An offset added to the constrained bone shearY. + public float OffsetShearY { get { return offsetShearY; } set { offsetShearY = value; } } + /// Reads the source bone's local transform instead of its world transform. public bool LocalSource { get { return localSource; } set { localSource = value; } } /// Sets the constrained bones' local transforms instead of their world transforms. @@ -114,7 +124,11 @@ namespace Spine { public class FromRotate : FromProperty { public override float Value (TransformConstraintData data, Bone source, bool local) { - return local ? source.arotation : MathUtils.Atan2(source.c, source.a) * MathUtils.RadDeg; + if (local) return source.arotation + data.offsetRotation; + float value = MathUtils.Atan2(source.c, source.a) * MathUtils.RadDeg + + (source.a * source.d - source.b * source.c > 0 ? data.offsetRotation : -data.offsetRotation); + if (value < 0) value += 360; + return value; } } @@ -191,7 +205,7 @@ namespace Spine { public class FromScaleX : FromProperty { public override float Value (TransformConstraintData data, Bone source, bool local) { - return local ? source.ascaleX : (float)Math.Sqrt(source.a * source.a + source.c * source.c); + return (local ? source.ascaleX : (float)Math.Sqrt(source.a * source.a + source.c * source.c)) + data.offsetScaleX; } } @@ -222,7 +236,7 @@ namespace Spine { public class FromScaleY : FromProperty { public override float Value (TransformConstraintData data, Bone source, bool local) { - return local ? source.ascaleY : (float)Math.Sqrt(source.b * source.b + source.d * source.d); + return (local ? source.ascaleY : (float)Math.Sqrt(source.b * source.b + source.d * source.d)) + data.offsetScaleY; } } @@ -253,7 +267,8 @@ namespace Spine { public class FromShearY : FromProperty { public override float Value (TransformConstraintData data, Bone source, bool local) { - return local ? source.ashearY : (MathUtils.Atan2(source.d, source.b) - MathUtils.Atan2(source.c, source.a)) * MathUtils.RadDeg - 90; + return (local ? source.ashearY : (MathUtils.Atan2(source.d, source.b) - MathUtils.Atan2(source.c, source.a)) * MathUtils.RadDeg - 90) + + data.offsetShearY; } }