mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[csharp] See #1346: Port bone/constraint association with skins. Also contains second (and final) partial port of commit ff5b854. Adapted spine-unity for skin changes. Fixed a bug in Skin setter property.
This commit is contained in:
parent
1eea0c24c9
commit
c63bc7b88f
@ -52,7 +52,7 @@ namespace Spine {
|
|||||||
/// <summary>The duration of the animation in seconds, which is the highest time of all keys in the timeline.</summary>
|
/// <summary>The duration of the animation in seconds, which is the highest time of all keys in the timeline.</summary>
|
||||||
public float Duration { get { return duration; } set { duration = value; } }
|
public float Duration { get { return duration; } set { duration = value; } }
|
||||||
|
|
||||||
/// <summary>The animation's name, which is unique within the skeleton.</summary>
|
/// <summary>The animation's name, which is unique across all animations in the skeleton.</summary>
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
|
|
||||||
/// <summary>Applies all the animation's timelines to the specified skeleton.</summary>
|
/// <summary>Applies all the animation's timelines to the specified skeleton.</summary>
|
||||||
|
|||||||
@ -195,8 +195,8 @@ namespace Spine {
|
|||||||
copy.rotation = rotation;
|
copy.rotation = rotation;
|
||||||
copy.width = width;
|
copy.width = width;
|
||||||
copy.height = height;
|
copy.height = height;
|
||||||
Array.Copy(uvs, 0, copy.uvs, 0, uvs.Length);
|
Array.Copy(uvs, 0, copy.uvs, 0, 8);
|
||||||
Array.Copy(offset, 0, copy.offset, 0, offset.Length);
|
Array.Copy(offset, 0, copy.offset, 0, 8);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,8 +133,7 @@ namespace Spine {
|
|||||||
return this == sourceAttachment;
|
return this == sourceAttachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>Internal method used by VertexAttachment subclasses to copy basic data. Does not copy id (generated) and name (set on
|
///<summary>Does not copy id (generated) or name (set on construction).</summary>
|
||||||
/// construction).</summary>
|
|
||||||
internal void CopyTo (VertexAttachment attachment) {
|
internal void CopyTo (VertexAttachment attachment) {
|
||||||
if (bones != null) {
|
if (bones != null) {
|
||||||
attachment.bones = new int[bones.Length];
|
attachment.bones = new int[bones.Length];
|
||||||
|
|||||||
@ -52,7 +52,7 @@ namespace Spine {
|
|||||||
internal float a, b, worldX;
|
internal float a, b, worldX;
|
||||||
internal float c, d, worldY;
|
internal float c, d, worldY;
|
||||||
|
|
||||||
internal bool sorted;
|
internal bool sorted, update;
|
||||||
|
|
||||||
public BoneData Data { get { return data; } }
|
public BoneData Data { get { return data; } }
|
||||||
public Skeleton Skeleton { get { return skeleton; } }
|
public Skeleton Skeleton { get { return skeleton; } }
|
||||||
|
|||||||
@ -37,11 +37,12 @@ namespace Spine {
|
|||||||
internal float length;
|
internal float length;
|
||||||
internal float x, y, rotation, scaleX = 1, scaleY = 1, shearX, shearY;
|
internal float x, y, rotation, scaleX = 1, scaleY = 1, shearX, shearY;
|
||||||
internal TransformMode transformMode = TransformMode.Normal;
|
internal TransformMode transformMode = TransformMode.Normal;
|
||||||
|
internal bool skinRequired;
|
||||||
|
|
||||||
/// <summary>The index of the bone in Skeleton.Bones</summary>
|
/// <summary>The index of the bone in Skeleton.Bones</summary>
|
||||||
public int Index { get { return index; } }
|
public int Index { get { return index; } }
|
||||||
|
|
||||||
/// <summary>The name of the bone, which is unique within the skeleton.</summary>
|
/// <summary>The name of the bone, which is unique across all bones in the skeleton.</summary>
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
|
|
||||||
/// <summary>May be null.</summary>
|
/// <summary>May be null.</summary>
|
||||||
@ -73,6 +74,11 @@ namespace Spine {
|
|||||||
/// <summary>The transform mode for how parent world transforms affect this bone.</summary>
|
/// <summary>The transform mode for how parent world transforms affect this bone.</summary>
|
||||||
public TransformMode TransformMode { get { return transformMode; } set { transformMode = value; } }
|
public TransformMode TransformMode { get { return transformMode; } set { transformMode = value; } }
|
||||||
|
|
||||||
|
///<summary>When true, <see cref="Skeleton.UpdateWorldTransform()"/> only updates this bone if the <see cref="Skeleton.Skin"/> contains this
|
||||||
|
/// bone.</summary>
|
||||||
|
/// <seealso cref="Skin.Bones"/>
|
||||||
|
public bool SkinRequired { get { return skinRequired; } set { skinRequired = value; } }
|
||||||
|
|
||||||
/// <param name="parent">May be null.</param>
|
/// <param name="parent">May be null.</param>
|
||||||
public BoneData (int index, string name, BoneData parent) {
|
public BoneData (int index, string name, BoneData parent) {
|
||||||
if (index < 0) throw new ArgumentException("index must be >= 0", "index");
|
if (index < 0) throw new ArgumentException("index must be >= 0", "index");
|
||||||
|
|||||||
@ -27,13 +27,36 @@
|
|||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
namespace Spine {
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
/// <summary>The interface for all constraints.</summary>
|
|
||||||
public interface IConstraint : IUpdatable {
|
|
||||||
/// <summary>The ordinal for the order a skeleton's constraints will be applied.</summary>
|
|
||||||
int Order { get; }
|
|
||||||
|
|
||||||
|
namespace Spine
|
||||||
|
{
|
||||||
|
/// <summary>The base class for all constraint datas.</summary>
|
||||||
|
public abstract class ConstraintData {
|
||||||
|
internal readonly string name;
|
||||||
|
internal int order;
|
||||||
|
internal bool skinRequired;
|
||||||
|
|
||||||
|
public ConstraintData (string name) {
|
||||||
|
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> The constraint's name, which is unique across all constraints in the skeleton of the same type.</summary>
|
||||||
|
public string Name { get { return name; } }
|
||||||
|
|
||||||
|
///<summary>The ordinal of this constraint for the order a skeleton's constraints will be applied by
|
||||||
|
/// <see cref="Skeleton.UpdateWorldTransform()"/>.</summary>
|
||||||
|
public int Order { get { return order; } set { order = value; } }
|
||||||
|
|
||||||
|
///<summary>When true, <see cref="Skeleton.UpdateWorldTransform()"/> only updates this constraint if the <see cref="Skeleton.Skin"/> contains
|
||||||
|
/// this constraint.</summary>
|
||||||
|
///<seealso cref="Skin.Constraints"/>
|
||||||
|
public bool SkinRequired { get { return skinRequired; } set { skinRequired = value; } }
|
||||||
|
|
||||||
|
override public string ToString () {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ namespace Spine {
|
|||||||
public class EventData {
|
public class EventData {
|
||||||
internal string name;
|
internal string name;
|
||||||
|
|
||||||
/// <summary>The name of the event, which is unique within the skeleton.</summary>
|
/// <summary>The name of the event, which is unique across all events in the skeleton.</summary>
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
public int Int { get; set; }
|
public int Int { get; set; }
|
||||||
public float Float { get; set; }
|
public float Float { get; set; }
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace Spine {
|
|||||||
/// <para>
|
/// <para>
|
||||||
/// See <a href="http://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide.</para>
|
/// See <a href="http://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IkConstraint : IConstraint {
|
public class IkConstraint : IUpdatable {
|
||||||
internal IkConstraintData data;
|
internal IkConstraintData data;
|
||||||
internal ExposedList<Bone> bones = new ExposedList<Bone>();
|
internal ExposedList<Bone> bones = new ExposedList<Bone>();
|
||||||
internal Bone target;
|
internal Bone target;
|
||||||
@ -93,11 +93,6 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int Order {
|
|
||||||
get { return data.order; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>The bones that will be modified by this IK constraint.</summary>
|
/// <summary>The bones that will be modified by this IK constraint.</summary>
|
||||||
public ExposedList<Bone> Bones {
|
public ExposedList<Bone> Bones {
|
||||||
get { return bones; }
|
get { return bones; }
|
||||||
|
|||||||
@ -32,23 +32,14 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Spine {
|
namespace Spine {
|
||||||
/// <summary>Stores the setup pose for an IkConstraint.</summary>
|
/// <summary>Stores the setup pose for an IkConstraint.</summary>
|
||||||
public class IkConstraintData {
|
public class IkConstraintData : ConstraintData {
|
||||||
internal string name;
|
|
||||||
internal int order;
|
|
||||||
internal List<BoneData> bones = new List<BoneData>();
|
internal List<BoneData> bones = new List<BoneData>();
|
||||||
internal BoneData target;
|
internal BoneData target;
|
||||||
internal int bendDirection = 1;
|
internal int bendDirection = 1;
|
||||||
internal bool compress, stretch, uniform;
|
internal bool compress, stretch, uniform;
|
||||||
internal float mix = 1;
|
internal float mix = 1;
|
||||||
|
|
||||||
/// <summary>The IK constraint's name, which is unique within the skeleton.</summary>
|
public IkConstraintData (string name) : base(name) {
|
||||||
public string Name {
|
|
||||||
get { return name; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Order {
|
|
||||||
get { return order; }
|
|
||||||
set { order = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>The bones that are constrained by this IK Constraint.</summary>
|
/// <summary>The bones that are constrained by this IK Constraint.</summary>
|
||||||
@ -98,14 +89,5 @@ namespace Spine {
|
|||||||
get { return uniform; }
|
get { return uniform; }
|
||||||
set { uniform = value; }
|
set { uniform = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IkConstraintData (string name) {
|
|
||||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
override public string ToString () {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ namespace Spine {
|
|||||||
/// <para>
|
/// <para>
|
||||||
/// See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide.</para>
|
/// See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PathConstraint : IConstraint {
|
public class PathConstraint : IUpdatable {
|
||||||
const int NONE = -1, BEFORE = -2, AFTER = -3;
|
const int NONE = -1, BEFORE = -2, AFTER = -3;
|
||||||
const float Epsilon = 0.00001f;
|
const float Epsilon = 0.00001f;
|
||||||
|
|
||||||
@ -446,7 +446,6 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get { return data.order; } }
|
|
||||||
/// <summary>The position along the path.</summary>
|
/// <summary>The position along the path.</summary>
|
||||||
public float Position { get { return position; } set { position = value; } }
|
public float Position { get { return position; } set { position = value; } }
|
||||||
/// <summary>The spacing between bones.</summary>
|
/// <summary>The spacing between bones.</summary>
|
||||||
@ -461,9 +460,5 @@ namespace Spine {
|
|||||||
public Slot Target { get { return target; } set { target = value; } }
|
public Slot Target { get { return target; } set { target = value; } }
|
||||||
/// <summary>The path constraint's setup pose data.</summary>
|
/// <summary>The path constraint's setup pose data.</summary>
|
||||||
public PathConstraintData Data { get { return data; } }
|
public PathConstraintData Data { get { return data; } }
|
||||||
|
|
||||||
override public string ToString () {
|
|
||||||
return data.name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,9 +30,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Spine {
|
namespace Spine {
|
||||||
public class PathConstraintData {
|
public class PathConstraintData : ConstraintData {
|
||||||
internal string name;
|
|
||||||
internal int order;
|
|
||||||
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
||||||
internal SlotData target;
|
internal SlotData target;
|
||||||
internal PositionMode positionMode;
|
internal PositionMode positionMode;
|
||||||
@ -41,8 +39,9 @@ namespace Spine {
|
|||||||
internal float offsetRotation;
|
internal float offsetRotation;
|
||||||
internal float position, spacing, rotateMix, translateMix;
|
internal float position, spacing, rotateMix, translateMix;
|
||||||
|
|
||||||
public string Name { get { return name; } }
|
public PathConstraintData (string name) : base(name) {
|
||||||
public int Order { get { return order; } set { order = value; } }
|
}
|
||||||
|
|
||||||
public ExposedList<BoneData> Bones { get { return bones; } }
|
public ExposedList<BoneData> Bones { get { return bones; } }
|
||||||
public SlotData Target { get { return target; } set { target = value; } }
|
public SlotData Target { get { return target; } set { target = value; } }
|
||||||
public PositionMode PositionMode { get { return positionMode; } set { positionMode = value; } }
|
public PositionMode PositionMode { get { return positionMode; } set { positionMode = value; } }
|
||||||
@ -53,15 +52,6 @@ namespace Spine {
|
|||||||
public float Spacing { get { return spacing; } set { spacing = value; } }
|
public float Spacing { get { return spacing; } set { spacing = value; } }
|
||||||
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
|
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
|
||||||
public float TranslateMix { get { return translateMix; } set { translateMix = value; } }
|
public float TranslateMix { get { return translateMix; } set { translateMix = value; } }
|
||||||
|
|
||||||
public PathConstraintData (String name) {
|
|
||||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString () {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PositionMode {
|
public enum PositionMode {
|
||||||
|
|||||||
@ -55,7 +55,7 @@ namespace Spine {
|
|||||||
public ExposedList<IkConstraint> IkConstraints { get { return ikConstraints; } }
|
public ExposedList<IkConstraint> IkConstraints { get { return ikConstraints; } }
|
||||||
public ExposedList<PathConstraint> PathConstraints { get { return pathConstraints; } }
|
public ExposedList<PathConstraint> PathConstraints { get { return pathConstraints; } }
|
||||||
public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } }
|
public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } }
|
||||||
public Skin Skin { get { return skin; } set { skin = value; } }
|
public Skin Skin { get { return skin; } set { SetSkin(value); } }
|
||||||
public float R { get { return r; } set { r = value; } }
|
public float R { get { return r; } set { r = value; } }
|
||||||
public float G { get { return g; } set { g = value; } }
|
public float G { get { return g; } set { g = value; } }
|
||||||
public float B { get { return b; } set { b = value; } }
|
public float B { get { return b; } set { b = value; } }
|
||||||
@ -118,21 +118,25 @@ namespace Spine {
|
|||||||
UpdateWorldTransform();
|
UpdateWorldTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added
|
/// <summary>Caches information about bones and constraints. Must be called if the skin is modified or if bones, constraints, or
|
||||||
/// or removed.</summary>
|
/// weighted path attachments are added or removed.</summary>
|
||||||
public void UpdateCache () {
|
public void UpdateCache () {
|
||||||
var updateCache = this.updateCache;
|
var updateCache = this.updateCache;
|
||||||
updateCache.Clear();
|
updateCache.Clear();
|
||||||
this.updateCacheReset.Clear();
|
this.updateCacheReset.Clear();
|
||||||
|
|
||||||
|
int boneCount = this.bones.Items.Length;
|
||||||
var bones = this.bones;
|
var bones = this.bones;
|
||||||
for (int i = 0, n = bones.Count; i < n; i++)
|
for (int i = 0; i < boneCount; i++) {
|
||||||
bones.Items[i].sorted = false;
|
Bone bone = bones.Items[i];
|
||||||
|
bone.update = !bone.data.skinRequired || (skin != null && skin.bones.Contains(bone.data));
|
||||||
|
bone.sorted = !bone.update;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count;
|
||||||
var ikConstraints = this.ikConstraints;
|
var ikConstraints = this.ikConstraints;
|
||||||
var transformConstraints = this.transformConstraints;
|
var transformConstraints = this.transformConstraints;
|
||||||
var pathConstraints = this.pathConstraints;
|
var pathConstraints = this.pathConstraints;
|
||||||
int ikCount = ikConstraints.Count, transformCount = transformConstraints.Count, pathCount = pathConstraints.Count;
|
|
||||||
int constraintCount = ikCount + transformCount + pathCount;
|
int constraintCount = ikCount + transformCount + pathCount;
|
||||||
//outer:
|
//outer:
|
||||||
for (int i = 0; i < constraintCount; i++) {
|
for (int i = 0; i < constraintCount; i++) {
|
||||||
@ -160,11 +164,13 @@ namespace Spine {
|
|||||||
continue_outer: {}
|
continue_outer: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0, n = bones.Count; i < n; i++)
|
for (int i = 0; i < boneCount; i++)
|
||||||
SortBone(bones.Items[i]);
|
SortBone(bones.Items[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SortIkConstraint (IkConstraint constraint) {
|
private void SortIkConstraint (IkConstraint constraint) {
|
||||||
|
if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return;
|
||||||
|
|
||||||
Bone target = constraint.target;
|
Bone target = constraint.target;
|
||||||
SortBone(target);
|
SortBone(target);
|
||||||
|
|
||||||
@ -185,15 +191,15 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SortPathConstraint (PathConstraint constraint) {
|
private void SortPathConstraint (PathConstraint constraint) {
|
||||||
|
if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return;
|
||||||
|
|
||||||
Slot slot = constraint.target;
|
Slot slot = constraint.target;
|
||||||
int slotIndex = slot.data.index;
|
int slotIndex = slot.data.index;
|
||||||
Bone slotBone = slot.bone;
|
Bone slotBone = slot.bone;
|
||||||
if (skin != null) SortPathConstraintAttachment(skin, slotIndex, slotBone);
|
if (skin != null) SortPathConstraintAttachment(skin, slotIndex, slotBone);
|
||||||
if (data.defaultSkin != null && data.defaultSkin != skin)
|
if (data.defaultSkin != null && data.defaultSkin != skin)
|
||||||
SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
|
SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
|
||||||
for (int ii = 0, nn = data.skins.Count; ii < nn; ii++)
|
|
||||||
SortPathConstraintAttachment(data.skins.Items[ii], slotIndex, slotBone);
|
|
||||||
|
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
if (attachment is PathAttachment) SortPathConstraintAttachment(attachment, slotBone);
|
if (attachment is PathAttachment) SortPathConstraintAttachment(attachment, slotBone);
|
||||||
|
|
||||||
@ -211,6 +217,8 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SortTransformConstraint (TransformConstraint constraint) {
|
private void SortTransformConstraint (TransformConstraint constraint) {
|
||||||
|
if (constraint.data.skinRequired && (skin == null || !skin.constraints.Contains(constraint.data))) return;
|
||||||
|
|
||||||
SortBone(constraint.target);
|
SortBone(constraint.target);
|
||||||
|
|
||||||
var constrained = constraint.bones;
|
var constrained = constraint.bones;
|
||||||
@ -269,6 +277,7 @@ namespace Spine {
|
|||||||
var bonesItems = bones.Items;
|
var bonesItems = bones.Items;
|
||||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||||
Bone bone = bonesItems[i];
|
Bone bone = bonesItems[i];
|
||||||
|
if (!bone.update) continue;
|
||||||
if (bone.sorted) SortReset(bone.children);
|
if (bone.sorted) SortReset(bone.children);
|
||||||
bone.sorted = false;
|
bone.sorted = false;
|
||||||
}
|
}
|
||||||
@ -295,7 +304,8 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the world transform for each bone and applies all constraints. The root bone will be temporarily parented to the specified bone.
|
/// Temporarily sets the root bone as a child of the specified bone, then updates the world transform for each bone and applies
|
||||||
|
/// all constraints.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateWorldTransform (Bone parent) {
|
public void UpdateWorldTransform (Bone parent) {
|
||||||
// This partial update avoids computing the world transform for constrained bones when 1) the bone is not updated
|
// This partial update avoids computing the world transform for constrained bones when 1) the bone is not updated
|
||||||
@ -315,8 +325,7 @@ namespace Spine {
|
|||||||
bone.appliedValid = true;
|
bone.appliedValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the parent bone transform to the root bone. The root bone
|
// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
|
||||||
// always inherits scale, rotation and reflection.
|
|
||||||
Bone rootBone = this.RootBone;
|
Bone rootBone = this.RootBone;
|
||||||
float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
float pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
||||||
rootBone.worldX = pa * x + pb * y + parent.worldX;
|
rootBone.worldX = pa * x + pb * y + parent.worldX;
|
||||||
@ -447,8 +456,12 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Attachments from the new skin are attached if the corresponding attachment from the old skin was attached.
|
/// <para>Sets the skin used to look up attachments before looking in the <see cref="SkeletonData.DefaultSkin"/>. If the
|
||||||
/// If there was no old skin, each slot's setup mode attachment is attached from the new skin.</para>
|
/// skin is changed, <see cref="UpdateCache()"/> is called.
|
||||||
|
/// </para>
|
||||||
|
/// <para>Attachments from the new skin are attached if the corresponding attachment from the old skin was attached.
|
||||||
|
/// If there was no old skin, each slot's setup mode attachment is attached from the new skin.
|
||||||
|
/// </para>
|
||||||
/// <para>After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
|
/// <para>After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
|
||||||
/// <see cref="Skeleton.SetSlotsToSetupPose()"/>.
|
/// <see cref="Skeleton.SetSlotsToSetupPose()"/>.
|
||||||
/// Also, often <see cref="AnimationState.Apply(Skeleton)"/> is called before the next time the
|
/// Also, often <see cref="AnimationState.Apply(Skeleton)"/> is called before the next time the
|
||||||
@ -456,6 +469,7 @@ namespace Spine {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="newSkin">May be null.</param>
|
/// <param name="newSkin">May be null.</param>
|
||||||
public void SetSkin (Skin newSkin) {
|
public void SetSkin (Skin newSkin) {
|
||||||
|
if (newSkin == skin) return;
|
||||||
if (newSkin != null) {
|
if (newSkin != null) {
|
||||||
if (skin != null)
|
if (skin != null)
|
||||||
newSkin.AttachAll(this, skin);
|
newSkin.AttachAll(this, skin);
|
||||||
@ -472,6 +486,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
skin = newSkin;
|
skin = newSkin;
|
||||||
|
UpdateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment name.</summary>
|
/// <summary>Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment name.</summary>
|
||||||
@ -528,7 +543,7 @@ namespace Spine {
|
|||||||
ExposedList<TransformConstraint> transformConstraints = this.transformConstraints;
|
ExposedList<TransformConstraint> transformConstraints = this.transformConstraints;
|
||||||
for (int i = 0, n = transformConstraints.Count; i < n; i++) {
|
for (int i = 0, n = transformConstraints.Count; i < n; i++) {
|
||||||
TransformConstraint transformConstraint = transformConstraints.Items[i];
|
TransformConstraint transformConstraint = transformConstraints.Items[i];
|
||||||
if (transformConstraint.data.name == constraintName) return transformConstraint;
|
if (transformConstraint.data.Name == constraintName) return transformConstraint;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -539,7 +554,7 @@ namespace Spine {
|
|||||||
ExposedList<PathConstraint> pathConstraints = this.pathConstraints;
|
ExposedList<PathConstraint> pathConstraints = this.pathConstraints;
|
||||||
for (int i = 0, n = pathConstraints.Count; i < n; i++) {
|
for (int i = 0, n = pathConstraints.Count; i < n; i++) {
|
||||||
PathConstraint constraint = pathConstraints.Items[i];
|
PathConstraint constraint = pathConstraints.Items[i];
|
||||||
if (constraint.data.name.Equals(constraintName)) return constraint;
|
if (constraint.data.Name.Equals(constraintName)) return constraint;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,6 +174,7 @@ namespace Spine {
|
|||||||
data.shearY = ReadFloat(input);
|
data.shearY = ReadFloat(input);
|
||||||
data.length = ReadFloat(input) * scale;
|
data.length = ReadFloat(input) * scale;
|
||||||
data.transformMode = TransformModeValues[ReadVarint(input, true)];
|
data.transformMode = TransformModeValues[ReadVarint(input, true)];
|
||||||
|
data.skinRequired = ReadBoolean(input);
|
||||||
if (nonessential) ReadInt(input); // Skip bone color.
|
if (nonessential) ReadInt(input); // Skip bone color.
|
||||||
skeletonData.bones.Add(data);
|
skeletonData.bones.Add(data);
|
||||||
}
|
}
|
||||||
@ -206,6 +207,7 @@ namespace Spine {
|
|||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
IkConstraintData data = new IkConstraintData(ReadString(input));
|
IkConstraintData data = new IkConstraintData(ReadString(input));
|
||||||
data.order = ReadVarint(input, true);
|
data.order = ReadVarint(input, true);
|
||||||
|
data.skinRequired = ReadBoolean(input);
|
||||||
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
||||||
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
||||||
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
||||||
@ -221,6 +223,7 @@ namespace Spine {
|
|||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
TransformConstraintData data = new TransformConstraintData(ReadString(input));
|
TransformConstraintData data = new TransformConstraintData(ReadString(input));
|
||||||
data.order = ReadVarint(input, true);
|
data.order = ReadVarint(input, true);
|
||||||
|
data.skinRequired = ReadBoolean(input);
|
||||||
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
||||||
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
||||||
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
data.target = skeletonData.bones.Items[ReadVarint(input, true)];
|
||||||
@ -243,6 +246,7 @@ namespace Spine {
|
|||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
PathConstraintData data = new PathConstraintData(ReadString(input));
|
PathConstraintData data = new PathConstraintData(ReadString(input));
|
||||||
data.order = ReadVarint(input, true);
|
data.order = ReadVarint(input, true);
|
||||||
|
data.skinRequired = ReadBoolean(input);
|
||||||
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++)
|
||||||
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
data.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
||||||
data.target = skeletonData.slots.Items[ReadVarint(input, true)];
|
data.target = skeletonData.slots.Items[ReadVarint(input, true)];
|
||||||
@ -260,7 +264,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default skin.
|
// Default skin.
|
||||||
Skin defaultSkin = ReadSkin(input, skeletonData, "default", nonessential);
|
Skin defaultSkin = ReadSkin(input, skeletonData, true, nonessential);
|
||||||
if (defaultSkin != null) {
|
if (defaultSkin != null) {
|
||||||
skeletonData.defaultSkin = defaultSkin;
|
skeletonData.defaultSkin = defaultSkin;
|
||||||
skeletonData.skins.Add(defaultSkin);
|
skeletonData.skins.Add(defaultSkin);
|
||||||
@ -268,7 +272,7 @@ namespace Spine {
|
|||||||
|
|
||||||
// Skins.
|
// Skins.
|
||||||
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
||||||
skeletonData.skins.Add(ReadSkin(input, skeletonData, ReadString(input), nonessential));
|
skeletonData.skins.Add(ReadSkin(input, skeletonData, false, nonessential));
|
||||||
|
|
||||||
// Linked meshes.
|
// Linked meshes.
|
||||||
for (int i = 0, n = linkedMeshes.Count; i < n; i++) {
|
for (int i = 0, n = linkedMeshes.Count; i < n; i++) {
|
||||||
@ -312,11 +316,19 @@ namespace Spine {
|
|||||||
|
|
||||||
|
|
||||||
/// <returns>May be null.</returns>
|
/// <returns>May be null.</returns>
|
||||||
private Skin ReadSkin (Stream input, SkeletonData skeletonData, String skinName, bool nonessential) {
|
private Skin ReadSkin (Stream input, SkeletonData skeletonData, bool defaultSkin, bool nonessential) {
|
||||||
int slotCount = ReadVarint(input, true);
|
Skin skin = new Skin(defaultSkin ? "default" : ReadString(input));
|
||||||
if (slotCount == 0) return null;
|
if (!defaultSkin) {
|
||||||
Skin skin = new Skin(skinName);
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
||||||
for (int i = 0; i < slotCount; i++) {
|
skin.bones.Add(skeletonData.bones.Items[ReadVarint(input, true)]);
|
||||||
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
||||||
|
skin.constraints.Add(skeletonData.ikConstraints.Items[ReadVarint(input, true)]);
|
||||||
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
||||||
|
skin.constraints.Add(skeletonData.transformConstraints.Items[ReadVarint(input, true)]);
|
||||||
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++)
|
||||||
|
skin.constraints.Add(skeletonData.pathConstraints.Items[ReadVarint(input, true)]);
|
||||||
|
}
|
||||||
|
for (int i = 0, n = ReadVarint(input, true); i < n; i++) {
|
||||||
int slotIndex = ReadVarint(input, true);
|
int slotIndex = ReadVarint(input, true);
|
||||||
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) {
|
for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) {
|
||||||
String name = ReadString(input);
|
String name = ReadString(input);
|
||||||
|
|||||||
@ -109,27 +109,30 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bones.
|
// Bones.
|
||||||
foreach (Dictionary<string, Object> boneMap in (List<Object>)root["bones"]) {
|
if (root.ContainsKey("bones")) {
|
||||||
BoneData parent = null;
|
foreach (Dictionary<string, Object> boneMap in (List<Object>)root["bones"]) {
|
||||||
if (boneMap.ContainsKey("parent")) {
|
BoneData parent = null;
|
||||||
parent = skeletonData.FindBone((string)boneMap["parent"]);
|
if (boneMap.ContainsKey("parent")) {
|
||||||
if (parent == null)
|
parent = skeletonData.FindBone((string)boneMap["parent"]);
|
||||||
throw new Exception("Parent bone not found: " + boneMap["parent"]);
|
if (parent == null)
|
||||||
|
throw new Exception("Parent bone not found: " + boneMap["parent"]);
|
||||||
|
}
|
||||||
|
var data = new BoneData(skeletonData.Bones.Count, (string)boneMap["name"], parent);
|
||||||
|
data.length = GetFloat(boneMap, "length", 0) * scale;
|
||||||
|
data.x = GetFloat(boneMap, "x", 0) * scale;
|
||||||
|
data.y = GetFloat(boneMap, "y", 0) * scale;
|
||||||
|
data.rotation = GetFloat(boneMap, "rotation", 0);
|
||||||
|
data.scaleX = GetFloat(boneMap, "scaleX", 1);
|
||||||
|
data.scaleY = GetFloat(boneMap, "scaleY", 1);
|
||||||
|
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);
|
||||||
|
data.skinRequired = GetBoolean(boneMap, "skin", false);
|
||||||
|
|
||||||
|
skeletonData.bones.Add(data);
|
||||||
}
|
}
|
||||||
var data = new BoneData(skeletonData.Bones.Count, (string)boneMap["name"], parent);
|
|
||||||
data.length = GetFloat(boneMap, "length", 0) * scale;
|
|
||||||
data.x = GetFloat(boneMap, "x", 0) * scale;
|
|
||||||
data.y = GetFloat(boneMap, "y", 0) * scale;
|
|
||||||
data.rotation = GetFloat(boneMap, "rotation", 0);
|
|
||||||
data.scaleX = GetFloat(boneMap, "scaleX", 1);
|
|
||||||
data.scaleY = GetFloat(boneMap, "scaleY", 1);
|
|
||||||
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);
|
|
||||||
|
|
||||||
skeletonData.bones.Add(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slots.
|
// Slots.
|
||||||
@ -171,16 +174,19 @@ namespace Spine {
|
|||||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["ik"]) {
|
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["ik"]) {
|
||||||
IkConstraintData data = new IkConstraintData((string)constraintMap["name"]);
|
IkConstraintData data = new IkConstraintData((string)constraintMap["name"]);
|
||||||
data.order = GetInt(constraintMap, "order", 0);
|
data.order = GetInt(constraintMap, "order", 0);
|
||||||
|
data.skinRequired = GetBoolean(constraintMap,"skin", false);
|
||||||
|
|
||||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
if (constraintMap.ContainsKey("bones")) {
|
||||||
BoneData bone = skeletonData.FindBone(boneName);
|
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||||
if (bone == null) throw new Exception("IK constraint bone not found: " + boneName);
|
BoneData bone = skeletonData.FindBone(boneName);
|
||||||
data.bones.Add(bone);
|
if (bone == null) throw new Exception("IK bone not found: " + boneName);
|
||||||
|
data.bones.Add(bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string targetName = (string)constraintMap["target"];
|
string targetName = (string)constraintMap["target"];
|
||||||
data.target = skeletonData.FindBone(targetName);
|
data.target = skeletonData.FindBone(targetName);
|
||||||
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
if (data.target == null) throw new Exception("IK target bone not found: " + targetName);
|
||||||
data.mix = GetFloat(constraintMap, "mix", 1);
|
data.mix = GetFloat(constraintMap, "mix", 1);
|
||||||
data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1;
|
data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1;
|
||||||
data.compress = GetBoolean(constraintMap, "compress", false);
|
data.compress = GetBoolean(constraintMap, "compress", false);
|
||||||
@ -196,16 +202,19 @@ namespace Spine {
|
|||||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["transform"]) {
|
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["transform"]) {
|
||||||
TransformConstraintData data = new TransformConstraintData((string)constraintMap["name"]);
|
TransformConstraintData data = new TransformConstraintData((string)constraintMap["name"]);
|
||||||
data.order = GetInt(constraintMap, "order", 0);
|
data.order = GetInt(constraintMap, "order", 0);
|
||||||
|
data.skinRequired = GetBoolean(constraintMap,"skin", false);
|
||||||
|
|
||||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
if (constraintMap.ContainsKey("bones")) {
|
||||||
BoneData bone = skeletonData.FindBone(boneName);
|
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||||
if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName);
|
BoneData bone = skeletonData.FindBone(boneName);
|
||||||
data.bones.Add(bone);
|
if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName);
|
||||||
|
data.bones.Add(bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string targetName = (string)constraintMap["target"];
|
string targetName = (string)constraintMap["target"];
|
||||||
data.target = skeletonData.FindBone(targetName);
|
data.target = skeletonData.FindBone(targetName);
|
||||||
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
|
if (data.target == null) throw new Exception("Transform constraint target bone not found: " + targetName);
|
||||||
|
|
||||||
data.local = GetBoolean(constraintMap, "local", false);
|
data.local = GetBoolean(constraintMap, "local", false);
|
||||||
data.relative = GetBoolean(constraintMap, "relative", false);
|
data.relative = GetBoolean(constraintMap, "relative", false);
|
||||||
@ -231,16 +240,19 @@ namespace Spine {
|
|||||||
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["path"]) {
|
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["path"]) {
|
||||||
PathConstraintData data = new PathConstraintData((string)constraintMap["name"]);
|
PathConstraintData data = new PathConstraintData((string)constraintMap["name"]);
|
||||||
data.order = GetInt(constraintMap, "order", 0);
|
data.order = GetInt(constraintMap, "order", 0);
|
||||||
|
data.skinRequired = GetBoolean(constraintMap,"skin", false);
|
||||||
|
|
||||||
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
if (constraintMap.ContainsKey("bones")) {
|
||||||
BoneData bone = skeletonData.FindBone(boneName);
|
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
|
||||||
if (bone == null) throw new Exception("Path bone not found: " + boneName);
|
BoneData bone = skeletonData.FindBone(boneName);
|
||||||
data.bones.Add(bone);
|
if (bone == null) throw new Exception("Path bone not found: " + boneName);
|
||||||
|
data.bones.Add(bone);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string targetName = (string)constraintMap["target"];
|
string targetName = (string)constraintMap["target"];
|
||||||
data.target = skeletonData.FindSlot(targetName);
|
data.target = skeletonData.FindSlot(targetName);
|
||||||
if (data.target == null) throw new Exception("Target slot not found: " + targetName);
|
if (data.target == null) throw new Exception("Path target slot not found: " + targetName);
|
||||||
|
|
||||||
data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true);
|
data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true);
|
||||||
data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true);
|
data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true);
|
||||||
@ -259,18 +271,48 @@ namespace Spine {
|
|||||||
|
|
||||||
// Skins.
|
// Skins.
|
||||||
if (root.ContainsKey("skins")) {
|
if (root.ContainsKey("skins")) {
|
||||||
foreach (KeyValuePair<string, Object> skinMap in (Dictionary<string, Object>)root["skins"]) {
|
foreach (Dictionary<string, object> skinMap in (List<object>)root["skins"]) {
|
||||||
var skin = new Skin(skinMap.Key);
|
Skin skin = new Skin((string)skinMap["name"]);
|
||||||
foreach (KeyValuePair<string, Object> slotEntry in (Dictionary<string, Object>)skinMap.Value) {
|
if (skinMap.ContainsKey("bones")) {
|
||||||
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
|
foreach (string entryName in (List<Object>)skinMap["bones"]) {
|
||||||
foreach (KeyValuePair<string, Object> entry in ((Dictionary<string, Object>)slotEntry.Value)) {
|
BoneData bone = skeletonData.FindBone(entryName);
|
||||||
try {
|
if (bone == null) throw new Exception("Skin bone not found: " + entryName);
|
||||||
Attachment attachment = ReadAttachment((Dictionary<string, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
|
skin.bones.Add(bone);
|
||||||
if (attachment != null) skin.SetAttachment(slotIndex, entry.Key, attachment);
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
|
if (skinMap.ContainsKey("ik")) {
|
||||||
}
|
foreach (string entryName in (List<Object>)skinMap["ik"]) {
|
||||||
}
|
IkConstraintData constraint = skeletonData.FindIkConstraint(entryName);
|
||||||
|
if (constraint == null) throw new Exception("Skin IK constraint not found: " + entryName);
|
||||||
|
skin.constraints.Add(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skinMap.ContainsKey("transform")) {
|
||||||
|
foreach (string entryName in (List<Object>)skinMap["transform"]) {
|
||||||
|
TransformConstraintData constraint = skeletonData.FindTransformConstraint(entryName);
|
||||||
|
if (constraint == null) throw new Exception("Skin transform constraint not found: " + entryName);
|
||||||
|
skin.constraints.Add(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skinMap.ContainsKey("path")) {
|
||||||
|
foreach (string entryName in (List<Object>)skinMap["path"]) {
|
||||||
|
PathConstraintData constraint = skeletonData.FindPathConstraint(entryName);
|
||||||
|
if (constraint == null) throw new Exception("Skin path constraint not found: " + entryName);
|
||||||
|
skin.constraints.Add(constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skinMap.ContainsKey("attachments")) {
|
||||||
|
foreach (KeyValuePair<string, Object> slotEntry in (Dictionary<string, Object>)skinMap["attachments"]) {
|
||||||
|
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
|
||||||
|
foreach (KeyValuePair<string, Object> entry in ((Dictionary<string, Object>)slotEntry.Value)) {
|
||||||
|
try {
|
||||||
|
Attachment attachment = ReadAttachment((Dictionary<string, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
|
||||||
|
if (attachment != null) skin.SetAttachment(slotIndex, entry.Key, attachment);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
skeletonData.skins.Add(skin);
|
skeletonData.skins.Add(skin);
|
||||||
if (skin.name == "default") skeletonData.defaultSkin = skin;
|
if (skin.name == "default") skeletonData.defaultSkin = skin;
|
||||||
@ -494,7 +536,7 @@ namespace Spine {
|
|||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
float time = (float)valueMap["time"];
|
float time = GetFloat(valueMap, "time", 0);
|
||||||
timeline.SetFrame(frameIndex++, time, (string)valueMap["name"]);
|
timeline.SetFrame(frameIndex++, time, (string)valueMap["name"]);
|
||||||
}
|
}
|
||||||
timelines.Add(timeline);
|
timelines.Add(timeline);
|
||||||
@ -506,7 +548,7 @@ namespace Spine {
|
|||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
float time = (float)valueMap["time"];
|
float time = GetFloat(valueMap, "time", 0);
|
||||||
string c = (string)valueMap["color"];
|
string c = (string)valueMap["color"];
|
||||||
timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
|
timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
@ -521,7 +563,7 @@ namespace Spine {
|
|||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
float time = (float)valueMap["time"];
|
float time = GetFloat(valueMap, "time", 0);
|
||||||
string light = (string)valueMap["light"];
|
string light = (string)valueMap["light"];
|
||||||
string dark = (string)valueMap["dark"];
|
string dark = (string)valueMap["dark"];
|
||||||
timeline.SetFrame(frameIndex, time, ToColor(light, 0), ToColor(light, 1), ToColor(light, 2), ToColor(light, 3),
|
timeline.SetFrame(frameIndex, time, ToColor(light, 0), ToColor(light, 1), ToColor(light, 2), ToColor(light, 3),
|
||||||
@ -554,7 +596,7 @@ namespace Spine {
|
|||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]);
|
timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "angle", 0));
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
}
|
}
|
||||||
@ -563,9 +605,11 @@ namespace Spine {
|
|||||||
|
|
||||||
} else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") {
|
} else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") {
|
||||||
TranslateTimeline timeline;
|
TranslateTimeline timeline;
|
||||||
float timelineScale = 1;
|
float timelineScale = 1, defaultValue = 0;
|
||||||
if (timelineName == "scale")
|
if (timelineName == "scale") {
|
||||||
timeline = new ScaleTimeline(values.Count);
|
timeline = new ScaleTimeline(values.Count);
|
||||||
|
defaultValue = 1;
|
||||||
|
}
|
||||||
else if (timelineName == "shear")
|
else if (timelineName == "shear")
|
||||||
timeline = new ShearTimeline(values.Count);
|
timeline = new ShearTimeline(values.Count);
|
||||||
else {
|
else {
|
||||||
@ -576,9 +620,9 @@ namespace Spine {
|
|||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
float time = (float)valueMap["time"];
|
float time = GetFloat(valueMap, "time", 0);
|
||||||
float x = GetFloat(valueMap, "x", 0);
|
float x = GetFloat(valueMap, "x", defaultValue);
|
||||||
float y = GetFloat(valueMap, "y", 0);
|
float y = GetFloat(valueMap, "y", defaultValue);
|
||||||
timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale);
|
timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale);
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
@ -603,7 +647,7 @@ namespace Spine {
|
|||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
timeline.SetFrame(
|
timeline.SetFrame(
|
||||||
frameIndex,
|
frameIndex,
|
||||||
(float)valueMap["time"],
|
GetFloat(valueMap, "time", 0),
|
||||||
GetFloat(valueMap, "mix", 1),
|
GetFloat(valueMap, "mix", 1),
|
||||||
GetBoolean(valueMap, "bendPositive", true) ? 1 : -1,
|
GetBoolean(valueMap, "bendPositive", true) ? 1 : -1,
|
||||||
GetBoolean(valueMap, "compress", true),
|
GetBoolean(valueMap, "compress", true),
|
||||||
@ -626,7 +670,7 @@ namespace Spine {
|
|||||||
timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
|
timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
float time = (float)valueMap["time"];
|
float time = GetFloat(valueMap, "time", 0);
|
||||||
float rotateMix = GetFloat(valueMap, "rotateMix", 1);
|
float rotateMix = GetFloat(valueMap, "rotateMix", 1);
|
||||||
float translateMix = GetFloat(valueMap, "translateMix", 1);
|
float translateMix = GetFloat(valueMap, "translateMix", 1);
|
||||||
float scaleMix = GetFloat(valueMap, "scaleMix", 1);
|
float scaleMix = GetFloat(valueMap, "scaleMix", 1);
|
||||||
@ -641,8 +685,8 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Path constraint timelines.
|
// Path constraint timelines.
|
||||||
if (map.ContainsKey("paths")) {
|
if (map.ContainsKey("path")) {
|
||||||
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["paths"]) {
|
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["path"]) {
|
||||||
int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
|
int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
|
||||||
if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
|
if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
|
||||||
PathConstraintData data = skeletonData.pathConstraints.Items[index];
|
PathConstraintData data = skeletonData.pathConstraints.Items[index];
|
||||||
@ -664,7 +708,7 @@ namespace Spine {
|
|||||||
timeline.pathConstraintIndex = index;
|
timeline.pathConstraintIndex = index;
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale);
|
timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, timelineName, 0) * timelineScale);
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
}
|
}
|
||||||
@ -676,7 +720,7 @@ namespace Spine {
|
|||||||
timeline.pathConstraintIndex = index;
|
timeline.pathConstraintIndex = index;
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
foreach (Dictionary<string, Object> valueMap in values) {
|
foreach (Dictionary<string, Object> valueMap in values) {
|
||||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
|
timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
}
|
}
|
||||||
@ -727,7 +771,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], deform);
|
timeline.SetFrame(frameIndex, GetFloat(valueMap, "time", 0), deform);
|
||||||
ReadCurve(valueMap, timeline, frameIndex);
|
ReadCurve(valueMap, timeline, frameIndex);
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
}
|
}
|
||||||
@ -770,7 +814,7 @@ namespace Spine {
|
|||||||
for (int i = slotCount - 1; i >= 0; i--)
|
for (int i = slotCount - 1; i >= 0; i--)
|
||||||
if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
|
if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
|
||||||
}
|
}
|
||||||
timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
|
timeline.SetFrame(frameIndex++, GetFloat(drawOrderMap, "time", 0), drawOrder);
|
||||||
}
|
}
|
||||||
timelines.Add(timeline);
|
timelines.Add(timeline);
|
||||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||||
@ -784,7 +828,7 @@ namespace Spine {
|
|||||||
foreach (Dictionary<string, Object> eventMap in eventsMap) {
|
foreach (Dictionary<string, Object> eventMap in eventsMap) {
|
||||||
EventData eventData = skeletonData.FindEvent((string)eventMap["name"]);
|
EventData eventData = skeletonData.FindEvent((string)eventMap["name"]);
|
||||||
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
|
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
|
||||||
var e = new Event((float)eventMap["time"], eventData) {
|
var e = new Event(GetFloat(eventMap, "time", 0), eventData) {
|
||||||
intValue = GetInt(eventMap, "int", eventData.Int),
|
intValue = GetInt(eventMap, "int", eventData.Int),
|
||||||
floatValue = GetFloat(eventMap, "float", eventData.Float),
|
floatValue = GetFloat(eventMap, "float", eventData.Float),
|
||||||
stringValue = GetString(eventMap, "string", eventData.String)
|
stringValue = GetString(eventMap, "string", eventData.String)
|
||||||
@ -807,12 +851,12 @@ namespace Spine {
|
|||||||
if (!valueMap.ContainsKey("curve"))
|
if (!valueMap.ContainsKey("curve"))
|
||||||
return;
|
return;
|
||||||
Object curveObject = valueMap["curve"];
|
Object curveObject = valueMap["curve"];
|
||||||
if (curveObject.Equals("stepped"))
|
if (curveObject is string)
|
||||||
timeline.SetStepped(frameIndex);
|
timeline.SetStepped(frameIndex);
|
||||||
else {
|
else {
|
||||||
var curve = curveObject as List<Object>;
|
var curve = curveObject as List<Object>;
|
||||||
if (curve != null)
|
if (curve != null)
|
||||||
timeline.SetCurve(frameIndex, (float)curve[0], (float)curve[1], (float)curve[2], (float)curve[3]);
|
timeline.SetCurve(frameIndex, (float)curveObject, GetFloat(valueMap, "c2", 0), GetFloat(valueMap, "c3", 1), GetFloat(valueMap, "c4", 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,9 +40,13 @@ namespace Spine {
|
|||||||
public class Skin {
|
public class Skin {
|
||||||
internal string name;
|
internal string name;
|
||||||
private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); // contains <SkinEntry, Attachment>
|
private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); // contains <SkinEntry, Attachment>
|
||||||
|
internal readonly ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
||||||
|
internal readonly ExposedList<ConstraintData> constraints = new ExposedList<ConstraintData>();
|
||||||
|
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
public OrderedDictionary Attachments { get { return attachments; } }
|
public OrderedDictionary Attachments { get { return attachments; } }
|
||||||
|
public ExposedList<BoneData> Bones { get { return bones; } }
|
||||||
|
public ExposedList<ConstraintData> Constraints { get { return constraints; } }
|
||||||
|
|
||||||
public Skin (string name) {
|
public Skin (string name) {
|
||||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
||||||
@ -59,13 +63,23 @@ namespace Spine {
|
|||||||
|
|
||||||
///<summary>Adds all attachments, bones, and constraints from the specified skin to this skin.</summary>
|
///<summary>Adds all attachments, bones, and constraints from the specified skin to this skin.</summary>
|
||||||
public void AddSkin (Skin skin) {
|
public void AddSkin (Skin skin) {
|
||||||
|
foreach (BoneData data in skin.bones)
|
||||||
|
if (!bones.Contains(data)) bones.Add(data);
|
||||||
|
|
||||||
|
foreach (ConstraintData data in skin.constraints)
|
||||||
|
if (!constraints.Contains(data)) constraints.Add(data);
|
||||||
|
|
||||||
foreach (SkinEntry entry in skin.attachments.Keys)
|
foreach (SkinEntry entry in skin.attachments.Keys)
|
||||||
SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment);
|
SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>Adds all attachments from the specified skin to this skin. Attachments are deep copied.</summary>
|
///<summary>Adds all attachments from the specified skin to this skin. Attachments are deep copied.</summary>
|
||||||
public void CopySkin (Skin skin) {
|
public void CopySkin (Skin skin) {
|
||||||
// note: bones and constraints are added in a separate commit.
|
foreach (BoneData data in skin.bones)
|
||||||
|
if (!bones.Contains(data)) bones.Add(data);
|
||||||
|
|
||||||
|
foreach (ConstraintData data in skin.constraints)
|
||||||
|
if (!constraints.Contains(data)) constraints.Add(data);
|
||||||
|
|
||||||
foreach (SkinEntry entry in skin.attachments.Keys) {
|
foreach (SkinEntry entry in skin.attachments.Keys) {
|
||||||
Attachment attachment = entry.Attachment.Copy();
|
Attachment attachment = entry.Attachment.Copy();
|
||||||
@ -98,13 +112,20 @@ namespace Spine {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns all attachments for the given slot in this skin.</summary>
|
/// <summary>Returns all attachments in this skin for the specified slot index.</summary>
|
||||||
/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
|
/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
|
||||||
public void GetAttachments (int slotIndex, List<SkinEntry> attachments) {
|
public void GetAttachments (int slotIndex, List<SkinEntry> attachments) {
|
||||||
foreach (SkinEntry entry in this.attachments.Keys)
|
foreach (SkinEntry entry in this.attachments.Keys)
|
||||||
if (entry.SlotIndex == slotIndex) attachments.Add(entry);
|
if (entry.SlotIndex == slotIndex) attachments.Add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///<summary>Clears all attachments, bones, and constraints.</summary>
|
||||||
|
public void Clear () {
|
||||||
|
attachments.Clear();
|
||||||
|
bones.Clear();
|
||||||
|
constraints.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
override public string ToString () {
|
override public string ToString () {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -141,6 +162,7 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>The name the attachment is associated with, equivalent to the skin placeholder name in the Spine editor.</summary>
|
||||||
public String Name {
|
public String Name {
|
||||||
get {
|
get {
|
||||||
return name;
|
return name;
|
||||||
|
|||||||
@ -40,8 +40,11 @@ namespace Spine {
|
|||||||
internal string attachmentName;
|
internal string attachmentName;
|
||||||
internal BlendMode blendMode;
|
internal BlendMode blendMode;
|
||||||
|
|
||||||
|
/// <summary>The index of the slot in <see cref="Skeleton.Slots"/>.</summary>
|
||||||
public int Index { get { return index; } }
|
public int Index { get { return index; } }
|
||||||
|
/// <summary>The name of the slot, which is unique across all slots in the skeleton.</summary>
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
|
/// <summary>The bone this slot belongs to.</summary>
|
||||||
public BoneData BoneData { get { return boneData; } }
|
public BoneData BoneData { get { return boneData; } }
|
||||||
public float R { get { return r; } set { r = value; } }
|
public float R { get { return r; } set { r = value; } }
|
||||||
public float G { get { return g; } set { g = value; } }
|
public float G { get { return g; } set { g = value; } }
|
||||||
@ -53,8 +56,9 @@ namespace Spine {
|
|||||||
public float B2 { get { return b2; } set { b2 = value; } }
|
public float B2 { get { return b2; } set { b2 = value; } }
|
||||||
public bool HasSecondColor { get { return hasSecondColor; } set { hasSecondColor = value; } }
|
public bool HasSecondColor { get { return hasSecondColor; } set { hasSecondColor = value; } }
|
||||||
|
|
||||||
/// <summary>May be null.</summary>
|
/// <summary>The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible.</summary>
|
||||||
public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
|
public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
|
||||||
|
/// <summary>The blend mode for drawing the slot's attachment.</summary>
|
||||||
public BlendMode BlendMode { get { return blendMode; } set { blendMode = value; } }
|
public BlendMode BlendMode { get { return blendMode; } set { blendMode = value; } }
|
||||||
|
|
||||||
public SlotData (int index, String name, BoneData boneData) {
|
public SlotData (int index, String name, BoneData boneData) {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace Spine {
|
|||||||
/// <para>
|
/// <para>
|
||||||
/// See <a href="http://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide.</para>
|
/// See <a href="http://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TransformConstraint : IConstraint {
|
public class TransformConstraint : IUpdatable {
|
||||||
internal TransformConstraintData data;
|
internal TransformConstraintData data;
|
||||||
internal ExposedList<Bone> bones;
|
internal ExposedList<Bone> bones;
|
||||||
internal Bone target;
|
internal Bone target;
|
||||||
@ -288,7 +288,6 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order { get { return data.order; } }
|
|
||||||
/// <summary>The bones that will be modified by this transform constraint.</summary>
|
/// <summary>The bones that will be modified by this transform constraint.</summary>
|
||||||
public ExposedList<Bone> Bones { get { return bones; } }
|
public ExposedList<Bone> Bones { get { return bones; } }
|
||||||
/// <summary>The target bone whose world transform will be copied to the constrained bones.</summary>
|
/// <summary>The target bone whose world transform will be copied to the constrained bones.</summary>
|
||||||
|
|||||||
@ -30,17 +30,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Spine {
|
namespace Spine {
|
||||||
public class TransformConstraintData {
|
public class TransformConstraintData : ConstraintData {
|
||||||
internal string name;
|
|
||||||
internal int order;
|
|
||||||
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
|
||||||
internal BoneData target;
|
internal BoneData target;
|
||||||
internal float rotateMix, translateMix, scaleMix, shearMix;
|
internal float rotateMix, translateMix, scaleMix, shearMix;
|
||||||
internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
|
internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
|
||||||
internal bool relative, local;
|
internal bool relative, local;
|
||||||
|
|
||||||
public string Name { get { return name; } }
|
|
||||||
public int Order { get { return order; } set { order = value; } }
|
|
||||||
public ExposedList<BoneData> Bones { get { return bones; } }
|
public ExposedList<BoneData> Bones { get { return bones; } }
|
||||||
public BoneData Target { get { return target; } set { target = value; } }
|
public BoneData Target { get { return target; } set { target = value; } }
|
||||||
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
|
public float RotateMix { get { return rotateMix; } set { rotateMix = value; } }
|
||||||
@ -58,13 +54,7 @@ namespace Spine {
|
|||||||
public bool Relative { get { return relative; } set { relative = value; } }
|
public bool Relative { get { return relative; } set { relative = value; } }
|
||||||
public bool Local { get { return local; } set { local = value; } }
|
public bool Local { get { return local; } set { local = value; } }
|
||||||
|
|
||||||
public TransformConstraintData (string name) {
|
public TransformConstraintData (string name) : base(name) {
|
||||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
override public string ToString () {
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -504,8 +504,17 @@ namespace Spine.Unity.Editor {
|
|||||||
|
|
||||||
if (!fieldMatchesSkin) {
|
if (!fieldMatchesSkin) {
|
||||||
Skin skinToSet = string.IsNullOrEmpty(componentSkinName) ? null : skeletonRenderer.Skeleton.Data.FindSkin(componentSkinName);
|
Skin skinToSet = string.IsNullOrEmpty(componentSkinName) ? null : skeletonRenderer.Skeleton.Data.FindSkin(componentSkinName);
|
||||||
skeletonRenderer.Skeleton.Skin = skinToSet;
|
skeletonRenderer.Skeleton.SetSkin(skinToSet);
|
||||||
skeletonRenderer.Skeleton.SetSlotsToSetupPose();
|
skeletonRenderer.Skeleton.SetSlotsToSetupPose();
|
||||||
|
|
||||||
|
// Note: the UpdateIfSkinMismatch concept shall be replaced with e.g. an OnValidate based
|
||||||
|
// solution or in a separate commit. The current solution does not repaint the Game view because
|
||||||
|
// it is first applying values and in the next editor pass is calling this skin-changing method.
|
||||||
|
if (skeletonRenderer is SkeletonAnimation)
|
||||||
|
((SkeletonAnimation) skeletonRenderer).Update(0f);
|
||||||
|
else if (skeletonRenderer is SkeletonMecanim)
|
||||||
|
((SkeletonMecanim) skeletonRenderer).Update();
|
||||||
|
|
||||||
skeletonRenderer.LateUpdate();
|
skeletonRenderer.LateUpdate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -707,9 +707,10 @@ namespace Spine.Unity.Editor {
|
|||||||
if (root == null || !root.ContainsKey("skins"))
|
if (root == null || !root.ContainsKey("skins"))
|
||||||
return requiredPaths;
|
return requiredPaths;
|
||||||
|
|
||||||
foreach (var skin in (Dictionary<string, object>)root["skins"]) {
|
foreach (Dictionary<string, object> skinMap in (List<object>)root["skins"]) {
|
||||||
foreach (var slot in (Dictionary<string, object>)skin.Value) {
|
if (!skinMap.ContainsKey("attachments"))
|
||||||
|
continue;
|
||||||
|
foreach (var slot in (Dictionary<string, object>)skinMap["attachments"]) {
|
||||||
foreach (var attachment in ((Dictionary<string, object>)slot.Value)) {
|
foreach (var attachment in ((Dictionary<string, object>)slot.Value)) {
|
||||||
var data = ((Dictionary<string, object>)attachment.Value);
|
var data = ((Dictionary<string, object>)attachment.Value);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user