diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs
index 1af9614e4..3087dc60b 100644
--- a/spine-csharp/src/Animation.cs
+++ b/spine-csharp/src/Animation.cs
@@ -176,7 +176,7 @@ namespace Spine {
}
public enum Property {
- Rotate = 0, X, Y, ScaleX, ScaleY, ShearX, ShearY, //
+ Rotate = 0, X, Y, ScaleX, ScaleY, ShearX, ShearY, Inherit, //
RGB, Alpha, RGB2, //
Attachment, Deform, //
Event, DrawOrder, //
@@ -980,6 +980,53 @@ namespace Spine {
}
}
+ /// Changes a bone's .
+
+ public class InheritTimeline : Timeline, IBoneTimeline {
+ public const int ENTRIES = 2;
+ public const int INHERIT = 1;
+
+ readonly int boneIndex;
+
+ public InheritTimeline (int frameCount, int boneIndex)
+ : base(frameCount, (int)Property.Inherit + "|" + boneIndex) {
+ this.boneIndex = boneIndex;
+ }
+
+ public int BoneIndex {
+ get {
+ return boneIndex;
+ }
+ }
+
+ public override int FrameEntries {
+ get { return ENTRIES; }
+ }
+
+ /// Sets the transform mode for the specified frame.
+ /// Between 0 and frameCount, inclusive.
+ /// The frame time in seconds.
+ public void SetFrame (int frame, float time, Inherit inherit) {
+ frame *= ENTRIES;
+ frames[frame] = time;
+ frames[frame + INHERIT] = (int)inherit;
+ }
+
+ override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList firedEvents, float alpha, MixBlend blend,
+ MixDirection direction) {
+
+ Bone bone = skeleton.bones.Items[boneIndex];
+ if (!bone.active) return;
+
+ float[] frames = this.frames;
+ if (time < frames[0]) {
+ if (blend == MixBlend.Setup || blend == MixBlend.First) bone.inherit = bone.data.inherit;
+ return;
+ }
+ bone.inherit = InheritEnum.Values[(int)frames[Search(frames, time, ENTRIES) + INHERIT]];
+ }
+ }
+
/// Changes a slot's .
public class RGBATimeline : CurveTimeline, ISlotTimeline {
public const int ENTRIES = 5;
diff --git a/spine-csharp/src/Bone.cs b/spine-csharp/src/Bone.cs
index f35fb0cd2..c090e706f 100644
--- a/spine-csharp/src/Bone.cs
+++ b/spine-csharp/src/Bone.cs
@@ -52,6 +52,7 @@ namespace Spine {
internal float a, b, worldX;
internal float c, d, worldY;
+ internal Inherit inherit;
internal bool sorted, active;
@@ -79,6 +80,9 @@ namespace Spine {
/// The local shearY.
public float ShearY { get { return shearY; } set { shearY = value; } }
+ /// Controls how parent world transforms affect this bone.
+ public Inherit Inherit { get { return inherit; } set { inherit = value; } }
+
/// The rotation, as calculated by any constraints.
public float AppliedRotation { get { return arotation; } set { arotation = value; } }
@@ -147,6 +151,7 @@ namespace Spine {
scaleY = bone.scaleY;
shearX = bone.shearX;
shearY = bone.shearY;
+ inherit = bone.inherit;
}
/// Computes the world transform using the parent bone and this bone's local applied transform.
@@ -192,8 +197,8 @@ namespace Spine {
worldX = pa * x + pb * y + parent.worldX;
worldY = pc * x + pd * y + parent.worldY;
- switch (data.transformMode) {
- case TransformMode.Normal: {
+ switch (inherit) {
+ case Inherit.Normal: {
float rx = (rotation + shearX) * MathUtils.DegRad;
float ry = (rotation + 90 + shearY) * MathUtils.DegRad;
float la = (float)Math.Cos(rx) * scaleX;
@@ -206,7 +211,7 @@ namespace Spine {
d = pc * lb + pd * ld;
return;
}
- case TransformMode.OnlyTranslation: {
+ case Inherit.OnlyTranslation: {
float rx = (rotation + shearX) * MathUtils.DegRad;
float ry = (rotation + 90 + shearY) * MathUtils.DegRad;
a = (float)Math.Cos(rx) * scaleX;
@@ -215,7 +220,7 @@ namespace Spine {
d = (float)Math.Sin(ry) * scaleY;
break;
}
- case TransformMode.NoRotationOrReflection: {
+ case Inherit.NoRotationOrReflection: {
float s = pa * pa + pc * pc, prx;
if (s > 0.0001f) {
s = Math.Abs(pa * pd - pb * pc) / s;
@@ -241,8 +246,8 @@ namespace Spine {
d = pc * lb + pd * ld;
break;
}
- case TransformMode.NoScale:
- case TransformMode.NoScaleOrReflection: {
+ case Inherit.NoScale:
+ case Inherit.NoScaleOrReflection: {
rotation *= MathUtils.DegRad;
float cos = (float)Math.Cos(rotation), sin = (float)Math.Sin(rotation);
float za = (pa * cos + pb * sin) / skeleton.scaleX;
@@ -252,8 +257,7 @@ namespace Spine {
za *= s;
zc *= s;
s = (float)Math.Sqrt(za * za + zc * zc);
- if (data.transformMode == TransformMode.NoScale
- && (pa * pd - pb * pc < 0) != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
+ if (inherit == Inherit.NoScale && (pa * pd - pb * pc < 0) != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
rotation = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
float zb = (float)Math.Cos(rotation) * s;
float zd = (float)Math.Sin(rotation) * s;
@@ -286,6 +290,7 @@ namespace Spine {
scaleY = data.scaleY;
shearX = data.shearX;
shearY = data.shearY;
+ inherit = data.inherit;
}
///
@@ -320,14 +325,14 @@ namespace Spine {
ay = (dy * id - dx * ic);
float ra, rb, rc, rd;
- if (data.transformMode == TransformMode.OnlyTranslation) {
+ if (inherit == Inherit.OnlyTranslation) {
ra = a;
rb = b;
rc = c;
rd = d;
} else {
- switch (data.transformMode) {
- case TransformMode.NoRotationOrReflection: {
+ switch (inherit) {
+ case Inherit.NoRotationOrReflection: {
float s = Math.Abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
float sa = pa / skeleton.scaleX;
float sc = pc / skeleton.scaleY;
@@ -338,8 +343,8 @@ namespace Spine {
ib = pb * pid;
break;
}
- case TransformMode.NoScale:
- case TransformMode.NoScaleOrReflection: {
+ case Inherit.NoScale:
+ case Inherit.NoScaleOrReflection: {
float r = rotation * MathUtils.DegRad, cos = (float)Math.Cos(r), sin = (float)Math.Sin(r);
pa = (pa * cos + pb * sin) / skeleton.scaleX;
pc = (pc * cos + pd * sin) / skeleton.scaleY;
@@ -348,7 +353,7 @@ namespace Spine {
pa *= s;
pc *= s;
s = (float)Math.Sqrt(pa * pa + pc * pc);
- if (data.transformMode == TransformMode.NoScale && pid < 0 != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
+ if (inherit == Inherit.NoScale && pid < 0 != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
r = MathUtils.PI / 2 + MathUtils.Atan2(pc, pa);
pb = (float)Math.Cos(r) * s;
pd = (float)Math.Sin(r) * s;
diff --git a/spine-csharp/src/BoneData.cs b/spine-csharp/src/BoneData.cs
index 203643c0b..53a6c5166 100644
--- a/spine-csharp/src/BoneData.cs
+++ b/spine-csharp/src/BoneData.cs
@@ -36,7 +36,7 @@ namespace Spine {
internal BoneData parent;
internal float length;
internal float x, y, rotation, scaleX = 1, scaleY = 1, shearX, shearY;
- internal TransformMode transformMode = TransformMode.Normal;
+ internal Inherit inherit = Inherit.Normal;
internal bool skinRequired;
/// The index of the bone in Skeleton.Bones
@@ -71,8 +71,8 @@ namespace Spine {
/// Local shearY.
public float ShearY { get { return shearY; } set { shearY = value; } }
- /// The transform mode for how parent world transforms affect this bone.
- public TransformMode TransformMode { get { return transformMode; } set { transformMode = value; } }
+ /// Determines how parent world transforms affect this bone.
+ public Inherit Inherit { get { return inherit; } set { inherit = value; } }
/// When true, only updates this bone if the contains
/// this bone.
@@ -93,13 +93,21 @@ namespace Spine {
}
}
- [Flags]
- public enum TransformMode {
- //0000 0 Flip Scale Rotation
- Normal = 0, // 0000
- OnlyTranslation = 7, // 0111
- NoRotationOrReflection = 1, // 0001
- NoScale = 2, // 0010
- NoScaleOrReflection = 6, // 0110
+ public enum Inherit {
+ Normal,
+ OnlyTranslation,
+ NoRotationOrReflection,
+ NoScale,
+ NoScaleOrReflection
+ }
+
+ public class InheritEnum {
+ public static readonly Inherit[] Values = {
+ Inherit.Normal,
+ Inherit.OnlyTranslation,
+ Inherit.NoRotationOrReflection,
+ Inherit.NoScale,
+ Inherit.NoScaleOrReflection
+ };
}
}
diff --git a/spine-csharp/src/IkConstraint.cs b/spine-csharp/src/IkConstraint.cs
index 94659ef55..8122208a9 100644
--- a/spine-csharp/src/IkConstraint.cs
+++ b/spine-csharp/src/IkConstraint.cs
@@ -175,12 +175,12 @@ namespace Spine {
float rotationIK = -bone.ashearX - bone.arotation;
float tx = 0, ty = 0;
- switch (bone.data.transformMode) {
- case TransformMode.OnlyTranslation:
+ switch (bone.inherit) {
+ case Inherit.OnlyTranslation:
tx = (targetX - bone.worldX) * Math.Sign(bone.skeleton.ScaleX);
ty = (targetY - bone.worldY) * Math.Sign(bone.skeleton.ScaleY);
break;
- case TransformMode.NoRotationOrReflection: {
+ case Inherit.NoRotationOrReflection: {
float s = Math.Abs(pa * pd - pb * pc) / Math.Max(0.0001f, pa * pa + pc * pc);
float sa = pa / bone.skeleton.scaleX;
float sc = pc / bone.skeleton.scaleY;
@@ -212,9 +212,9 @@ namespace Spine {
float sx = bone.ascaleX, sy = bone.ascaleY;
if (compress || stretch) {
- switch (bone.data.transformMode) {
- case TransformMode.NoScale:
- case TransformMode.NoScaleOrReflection:
+ switch (bone.inherit) {
+ case Inherit.NoScale:
+ case Inherit.NoScaleOrReflection:
tx = targetX - bone.worldX;
ty = targetY - bone.worldY;
break;
@@ -238,6 +238,7 @@ namespace Spine {
float softness, float alpha) {
if (parent == null) throw new ArgumentNullException("parent", "parent cannot be null.");
if (child == null) throw new ArgumentNullException("child", "child cannot be null.");
+ if (parent.inherit != Inherit.Normal || child.inherit != Inherit.Normal) return;
float px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX;
int os1, os2, s2;
if (psx < 0) {
diff --git a/spine-csharp/src/SkeletonBinary.cs b/spine-csharp/src/SkeletonBinary.cs
index f9f0f503e..c66d0270c 100644
--- a/spine-csharp/src/SkeletonBinary.cs
+++ b/spine-csharp/src/SkeletonBinary.cs
@@ -53,6 +53,7 @@ namespace Spine {
public const int BONE_SHEAR = 7;
public const int BONE_SHEARX = 8;
public const int BONE_SHEARY = 9;
+ public const int BONE_INHERIT = 10;
public const int SLOT_ATTACHMENT = 0;
public const int SLOT_RGBA = 1;
@@ -118,14 +119,6 @@ namespace Spine {
}
#endif // WINDOWS_STOREAPP
- public static readonly TransformMode[] TransformModeValues = {
- TransformMode.Normal,
- TransformMode.OnlyTranslation,
- TransformMode.NoRotationOrReflection,
- TransformMode.NoScale,
- TransformMode.NoScaleOrReflection
- };
-
/// Returns the version string of binary skeleton data.
public static string GetVersionString (Stream file) {
if (file == null) throw new ArgumentNullException("file");
@@ -187,7 +180,7 @@ namespace Spine {
data.shearX = input.ReadFloat();
data.shearY = input.ReadFloat();
data.Length = input.ReadFloat() * scale;
- data.transformMode = TransformModeValues[input.ReadInt(true)];
+ data.inherit = InheritEnum.Values[input.ReadInt(true)];
data.skinRequired = input.ReadBoolean();
if (nonessential) { // discard non-essential data
input.ReadInt(); // Color.rgba8888ToColor(data.color, input.readInt());
@@ -844,7 +837,15 @@ namespace Spine {
for (int i = 0, n = input.ReadInt(true); i < n; i++) {
int boneIndex = input.ReadInt(true);
for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
- int type = input.ReadUByte(), frameCount = input.ReadInt(true), bezierCount = input.ReadInt(true);
+ int type = input.ReadUByte(), frameCount = input.ReadInt(true);
+ if (type == BONE_INHERIT) {
+ InheritTimeline timeline = new InheritTimeline(frameCount, boneIndex);
+ for (int frame = 0; frame < frameCount; frame++)
+ timeline.SetFrame(frame, input.ReadFloat(), InheritEnum.Values[input.ReadUByte()]);
+ timelines.Add(timeline);
+ continue;
+ }
+ int bezierCount = input.ReadInt(true);
switch (type) {
case BONE_ROTATE:
ReadTimeline(input, timelines, new RotateTimeline(frameCount, bezierCount, boneIndex), 1);
diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs
index bd166bfb8..852e9b369 100644
--- a/spine-csharp/src/SkeletonJson.cs
+++ b/spine-csharp/src/SkeletonJson.cs
@@ -133,8 +133,8 @@ namespace Spine {
data.shearX = GetFloat(boneMap, "shearX", 0);
data.shearY = GetFloat(boneMap, "shearY", 0);
- string tm = GetString(boneMap, "transform", TransformMode.Normal.ToString());
- data.transformMode = (TransformMode)Enum.Parse(typeof(TransformMode), tm, true);
+ string inheritString = GetString(boneMap, "inherit", Inherit.Normal.ToString());
+ data.inherit = (Inherit)Enum.Parse(typeof(Inherit), inheritString, true);
data.skinRequired = GetBoolean(boneMap, "skin", false);
skeletonData.bones.Add(data);
@@ -874,7 +874,19 @@ namespace Spine {
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(frames, frames, boneIndex), 0, 1));
else if (timelineName == "sheary")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(frames, frames, boneIndex), 0, 1));
- else
+ else if (timelineName == "inherit") {
+ InheritTimeline timeline = new InheritTimeline(frames, boneIndex);
+ for (int frame = 0; ; frame++) {
+ Dictionary keyMap = (Dictionary)keyMapEnumerator.Current;
+ float time = GetFloat(keyMap, "time", 0);
+ Inherit inherit = (Inherit)Enum.Parse(typeof(Inherit), GetString(keyMap, "inherit", Inherit.Normal.ToString()), true);
+ timeline.SetFrame(frame, time, inherit);
+ if (!keyMapEnumerator.MoveNext()) {
+ break;
+ }
+ }
+ timelines.Add(timeline);
+ } else
throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
}
}
diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs
index 58168f661..455f4743b 100644
--- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs
+++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs
@@ -329,13 +329,13 @@ namespace Spine.Unity.Editor {
boneTransform.parent = parentTransform;
boneTransform.localPosition = new Vector3(boneData.X, boneData.Y, 0);
- TransformMode tm = boneData.TransformMode;
- if (tm.InheritsRotation())
+ Inherit inherit = boneData.Inherit;
+ if (inherit.InheritsRotation())
boneTransform.localRotation = Quaternion.Euler(0, 0, boneData.Rotation);
else
boneTransform.rotation = Quaternion.Euler(0, 0, boneData.Rotation);
- if (tm.InheritsScale())
+ if (inherit.InheritsScale())
boneTransform.localScale = new Vector3(boneData.ScaleX, boneData.ScaleY, 1);
}
@@ -774,7 +774,7 @@ namespace Spine.Unity.Editor {
}
foreach (Bone b in skeleton.Bones) {
- if (!b.Data.TransformMode.InheritsRotation()) {
+ if (!b.Data.Inherit.InheritsRotation()) {
int index = b.Data.Index;
if (ignoreRotateTimelineIndexes.Contains(index) == false) {
ignoreRotateTimelineIndexes.Add(index);
@@ -832,7 +832,7 @@ namespace Spine.Unity.Editor {
static void BakeBoneConstraints (Bone bone, Spine.Animation animation, AnimationClip clip) {
Skeleton skeleton = bone.Skeleton;
- bool inheritRotation = bone.Data.TransformMode.InheritsRotation();
+ bool inheritRotation = bone.Data.Inherit.InheritsRotation();
animation.Apply(skeleton, 0, 0, false, null, 1f, MixBlend.Setup, MixDirection.In);
skeleton.UpdateWorldTransform(Skeleton.Physics.Update);
diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs
index 246502bef..74da6287c 100644
--- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs
+++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtilityBone.cs
@@ -134,7 +134,7 @@ namespace Spine.Unity {
zPosition ? 0 : thisTransform.localPosition.z);
if (rotation) {
- if (bone.Data.TransformMode.InheritsRotation()) {
+ if (bone.Data.Inherit.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.Rotation);
} else {
Vector3 euler = skeletonTransform.rotation.eulerAngles;
@@ -154,7 +154,7 @@ namespace Spine.Unity {
zPosition ? 0 : thisTransform.localPosition.z);
if (rotation) {
- if (bone.Data.TransformMode.InheritsRotation()) {
+ if (bone.Data.Inherit.InheritsRotation()) {
thisTransform.localRotation = Quaternion.Euler(0, 0, bone.AppliedRotation);
} else {
Vector3 euler = skeletonTransform.rotation.eulerAngles;
@@ -222,7 +222,7 @@ namespace Spine.Unity {
}
public static bool BoneTransformModeIncompatible (Bone bone) {
- return !bone.Data.TransformMode.InheritsScale();
+ return !bone.Data.Inherit.InheritsScale();
}
public void AddBoundingBox (string skinName, string slotName, string attachmentName) {
diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs
index fc5f6fa55..f32ed5e40 100644
--- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs
+++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/SkeletonExtensions.cs
@@ -325,8 +325,8 @@ namespace Spine {
result.x = pa * boneData.X + pb * boneData.Y + parentMatrix.x;
result.y = pc * boneData.X + pd * boneData.Y + parentMatrix.y;
- switch (boneData.TransformMode) {
- case TransformMode.Normal: {
+ switch (boneData.Inherit) {
+ case Inherit.Normal: {
float rotationY = boneData.Rotation + 90 + boneData.ShearY;
float la = MathUtils.CosDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
float lb = MathUtils.CosDeg(rotationY) * boneData.ScaleY;
@@ -338,7 +338,7 @@ namespace Spine {
result.d = pc * lb + pd * ld;
break;
}
- case TransformMode.OnlyTranslation: {
+ case Inherit.OnlyTranslation: {
float rotationY = boneData.Rotation + 90 + boneData.ShearY;
result.a = MathUtils.CosDeg(boneData.Rotation + boneData.ShearX) * boneData.ScaleX;
result.b = MathUtils.CosDeg(rotationY) * boneData.ScaleY;
@@ -346,7 +346,7 @@ namespace Spine {
result.d = MathUtils.SinDeg(rotationY) * boneData.ScaleY;
break;
}
- case TransformMode.NoRotationOrReflection: {
+ case Inherit.NoRotationOrReflection: {
float s = pa * pa + pc * pc, prx;
if (s > 0.0001f) {
s = Math.Abs(pa * pd - pb * pc) / s;
@@ -370,8 +370,8 @@ namespace Spine {
result.d = pc * lb + pd * ld;
break;
}
- case TransformMode.NoScale:
- case TransformMode.NoScaleOrReflection: {
+ case Inherit.NoScale:
+ case Inherit.NoScaleOrReflection: {
float cos = MathUtils.CosDeg(boneData.Rotation), sin = MathUtils.SinDeg(boneData.Rotation);
float za = pa * cos + pb * sin;
float zc = pc * cos + pd * sin;
@@ -388,7 +388,7 @@ namespace Spine {
float lb = MathUtils.CosDeg(90 + boneData.ShearY) * boneData.ScaleY;
float lc = MathUtils.SinDeg(boneData.ShearX) * boneData.ScaleX;
float ld = MathUtils.SinDeg(90 + boneData.ShearY) * boneData.ScaleY;
- if (boneData.TransformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) {
+ if (boneData.Inherit != Inherit.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) {
zb = -zb;
zd = -zd;
}
@@ -446,15 +446,13 @@ namespace Spine {
return va.Bones != null && va.Bones.Length > 0;
}
- #region Transform Modes
- public static bool InheritsRotation (this TransformMode mode) {
- const int RotationBit = 0;
- return ((int)mode & (1U << RotationBit)) == 0;
+ #region Inherit Modes
+ public static bool InheritsRotation (this Inherit mode) {
+ return mode == Inherit.Normal || mode == Inherit.NoScale || mode == Inherit.NoScaleOrReflection;
}
- public static bool InheritsScale (this TransformMode mode) {
- const int ScaleBit = 1;
- return ((int)mode & (1U << ScaleBit)) == 0;
+ public static bool InheritsScale (this Inherit mode) {
+ return mode == Inherit.Normal || mode == Inherit.NoRotationOrReflection;
}
#endregion
}