diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index 8d4e96526..9b93acbe3 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -199,7 +199,7 @@ namespace Spine { } internal enum Property { - Rotate=0, TranslateX, TranslateY, ScaleX, ScaleY, ShearX, ShearY, // + Rotate=0, X, Y, ScaleX, ScaleY, ShearX, ShearY, // RGB, Alpha, RGB2, // Attachment, Deform, // Event, DrawOrder, // @@ -333,7 +333,7 @@ namespace Spine { /// The ordinal of this Bezier curve for this timeline, between 0 and bezierCount - 1 (specified /// in the constructor), inclusive. /// Between 0 and frameCount - 1, inclusive. - /// The index of the value for this frame that this curve is used for. + /// The index of the value for the frame this curve is used for. /// The time for the first key. /// The value for the first key. /// The time for the first Bezier handle. @@ -518,8 +518,8 @@ namespace Spine { public TranslateTimeline (int frameCount, int bezierCount, int boneIndex) : base(frameCount, bezierCount, // - (int)Property.TranslateX + "|" + boneIndex, // - (int) Property.TranslateY + "|" + boneIndex) { + (int)Property.X + "|" + boneIndex, // + (int) Property.Y + "|" + boneIndex) { this.boneIndex = boneIndex; } @@ -593,7 +593,7 @@ namespace Spine { readonly int boneIndex; public TranslateXTimeline (int frameCount, int bezierCount, int boneIndex) - : base(frameCount, bezierCount, (int)Property.TranslateX + "|" + boneIndex) { + : base(frameCount, bezierCount, (int)Property.X + "|" + boneIndex) { this.boneIndex = boneIndex; } @@ -642,7 +642,7 @@ namespace Spine { readonly int boneIndex; public TranslateYTimeline (int frameCount, int bezierCount, int boneIndex) - : base(frameCount, bezierCount, (int)Property.TranslateY + "|" + boneIndex) { + : base(frameCount, bezierCount, (int)Property.Y + "|" + boneIndex) { this.boneIndex = boneIndex; } @@ -1705,12 +1705,11 @@ namespace Spine { slot.ClampSecondColor(); } else { - float br, bg, bb, ba, br2, bg2, bb2; + float br, bg, bb, br2, bg2, bb2; if (blend == MixBlend.Setup) { br = slot.data.r; bg = slot.data.g; bb = slot.data.b; - ba = slot.data.a; br2 = slot.data.r2; bg2 = slot.data.g2; bb2 = slot.data.b2; @@ -1719,7 +1718,6 @@ namespace Spine { br = slot.r; bg = slot.g; bb = slot.b; - ba = slot.a; br2 = slot.r2; bg2 = slot.g2; bb2 = slot.b2; @@ -2308,8 +2306,8 @@ namespace Spine { /// Changes a transform constraint's mixes. public class TransformConstraintTimeline : CurveTimeline { - public const int ENTRIES = 5; - private const int ROTATE = 1, TRANSLATE = 2, SCALE = 3, SHEAR = 4; + public const int ENTRIES = 7; + private const int ROTATE = 1, X = 2, Y = 3, SCALEX = 4, SCALEY = 5, SHEARY = 6; readonly int transformConstraintIndex; @@ -2335,13 +2333,16 @@ namespace Spine { /// Sets the time, rotate mix, translate mix, scale mix, and shear mix for the specified frame. /// Between 0 and frameCount, inclusive. /// The frame time in seconds. - public void SetFrame (int frame, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) { + public void SetFrame (int frame, float time, float mixRotate, float mixX, float mixY, float mixScaleX, float mixScaleY, + float mixShearY) { frame *= ENTRIES; frames[frame] = time; - frames[frame + ROTATE] = rotateMix; - frames[frame + TRANSLATE] = translateMix; - frames[frame + SCALE] = scaleMix; - frames[frame + SHEAR] = shearMix; + frames[frame + ROTATE] = mixRotate; + frames[frame + X] = mixX; + frames[frame + Y] = mixY; + frames[frame + SCALEX] = mixScaleX; + frames[frame + SCALEY] = mixScaleY; + frames[frame + SHEARY] = mixShearY; } override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, @@ -2354,61 +2355,77 @@ namespace Spine { TransformConstraintData data = constraint.data; switch (blend) { case MixBlend.Setup: - constraint.rotateMix = data.rotateMix; - constraint.translateMix = data.translateMix; - constraint.scaleMix = data.scaleMix; - constraint.shearMix = data.shearMix; + constraint.mixRotate = data.mixRotate; + constraint.mixX = data.mixX; + constraint.mixY = data.mixY; + constraint.mixScaleX = data.mixScaleX; + constraint.mixScaleY = data.mixScaleY; + constraint.mixShearY = data.mixShearY; return; case MixBlend.First: - constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; - constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; - constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (data.mixX - constraint.mixX) * alpha; + constraint.mixY += (data.mixY - constraint.mixY) * alpha; + constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha; return; } return; } - float rotate, translate, scale, shear; + float rotate, x, y, scaleX, scaleY, shearY; int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; switch (curveType) { case LINEAR: float before = frames[i]; rotate = frames[i + ROTATE]; - translate = frames[i + TRANSLATE]; - scale = frames[i + SCALE]; - shear = frames[i + SHEAR]; + x = frames[i + X]; + y = frames[i + Y]; + scaleX = frames[i + SCALEX]; + scaleY = frames[i + SCALEY]; + shearY = frames[i + SHEARY]; float t = (time - before) / (frames[i + ENTRIES] - before); rotate += (frames[i + ENTRIES + ROTATE] - rotate) * t; - translate += (frames[i + ENTRIES + TRANSLATE] - translate) * t; - scale += (frames[i + ENTRIES + SCALE] - scale) * t; - shear += (frames[i + ENTRIES + SHEAR] - shear) * t; + x += (frames[i + ENTRIES + X] - x) * t; + y += (frames[i + ENTRIES + Y] - y) * t; + scaleX += (frames[i + ENTRIES + SCALEX] - scaleX) * t; + scaleY += (frames[i + ENTRIES + SCALEY] - scaleY) * t; + shearY += (frames[i + ENTRIES + SHEARY] - shearY) * t; break; case STEPPED: rotate = frames[i + ROTATE]; - translate = frames[i + TRANSLATE]; - scale = frames[i + SCALE]; - shear = frames[i + SHEAR]; + x = frames[i + X]; + y = frames[i + Y]; + scaleX = frames[i + SCALEX]; + scaleY = frames[i + SCALEY]; + shearY = frames[i + SHEARY]; break; default: rotate = GetBezierValue(time, i, ROTATE, curveType - BEZIER); - translate = GetBezierValue(time, i, TRANSLATE, curveType + BEZIER_SIZE - BEZIER); - scale = GetBezierValue(time, i, TRANSLATE, curveType + BEZIER_SIZE * 2 - BEZIER); - shear = GetBezierValue(time, i, TRANSLATE, curveType + BEZIER_SIZE * 3 - BEZIER); + x = GetBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER); + y = GetBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER); + scaleX = GetBezierValue(time, i, SCALEX, curveType + BEZIER_SIZE * 3 - BEZIER); + scaleY = GetBezierValue(time, i, SCALEY, curveType + BEZIER_SIZE * 4 - BEZIER); + shearY = GetBezierValue(time, i, SHEARY, curveType + BEZIER_SIZE * 5 - BEZIER); break; } if (blend == MixBlend.Setup) { TransformConstraintData data = constraint.data; - constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; - constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; - constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; - constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; + constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha; + constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha; + constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha; } else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; - constraint.scaleMix += (scale - constraint.scaleMix) * alpha; - constraint.shearMix += (shear - constraint.shearMix) * alpha; + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; + constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha; + constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha; + constraint.mixShearY += (shearY - constraint.mixShearY) * alpha; } } } @@ -2499,8 +2516,12 @@ namespace Spine { } } - /// Changes a path constraint's mixes. - public class PathConstraintMixTimeline : CurveTimeline2 { + /// Changes a transform constraint's , , and + /// . + public class PathConstraintMixTimeline : CurveTimeline { + public const int ENTRIES = 4; + private const int ROTATE = 1, X = 2, Y = 3; + readonly int pathConstraintIndex; public PathConstraintMixTimeline (int frameCount, int bezierCount, int pathConstraintIndex) @@ -2508,6 +2529,10 @@ namespace Spine { this.pathConstraintIndex = pathConstraintIndex; } + public override int FrameEntries { + get { return ENTRIES; } + } + /// The index of the path constraint slot in that will be changed when this timeline /// is applied. public int PathConstraintIndex { @@ -2516,6 +2541,17 @@ namespace Spine { } } + /// Sets the time and color for the specified frame. + /// Between 0 and frameCount, inclusive. + /// The frame time in seconds. + public void SetFrame (int frame, float time, float mixRotate, float mixX, float mixY) { + frame <<= 2; + frames[frame] = time; + frames[frame + ROTATE] = mixRotate; + frames[frame + X] = mixX; + frames[frame + Y] = mixY; + } + override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend, MixDirection direction) { PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex]; @@ -2525,44 +2561,53 @@ namespace Spine { if (time < frames[0]) { // Time is before first frame. switch (blend) { case MixBlend.Setup: - constraint.rotateMix = constraint.data.rotateMix; - constraint.translateMix = constraint.data.translateMix; + constraint.mixRotate = constraint.data.mixRotate; + constraint.mixX = constraint.data.mixX; + constraint.mixY = constraint.data.mixY; return; case MixBlend.First: - constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; - constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + constraint.mixRotate += (constraint.data.mixRotate - constraint.mixRotate) * alpha; + constraint.mixX += (constraint.data.mixX - constraint.mixX) * alpha; + constraint.mixY += (constraint.data.mixY - constraint.mixY) * alpha; return; } return; } - float rotate, translate; - int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; + float rotate, x, y; + int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2]; switch (curveType) { case LINEAR: float before = frames[i]; - rotate = frames[i + VALUE1]; - translate = frames[i + VALUE2]; + rotate = frames[i + ROTATE]; + x = frames[i + X]; + y = frames[i + Y]; float t = (time - before) / (frames[i + ENTRIES] - before); - rotate += (frames[i + ENTRIES + VALUE1] - rotate) * t; - translate += (frames[i + ENTRIES + VALUE2] - translate) * t; + rotate += (frames[i + ENTRIES + ROTATE] - rotate) * t; + x += (frames[i + ENTRIES + X] - x) * t; + y += (frames[i + ENTRIES + Y] - y) * t; break; case STEPPED: - rotate = frames[i + VALUE1]; - translate = frames[i + VALUE2]; + rotate = frames[i + ROTATE]; + x = frames[i + X]; + y = frames[i + Y]; break; default: - rotate = GetBezierValue(time, i, VALUE1, curveType - BEZIER); - translate = GetBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER); + rotate = GetBezierValue(time, i, ROTATE, curveType - BEZIER); + x = GetBezierValue(time, i, X, curveType + BEZIER_SIZE - BEZIER); + y = GetBezierValue(time, i, Y, curveType + BEZIER_SIZE * 2 - BEZIER); break; } if (blend == MixBlend.Setup) { - constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; - constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + PathConstraintData data = constraint.data; + constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha; + constraint.mixX = data.mixX + (x - data.mixX) * alpha; + constraint.mixY = data.mixY + (y - data.mixY) * alpha; } else { - constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; - constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.mixRotate += (rotate - constraint.mixRotate) * alpha; + constraint.mixX += (x - constraint.mixX) * alpha; + constraint.mixY += (y - constraint.mixY) * alpha; } } } diff --git a/spine-csharp/src/Attachments/PathAttachment.cs b/spine-csharp/src/Attachments/PathAttachment.cs index 375379d5e..821c78543 100644 --- a/spine-csharp/src/Attachments/PathAttachment.cs +++ b/spine-csharp/src/Attachments/PathAttachment.cs @@ -37,7 +37,10 @@ namespace Spine { /// The length in the setup pose from the start of the path to the end of each curve. public float[] Lengths { get { return lengths; } set { lengths = value; } } + /// If true, the start and end knots are connected. public bool Closed { get { return closed; } set { closed = value; } } + /// If true, additional calculations are performed to make computing positions along the path more accurate and movement along + /// the path have a constant speed. public bool ConstantSpeed { get { return constantSpeed; } set { constantSpeed = value; } } public PathAttachment (String name) diff --git a/spine-csharp/src/IkConstraint.cs b/spine-csharp/src/IkConstraint.cs index a8e91d901..2c3def264 100644 --- a/spine-csharp/src/IkConstraint.cs +++ b/spine-csharp/src/IkConstraint.cs @@ -104,7 +104,7 @@ namespace Spine { set { target = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. public float Mix { get { return mix; } set { mix = value; } diff --git a/spine-csharp/src/IkConstraintData.cs b/spine-csharp/src/IkConstraintData.cs index bc6a1c76f..6e46e43cc 100644 --- a/spine-csharp/src/IkConstraintData.cs +++ b/spine-csharp/src/IkConstraintData.cs @@ -54,7 +54,7 @@ namespace Spine { } /// - /// A percentage (0-1) that controls the mix between the constraint and unconstrained rotations. + /// A percentage (0-1) that controls the mix between the constraint and unconstrained rotation. public float Mix { get { return mix; } set { mix = value; } diff --git a/spine-csharp/src/PathConstraint.cs b/spine-csharp/src/PathConstraint.cs index a11ce2ddd..9ac7c4ac5 100644 --- a/spine-csharp/src/PathConstraint.cs +++ b/spine-csharp/src/PathConstraint.cs @@ -45,7 +45,7 @@ namespace Spine { internal PathConstraintData data; internal ExposedList bones; internal Slot target; - internal float position, spacing, rotateMix, translateMix; + internal float position, spacing, mixRotate, mixX, mixY; internal bool active; @@ -63,8 +63,9 @@ namespace Spine { target = skeleton.FindSlot(data.target.name); position = data.position; spacing = data.spacing; - rotateMix = data.rotateMix; - translateMix = data.translateMix; + mixRotate = data.mixRotate; + mixX = data.mixX; + mixY = data.mixY; } /// Copy constructor. @@ -78,60 +79,88 @@ namespace Spine { target = skeleton.slots.Items[constraint.target.data.index]; position = constraint.position; spacing = constraint.spacing; - rotateMix = constraint.rotateMix; - translateMix = constraint.translateMix; + mixRotate = constraint.mixRotate; + mixX = constraint.mixX; + mixY = constraint.mixY; } public void Update () { PathAttachment attachment = target.Attachment as PathAttachment; if (attachment == null) return; - float rotateMix = this.rotateMix, translateMix = this.translateMix; - bool translate = translateMix > 0, rotate = rotateMix > 0; - if (!translate && !rotate) return; + float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; + if (mixRotate == 0 && mixX == 0 && mixY == 0) return; PathConstraintData data = this.data; - bool percentSpacing = data.spacingMode == SpacingMode.Percent; - RotateMode rotateMode = data.rotateMode; - bool tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale; + bool tangents = data.rotateMode == RotateMode.Tangent, scale = data.rotateMode == RotateMode.ChainScale; int boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1; Bone[] bonesItems = this.bones.Items; - ExposedList spaces = this.spaces.Resize(spacesCount), lengths = null; + float[] spaces = this.spaces.Resize(spacesCount).Items, lengths = scale ? this.lengths.Resize(boneCount).Items : null; float spacing = this.spacing; - if (scale || !percentSpacing) { - if (scale) lengths = this.lengths.Resize(boneCount); - bool lengthSpacing = data.spacingMode == SpacingMode.Length; - for (int i = 0, n = spacesCount - 1; i < n;) { - Bone bone = bonesItems[i]; - float setupLength = bone.data.length; - if (setupLength < PathConstraint.Epsilon) { - if (scale) lengths.Items[i] = 0; - spaces.Items[++i] = 0; - } else if (percentSpacing) { - if (scale) { + switch (data.spacingMode) { + case SpacingMode.Percent: + for (int i = 0, n = spacesCount - 1; i < n;) { + Bone bone = bonesItems[i]; + float setupLength = bone.data.length; + if (setupLength < PathConstraint.Epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = 0; + } else { + if (scale) { + float x = setupLength * bone.a, y = setupLength * bone.c; + lengths[i] = (float)Math.Sqrt(x * x + y * y); + } + spaces[++i] = spacing; + } + } + break; + case SpacingMode.Proportional: { + float sum = 0; + for (int i = 0; i < boneCount;) { + Bone bone = bonesItems[i]; + float setupLength = bone.data.length; + if (setupLength < PathConstraint.Epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = 0; + } else { float x = setupLength * bone.a, y = setupLength * bone.c; float length = (float)Math.Sqrt(x * x + y * y); - lengths.Items[i] = length; + if (scale) lengths[i] = length; + spaces[++i] = length; + sum += length; } - spaces.Items[++i] = spacing; - } else { - float x = setupLength * bone.a, y = setupLength * bone.c; - float length = (float)Math.Sqrt(x * x + y * y); - if (scale) lengths.Items[i] = length; - spaces.Items[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; } + sum = spacesCount / sum * spacing; + for (int i = 1; i < spacesCount; i++) + spaces[i] *= sum; + break; + } + default: { + bool lengthSpacing = data.spacingMode == SpacingMode.Length; + + for (int i = 0, n = spacesCount - 1; i < n;) { + Bone bone = bonesItems[i]; + float setupLength = bone.data.length; + if (setupLength < PathConstraint.Epsilon) { + if (scale) lengths[i] = 0; + spaces[++i] = 0; + } + else { + float x = setupLength * bone.a, y = setupLength * bone.c; + float length = (float)Math.Sqrt(x * x + y * y); + if (scale) lengths[i] = length; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + break; } - } else { - for (int i = 1; i < spacesCount; i++) - spaces.Items[i] = spacing; } - float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents, - data.positionMode == PositionMode.Percent, percentSpacing); + float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents); float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; bool tip; if (offsetRotation == 0) { - tip = rotateMode == RotateMode.Chain; + tip = data.rotateMode == RotateMode.Chain; } else { tip = false; Bone p = target.bone; @@ -139,24 +168,24 @@ namespace Spine { } for (int i = 0, p = 3; i < boneCount; i++, p += 3) { Bone bone = bonesItems[i]; - bone.worldX += (boneX - bone.worldX) * translateMix; - bone.worldY += (boneY - bone.worldY) * translateMix; + bone.worldX += (boneX - bone.worldX) * mixX; + bone.worldY += (boneY - bone.worldY) * mixY; float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; if (scale) { - float length = lengths.Items[i]; + float length = lengths[i]; if (length >= PathConstraint.Epsilon) { - float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; + float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1; bone.a *= s; bone.c *= s; } } boneX = x; boneY = y; - if (rotate) { + if (mixRotate > 0) { float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin; if (tangents) r = positions[p - 1]; - else if (spaces.Items[i + 1] < PathConstraint.Epsilon) + else if (spaces[i + 1] < PathConstraint.Epsilon) r = positions[p + 2]; else r = MathUtils.Atan2(dy, dx); @@ -165,15 +194,15 @@ namespace Spine { cos = MathUtils.Cos(r); sin = MathUtils.Sin(r); float length = bone.data.length; - boneX += (length * (cos * a - sin * c) - dx) * rotateMix; - boneY += (length * (sin * a + cos * c) - dy) * rotateMix; + boneX += (length * (cos * a - sin * c) - dx) * mixRotate; + boneY += (length * (sin * a + cos * c) - dy) * mixRotate; } else r += offsetRotation; if (r > MathUtils.PI) r -= MathUtils.PI2; else if (r < -MathUtils.PI) // r += MathUtils.PI2; - r *= rotateMix; + r *= mixRotate; cos = MathUtils.Cos(r); sin = MathUtils.Sin(r); bone.a = cos * a - sin * c; @@ -185,28 +214,38 @@ namespace Spine { } } - float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents, bool percentPosition, - bool percentSpacing) { + float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents) { Slot target = this.target; float position = this.position; - float[] spacesItems = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world; + float[] spaces = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world; bool closed = path.Closed; int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE; - float pathLength = 0; - + float pathLength; + float multiplier; if (!path.ConstantSpeed) { float[] lengths = path.Lengths; curveCount -= closed ? 1 : 2; pathLength = lengths[curveCount]; - if (percentPosition) position *= pathLength; - if (percentSpacing) { - for (int i = 1; i < spacesCount; i++) - spacesItems[i] *= pathLength; + + if (data.positionMode == PositionMode.Percent) position *= pathLength; + + //float multiplier; + switch (data.spacingMode) { + case SpacingMode.Percent: + multiplier = pathLength; + break; + case SpacingMode.Proportional: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + break; } + world = this.world.Resize(8).Items; for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { - float space = spacesItems[i]; + float space = spaces[i] * multiplier; position += space; float p = position; @@ -307,20 +346,26 @@ namespace Spine { x1 = x2; y1 = y2; } - if (percentPosition) - position *= pathLength; - else - position *= pathLength / path.lengths[curveCount - 1]; - if (percentSpacing) { - for (int i = 1; i < spacesCount; i++) - spacesItems[i] *= pathLength; + if (data.positionMode == PositionMode.Percent) position *= pathLength; + + //float multiplier; + switch (data.spacingMode) { + case SpacingMode.Percent: + multiplier = pathLength; + break; + case SpacingMode.Proportional: + multiplier = pathLength / spacesCount; + break; + default: + multiplier = 1; + break; } float[] segments = this.segments; float curveLength = 0; for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { - float space = spacesItems[i]; + float space = spaces[i] * multiplier; position += space; float p = position; @@ -448,9 +493,11 @@ namespace Spine { /// The spacing between bones. public float Spacing { get { return spacing; } set { spacing = value; } } /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. - public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained translations. - public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + public float MixRotate { get { return mixRotate; } set { mixRotate = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + public float MixX { get { return mixX; } set { mixX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + public float MixY { get { return mixY; } set { mixY = value; } } /// The bones that will be modified by this path constraint. public ExposedList Bones { get { return bones; } } /// The slot whose path attachment will be used to constrained the bones. diff --git a/spine-csharp/src/PathConstraintData.cs b/spine-csharp/src/PathConstraintData.cs index fa6e71fd9..cd71b3c86 100644 --- a/spine-csharp/src/PathConstraintData.cs +++ b/spine-csharp/src/PathConstraintData.cs @@ -37,7 +37,7 @@ namespace Spine { internal SpacingMode spacingMode; internal RotateMode rotateMode; internal float offsetRotation; - internal float position, spacing, rotateMix, translateMix; + internal float position, spacing, mixRotate, mixX, mixY; public PathConstraintData (string name) : base(name) { } @@ -50,8 +50,12 @@ namespace Spine { public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } } public float Position { get { return position; } set { position = value; } } public float Spacing { get { return spacing; } set { spacing = value; } } - public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } - public float TranslateMix { get { return translateMix; } set { translateMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + public float RotateMix { get { return mixRotate; } set { mixRotate = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + public float MixX { get { return mixX; } set { mixX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + public float MixY { get { return mixY; } set { mixY = value; } } } public enum PositionMode { @@ -59,7 +63,7 @@ namespace Spine { } public enum SpacingMode { - Length, Fixed, Percent + Length, Fixed, Percent, Proportional } public enum RotateMode { diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index 6745c6673..d3257864a 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -379,10 +379,12 @@ namespace Spine { for (int i = 0, n = this.transformConstraints.Count; i < n; i++) { TransformConstraint constraint = transformConstraints[i]; TransformConstraintData constraintData = constraint.data; - constraint.rotateMix = constraintData.rotateMix; - constraint.translateMix = constraintData.translateMix; - constraint.scaleMix = constraintData.scaleMix; - constraint.shearMix = constraintData.shearMix; + constraint.mixRotate = constraintData.mixRotate; + constraint.mixX = constraintData.mixX; + constraint.mixY = constraintData.mixY; + constraint.mixScaleX = constraintData.mixScaleX; + constraint.mixScaleY = constraintData.mixScaleY; + constraint.mixShearY = constraintData.mixShearY; } var pathConstraints = this.pathConstraints.Items; @@ -391,8 +393,9 @@ namespace Spine { PathConstraintData constraintData = constraint.data; constraint.position = constraintData.position; constraint.spacing = constraintData.spacing; - constraint.rotateMix = constraintData.rotateMix; - constraint.translateMix = constraintData.translateMix; + constraint.mixRotate = constraintData.mixRotate; + constraint.mixX = constraintData.mixX; + constraint.mixY = constraintData.mixY; } } diff --git a/spine-csharp/src/SkeletonBinary.cs b/spine-csharp/src/SkeletonBinary.cs index 02cd83a2d..12a872040 100644 --- a/spine-csharp/src/SkeletonBinary.cs +++ b/spine-csharp/src/SkeletonBinary.cs @@ -57,9 +57,9 @@ namespace Spine { public const int SLOT_ATTACHMENT = 0; public const int SLOT_RGBA = 1; public const int SLOT_RGB = 2; - public const int SLOT_ALPHA = 3; - public const int SLOT_RGBA2 = 4; - public const int SLOT_RGB2 = 5; + public const int SLOT_RGBA2 = 3; + public const int SLOT_RGB2 = 4; + public const int SLOT_ALPHA = 5; public const int PATH_POSITION = 0; public const int PATH_SPACING = 1; @@ -240,10 +240,12 @@ namespace Spine { data.offsetScaleX = input.ReadFloat(); data.offsetScaleY = input.ReadFloat(); data.offsetShearY = input.ReadFloat(); - data.rotateMix = input.ReadFloat(); - data.translateMix = input.ReadFloat(); - data.scaleMix = input.ReadFloat(); - data.shearMix = input.ReadFloat(); + data.mixRotate = input.ReadFloat(); + data.mixX = input.ReadFloat(); + data.mixY = input.ReadFloat(); + data.mixScaleX = input.ReadFloat(); + data.mixScaleY = input.ReadFloat(); + data.mixShearY = input.ReadFloat(); o[i] = data; } @@ -265,8 +267,9 @@ namespace Spine { if (data.positionMode == PositionMode.Fixed) data.position *= scale; data.spacing = input.ReadFloat(); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale; - data.rotateMix = input.ReadFloat(); - data.translateMix = input.ReadFloat(); + data.mixRotate = input.ReadFloat(); + data.mixX = input.ReadFloat(); + data.mixY = input.ReadFloat(); o[i] = data; } @@ -637,8 +640,7 @@ namespace Spine { timeline.SetFrame(frame, time, r, g, b); if (frame == frameLast) break; float time2 = input.ReadFloat(); - float r2 = input.Read() / 255f, g2 = input.Read() / 255f; - float b2 = input.Read() / 255f, a2 = input.Read() / 255f; + float r2 = input.Read() / 255f, g2 = input.Read() / 255f, b2 = input.Read() / 255f; switch (input.ReadByte()) { case CURVE_STEPPED: timeline.SetStepped(frame); @@ -826,29 +828,33 @@ namespace Spine { for (int i = 0, n = input.ReadInt(true); i < n; i++) { int index = input.ReadInt(true), frameCount = input.ReadInt(true), frameLast = frameCount - 1; TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount, input.ReadInt(true), index); - float time = input.ReadFloat(), rotateMix = input.ReadFloat(), translateMix = input.ReadFloat(), - scaleMix = input.ReadFloat(), shearMix = input.ReadFloat(); + float time = input.ReadFloat(), mixRotate = input.ReadFloat(), mixX = input.ReadFloat(), mixY = input.ReadFloat(), + mixScaleX = input.ReadFloat(), mixScaleY = input.ReadFloat(), mixShearY = input.ReadFloat(); for (int frame = 0, bezier = 0; ; frame++) { - timeline.SetFrame(frame, time, rotateMix, translateMix, scaleMix, shearMix); + timeline.SetFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); if (frame == frameLast) break; - float time2 = input.ReadFloat(), rotateMix2 = input.ReadFloat(), translateMix2 = input.ReadFloat(), - scaleMix2 = input.ReadFloat(), shearMix2 = input.ReadFloat(); + float time2 = input.ReadFloat(), mixRotate2 = input.ReadFloat(), mixX2 = input.ReadFloat(), mixY2 = input.ReadFloat(), + mixScaleX2 = input.ReadFloat(), mixScaleY2 = input.ReadFloat(), mixShearY2 = input.ReadFloat(); switch (input.ReadByte()) { case CURVE_STEPPED: timeline.SetStepped(frame); break; case CURVE_BEZIER: - SetBezier(input, timeline, bezier++, frame, 0, time, time2, rotateMix, rotateMix2, 1); - SetBezier(input, timeline, bezier++, frame, 1, time, time2, translateMix, translateMix2, 1); - SetBezier(input, timeline, bezier++, frame, 2, time, time2, scaleMix, scaleMix2, 1); - SetBezier(input, timeline, bezier++, frame, 3, time, time2, shearMix, shearMix2, 1); + SetBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + SetBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + SetBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + SetBezier(input, timeline, bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + SetBezier(input, timeline, bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + SetBezier(input, timeline, bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1); break; } time = time2; - rotateMix = rotateMix2; - translateMix = translateMix2; - scaleMix = scaleMix2; - shearMix = shearMix2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixShearY = mixShearY2; } timelines.Add(timeline); } @@ -870,8 +876,30 @@ namespace Spine { data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); break; case PATH_MIX: - timelines - .Add(ReadTimeline(input, new PathConstraintMixTimeline(input.ReadInt(true), input.ReadInt(true), index), 1)); + PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(input.ReadInt(true), input.ReadInt(true), + index); + float time = input.ReadFloat(), mixRotate = input.ReadFloat(), mixX = input.ReadFloat(), mixY = input.ReadFloat(); + for (int frame = 0, bezier = 0, frameLast = nn - 1; ; frame++) { + timeline.SetFrame(frame, time, mixRotate, mixX, mixY); + if (frame == frameLast) break; + float time2 = input.ReadFloat(), mixRotate2 = input.ReadFloat(), mixX2 = input.ReadFloat(), + mixY2 = input.ReadFloat(); + switch (input.ReadByte()) { + case CURVE_STEPPED: + timeline.SetStepped(frame); + break; + case CURVE_BEZIER: + SetBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); + SetBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); + SetBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); + break; + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + } + timelines.Add(timeline); break; } } diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index e71d1b2b8..d64c80b1b 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -231,10 +231,12 @@ namespace Spine { data.offsetScaleY = GetFloat(constraintMap, "scaleY", 0); data.offsetShearY = GetFloat(constraintMap, "shearY", 0); - data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); - data.translateMix = GetFloat(constraintMap, "translateMix", 1); - data.scaleMix = GetFloat(constraintMap, "scaleMix", 1); - data.shearMix = GetFloat(constraintMap, "shearMix", 1); + data.mixRotate = GetFloat(constraintMap, "mixRotate", 1); + data.mixX = GetFloat(constraintMap, "mixX", 1); + data.mixY = GetFloat(constraintMap, "mixY", data.mixX); + data.mixScaleX = GetFloat(constraintMap, "mixScaleX", 1); + data.mixScaleY = GetFloat(constraintMap, "mixScaleY", data.mixScaleX); + data.mixShearY = GetFloat(constraintMap, "mixShearY", 1); skeletonData.transformConstraints.Add(data); } @@ -267,8 +269,10 @@ namespace Spine { if (data.positionMode == PositionMode.Fixed) data.position *= scale; data.spacing = GetFloat(constraintMap, "spacing", 0); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale; - data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); - data.translateMix = GetFloat(constraintMap, "translateMix", 1); + data.mixRotate = GetFloat(constraintMap, "mixRotate", 1); + data.mixX = GetFloat(constraintMap, "mixX", 1); + data.mixY = GetFloat(constraintMap, "mixY", 1); + skeletonData.pathConstraints.Add(data); } @@ -595,9 +599,9 @@ namespace Spine { var keyMap = (Dictionary)keyMapEnumerator.Current; float time = GetFloat(keyMap, "time", 0); string color = (string)keyMap["color"]; - float r = ToColor(color, 0); - float g = ToColor(color, 1); - float b = ToColor(color, 2); + float r = ToColor(color, 0, 6); + float g = ToColor(color, 1, 6); + float b = ToColor(color, 2, 6); for (int frame = 0, bezier = 0; ; frame++) { timeline.SetFrame(frame, time, r, g, b); bool hasNext = keyMapEnumerator.MoveNext(); @@ -609,9 +613,9 @@ namespace Spine { float time2 = GetFloat(nextMap, "time", 0); color = (string)nextMap["color"]; - float nr = ToColor(color, 0); - float ng = ToColor(color, 1); - float nb = ToColor(color, 2); + float nr = ToColor(color, 0, 6); + float ng = ToColor(color, 1, 6); + float nb = ToColor(color, 2, 6); if (keyMap.ContainsKey("curve")) { object curve = keyMap["curve"]; @@ -645,9 +649,9 @@ namespace Spine { float b = ToColor(color, 2); float a = ToColor(color, 3); color = (string)keyMap["dark"]; - float r2 = ToColor(color, 0); - float g2 = ToColor(color, 1); - float b2 = ToColor(color, 2); + float r2 = ToColor(color, 0, 6); + float g2 = ToColor(color, 1, 6); + float b2 = ToColor(color, 2, 6); for (int frame = 0, bezier = 0; ; frame++) { timeline.SetFrame(frame, time, r, g, b, a, r2, g2, b2); bool hasNext = keyMapEnumerator.MoveNext(); @@ -664,9 +668,9 @@ namespace Spine { float nb = ToColor(color, 2); float na = ToColor(color, 3); color = (string)nextMap["dark"]; - float nr2 = ToColor(color, 0); - float ng2 = ToColor(color, 1); - float nb2 = ToColor(color, 2); + float nr2 = ToColor(color, 0, 6); + float ng2 = ToColor(color, 1, 6); + float nb2 = ToColor(color, 2, 6); if (keyMap.ContainsKey("curve")) { object curve = keyMap["curve"]; @@ -698,13 +702,13 @@ namespace Spine { var keyMap = (Dictionary)keyMapEnumerator.Current; float time = GetFloat(keyMap, "time", 0); string color = (string)keyMap["light"]; - float r = ToColor(color, 0); - float g = ToColor(color, 1); - float b = ToColor(color, 2); + float r = ToColor(color, 0, 6); + float g = ToColor(color, 1, 6); + float b = ToColor(color, 2, 6); color = (string)keyMap["dark"]; - float r2 = ToColor(color, 0); - float g2 = ToColor(color, 1); - float b2 = ToColor(color, 2); + float r2 = ToColor(color, 0, 6); + float g2 = ToColor(color, 1, 6); + float b2 = ToColor(color, 2, 6); for (int frame = 0, bezier = 0; ; frame++) { timeline.SetFrame(frame, time, r, g, b, r2, g2, b2); bool hasNext = keyMapEnumerator.MoveNext(); @@ -716,13 +720,13 @@ namespace Spine { float time2 = GetFloat(nextMap, "time", 0); color = (string)nextMap["light"]; - float nr = ToColor(color, 0); - float ng = ToColor(color, 1); - float nb = ToColor(color, 2); + float nr = ToColor(color, 0, 6); + float ng = ToColor(color, 1, 6); + float nb = ToColor(color, 2, 6); color = (string)nextMap["dark"]; - float nr2 = ToColor(color, 0); - float ng2 = ToColor(color, 1); - float nb2 = ToColor(color, 2); + float nr2 = ToColor(color, 0, 6); + float ng2 = ToColor(color, 1, 6); + float nb2 = ToColor(color, 2, 6); if (keyMap.ContainsKey("curve")) { object curve = keyMap["curve"]; @@ -849,10 +853,11 @@ namespace Spine { TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMapValues.Count, timelineMapValues.Count << 2, skeletonData.TransformConstraints.IndexOf(constraint)); float time = GetFloat(keyMap, "time", 0); - float rotateMix = GetFloat(keyMap, "rotateMix", 1), translateMix = GetFloat(keyMap, "translateMix", 1); - float scaleMix = GetFloat(keyMap, "scaleMix", 1), shearMix = GetFloat(keyMap, "shearMix", 1); + float mixRotate = GetFloat(keyMap, "mixRotate", 1), mixShearY = GetFloat(keyMap, "mixShearY", 1); + float mixX = GetFloat(keyMap, "mixX", 1), mixY = GetFloat(keyMap, "mixY", mixX); + float mixScaleX = GetFloat(keyMap, "mixScaleX", 1), mixScaleY = GetFloat(keyMap, "mixScaleY", mixScaleX); for (int frame = 0, bezier = 0; ; frame++) { - timeline.SetFrame(frame, time, rotateMix, translateMix, scaleMix, shearMix); + timeline.SetFrame(frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY); hasNext = keyMapEnumerator.MoveNext(); if (!hasNext) { timeline.Shrink(bezier); @@ -860,20 +865,25 @@ namespace Spine { } var nextMap = (Dictionary)keyMapEnumerator.Current; float time2 = GetFloat(nextMap, "time", 0); - float rotateMix2 = GetFloat(nextMap, "rotateMix", 1), translateMix2 = GetFloat(nextMap, "translateMix", 1); - float scaleMix2 = GetFloat(nextMap, "scaleMix", 1), shearMix2 = GetFloat(nextMap, "shearMix", 1); + float mixRotate2 = GetFloat(nextMap, "mixRotate", 1), mixShearY2 = GetFloat(nextMap, "mixShearY", 1); + float mixX2 = GetFloat(nextMap, "mixX", 1), mixY2 = GetFloat(nextMap, "mixY", mixX2); + float mixScaleX2 = GetFloat(nextMap, "mixScaleX", 1), mixScaleY2 = GetFloat(nextMap, "mixScaleY", mixScaleX2); if (keyMap.ContainsKey("curve")) { object curve = keyMap["curve"]; - bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, rotateMix, rotateMix2, 1); - bezier = ReadCurve(curve, timeline, bezier, frame, 1, time, time2, translateMix, translateMix2, 1); - bezier = ReadCurve(curve, timeline, bezier, frame, 2, time, time2, scaleMix, scaleMix2, 1); - bezier = ReadCurve(curve, timeline, bezier, frame, 3, time, time2, shearMix, shearMix2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 3, time, time2, mixScaleX, mixScaleX2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 4, time, time2, mixScaleY, mixScaleY2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 5, time, time2, mixShearY, mixShearY2, 1); } time = time2; - rotateMix = rotateMix2; - translateMix = translateMix2; - scaleMix = scaleMix2; - shearMix = shearMix2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + mixScaleX = mixScaleX2; + mixScaleY = mixScaleY2; + mixScaleX = mixScaleX2; keyMap = nextMap; } timelines.Add(timeline); @@ -903,8 +913,35 @@ namespace Spine { data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); } else if (timelineName == "mix") { - CurveTimeline2 timeline = new PathConstraintMixTimeline(values.Count, values.Count << 1, index); - timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "rotateMix", "translateMix", 1, 1)); + PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count, values.Count * 3, index); + var keyMap = (Dictionary)keyMapEnumerator.Current; + float time = GetFloat(keyMap, "time", 0); + float mixRotate = GetFloat(keyMap, "mixRotate", 1); + float mixX = GetFloat(keyMap, "mixX", 1), mixY = GetFloat(keyMap, "mixY", mixX); + for (int frame = 0, bezier = 0; ; frame++) { + timeline.SetFrame(frame, time, mixRotate, mixX, mixY); + hasNext = keyMapEnumerator.MoveNext(); + if (!hasNext) { + timeline.Shrink(bezier); + break; + } + var nextMap = (Dictionary)keyMapEnumerator.Current; + float time2 = GetFloat(nextMap, "time", 0); + float mixRotate2 = GetFloat(nextMap, "mixRotate", 1); + float mixX2 = GetFloat(nextMap, "mixX", 1), mixY2 = GetFloat(nextMap, "mixY", mixX2); + if (keyMap.ContainsKey("curve")) { + object curve = keyMap["curve"]; + bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 1, time, time2, mixX, mixX2, 1); + bezier = ReadCurve(curve, timeline, bezier, frame, 2, time, time2, mixY, mixY2, 1); + } + time = time2; + mixRotate = mixRotate2; + mixX = mixX2; + mixY = mixY2; + keyMap = nextMap; + } + timelines.Add(timeline); } } } diff --git a/spine-csharp/src/TransformConstraint.cs b/spine-csharp/src/TransformConstraint.cs index 4305e5e09..0985a53fb 100644 --- a/spine-csharp/src/TransformConstraint.cs +++ b/spine-csharp/src/TransformConstraint.cs @@ -41,7 +41,7 @@ namespace Spine { internal TransformConstraintData data; internal ExposedList bones; internal Bone target; - internal float rotateMix, translateMix, scaleMix, shearMix; + internal float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; internal bool active; @@ -49,11 +49,12 @@ namespace Spine { if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); this.data = data; - rotateMix = data.rotateMix; - translateMix = data.translateMix; - scaleMix = data.scaleMix; - shearMix = data.shearMix; - + mixRotate = data.mixRotate; + mixX = data.mixX; + mixY = data.mixY; + mixScaleX = data.mixScaleX; + mixScaleY = data.mixScaleY; + mixShearY = data.mixShearY; bones = new ExposedList(); foreach (BoneData boneData in data.bones) bones.Add (skeleton.FindBone(boneData.name)); @@ -70,14 +71,16 @@ namespace Spine { foreach (Bone bone in constraint.Bones) bones.Add(skeleton.Bones.Items[bone.data.index]); target = skeleton.Bones.Items[constraint.target.data.index]; - rotateMix = constraint.rotateMix; - translateMix = constraint.translateMix; - scaleMix = constraint.scaleMix; - shearMix = constraint.shearMix; + mixRotate = constraint.mixRotate; + mixX = constraint.mixX; + mixY = constraint.mixY; + mixScaleX = constraint.mixScaleX; + mixScaleY = constraint.mixScaleY; + mixShearY = constraint.mixShearY; } public void Update () { - if (rotateMix == 0 && translateMix == 0 && scaleMix == 0 && shearMix == 0) return; + if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleX == 0 && mixShearY == 0) return; if (data.local) { if (data.relative) ApplyRelativeLocal(); @@ -92,22 +95,27 @@ namespace Spine { } void ApplyAbsoluteWorld () { - float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, + mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + bool translate = mixX != 0 || mixY != 0; + Bone target = this.target; float ta = target.a, tb = target.b, tc = target.c, td = target.d; float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad; float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect; + var bones = this.bones.Items; for (int i = 0, n = this.bones.Count; i < n; i++) { Bone bone = bones[i]; - if (rotateMix != 0) { + if (mixRotate != 0) { float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float r = MathUtils.Atan2(tc, ta) - MathUtils.Atan2(c, a) + offsetRotation; if (r > MathUtils.PI) r -= MathUtils.PI2; - else if (r < -MathUtils.PI) r += MathUtils.PI2; - r *= rotateMix; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= mixRotate; float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r); bone.a = cos * a - sin * c; bone.b = cos * b - sin * d; @@ -115,32 +123,35 @@ namespace Spine { bone.d = sin * b + cos * d; } - if (translateMix != 0) { + if (translate) { float tx, ty; //Vector2 temp = this.temp; target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY)); - bone.worldX += (tx - bone.worldX) * translateMix; - bone.worldY += (ty - bone.worldY) * translateMix; + bone.worldX += (tx - bone.worldX) * mixX; + bone.worldY += (ty - bone.worldY) * mixY; } - if (scaleMix > 0) { + if (mixScaleX != 0) { float s = (float)Math.Sqrt(bone.a * bone.a + bone.c * bone.c); - if (s != 0) s = (s + ((float)Math.Sqrt(ta * ta + tc * tc) - s + data.offsetScaleX) * scaleMix) / s; + if (s != 0) s = (s + ((float)Math.Sqrt(ta * ta + tc * tc) - s + data.offsetScaleX) * mixScaleX) / s; bone.a *= s; bone.c *= s; - s = (float)Math.Sqrt(bone.b * bone.b + bone.d * bone.d); - if (s != 0) s = (s + ((float)Math.Sqrt(tb * tb + td * td) - s + data.offsetScaleY) * scaleMix) / s; + } + if (mixScaleY != 0) { + float s = (float)Math.Sqrt(bone.b * bone.b + bone.d * bone.d); + if (s != 0) s = (s + ((float)Math.Sqrt(tb * tb + td * td) - s + data.offsetScaleY) * mixScaleY) / s; bone.b *= s; bone.d *= s; } - if (shearMix > 0) { + if (mixShearY > 0) { float b = bone.b, d = bone.d; float by = MathUtils.Atan2(d, b); float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta) - (by - MathUtils.Atan2(bone.c, bone.a)); if (r > MathUtils.PI) r -= MathUtils.PI2; - else if (r < -MathUtils.PI) r += MathUtils.PI2; - r = by + (r + offsetShearY) * shearMix; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r = by + (r + offsetShearY) * mixShearY; float s = (float)Math.Sqrt(b * b + d * d); bone.b = MathUtils.Cos(r) * s; bone.d = MathUtils.Sin(r) * s; @@ -151,22 +162,27 @@ namespace Spine { } void ApplyRelativeWorld () { - float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, + mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + bool translate = mixX != 0 || mixY != 0; + Bone target = this.target; float ta = target.a, tb = target.b, tc = target.c, td = target.d; float degRadReflect = ta * td - tb * tc > 0 ? MathUtils.DegRad : -MathUtils.DegRad; float offsetRotation = data.offsetRotation * degRadReflect, offsetShearY = data.offsetShearY * degRadReflect; + var bones = this.bones.Items; for (int i = 0, n = this.bones.Count; i < n; i++) { Bone bone = bones[i]; - if (rotateMix != 0) { + if (mixRotate != 0) { float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float r = MathUtils.Atan2(tc, ta) + offsetRotation; if (r > MathUtils.PI) r -= MathUtils.PI2; - else if (r < -MathUtils.PI) r += MathUtils.PI2; - r *= rotateMix; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; + r *= mixRotate; float cos = MathUtils.Cos(r), sin = MathUtils.Sin(r); bone.a = cos * a - sin * c; bone.b = cos * b - sin * d; @@ -174,29 +190,32 @@ namespace Spine { bone.d = sin * b + cos * d; } - if (translateMix != 0) { + if (translate) { float tx, ty; //Vector2 temp = this.temp; target.LocalToWorld(data.offsetX, data.offsetY, out tx, out ty); //target.localToWorld(temp.set(data.offsetX, data.offsetY)); - bone.worldX += tx * translateMix; - bone.worldY += ty * translateMix; + bone.worldX += tx * mixX; + bone.worldY += ty * mixY; } - if (scaleMix > 0) { - float s = ((float)Math.Sqrt(ta * ta + tc * tc) - 1 + data.offsetScaleX) * scaleMix + 1; + if (mixScaleX != 0) { + float s = ((float)Math.Sqrt(ta * ta + tc * tc) - 1 + data.offsetScaleX) * mixScaleX + 1; bone.a *= s; bone.c *= s; - s = ((float)Math.Sqrt(tb * tb + td * td) - 1 + data.offsetScaleY) * scaleMix + 1; + } + if (mixScaleY != 0) { + float s = ((float)Math.Sqrt(tb * tb + td * td) - 1 + data.offsetScaleY) * mixScaleY + 1; bone.b *= s; bone.d *= s; } - if (shearMix > 0) { + if (mixShearY > 0) { float r = MathUtils.Atan2(td, tb) - MathUtils.Atan2(tc, ta); if (r > MathUtils.PI) r -= MathUtils.PI2; - else if (r < -MathUtils.PI) r += MathUtils.PI2; + else if (r < -MathUtils.PI) // + r += MathUtils.PI2; float b = bone.b, d = bone.d; - r = MathUtils.Atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix; + r = MathUtils.Atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * mixShearY; float s = (float)Math.Sqrt(b * b + d * d); bone.b = MathUtils.Cos(r) * s; bone.d = MathUtils.Sin(r) * s; @@ -207,38 +226,39 @@ namespace Spine { } void ApplyAbsoluteLocal () { - float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, + mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + Bone target = this.target; if (!target.appliedValid) target.UpdateAppliedTransform(); + var bones = this.bones.Items; for (int i = 0, n = this.bones.Count; i < n; i++) { Bone bone = bones[i]; if (!bone.appliedValid) bone.UpdateAppliedTransform(); float rotation = bone.arotation; - if (rotateMix != 0) { + if (mixRotate != 0) { float r = target.arotation - rotation + data.offsetRotation; r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; - rotation += r * rotateMix; + rotation += r * mixRotate; } float x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax - x + data.offsetX) * translateMix; - y += (target.ay - y + data.offsetY) * translateMix; - } + x += (target.ax - x + data.offsetX) * mixX; + y += (target.ay - y + data.offsetY) * mixY; float scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix != 0) { - if (scaleX != 0) scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * scaleMix) / scaleX; - if (scaleY != 0) scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * scaleMix) / scaleY; - } + if (mixScaleX != 0 && scaleX != 0) + scaleX = (scaleX + (target.ascaleX - scaleX + data.offsetScaleX) * mixScaleX) / scaleX; + if (mixScaleY != 0 && scaleY != 0) + scaleY = (scaleY + (target.ascaleY - scaleY + data.offsetScaleY) * mixScaleY) / scaleY; float shearY = bone.ashearY; - if (shearMix != 0) { + if (mixShearY != 0) { float r = target.ashearY - shearY + data.offsetShearY; r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; - shearY += r * shearMix; + shearY += r * mixShearY; } bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); @@ -246,31 +266,23 @@ namespace Spine { } void ApplyRelativeLocal () { - float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, + mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; + Bone target = this.target; if (!target.appliedValid) target.UpdateAppliedTransform(); + var bones = this.bones.Items; for (int i = 0, n = this.bones.Count; i < n; i++) { Bone bone = bones[i]; if (!bone.appliedValid) bone.UpdateAppliedTransform(); - float rotation = bone.arotation; - if (rotateMix != 0) rotation += (target.arotation + data.offsetRotation) * rotateMix; - - float x = bone.ax, y = bone.ay; - if (translateMix != 0) { - x += (target.ax + data.offsetX) * translateMix; - y += (target.ay + data.offsetY) * translateMix; - } - - float scaleX = bone.ascaleX, scaleY = bone.ascaleY; - if (scaleMix != 0) { - scaleX *= ((target.ascaleX - 1 + data.offsetScaleX) * scaleMix) + 1; - scaleY *= ((target.ascaleY - 1 + data.offsetScaleY) * scaleMix) + 1; - } - - float shearY = bone.ashearY; - if (shearMix != 0) shearY += (target.ashearY + data.offsetShearY) * shearMix; + float rotation = bone.arotation + (target.arotation + data.offsetRotation) * mixRotate; + float x = bone.ax + (target.ax + data.offsetX) * mixX; + float y = bone.ay + (target.ay + data.offsetY) * mixY; + float scaleX = (bone.ascaleX * ((target.ascaleX - 1 + data.offsetScaleX) * mixScaleX) + 1); + float scaleY = (bone.ascaleY * ((target.ascaleY - 1 + data.offsetScaleY) * mixScaleY) + 1); + float shearY = bone.ashearY + (target.ashearY + data.offsetShearY) * mixShearY; bone.UpdateWorldTransform(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); } @@ -280,14 +292,18 @@ namespace Spine { public ExposedList Bones { get { return bones; } } /// The target bone whose world transform will be copied to the constrained bones. public Bone Target { get { return target; } set { target = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. - public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained translations. - public float TranslateMix { get { return translateMix; } set { translateMix = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained scales. - public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } } - /// A percentage (0-1) that controls the mix between the constrained and unconstrained scales. - public float ShearMix { get { return shearMix; } set { shearMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + public float MixRotate { get { return mixRotate; } set { mixRotate = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + public float MixX { get { return mixX; } set { mixX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + public float MixY { get { return mixY; } set { mixY = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. + public float MixScaleX { get { return mixScaleX; } set { mixScaleX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. + 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; } } public bool Active { get { return active; } } /// The transform constraint's setup pose data. public TransformConstraintData Data { get { return data; } } diff --git a/spine-csharp/src/TransformConstraintData.cs b/spine-csharp/src/TransformConstraintData.cs index f3da4d6a0..f33bb76e3 100644 --- a/spine-csharp/src/TransformConstraintData.cs +++ b/spine-csharp/src/TransformConstraintData.cs @@ -33,16 +33,24 @@ namespace Spine { public class TransformConstraintData : ConstraintData { internal ExposedList bones = new ExposedList(); internal BoneData target; - internal float rotateMix, translateMix, scaleMix, shearMix; + internal float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY; internal bool relative, local; public ExposedList Bones { get { return bones; } } public BoneData Target { get { return target; } set { target = value; } } - public float RotateMix { get { return rotateMix; } set { rotateMix = value; } } - public float TranslateMix { get { return translateMix; } set { translateMix = value; } } - public float ScaleMix { get { return scaleMix; } set { scaleMix = value; } } - public float ShearMix { get { return shearMix; } set { shearMix = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + public float MixRotate { get { return mixRotate; } set { mixRotate = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + public float MixX { get { return mixX; } set { mixX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + public float MixY { get { return mixY; } set { mixY = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. + public float MixScaleX { get { return mixScaleX; } set { mixScaleX = value; } } + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. + 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; } } public float OffsetRotation { get { return offsetRotation; } set { offsetRotation = value; } } public float OffsetX { get { return offsetX; } set { offsetX = value; } } diff --git a/spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs b/spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs index 6afc574d4..ad0753ef4 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/MecanimAnimationMatchModifier/AnimationMatchModifierAsset.cs @@ -206,7 +206,7 @@ namespace Spine.Unity.Examples { static TransformConstraintTimeline GetFillerTimeline (TransformConstraintTimeline timeline, SkeletonData skeletonData) { var t = new TransformConstraintTimeline(1, 0, timeline.TransformConstraintIndex); var data = skeletonData.TransformConstraints.Items[timeline.TransformConstraintIndex]; - t.SetFrame(0, 0, data.RotateMix, data.TranslateMix, data.ScaleMix, data.ShearMix); + t.SetFrame(0, 0, data.MixRotate, data.MixX, data.MixY, data.MixScaleX, data.MixScaleY, data.MixShearY); return t; } @@ -227,7 +227,7 @@ namespace Spine.Unity.Examples { static PathConstraintMixTimeline GetFillerTimeline (PathConstraintMixTimeline timeline, SkeletonData skeletonData) { var t = new PathConstraintMixTimeline(1, 0, timeline.PathConstraintIndex); var data = skeletonData.PathConstraints.Items[timeline.PathConstraintIndex]; - t.SetFrame(0, 0, data.RotateMix, data.TranslateMix); + t.SetFrame(0, 0, data.RotateMix, data.MixX, data.MixY); return t; } #endregion diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll.cs index 6f7750ccd..0a57df9e9 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll.cs @@ -212,16 +212,19 @@ namespace Spine.Unity.Examples { if (disableOtherConstraints) { var transformConstraints = skeleton.TransformConstraints; for (int i = 0, n = transformConstraints.Count; i < n; i++) { - transformConstraints.Items[i].RotateMix = 0; - transformConstraints.Items[i].ScaleMix = 0; - transformConstraints.Items[i].ShearMix = 0; - transformConstraints.Items[i].TranslateMix = 0; + transformConstraints.Items[i].MixRotate = 0; + transformConstraints.Items[i].MixScaleX = 0; + transformConstraints.Items[i].MixScaleY = 0; + transformConstraints.Items[i].MixShearY = 0; + transformConstraints.Items[i].MixX = 0; + transformConstraints.Items[i].MixY = 0; } var pathConstraints = skeleton.PathConstraints; for (int i = 0, n = pathConstraints.Count; i < n; i++) { - pathConstraints.Items[i].RotateMix = 0; - pathConstraints.Items[i].TranslateMix = 0; + pathConstraints.Items[i].MixRotate = 0; + pathConstraints.Items[i].MixX = 0; + pathConstraints.Items[i].MixY = 0; } } diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll2D.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll2D.cs index cad12b8bc..e064f1c69 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll2D.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonUtility Modules/SkeletonRagdoll2D.cs @@ -224,16 +224,19 @@ namespace Spine.Unity.Examples { if (disableOtherConstraints) { var transformConstraints = skeleton.TransformConstraints; for (int i = 0, n = transformConstraints.Count; i < n; i++) { - transformConstraints.Items[i].RotateMix = 0; - transformConstraints.Items[i].ScaleMix = 0; - transformConstraints.Items[i].ShearMix = 0; - transformConstraints.Items[i].TranslateMix = 0; + transformConstraints.Items[i].MixRotate = 0; + transformConstraints.Items[i].MixScaleX = 0; + transformConstraints.Items[i].MixScaleY = 0; + transformConstraints.Items[i].MixShearY = 0; + transformConstraints.Items[i].MixX = 0; + transformConstraints.Items[i].MixY = 0; } var pathConstraints = skeleton.PathConstraints; for (int i = 0, n = pathConstraints.Count; i < n; i++) { - pathConstraints.Items[i].RotateMix = 0; - pathConstraints.Items[i].TranslateMix = 0; + pathConstraints.Items[i].MixRotate = 0; + pathConstraints.Items[i].MixX = 0; + pathConstraints.Items[i].MixY = 0; } } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs index 84f382785..f2b69a7fc 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineHandles.cs @@ -359,8 +359,9 @@ namespace Spine.Unity.Editor { var targetBone = tc.Target; targetPos = targetBone.GetWorldPosition(transform, skeletonRenderScale); - if (tc.TranslateMix > 0) { - if (tc.TranslateMix != 1f) { + if (tc.MixX > 0 || tc.MixY > 0) { + if ((tc.MixX > 0 && tc.MixX != 1f) || + (tc.MixY > 0 && tc.MixY != 1f)) { Handles.color = handleColor; foreach (var b in tc.Bones) { pos = b.GetWorldPosition(transform, skeletonRenderScale); @@ -416,7 +417,7 @@ namespace Spine.Unity.Editor { // Path Constraints handleColor = SpineHandles.PathColor; foreach (var pc in skeleton.PathConstraints) { - active = pc.TranslateMix > 0; + active = pc.MixX > 0 || pc.MixY > 0 || pc.MixRotate > 0; if (active) foreach (var b in pc.Bones) SpineHandles.DrawBoneCircle(b.GetWorldPosition(transform, skeletonRenderScale), handleColor, normal, 1f * skeletonRenderScale); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs index 4170a5542..011c6f013 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonDebugWindow.cs @@ -419,10 +419,12 @@ namespace Spine.Unity.Editor { EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); - c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); - c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); - c.ScaleMix = EditorGUILayout.Slider("ScaleMix", c.ScaleMix, MixMin, MixMax); - c.ShearMix = EditorGUILayout.Slider("ShearMix", c.ShearMix, MixMin, MixMax); + c.MixX = EditorGUILayout.Slider("Mix Translate X", c.MixX, MixMin, MixMax); + c.MixY = EditorGUILayout.Slider("Mix Translate Y", c.MixY, MixMin, MixMax); + c.MixRotate = EditorGUILayout.Slider("Mix Rotate", c.MixRotate, MixMin, MixMax); + c.MixScaleX = EditorGUILayout.Slider("Mix Scale X", c.MixScaleX, MixMin, MixMax); + c.MixScaleY = EditorGUILayout.Slider("Mix Scale Y", c.MixScaleY, MixMin, MixMax); + c.MixShearY = EditorGUILayout.Slider("Mix Shear Y", c.MixShearY, MixMin, MixMax); if (EditorGUI.EndChangeCheck()) requireRepaint = true; EditorGUILayout.Space(); @@ -452,8 +454,9 @@ namespace Spine.Unity.Editor { EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); - c.RotateMix = EditorGUILayout.Slider("RotateMix", c.RotateMix, MixMin, MixMax); - c.TranslateMix = EditorGUILayout.Slider("TranslateMix", c.TranslateMix, MixMin, MixMax); + c.MixRotate = EditorGUILayout.Slider("Mix Rotate", c.MixRotate, MixMin, MixMax); + c.MixX = EditorGUILayout.Slider("Mix Translate X", c.MixX, MixMin, MixMax); + c.MixY = EditorGUILayout.Slider("Mix Translate Y", c.MixY, MixMin, MixMax); c.Position = EditorGUILayout.FloatField("Position", c.Position); c.Spacing = EditorGUILayout.FloatField("Spacing", c.Spacing); if (EditorGUI.EndChangeCheck()) requireRepaint = true;