[csharp][unity] Port sequence attachment. See #1956. Also port of other 4.1-beta branch changes compared to 4.0.

This commit is contained in:
Harald Csaszar 2021-11-03 15:23:31 +01:00
parent 536e56ae05
commit 3250e74e26
115 changed files with 4880 additions and 3278 deletions

View File

@ -14,6 +14,22 @@
## C# ## ## C# ##
* **Additions**
* Full support for sequences.
* `RegionAttachment` and `MeshAttachment` now provide a `Region` property. Use this property instead of the removed `RendererObject` property (see section *Breaking Changes* below).
* **Breaking changes**
* Removed `RendererObject` property from `RegionAttachment` and `MeshAttachment`. Use `attachment.Region` property instead. Removed removed `IHasRendererObject` interface. Use `IHasTextureRegion` instead.
* Replaced `RegionAttachment.UpdateOffset` and `MeshAttachment.UpdateUVs` with `Attachment.UpdateRegion`. The caller must ensure that the attachment's region is not `null`.
* Removed `AttachmentRegionExtensions` methods `Attachment.SetRegion`, `MeshAttachment.SetRegion` and `RegionAttachment.SetRegion(region, update)`. Use `attachment.Region = region; if (update) attachment.UpdateRegion()` instead.
* `AttachmentLoader.NewRegionAttachment()` and `AttachmentLoader.NewMeshAttachment()` take an additional `Sequence` parameter.
* `VertexAttachment.DeformAttachment` property has been replaced with `VertexAttachment.TimelineAttachment`.
* `RegionAttachment.ComputeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument.
* Removed `Skeleton.Update(float deltaTime)` method.
* Removed `Slot.AttachmentTime` property.
* Removed extension method `AtlasRegion.GetSpineAtlasRect()` parameter `includeRotate` (with default value `true`). Most likely this method was never used with `includeRotate=false` in user code so no changes are required.
* `AtlasRegion.PackedWidth` and `AtlasRegion.PackedHeight` are swapped compared to 4.0 when packing rotation is equal to 90 degrees. Most likely this property was never accessed in user code so no changes are required.
### Unity ### Unity
* **Officially supported Unity versions are 2017.1-2021.1**. * **Officially supported Unity versions are 2017.1-2021.1**.
@ -34,7 +50,7 @@
* **Breaking change**: `AttachmentLoader#newRegionAttachment()` and `AttachmentLoader#newMeshAttachment()` take an additional `Sequence` parameter. * **Breaking change**: `AttachmentLoader#newRegionAttachment()` and `AttachmentLoader#newMeshAttachment()` take an additional `Sequence` parameter.
* **Breaking change**: `Slot#setAttachmentTime()` and `Slot#getAttachmentTime()` have been removed. * **Breaking change**: `Slot#setAttachmentTime()` and `Slot#getAttachmentTime()` have been removed.
* **Breaking change**: `VertexAttachment#setDeformAttachment()` and `VertexAttachment#getDeformAttachment()` have been replaced with `VertexAttachment#setTimelineAttachment()` and `VertexAttachment#getTimelineAttachment()`. * **Breaking change**: `VertexAttachment#setDeformAttachment()` and `VertexAttachment#getDeformAttachment()` have been replaced with `VertexAttachment#setTimelineAttachment()` and `VertexAttachment#getTimelineAttachment()`.
* **Breaking change**: `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The called must ensure that the attachment's region is not `null`. * **Breaking change**: `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The caller must ensure that the attachment's region is not `null`.
* **Breaking change**: `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument. * **Breaking change**: `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument.
* **Addition**: full support for sequences. * **Addition**: full support for sequences.
@ -45,7 +61,7 @@
* **Breaking change**: `AttachmentLoader#newRegionAttachment()` and `AttachmentLoader#newMeshAttachment()` take an additional `Sequence` parameter. * **Breaking change**: `AttachmentLoader#newRegionAttachment()` and `AttachmentLoader#newMeshAttachment()` take an additional `Sequence` parameter.
* **Breaking change**: `Slot#attachmentTime` and has been removed. * **Breaking change**: `Slot#attachmentTime` and has been removed.
* **Breaking change**: `VertexAttachment#deformAttachment` has been replaced with `VertexAttachment#timelineAttachment`. * **Breaking change**: `VertexAttachment#deformAttachment` has been replaced with `VertexAttachment#timelineAttachment`.
* **Breaking change**: `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The called must ensure that the attachment's region is not `null`. * **Breaking change**: `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The caller must ensure that the attachment's region is not `null`.
* **Breaking change**: `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument. * **Breaking change**: `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument.
* **Addition**: full support for sequences. * **Addition**: full support for sequences.

View File

@ -181,7 +181,8 @@ namespace Spine {
Attachment, Deform, // Attachment, Deform, //
Event, DrawOrder, // Event, DrawOrder, //
IkConstraint, TransformConstraint, // IkConstraint, TransformConstraint, //
PathConstraintPosition, PathConstraintSpacing, PathConstraintMix PathConstraintPosition, PathConstraintSpacing, PathConstraintMix, //
Sequence
} }
/// <summary> /// <summary>
@ -1786,7 +1787,7 @@ namespace Spine {
} }
} }
/// <summary>The attachment that will be deformed.</summary> /// <summary>The attachment that will be deformed.</summary>
/// <seealso cref="VertexAttachment.DeformAttachment"/> /// <seealso cref="VertexAttachment.TimelineAttachment"/>
public VertexAttachment Attachment { public VertexAttachment Attachment {
get { get {
return attachment; return attachment;
@ -1869,9 +1870,9 @@ namespace Spine {
Slot slot = skeleton.slots.Items[slotIndex]; Slot slot = skeleton.slots.Items[slotIndex];
if (!slot.bone.active) return; if (!slot.bone.active) return;
var vertexAttachment = slot.attachment as VertexAttachment; var vertexAttachment = slot.attachment as VertexAttachment;
if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return; if (vertexAttachment == null || vertexAttachment.TimelineAttachment != attachment) return;
var deformArray = slot.Deform; var deformArray = slot.deform;
if (deformArray.Count == 0) blend = MixBlend.Setup; if (deformArray.Count == 0) blend = MixBlend.Setup;
float[][] vertices = this.vertices; float[][] vertices = this.vertices;
@ -2583,4 +2584,94 @@ namespace Spine {
} }
} }
} }
/// <summary>Changes a slot's <see cref="Slot.SequenceIndex"/> for an attachment's <see cref="Sequence"/>.</summary>
public class SequenceTimeline : Timeline, ISlotTimeline {
public const int ENTRIES = 3;
private const int MODE = 1, DELAY = 2;
readonly int slotIndex;
readonly IHasTextureRegion attachment;
public SequenceTimeline (int frameCount, int slotIndex, Attachment attachment)
: base(frameCount, (int)Property.Sequence + "|" + slotIndex + "|" + ((IHasTextureRegion)attachment).Sequence.Id) {
this.slotIndex = slotIndex;
this.attachment = (IHasTextureRegion)attachment;
}
public override int FrameEntries {
get { return ENTRIES; }
}
public int SlotIndex {
get {
return slotIndex;
}
}
public Attachment Attachment {
get {
return (Attachment)attachment;
}
}
/// <summary>Sets the time, mode, index, and frame time for the specified frame.</summary>
/// <param name="frame">Between 0 and <code>frameCount</code>, inclusive.</param>
/// <param name="time">Seconds between frames.</param>
public void SetFrame (int frame, float time, SequenceMode mode, int index, float delay) {
frame *= ENTRIES;
frames[frame] = time;
frames[frame + MODE] = (int)mode | (index << 4);
frames[frame + DELAY] = delay;
}
override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> firedEvents, float alpha, MixBlend blend,
MixDirection direction) {
Slot slot = skeleton.slots.Items[slotIndex];
if (!slot.bone.active) return;
Attachment slotAttachment = slot.attachment;
if (slotAttachment != attachment) {
VertexAttachment vertexAttachment = slotAttachment as VertexAttachment;
if ((vertexAttachment == null)
|| vertexAttachment.TimelineAttachment != attachment) return;
}
float[] frames = this.frames;
if (time < frames[0]) { // Time is before first frame.
if (blend == MixBlend.Setup || blend == MixBlend.First) slot.SequenceIndex = -1;
return;
}
int i = Search(frames, time, ENTRIES);
float before = frames[i];
int modeAndIndex = (int)frames[i + MODE];
float delay = frames[i + DELAY];
int index = modeAndIndex >> 4, count = attachment.Sequence.Regions.Length;
SequenceMode mode = (SequenceMode)(modeAndIndex & 0xf);
if (mode != SequenceMode.Hold) {
index += (int)((time - before) / delay + 0.00001f);
switch (mode) {
case SequenceMode.Once:
index = Math.Min(count - 1, index);
break;
case SequenceMode.Loop:
index %= count;
break;
case SequenceMode.Pingpong:
int n = (count << 1) - 2;
index %= n;
if (index >= count) index = n - index;
break;
case SequenceMode.OnceReverse:
index = Math.Max(count - 1 - index, 0);
break;
case SequenceMode.LoopReverse:
index = count - 1 - (index % count);
break;
}
}
slot.SequenceIndex = index;
}
}
} }

View File

@ -1107,9 +1107,12 @@ namespace Spine {
} }
/// <summary> /// <summary>
/// Uses <see cref="TrackEntry.TrackTime"/> to compute the <code>AnimationTime</code>, which is between <see cref="TrackEntry.AnimationStart"/> /// Uses <see cref="TrackEntry.TrackTime"/> to compute the <code>AnimationTime</code>. When the <code>TrackTime</code> is 0, the
/// and <see cref="TrackEntry.AnimationEnd"/>. When the <code>TrackTime</code> is 0, the <code>AnimationTime</code> is equal to the /// <code>AnimationTime</code> is equal to the <code>AnimationStart</code> time.
/// <code>AnimationStart</code> time. /// <para>
/// The <code>animationTime</code> is between <see cref="AnimationStart"/> and <see cref="AnimationEnd"/>, except if this
/// track entry is non-looping and <see cref="AnimationEnd"/> is >= to the animation <see cref="Animation.Duration"/>, then
/// <code>animationTime</code> continues to increase past <see cref="AnimationEnd"/>.</para>
/// </summary> /// </summary>
public float AnimationTime { public float AnimationTime {
get { get {
@ -1118,7 +1121,8 @@ namespace Spine {
if (duration == 0) return animationStart; if (duration == 0) return animationStart;
return (trackTime % duration) + animationStart; return (trackTime % duration) + animationStart;
} }
return Math.Min(trackTime + animationStart, animationEnd); float animationTime = trackTime + animationStart;
return animationEnd >= animation.duration ? animationTime : Math.Min(animationTime, animationEnd);
} }
} }

View File

@ -245,6 +245,10 @@ namespace Spine {
if (region.degrees == 90) { if (region.degrees == 90) {
region.u2 = (region.x + region.height) / (float)page.width; region.u2 = (region.x + region.height) / (float)page.width;
region.v2 = (region.y + region.width) / (float)page.height; region.v2 = (region.y + region.width) / (float)page.height;
var tempSwap = region.packedWidth;
region.packedWidth = region.packedHeight;
region.packedHeight = tempSwap;
} else { } else {
region.u2 = (region.x + region.width) / (float)page.width; region.u2 = (region.x + region.width) / (float)page.width;
region.v2 = (region.y + region.height) / (float)page.height; region.v2 = (region.y + region.height) / (float)page.height;
@ -339,19 +343,23 @@ namespace Spine {
} }
} }
public class AtlasRegion { public class AtlasRegion : TextureRegion {
public AtlasPage page; public AtlasPage page;
public string name; public string name;
public int x, y, width, height; public int x, y;
public float u, v, u2, v2;
public float offsetX, offsetY; public float offsetX, offsetY;
public int originalWidth, originalHeight; public int originalWidth, originalHeight;
public int packedWidth { get { return width; } set { width = value; } }
public int packedHeight { get { return height; } set { height = value; } }
public int degrees; public int degrees;
public bool rotate; public bool rotate;
public int index; public int index;
public string[] names; public string[] names;
public int[][] values; public int[][] values;
override public int OriginalWidth { get { return originalWidth; } }
override public int OriginalHeight { get { return originalHeight; } }
public AtlasRegion Clone () { public AtlasRegion Clone () {
return MemberwiseClone() as AtlasRegion; return MemberwiseClone() as AtlasRegion;
} }

View File

@ -43,37 +43,38 @@ namespace Spine {
this.atlasArray = atlasArray; this.atlasArray = atlasArray;
} }
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { private void LoadSequence (string name, string basePath, Sequence sequence) {
AtlasRegion region = FindRegion(path); TextureRegion[] regions = sequence.Regions;
if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name)); for (int i = 0, n = regions.Length; i < n; i++) {
string path = sequence.GetPath(basePath, i);
regions[i] = FindRegion(path);
if (regions[i] == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
}
}
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
RegionAttachment attachment = new RegionAttachment(name); RegionAttachment attachment = new RegionAttachment(name);
attachment.RendererObject = region; if (sequence != null)
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees); LoadSequence(name, path, sequence);
attachment.regionOffsetX = region.offsetX; else {
attachment.regionOffsetY = region.offsetY; AtlasRegion region = FindRegion(path);
attachment.regionWidth = region.width; if (region == null)
attachment.regionHeight = region.height; throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
attachment.regionOriginalWidth = region.originalWidth; attachment.Region = region;
attachment.regionOriginalHeight = region.originalHeight; }
return attachment; return attachment;
} }
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
AtlasRegion region = FindRegion(path);
if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
MeshAttachment attachment = new MeshAttachment(name); MeshAttachment attachment = new MeshAttachment(name);
attachment.RendererObject = region; if (sequence != null)
attachment.RegionU = region.u; LoadSequence(name, path, sequence);
attachment.RegionV = region.v; else {
attachment.RegionU2 = region.u2; AtlasRegion region = FindRegion(path);
attachment.RegionV2 = region.v2; if (region == null)
attachment.RegionDegrees = region.degrees; throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
attachment.regionOffsetX = region.offsetX; attachment.Region = region;
attachment.regionOffsetY = region.offsetY; }
attachment.regionWidth = region.width;
attachment.regionHeight = region.height;
attachment.regionOriginalWidth = region.originalWidth;
attachment.regionOriginalHeight = region.originalHeight;
return attachment; return attachment;
} }

View File

@ -30,12 +30,20 @@
using System; using System;
namespace Spine { namespace Spine {
/// <summary>The base class for all attachments.</summary>
abstract public class Attachment { abstract public class Attachment {
public string Name { get; private set; } /// <summary>The attachment's name.</summary>
public string Name { get; }
protected Attachment (string name) { protected Attachment (string name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null"); if (name == null) throw new ArgumentNullException("name", "name cannot be null");
Name = name; this.Name = name;
}
/// <summary>Copy constructor.</summary>
protected Attachment (Attachment other) {
Name = other.Name;
} }
override public string ToString () { override public string ToString () {
@ -45,8 +53,4 @@ namespace Spine {
///<summary>Returns a copy of the attachment.</summary> ///<summary>Returns a copy of the attachment.</summary>
public abstract Attachment Copy (); public abstract Attachment Copy ();
} }
public interface IHasRendererObject {
object RendererObject { get; set; }
}
} }

View File

@ -30,10 +30,10 @@
namespace Spine { namespace Spine {
public interface AttachmentLoader { public interface AttachmentLoader {
/// <return>May be null to not load any attachment.</return> /// <return>May be null to not load any attachment.</return>
RegionAttachment NewRegionAttachment (Skin skin, string name, string path); RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence);
/// <return>May be null to not load any attachment.</return> /// <return>May be null to not load any attachment.</return>
MeshAttachment NewMeshAttachment (Skin skin, string name, string path); MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence);
/// <return>May be null to not load any attachment.</return> /// <return>May be null to not load any attachment.</return>
BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name); BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name);

View File

@ -29,6 +29,6 @@
namespace Spine { namespace Spine {
public enum AttachmentType { public enum AttachmentType {
Region, Boundingbox, Mesh, Linkedmesh, Path, Point, Clipping Region, Boundingbox, Mesh, Linkedmesh, Path, Point, Clipping, Sequence
} }
} }

View File

@ -36,10 +36,13 @@ namespace Spine {
: base(name) { : base(name) {
} }
/// <summary>Copy constructor.</summary>
protected BoundingBoxAttachment (BoundingBoxAttachment other)
: base(other) {
}
public override Attachment Copy () { public override Attachment Copy () {
BoundingBoxAttachment copy = new BoundingBoxAttachment(this.Name); return new BoundingBoxAttachment(this);
CopyTo(copy);
return copy;
} }
} }
} }

View File

@ -38,11 +38,14 @@ namespace Spine {
public ClippingAttachment (string name) : base(name) { public ClippingAttachment (string name) : base(name) {
} }
/// <summary>Copy constructor.</summary>
protected ClippingAttachment (ClippingAttachment other)
: base(other) {
endSlot = other.endSlot;
}
public override Attachment Copy () { public override Attachment Copy () {
ClippingAttachment copy = new ClippingAttachment(this.Name); return new ClippingAttachment(this);
CopyTo(copy);
copy.endSlot = endSlot;
return copy;
} }
} }
} }

View File

@ -0,0 +1,56 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
using System.Text;
namespace Spine {
public interface IHasTextureRegion {
/// <summary>The name used to find the <see cref="Region"/></summary>
public string Path { get; set; }
/// <summary>
/// Sets the region used to draw the attachment. After setting the region or if the region's properties are changed,
/// <see cref="UpdateRegion()"/> must be called.
/// </summary>
public TextureRegion Region { get; set; }
/// <summary>
/// Updates any values the attachment calculates using the <see cref="Region"/>. Must be called after setting the
/// <see cref="Region"/> or if the region's properties are changed.
/// </summary>
public void UpdateRegion ();
public float R { get; set; }
public float G { get; set; }
public float B { get; set; }
public float A { get; set; }
public Sequence Sequence { get; set; }
}
}

View File

@ -1,6 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 6e55c8477eccddc4cb5c3551a3945ca7 guid: d0e8b0a33cae75d498aa8c328787cafb
MonoImporter: MonoImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
defaultReferences: [] defaultReferences: []
executionOrder: 0 executionOrder: 0

View File

@ -31,17 +31,27 @@ using System;
namespace Spine { namespace Spine {
/// <summary>Attachment that displays a texture region using a mesh.</summary> /// <summary>Attachment that displays a texture region using a mesh.</summary>
public class MeshAttachment : VertexAttachment, IHasRendererObject { public class MeshAttachment : VertexAttachment, IHasTextureRegion {
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight; internal TextureRegion region;
private MeshAttachment parentMesh; internal string path;
internal float[] uvs, regionUVs; internal float[] regionUVs, uvs;
internal int[] triangles; internal int[] triangles;
internal float r = 1, g = 1, b = 1, a = 1; internal float r = 1, g = 1, b = 1, a = 1;
internal int hulllength; internal int hullLength;
private MeshAttachment parentMesh;
private Sequence sequence;
public int HullLength { get { return hulllength; } set { hulllength = value; } } public TextureRegion Region {
get { return region; }
set {
if (value == null) throw new ArgumentNullException("region", "region cannot be null.");
region = value;
}
}
public int HullLength { get { return hullLength; } set { hullLength = value; } }
public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } } public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } }
/// <summary>The UV pair for each vertex, normalized within the entire texture. <seealso cref="MeshAttachment.UpdateUVs"/></summary> /// <summary>The UV pair for each vertex, normalized within the entire texture.
/// <seealso cref="MeshAttachment.UpdateRegion"/></summary>
public float[] UVs { get { return uvs; } set { uvs = value; } } public float[] UVs { get { return uvs; } set { uvs = value; } }
public int[] Triangles { get { return triangles; } set { triangles = value; } } public int[] Triangles { get { return triangles; } set { triangles = value; } }
@ -50,19 +60,8 @@ namespace Spine {
public float B { get { return b; } set { b = value; } } public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } } public float A { get { return a; } set { a = value; } }
public string Path { get; set; } public string Path { get { return path; } set { path = value; } }
public object RendererObject { get; set; } public Sequence Sequence { get { return sequence; } set { sequence = value; } }
public float RegionU { get; set; }
public float RegionV { get; set; }
public float RegionU2 { get; set; }
public float RegionV2 { get; set; }
public int RegionDegrees { get; set; }
public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
public MeshAttachment ParentMesh { public MeshAttachment ParentMesh {
get { return parentMesh; } get { return parentMesh; }
@ -91,131 +90,131 @@ namespace Spine {
: base(name) { : base(name) {
} }
public void UpdateUVs () { /// <summary>Copy constructor. Use <see cref="NewLinkedMesh"/> if the other mesh is a linked mesh.</summary>
protected MeshAttachment (MeshAttachment other)
: base(other) {
if (parentMesh != null) throw new ArgumentException("Use newLinkedMesh to copy a linked mesh.");
region = other.region;
path = other.path;
r = other.r;
g = other.g;
b = other.b;
a = other.a;
regionUVs = new float[other.regionUVs.Length];
Array.Copy(other.regionUVs, 0, regionUVs, 0, regionUVs.Length);
uvs = new float[other.uvs.Length];
Array.Copy(other.uvs, 0, uvs, 0, uvs.Length);
triangles = new int[other.triangles.Length];
Array.Copy(other.triangles, 0, triangles, 0, triangles.Length);
hullLength = other.hullLength;
sequence = other.sequence == null ? null : new Sequence(other.sequence);
// Nonessential.
if (other.Edges != null) {
Edges = new int[other.Edges.Length];
Array.Copy(other.Edges, 0, Edges, 0, Edges.Length);
}
Width = other.Width;
Height = other.Height;
}
public void UpdateRegion () {
float[] regionUVs = this.regionUVs; float[] regionUVs = this.regionUVs;
if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length]; if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length];
float[] uvs = this.uvs; float[] uvs = this.uvs;
float u = RegionU, v = RegionV, width = 0, height = 0; int n = uvs.Length;
float u, v, width, height;
if (RegionDegrees == 90) { if (region is AtlasRegion) {
float textureHeight = this.regionWidth / (RegionV2 - RegionV); u = this.region.u;
float textureWidth = this.regionHeight / (RegionU2 - RegionU); v = this.region.v;
u -= (RegionOriginalHeight - RegionOffsetY - RegionHeight) / textureWidth; AtlasRegion region = (AtlasRegion)this.region;
v -= (RegionOriginalWidth - RegionOffsetX - RegionWidth) / textureHeight; // Note: difference from reference implementation.
width = RegionOriginalHeight / textureWidth; // Covers rotation since region.width and height are already setup accordingly.
height = RegionOriginalWidth / textureHeight; float textureWidth = this.region.width / (region.u2 - region.u);
float textureHeight = this.region.height / (region.v2 - region.v);
for (int i = 0, n = uvs.Length; i < n; i += 2) { switch (region.degrees) {
uvs[i] = u + regionUVs[i + 1] * width; case 90:
uvs[i + 1] = v + (1 - regionUVs[i]) * height; u -= (region.originalHeight - region.offsetY - region.packedWidth) / textureWidth;
} v -= (region.originalWidth - region.offsetX - region.packedHeight) / textureHeight;
} else if (RegionDegrees == 180) { width = region.originalHeight / textureWidth;
float textureWidth = this.regionWidth / (RegionU2 - RegionU); height = region.originalWidth / textureHeight;
float textureHeight = this.regionHeight / (RegionV2 - RegionV); for (int i = 0; i < n; i += 2) {
u -= (RegionOriginalWidth - RegionOffsetX - RegionWidth) / textureWidth; uvs[i] = u + regionUVs[i + 1] * width;
v -= RegionOffsetY / textureHeight; uvs[i + 1] = v + (1 - regionUVs[i]) * height;
width = RegionOriginalWidth / textureWidth; }
height = RegionOriginalHeight / textureHeight; return;
case 180:
for (int i = 0, n = uvs.Length; i < n; i += 2) { u -= (region.originalWidth - region.offsetX - region.packedWidth) / textureWidth;
uvs[i] = u + (1 - regionUVs[i]) * width; v -= region.offsetY / textureHeight;
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; width = region.originalWidth / textureWidth;
} height = region.originalHeight / textureHeight;
} else if (RegionDegrees == 270) { for (int i = 0; i < n; i += 2) {
float textureWidth = this.regionWidth / (RegionU2 - RegionU); uvs[i] = u + (1 - regionUVs[i]) * width;
float textureHeight = this.regionHeight / (RegionV2 - RegionV); uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
u -= RegionOffsetY / textureWidth; }
v -= RegionOffsetX / textureHeight; return;
width = RegionOriginalHeight / textureWidth; case 270:
height = RegionOriginalWidth / textureHeight; u -= region.offsetY / textureWidth;
v -= region.offsetX / textureHeight;
for (int i = 0, n = uvs.Length; i < n; i += 2) { width = region.originalHeight / textureWidth;
uvs[i] = u + (1 - regionUVs[i + 1]) * width; height = region.originalWidth / textureHeight;
uvs[i + 1] = v + regionUVs[i] * height; for (int i = 0; i < n; i += 2) {
uvs[i] = u + (1 - regionUVs[i + 1]) * width;
uvs[i + 1] = v + regionUVs[i] * height;
}
return;
} }
u -= region.offsetX / textureWidth;
v -= (region.originalHeight - region.offsetY - region.packedHeight) / textureHeight;
width = region.originalWidth / textureWidth;
height = region.originalHeight / textureHeight;
} else if (region == null) {
u = v = 0;
width = height = 1;
} else { } else {
float textureWidth = this.regionWidth / (RegionU2 - RegionU); u = region.u;
float textureHeight = this.regionHeight / (RegionV2 - RegionV); v = region.v;
u -= RegionOffsetX / textureWidth; width = region.u2 - u;
v -= (RegionOriginalHeight - RegionOffsetY - RegionHeight) / textureHeight; height = region.v2 - v;
width = RegionOriginalWidth / textureWidth; }
height = RegionOriginalHeight / textureHeight; for (int i = 0; i < n; i += 2) {
uvs[i] = u + regionUVs[i] * width;
for (int i = 0, n = uvs.Length; i < n; i += 2) { uvs[i + 1] = v + regionUVs[i + 1] * height;
uvs[i] = u + regionUVs[i] * width;
uvs[i + 1] = v + regionUVs[i + 1] * height;
}
} }
} }
public override Attachment Copy () { /// <summary>If the attachment has a <see cref="Sequence"/>, the region may be changed.</summary>
if (parentMesh != null) return NewLinkedMesh(); override public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
if (sequence != null) sequence.Apply(slot, this);
MeshAttachment copy = new MeshAttachment(this.Name); base.ComputeWorldVertices(slot, start, count, worldVertices, offset, stride);
copy.RendererObject = RendererObject;
copy.regionOffsetX = regionOffsetX;
copy.regionOffsetY = regionOffsetY;
copy.regionWidth = regionWidth;
copy.regionHeight = regionHeight;
copy.regionOriginalWidth = regionOriginalWidth;
copy.regionOriginalHeight = regionOriginalHeight;
copy.RegionDegrees = RegionDegrees;
copy.RegionU = RegionU;
copy.RegionV = RegionV;
copy.RegionU2 = RegionU2;
copy.RegionV2 = RegionV2;
copy.Path = Path;
copy.r = r;
copy.g = g;
copy.b = b;
copy.a = a;
CopyTo(copy);
copy.regionUVs = new float[regionUVs.Length];
Array.Copy(regionUVs, 0, copy.regionUVs, 0, regionUVs.Length);
copy.uvs = new float[uvs.Length];
Array.Copy(uvs, 0, copy.uvs, 0, uvs.Length);
copy.triangles = new int[triangles.Length];
Array.Copy(triangles, 0, copy.triangles, 0, triangles.Length);
copy.HullLength = HullLength;
// Nonessential.
if (Edges != null) {
copy.Edges = new int[Edges.Length];
Array.Copy(Edges, 0, copy.Edges, 0, Edges.Length);
}
copy.Width = Width;
copy.Height = Height;
return copy;
} }
///<summary>Returns a new mesh with this mesh set as the <see cref="ParentMesh"/>. ///<summary>Returns a new mesh with this mesh set as the <see cref="ParentMesh"/>.
public MeshAttachment NewLinkedMesh () { public MeshAttachment NewLinkedMesh () {
MeshAttachment mesh = new MeshAttachment(Name); MeshAttachment mesh = new MeshAttachment(Name);
mesh.RendererObject = RendererObject;
mesh.regionOffsetX = regionOffsetX;
mesh.regionOffsetY = regionOffsetY;
mesh.regionWidth = regionWidth;
mesh.regionHeight = regionHeight;
mesh.regionOriginalWidth = regionOriginalWidth;
mesh.regionOriginalHeight = regionOriginalHeight;
mesh.RegionDegrees = RegionDegrees;
mesh.RegionU = RegionU;
mesh.RegionV = RegionV;
mesh.RegionU2 = RegionU2;
mesh.RegionV2 = RegionV2;
mesh.Path = Path; mesh.timelineAttachment = timelineAttachment;
mesh.region = region;
mesh.path = path;
mesh.r = r; mesh.r = r;
mesh.g = g; mesh.g = g;
mesh.b = b; mesh.b = b;
mesh.a = a; mesh.a = a;
mesh.deformAttachment = deformAttachment;
mesh.ParentMesh = parentMesh != null ? parentMesh : this; mesh.ParentMesh = parentMesh != null ? parentMesh : this;
mesh.UpdateUVs(); if (mesh.Region != null) mesh.UpdateRegion();
return mesh; return mesh;
} }
public override Attachment Copy () {
return parentMesh != null ? NewLinkedMesh() : new MeshAttachment(this);
}
} }
} }

View File

@ -47,14 +47,19 @@ namespace Spine {
: base(name) { : base(name) {
} }
/// <summary>Copy constructor.</summary>
protected PathAttachment (PathAttachment other)
: base(other) {
lengths = new float[other.lengths.Length];
Array.Copy(other.lengths, 0, lengths, 0, lengths.Length);
closed = other.closed;
constantSpeed = other.constantSpeed;
}
public override Attachment Copy () { public override Attachment Copy () {
PathAttachment copy = new PathAttachment(this.Name); return new PathAttachment(this);
CopyTo(copy);
copy.lengths = new float[lengths.Length];
Array.Copy(lengths, 0, copy.lengths, 0, lengths.Length);
copy.closed = closed;
copy.constantSpeed = constantSpeed;
return copy;
} }
} }
} }

View File

@ -45,6 +45,14 @@ namespace Spine {
: base(name) { : base(name) {
} }
/** Copy constructor. */
protected PointAttachment (PointAttachment other)
: base(other) {
x = other.x;
y = other.y;
rotation = other.rotation;
}
public void ComputeWorldPosition (Bone bone, out float ox, out float oy) { public void ComputeWorldPosition (Bone bone, out float ox, out float oy) {
bone.LocalToWorld(this.x, this.y, out ox, out oy); bone.LocalToWorld(this.x, this.y, out ox, out oy);
} }
@ -57,11 +65,7 @@ namespace Spine {
} }
public override Attachment Copy () { public override Attachment Copy () {
PointAttachment copy = new PointAttachment(this.Name); return new PointAttachment(this);
copy.x = x;
copy.y = y;
copy.rotation = rotation;
return copy;
} }
} }
} }

View File

@ -31,20 +31,17 @@ using System;
namespace Spine { namespace Spine {
/// <summary>Attachment that displays a texture region.</summary> /// <summary>Attachment that displays a texture region.</summary>
public class RegionAttachment : Attachment, IHasRendererObject { public class RegionAttachment : Attachment, IHasTextureRegion {
public const int BLX = 0; public const int BLX = 0, BLY = 1;
public const int BLY = 1; public const int ULX = 2, ULY = 3;
public const int ULX = 2; public const int URX = 4, URY = 5;
public const int ULY = 3; public const int BRX = 6, BRY = 7;
public const int URX = 4;
public const int URY = 5;
public const int BRX = 6;
public const int BRY = 7;
internal TextureRegion region;
internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height; internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
internal float[] offset = new float[8], uvs = new float[8]; internal float[] offset = new float[8], uvs = new float[8];
internal float r = 1, g = 1, b = 1, a = 1; internal float r = 1, g = 1, b = 1, a = 1;
internal Sequence sequence;
public float X { get { return x; } set { x = value; } } public float X { get { return x; } set { x = value; } }
public float Y { get { return y; } set { y = value; } } public float Y { get { return y; } set { y = value; } }
@ -60,31 +57,73 @@ namespace Spine {
public float A { get { return a; } set { a = value; } } public float A { get { return a; } set { a = value; } }
public string Path { get; set; } public string Path { get; set; }
public object RendererObject { get; set; } public TextureRegion Region { get { return region; } set { region = value; } }
public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
/// <summary>For each of the 4 vertices, a pair of <code>x,y</code> values that is the local position of the vertex.</summary>
/// <seealso cref="UpdateRegion"/>
public float[] Offset { get { return offset; } } public float[] Offset { get { return offset; } }
public float[] UVs { get { return uvs; } } public float[] UVs { get { return uvs; } }
public Sequence Sequence { get { return sequence; } set { sequence = value; } }
public RegionAttachment (string name) public RegionAttachment (string name)
: base(name) { : base(name) {
} }
public void UpdateOffset () { /// <summary>Copy constructor.</summary>
float regionScaleX = width / regionOriginalWidth * scaleX; public RegionAttachment (RegionAttachment other)
float regionScaleY = height / regionOriginalHeight * scaleY; : base(other) {
float localX = -width / 2 * scaleX + regionOffsetX * regionScaleX; region = other.region;
float localY = -height / 2 * scaleY + regionOffsetY * regionScaleY; Path = other.Path;
float localX2 = localX + regionWidth * regionScaleX; x = other.x;
float localY2 = localY + regionHeight * regionScaleY; y = other.y;
scaleX = other.scaleX;
scaleY = other.scaleY;
rotation = other.rotation;
width = other.width;
height = other.height;
Array.Copy(other.uvs, 0, uvs, 0, 8);
Array.Copy(other.offset, 0, offset, 0, 8);
r = other.r;
g = other.g;
b = other.b;
a = other.a;
sequence = other.sequence == null ? null : new Sequence(other.sequence);
}
/// <summary>Calculates the <see cref="Offset"/> and <see cref="UVs"/> using the region and the attachment's transform. Must be called if the
/// region, the region's properties, or the transform are changed.</summary>
public void UpdateRegion () {
float width = Width;
float height = Height;
float localX2 = width / 2;
float localY2 = height / 2;
float localX = -localX2;
float localY = -localY2;
bool rotated = false;
if (region is AtlasRegion) {
AtlasRegion region = (AtlasRegion)this.region;
localX += region.offsetX / region.originalWidth * width;
localY += region.offsetY / region.originalHeight * height;
if (region.degrees == 90) {
rotated = true;
localX2 -= (region.originalWidth - region.offsetX - region.packedHeight) / region.originalWidth * width;
localY2 -= (region.originalHeight - region.offsetY - region.packedWidth) / region.originalHeight * height;
} else {
localX2 -= (region.originalWidth - region.offsetX - region.packedWidth) / region.originalWidth * width;
localY2 -= (region.originalHeight - region.offsetY - region.packedHeight) / region.originalHeight * height;
}
}
float scaleX = ScaleX;
float scaleY = ScaleY;
localX *= scaleX;
localY *= scaleY;
localX2 *= scaleX;
localY2 *= scaleY;
float rotation = Rotation;
float cos = MathUtils.CosDeg(this.rotation); float cos = MathUtils.CosDeg(this.rotation);
float sin = MathUtils.SinDeg(this.rotation); float sin = MathUtils.SinDeg(this.rotation);
float x = this.x, y = this.y; float x = X;
float y = Y;
float localXCos = localX * cos + x; float localXCos = localX * cos + x;
float localXSin = localX * sin; float localXSin = localX * sin;
float localYCos = localY * cos + y; float localYCos = localY * cos + y;
@ -102,39 +141,41 @@ namespace Spine {
offset[URY] = localY2Cos + localX2Sin; offset[URY] = localY2Cos + localX2Sin;
offset[BRX] = localX2Cos - localYSin; offset[BRX] = localX2Cos - localYSin;
offset[BRY] = localYCos + localX2Sin; offset[BRY] = localYCos + localX2Sin;
}
public void SetUVs (float u, float v, float u2, float v2, int degrees) {
float[] uvs = this.uvs; float[] uvs = this.uvs;
// UV values differ from spine-libgdx. if (rotated) {
if (degrees == 90) { uvs[URX] = region.u;
uvs[URX] = u; uvs[URY] = region.v2;
uvs[URY] = v2; uvs[BRX] = region.u;
uvs[BRX] = u; uvs[BRY] = region.v;
uvs[BRY] = v; uvs[BLX] = region.u2;
uvs[BLX] = u2; uvs[BLY] = region.v;
uvs[BLY] = v; uvs[ULX] = region.u2;
uvs[ULX] = u2; uvs[ULY] = region.v2;
uvs[ULY] = v2;
} else { } else {
uvs[ULX] = u; uvs[ULX] = region.u;
uvs[ULY] = v2; uvs[ULY] = region.v2;
uvs[URX] = u; uvs[URX] = region.u;
uvs[URY] = v; uvs[URY] = region.v;
uvs[BRX] = u2; uvs[BRX] = region.u2;
uvs[BRY] = v; uvs[BRY] = region.v;
uvs[BLX] = u2; uvs[BLX] = region.u2;
uvs[BLY] = v2; uvs[BLY] = region.v2;
} }
} }
/// <summary>Transforms the attachment's four vertices to world coordinates.</summary> /// <summary>
/// Transforms the attachment's four vertices to world coordinates. If the attachment has a <see cref="Sequence"/> the region may
/// be changed.</summary>
/// <param name="bone">The parent bone.</param> /// <param name="bone">The parent bone.</param>
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to offset + 8.</param> /// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to offset + 8.</param>
/// <param name="offset">The worldVertices index to begin writing values.</param> /// <param name="offset">The worldVertices index to begin writing values.</param>
/// <param name="stride">The number of worldVertices entries between the value pairs written.</param> /// <param name="stride">The number of worldVertices entries between the value pairs written.</param>
public void ComputeWorldVertices (Bone bone, float[] worldVertices, int offset, int stride = 2) { public void ComputeWorldVertices (Slot slot, float[] worldVertices, int offset, int stride = 2) {
if (sequence != null) sequence.Apply(slot, this);
float[] vertexOffset = this.offset; float[] vertexOffset = this.offset;
Bone bone = slot.Bone;
float bwx = bone.worldX, bwy = bone.worldY; float bwx = bone.worldX, bwy = bone.worldY;
float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
float offsetX, offsetY; float offsetX, offsetY;
@ -166,29 +207,7 @@ namespace Spine {
} }
public override Attachment Copy () { public override Attachment Copy () {
RegionAttachment copy = new RegionAttachment(this.Name); return new RegionAttachment(this);
copy.RendererObject = RendererObject;
copy.regionOffsetX = regionOffsetX;
copy.regionOffsetY = regionOffsetY;
copy.regionWidth = regionWidth;
copy.regionHeight = regionHeight;
copy.regionOriginalWidth = regionOriginalWidth;
copy.regionOriginalHeight = regionOriginalHeight;
copy.Path = Path;
copy.x = x;
copy.y = y;
copy.scaleX = scaleX;
copy.scaleY = scaleY;
copy.rotation = rotation;
copy.width = width;
copy.height = height;
Array.Copy(uvs, 0, copy.uvs, 0, 8);
Array.Copy(offset, 0, copy.offset, 0, 8);
copy.r = r;
copy.g = g;
copy.b = b;
copy.a = a;
return copy;
} }
} }
} }

View File

@ -0,0 +1,95 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
using System.Text;
namespace Spine {
public class Sequence {
static int nextID = 0;
static readonly Object nextIdLock = new Object();
internal readonly int id;
internal readonly TextureRegion[] regions;
internal int start, digits, setupIndex;
public int Start { get { return start; } set { start = value; } }
public int Digits { get { return digits; } set { digits = value; } }
/// <summary>The index of the region to show for the setup pose.</summary>
public int SetupIndex { get { return setupIndex; } set { setupIndex = value; } }
public TextureRegion[] Regions { get { return regions; } }
/// <summary>Returns a unique ID for this attachment.</summary>
public int Id { get { return id; } }
public Sequence (int count) {
lock (Sequence.nextIdLock) {
id = Sequence.nextID++;
}
regions = new TextureRegion[count];
}
/// <summary>Copy constructor.</summary>
public Sequence (Sequence other) {
lock (Sequence.nextIdLock) {
id = Sequence.nextID++;
}
regions = new TextureRegion[other.regions.Length];
Array.Copy(other.regions, 0, regions, 0, regions.Length);
start = other.start;
digits = other.digits;
setupIndex = other.setupIndex;
}
public void Apply (Slot slot, IHasTextureRegion attachment) {
int index = slot.SequenceIndex;
if (index == -1) index = setupIndex;
if (index >= regions.Length) index = regions.Length - 1;
TextureRegion region = regions[index];
if (attachment.Region != region) {
attachment.Region = region;
attachment.UpdateRegion();
}
}
public string GetPath (string basePath, int index) {
StringBuilder buffer = new StringBuilder(basePath.Length + digits);
buffer.Append(basePath);
string frame = (start + index).ToString();
for (int i = digits - frame.Length; i > 0; i--)
buffer.Append('0');
buffer.Append(frame);
return buffer.ToString();
}
}
public enum SequenceMode {
Hold, Once, Loop, Pingpong, OnceReverse, LoopReverse, PingpongReverse
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 522632bd4e297fe47acf78100bfd8689
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -37,27 +37,50 @@ namespace Spine {
static readonly Object nextIdLock = new Object(); static readonly Object nextIdLock = new Object();
internal readonly int id; internal readonly int id;
internal VertexAttachment timelineAttachment;
internal int[] bones; internal int[] bones;
internal float[] vertices; internal float[] vertices;
internal int worldVerticesLength; internal int worldVerticesLength;
internal VertexAttachment deformAttachment;
/// <summary>Gets a unique ID for this attachment.</summary> /// <summary>Gets a unique ID for this attachment.</summary>
public int Id { get { return id; } } public int Id { get { return id; } }
public int[] Bones { get { return bones; } set { bones = value; } } public int[] Bones { get { return bones; } set { bones = value; } }
public float[] Vertices { get { return vertices; } set { vertices = value; } } public float[] Vertices { get { return vertices; } set { vertices = value; } }
public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } } public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } }
///<summary>Deform keys for the deform attachment are also applied to this attachment. ///<summary>Timelines for the timeline attachment are also applied to this attachment.
/// May be null if no deform keys should be applied.</summary> /// May be null if no attachment-specific timelines should be applied.</summary>
public VertexAttachment DeformAttachment { get { return deformAttachment; } set { deformAttachment = value; } } public VertexAttachment TimelineAttachment { get { return timelineAttachment; } set { timelineAttachment = value; } }
public VertexAttachment (string name) public VertexAttachment (string name)
: base(name) { : base(name) {
deformAttachment = this;
lock (VertexAttachment.nextIdLock) { lock (VertexAttachment.nextIdLock) {
id = VertexAttachment.nextID++; id = VertexAttachment.nextID++;
} }
timelineAttachment = this;
}
/// <summary>Copy constructor.</summary>
public VertexAttachment (VertexAttachment other)
: base(other) {
lock (VertexAttachment.nextIdLock) {
id = VertexAttachment.nextID++;
}
timelineAttachment = other.timelineAttachment;
if (other.bones != null) {
bones = new int[other.bones.Length];
Array.Copy(other.bones, 0, bones, 0, bones.Length);
} else
bones = null;
if (other.vertices != null) {
vertices = new float[other.vertices.Length];
Array.Copy(other.vertices, 0, vertices, 0, vertices.Length);
} else
vertices = null;
worldVerticesLength = other.worldVerticesLength;
} }
public void ComputeWorldVertices (Slot slot, float[] worldVertices) { public void ComputeWorldVertices (Slot slot, float[] worldVertices) {
@ -76,7 +99,7 @@ namespace Spine {
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param> /// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param>
/// <param name="offset">The <paramref name="worldVertices"/> index to begin writing values.</param> /// <param name="offset">The <paramref name="worldVertices"/> index to begin writing values.</param>
/// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param> /// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param>
public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) { public virtual void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
count = offset + (count >> 1) * stride; count = offset + (count >> 1) * stride;
ExposedList<float> deformArray = slot.deform; ExposedList<float> deformArray = slot.deform;
float[] vertices = this.vertices; float[] vertices = this.vertices;
@ -131,23 +154,5 @@ namespace Spine {
} }
} }
} }
///<summary>Does not copy id (generated) or name (set on construction).</summary>
internal void CopyTo (VertexAttachment attachment) {
if (bones != null) {
attachment.bones = new int[bones.Length];
Array.Copy(bones, 0, attachment.bones, 0, bones.Length);
} else
attachment.bones = null;
if (vertices != null) {
attachment.vertices = new float[vertices.Length];
Array.Copy(vertices, 0, attachment.vertices, 0, vertices.Length);
} else
attachment.vertices = null;
attachment.worldVerticesLength = worldVerticesLength;
attachment.deformAttachment = deformAttachment;
}
} }
} }

View File

@ -121,8 +121,6 @@ namespace Spine {
/// <summary>Returns the magnitide (always positive) of the world scale Y.</summary> /// <summary>Returns the magnitide (always positive) of the world scale Y.</summary>
public float WorldScaleY { get { return (float)Math.Sqrt(b * b + d * d); } } public float WorldScaleY { get { return (float)Math.Sqrt(b * b + d * d); } }
/// <summary>Copy constructor. Does not copy the <see cref="Children"/> bones.</summary>
/// <param name="parent">May be null.</param>
public Bone (BoneData data, Skeleton skeleton, Bone parent) { public Bone (BoneData data, Skeleton skeleton, Bone parent) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
@ -132,6 +130,23 @@ namespace Spine {
SetToSetupPose(); SetToSetupPose();
} }
/// <summary>Copy constructor. Does not copy the <see cref="Children"/> bones.</summary>
/// <param name="parent">May be null.</param>
public Bone (Bone bone, Skeleton skeleton, Bone parent) {
if (bone == null) throw new ArgumentNullException("bone", "bone cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
this.skeleton = skeleton;
this.parent = parent;
data = bone.data;
x = bone.x;
y = bone.y;
rotation = bone.rotation;
scaleX = bone.scaleX;
scaleY = bone.scaleY;
shearX = bone.shearX;
shearY = bone.shearY;
}
/// <summary>Computes the world transform using the parent bone and this bone's local applied transform.</summary> /// <summary>Computes the world transform using the parent bone and this bone's local applied transform.</summary>
public void Update () { public void Update () {
UpdateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY); UpdateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY);

View File

@ -38,8 +38,8 @@ namespace Spine {
/// 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 : IUpdatable { public class IkConstraint : IUpdatable {
internal IkConstraintData data; internal readonly IkConstraintData data;
internal ExposedList<Bone> bones = new ExposedList<Bone>(); internal readonly ExposedList<Bone> bones = new ExposedList<Bone>();
internal Bone target; internal Bone target;
internal int bendDirection; internal int bendDirection;
internal bool compress, stretch; internal bool compress, stretch;
@ -59,8 +59,8 @@ namespace Spine {
bones = new ExposedList<Bone>(data.bones.Count); bones = new ExposedList<Bone>(data.bones.Count);
foreach (BoneData boneData in data.bones) foreach (BoneData boneData in data.bones)
bones.Add(skeleton.FindBone(boneData.name)); bones.Add(skeleton.bones.Items[boneData.index]);
target = skeleton.FindBone(data.target.name); target = skeleton.bones.Items[data.target.index];
} }
/// <summary>Copy constructor.</summary> /// <summary>Copy constructor.</summary>

View File

@ -42,16 +42,16 @@ namespace Spine {
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;
internal PathConstraintData data; internal readonly PathConstraintData data;
internal ExposedList<Bone> bones; internal readonly ExposedList<Bone> bones;
internal Slot target; internal Slot target;
internal float position, spacing, mixRotate, mixX, mixY; internal float position, spacing, mixRotate, mixX, mixY;
internal bool active; internal bool active;
internal ExposedList<float> spaces = new ExposedList<float>(), positions = new ExposedList<float>(); internal readonly ExposedList<float> spaces = new ExposedList<float>(), positions = new ExposedList<float>();
internal ExposedList<float> world = new ExposedList<float>(), curves = new ExposedList<float>(), lengths = new ExposedList<float>(); internal readonly ExposedList<float> world = new ExposedList<float>(), curves = new ExposedList<float>(), lengths = new ExposedList<float>();
internal float[] segments = new float[10]; internal readonly float[] segments = new float[10];
public PathConstraint (PathConstraintData data, Skeleton skeleton) { public PathConstraint (PathConstraintData data, Skeleton skeleton) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
@ -59,8 +59,8 @@ namespace Spine {
this.data = data; this.data = data;
bones = new ExposedList<Bone>(data.Bones.Count); bones = new ExposedList<Bone>(data.Bones.Count);
foreach (BoneData boneData in data.bones) foreach (BoneData boneData in data.bones)
bones.Add(skeleton.FindBone(boneData.name)); bones.Add(skeleton.bones.Items[boneData.index]);
target = skeleton.FindSlot(data.target.name); target = skeleton.slots.Items[data.target.index];
position = data.position; position = data.position;
spacing = data.spacing; spacing = data.spacing;
mixRotate = data.mixRotate; mixRotate = data.mixRotate;
@ -73,9 +73,9 @@ namespace Spine {
if (constraint == null) throw new ArgumentNullException("constraint cannot be null."); if (constraint == null) throw new ArgumentNullException("constraint cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
data = constraint.data; data = constraint.data;
bones = new ExposedList<Bone>(constraint.Bones.Count); bones = new ExposedList<Bone>(constraint.bones.Count);
foreach (Bone bone in constraint.Bones) foreach (Bone bone in constraint.bones)
bones.Add(skeleton.Bones.Items[bone.data.index]); bones.Add(skeleton.bones.Items[bone.data.index]);
target = skeleton.slots.Items[constraint.target.data.index]; target = skeleton.slots.Items[constraint.target.data.index];
position = constraint.position; position = constraint.position;
spacing = constraint.spacing; spacing = constraint.spacing;
@ -506,5 +506,9 @@ namespace Spine {
public bool Active { get { return active; } } public bool Active { get { return active; } }
/// <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;
}
} }
} }

View File

@ -39,10 +39,10 @@ namespace Spine {
internal ExposedList<IkConstraint> ikConstraints; internal ExposedList<IkConstraint> ikConstraints;
internal ExposedList<TransformConstraint> transformConstraints; internal ExposedList<TransformConstraint> transformConstraints;
internal ExposedList<PathConstraint> pathConstraints; internal ExposedList<PathConstraint> pathConstraints;
internal ExposedList<SpringConstraint> springConstraints;
internal ExposedList<IUpdatable> updateCache = new ExposedList<IUpdatable>(); internal ExposedList<IUpdatable> updateCache = new ExposedList<IUpdatable>();
internal Skin skin; internal Skin skin;
internal float r = 1, g = 1, b = 1, a = 1; internal float r = 1, g = 1, b = 1, a = 1;
internal float time;
private float scaleX = 1, scaleY = 1; private float scaleX = 1, scaleY = 1;
internal float x, y; internal float x, y;
@ -53,6 +53,7 @@ namespace Spine {
public ExposedList<Slot> DrawOrder { get { return drawOrder; } } public ExposedList<Slot> DrawOrder { get { return drawOrder; } }
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<SpringConstraint> SpringConstraints { get { return SpringConstraints; } }
public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } } public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } }
public Skin Skin { public Skin Skin {
@ -65,7 +66,6 @@ namespace Spine {
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; } }
public float A { get { return a; } set { a = value; } } public float A { get { return a; } set { a = value; } }
public float Time { get { return time; } set { time = value; } }
public float X { get { return x; } set { x = value; } } public float X { get { return x; } set { x = value; } }
public float Y { get { return y; } set { y = value; } } public float Y { get { return y; } set { y = value; } }
public float ScaleX { get { return scaleX; } set { scaleX = value; } } public float ScaleX { get { return scaleX; } set { scaleX = value; } }
@ -121,8 +121,68 @@ namespace Spine {
foreach (PathConstraintData pathConstraintData in data.pathConstraints) foreach (PathConstraintData pathConstraintData in data.pathConstraints)
pathConstraints.Add(new PathConstraint(pathConstraintData, this)); pathConstraints.Add(new PathConstraint(pathConstraintData, this));
springConstraints = new ExposedList<SpringConstraint>(data.springConstraints.Count);
foreach (SpringConstraintData springConstraintData in data.springConstraints)
springConstraints.Add(new SpringConstraint(springConstraintData, this));
UpdateCache();
}
/// <summary>Copy constructor.</summary>
public Skeleton (Skeleton skeleton) {
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
data = skeleton.data;
bones = new ExposedList<Bone>(skeleton.bones.Count);
foreach (Bone bone in skeleton.bones) {
Bone newBone;
if (bone.parent == null)
newBone = new Bone(bone, this, null);
else {
Bone parent = bones.Items[bone.parent.data.index];
newBone = new Bone(bone, this, parent);
parent.children.Add(newBone);
}
bones.Add(newBone);
}
slots = new ExposedList<Slot>(skeleton.slots.Count);
Bone[] bonesItems = bones.Items;
foreach (Slot slot in skeleton.slots) {
Bone bone = bonesItems[slot.bone.data.index];
slots.Add(new Slot(slot, bone));
}
drawOrder = new ExposedList<Slot>(slots.Count);
Slot[] slotsItems = slots.Items;
foreach (Slot slot in skeleton.drawOrder)
drawOrder.Add(slotsItems[slot.data.index]);
ikConstraints = new ExposedList<IkConstraint>(skeleton.ikConstraints.Count);
foreach (IkConstraint ikConstraint in skeleton.ikConstraints)
ikConstraints.Add(new IkConstraint(ikConstraint, this));
transformConstraints = new ExposedList<TransformConstraint>(skeleton.transformConstraints.Count);
foreach (TransformConstraint transformConstraint in skeleton.transformConstraints)
transformConstraints.Add(new TransformConstraint(transformConstraint, this));
pathConstraints = new ExposedList<PathConstraint>(skeleton.pathConstraints.Count);
foreach (PathConstraint pathConstraint in skeleton.pathConstraints)
pathConstraints.Add(new PathConstraint(pathConstraint, this));
springConstraints = new ExposedList<SpringConstraint>(skeleton.springConstraints.Count);
foreach (SpringConstraint springConstraint in skeleton.springConstraints)
springConstraints.Add(new SpringConstraint(springConstraint, this));
skin = skeleton.skin;
r = skeleton.r;
g = skeleton.g;
b = skeleton.b;
a = skeleton.a;
scaleX = skeleton.scaleX;
scaleY = skeleton.scaleY;
UpdateCache(); UpdateCache();
//UpdateWorldTransform();
} }
/// <summary>Caches information about bones and constraints. Must be called if the <see cref="Skin"/> is modified or if bones, constraints, or /// <summary>Caches information about bones and constraints. Must be called if the <see cref="Skin"/> is modified or if bones, constraints, or
@ -150,11 +210,13 @@ namespace Spine {
} }
} }
int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count; int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count,
springCount = this.springConstraints.Count;
IkConstraint[] ikConstraints = this.ikConstraints.Items; IkConstraint[] ikConstraints = this.ikConstraints.Items;
TransformConstraint[] transformConstraints = this.transformConstraints.Items; TransformConstraint[] transformConstraints = this.transformConstraints.Items;
PathConstraint[] pathConstraints = this.pathConstraints.Items; PathConstraint[] pathConstraints = this.pathConstraints.Items;
int constraintCount = ikCount + transformCount + pathCount; SpringConstraint[] springConstraints = this.springConstraints.Items;
int constraintCount = ikCount + transformCount + pathCount + springCount;
for (int i = 0; i < constraintCount; i++) { for (int i = 0; i < constraintCount; i++) {
for (int ii = 0; ii < ikCount; ii++) { for (int ii = 0; ii < ikCount; ii++) {
IkConstraint constraint = ikConstraints[ii]; IkConstraint constraint = ikConstraints[ii];
@ -177,6 +239,13 @@ namespace Spine {
goto continue_outer; goto continue_outer;
} }
} }
for (int ii = 0; ii < springCount; ii++) {
SpringConstraint constraint = springConstraints[ii];
if (constraint.data.order == i) {
SortSpringConstraint(constraint);
goto continue_outer;
}
}
continue_outer: { } continue_outer: { }
} }
@ -210,34 +279,6 @@ namespace Spine {
} }
} }
private void SortPathConstraint (PathConstraint constraint) {
constraint.active = constraint.target.bone.active
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data)));
if (!constraint.active) return;
Slot slot = constraint.target;
int slotIndex = slot.data.index;
Bone slotBone = slot.bone;
if (skin != null) SortPathConstraintAttachment(skin, slotIndex, slotBone);
if (data.defaultSkin != null && data.defaultSkin != skin)
SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
Attachment attachment = slot.attachment;
if (attachment is PathAttachment) SortPathConstraintAttachment(attachment, slotBone);
var constrained = constraint.bones.Items;
int boneCount = constraint.bones.Count;
for (int i = 0; i < boneCount; i++)
SortBone(constrained[i]);
updateCache.Add(constraint);
for (int i = 0; i < boneCount; i++)
SortReset(constrained[i].children);
for (int i = 0; i < boneCount; i++)
constrained[i].sorted = true;
}
private void SortTransformConstraint (TransformConstraint constraint) { private void SortTransformConstraint (TransformConstraint constraint) {
constraint.active = constraint.target.active constraint.active = constraint.target.active
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data))); && (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data)));
@ -266,6 +307,34 @@ namespace Spine {
constrained[i].sorted = true; constrained[i].sorted = true;
} }
private void SortPathConstraint (PathConstraint constraint) {
constraint.active = constraint.target.bone.active
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data)));
if (!constraint.active) return;
Slot slot = constraint.target;
int slotIndex = slot.data.index;
Bone slotBone = slot.bone;
if (skin != null) SortPathConstraintAttachment(skin, slotIndex, slotBone);
if (data.defaultSkin != null && data.defaultSkin != skin)
SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
Attachment attachment = slot.attachment;
if (attachment is PathAttachment) SortPathConstraintAttachment(attachment, slotBone);
var constrained = constraint.bones.Items;
int boneCount = constraint.bones.Count;
for (int i = 0; i < boneCount; i++)
SortBone(constrained[i]);
updateCache.Add(constraint);
for (int i = 0; i < boneCount; i++)
SortReset(constrained[i].children);
for (int i = 0; i < boneCount; i++)
constrained[i].sorted = true;
}
private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) { private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) {
foreach (var entry in skin.Attachments) foreach (var entry in skin.Attachments)
if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone); if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone);
@ -287,6 +356,23 @@ namespace Spine {
} }
} }
private void SortSpringConstraint (SpringConstraint constraint) {
constraint.active = !constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data));
if (!constraint.active) return;
Object[] constrained = constraint.bones.Items;
int boneCount = constraint.bones.Count;
for (int i = 0; i < boneCount; i++)
SortBone((Bone)constrained[i]);
updateCache.Add(constraint);
for (int i = 0; i < boneCount; i++)
SortReset(((Bone)constrained[i]).children);
for (int i = 0; i < boneCount; i++)
((Bone)constrained[i]).sorted = true;
}
private void SortBone (Bone bone) { private void SortBone (Bone bone) {
if (bone.sorted) return; if (bone.sorted) return;
Bone parent = bone.parent; Bone parent = bone.parent;
@ -372,7 +458,7 @@ namespace Spine {
for (int i = 0, n = this.bones.Count; i < n; i++) for (int i = 0, n = this.bones.Count; i < n; i++)
bones[i].SetToSetupPose(); bones[i].SetToSetupPose();
var ikConstraints = this.ikConstraints.Items; IkConstraint[] ikConstraints = this.ikConstraints.Items;
for (int i = 0, n = this.ikConstraints.Count; i < n; i++) { for (int i = 0, n = this.ikConstraints.Count; i < n; i++) {
IkConstraint constraint = ikConstraints[i]; IkConstraint constraint = ikConstraints[i];
IkConstraintData data = constraint.data; IkConstraintData data = constraint.data;
@ -383,7 +469,7 @@ namespace Spine {
constraint.stretch = data.stretch; constraint.stretch = data.stretch;
} }
var transformConstraints = this.transformConstraints.Items; TransformConstraint[] transformConstraints = this.transformConstraints.Items;
for (int i = 0, n = this.transformConstraints.Count; i < n; i++) { for (int i = 0, n = this.transformConstraints.Count; i < n; i++) {
TransformConstraint constraint = transformConstraints[i]; TransformConstraint constraint = transformConstraints[i];
TransformConstraintData data = constraint.data; TransformConstraintData data = constraint.data;
@ -395,7 +481,7 @@ namespace Spine {
constraint.mixShearY = data.mixShearY; constraint.mixShearY = data.mixShearY;
} }
var pathConstraints = this.pathConstraints.Items; PathConstraint[] pathConstraints = this.pathConstraints.Items;
for (int i = 0, n = this.pathConstraints.Count; i < n; i++) { for (int i = 0, n = this.pathConstraints.Count; i < n; i++) {
PathConstraint constraint = pathConstraints[i]; PathConstraint constraint = pathConstraints[i];
PathConstraintData data = constraint.data; PathConstraintData data = constraint.data;
@ -405,6 +491,20 @@ namespace Spine {
constraint.mixX = data.mixX; constraint.mixX = data.mixX;
constraint.mixY = data.mixY; constraint.mixY = data.mixY;
} }
SpringConstraint[] springConstraints = this.springConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) {
SpringConstraint constraint = springConstraints[i];
SpringConstraintData data = constraint.data;
constraint.mix = data.mix;
constraint.friction = data.friction;
constraint.gravity = data.gravity;
constraint.wind = data.wind;
constraint.stiffness = data.stiffness;
constraint.damping = data.damping;
constraint.rope = data.rope;
constraint.stretch = data.stretch;
}
} }
public void SetSlotsToSetupPose () { public void SetSlotsToSetupPose () {
@ -558,8 +658,17 @@ namespace Spine {
return null; return null;
} }
public void Update (float delta) { /// <summary>Finds a spring constraint by comparing each spring constraint's name. It is more efficient to cache the results of this
time += delta; /// method than to call it repeatedly.</summary>
/// <returns>May be null.</returns>
public SpringConstraint FindSpringConstraint (String constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
SpringConstraint[] springConstraints = this.springConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) {
SpringConstraint constraint = springConstraints[i];
if (constraint.data.name.Equals(constraintName)) return constraint;
}
return null;
} }
/// <summary>Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.</summary> /// <summary>Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.</summary>
@ -579,12 +688,12 @@ namespace Spine {
int verticesLength = 0; int verticesLength = 0;
float[] vertices = null; float[] vertices = null;
Attachment attachment = slot.attachment; Attachment attachment = slot.attachment;
var regionAttachment = attachment as RegionAttachment; RegionAttachment region = attachment as RegionAttachment;
if (regionAttachment != null) { if (region != null) {
verticesLength = 8; verticesLength = 8;
vertices = temp; vertices = temp;
if (vertices.Length < 8) vertices = temp = new float[8]; if (vertices.Length < 8) vertices = temp = new float[8];
regionAttachment.ComputeWorldVertices(slot.bone, temp, 0); region.ComputeWorldVertices(slot, temp, 0, 2);
} else { } else {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
@ -592,7 +701,7 @@ namespace Spine {
verticesLength = mesh.WorldVerticesLength; verticesLength = mesh.WorldVerticesLength;
vertices = temp; vertices = temp;
if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength]; if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength];
mesh.ComputeWorldVertices(slot, 0, verticesLength, temp, 0); mesh.ComputeWorldVertices(slot, 0, verticesLength, temp, 0, 2);
} }
} }

View File

@ -61,6 +61,9 @@ namespace Spine {
public const int SLOT_RGB2 = 4; public const int SLOT_RGB2 = 4;
public const int SLOT_ALPHA = 5; public const int SLOT_ALPHA = 5;
public const int ATTACHMENT_DEFORM = 0;
public const int ATTACHMENT_SEQUENCE = 1;
public const int PATH_POSITION = 0; public const int PATH_POSITION = 0;
public const int PATH_SPACING = 1; public const int PATH_SPACING = 1;
public const int PATH_MIX = 2; public const int PATH_MIX = 2;
@ -296,9 +299,9 @@ namespace Spine {
if (skin == null) throw new Exception("Skin not found: " + linkedMesh.skin); if (skin == null) throw new Exception("Skin not found: " + linkedMesh.skin);
Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent);
if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent);
linkedMesh.mesh.DeformAttachment = linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh; linkedMesh.mesh.TimelineAttachment = linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh;
linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
linkedMesh.mesh.UpdateUVs(); if (linkedMesh.mesh.Sequence == null) linkedMesh.mesh.UpdateRegion();
} }
linkedMeshes.Clear(); linkedMeshes.Clear();
@ -384,9 +387,10 @@ namespace Spine {
float width = input.ReadFloat(); float width = input.ReadFloat();
float height = input.ReadFloat(); float height = input.ReadFloat();
int color = input.ReadInt(); int color = input.ReadInt();
Sequence sequence = ReadSequence(input);
if (path == null) path = name; if (path == null) path = name;
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path, sequence);
if (region == null) return null; if (region == null) return null;
region.Path = path; region.Path = path;
region.x = x * scale; region.x = x * scale;
@ -400,7 +404,8 @@ namespace Spine {
region.g = ((color & 0x00ff0000) >> 16) / 255f; region.g = ((color & 0x00ff0000) >> 16) / 255f;
region.b = ((color & 0x0000ff00) >> 8) / 255f; region.b = ((color & 0x0000ff00) >> 8) / 255f;
region.a = ((color & 0x000000ff)) / 255f; region.a = ((color & 0x000000ff)) / 255f;
region.UpdateOffset(); region.sequence = sequence;
if (sequence == null) region.UpdateRegion();
return region; return region;
} }
case AttachmentType.Boundingbox: { case AttachmentType.Boundingbox: {
@ -424,6 +429,7 @@ namespace Spine {
int[] triangles = ReadShortArray(input); int[] triangles = ReadShortArray(input);
Vertices vertices = ReadVertices(input, vertexCount); Vertices vertices = ReadVertices(input, vertexCount);
int hullLength = input.ReadInt(true); int hullLength = input.ReadInt(true);
Sequence sequence = ReadSequence(input);
int[] edges = null; int[] edges = null;
float width = 0, height = 0; float width = 0, height = 0;
if (nonessential) { if (nonessential) {
@ -433,7 +439,7 @@ namespace Spine {
} }
if (path == null) path = name; if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) return null;
mesh.Path = path; mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f; mesh.r = ((color & 0xff000000) >> 24) / 255f;
@ -445,8 +451,9 @@ namespace Spine {
mesh.WorldVerticesLength = vertexCount << 1; mesh.WorldVerticesLength = vertexCount << 1;
mesh.triangles = triangles; mesh.triangles = triangles;
mesh.regionUVs = uvs; mesh.regionUVs = uvs;
mesh.UpdateUVs(); if (sequence == null) mesh.UpdateRegion();
mesh.HullLength = hullLength << 1; mesh.HullLength = hullLength << 1;
mesh.Sequence = sequence;
if (nonessential) { if (nonessential) {
mesh.Edges = edges; mesh.Edges = edges;
mesh.Width = width * scale; mesh.Width = width * scale;
@ -459,7 +466,8 @@ namespace Spine {
int color = input.ReadInt(); int color = input.ReadInt();
String skinName = input.ReadStringRef(); String skinName = input.ReadStringRef();
String parent = input.ReadStringRef(); String parent = input.ReadStringRef();
bool inheritDeform = input.ReadBoolean(); bool inheritTimelines = input.ReadBoolean();
Sequence sequence = ReadSequence(input);
float width = 0, height = 0; float width = 0, height = 0;
if (nonessential) { if (nonessential) {
width = input.ReadFloat(); width = input.ReadFloat();
@ -467,18 +475,19 @@ namespace Spine {
} }
if (path == null) path = name; if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) return null;
mesh.Path = path; mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f; mesh.r = ((color & 0xff000000) >> 24) / 255f;
mesh.g = ((color & 0x00ff0000) >> 16) / 255f; mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
mesh.b = ((color & 0x0000ff00) >> 8) / 255f; mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
mesh.a = ((color & 0x000000ff)) / 255f; mesh.a = ((color & 0x000000ff)) / 255f;
mesh.Sequence = sequence;
if (nonessential) { if (nonessential) {
mesh.Width = width * scale; mesh.Width = width * scale;
mesh.Height = height * scale; mesh.Height = height * scale;
} }
linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform)); linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritTimelines));
return mesh; return mesh;
} }
case AttachmentType.Path: { case AttachmentType.Path: {
@ -535,6 +544,15 @@ namespace Spine {
return null; return null;
} }
private Sequence ReadSequence (SkeletonInput input) {
if (!input.ReadBoolean()) return null;
Sequence sequence = new Sequence(input.ReadInt(true));
sequence.Start = input.ReadInt(true);
sequence.Digits = input.ReadInt(true);
sequence.SetupIndex = input.ReadInt(true);
return sequence;
}
private Vertices ReadVertices (SkeletonInput input, int vertexCount) { private Vertices ReadVertices (SkeletonInput input, int vertexCount) {
float scale = this.scale; float scale = this.scale;
int verticesLength = vertexCount << 1; int verticesLength = vertexCount << 1;
@ -904,58 +922,76 @@ namespace Spine {
} }
} }
// Deform timelines. // Attachment timelines.
for (int i = 0, n = input.ReadInt(true); i < n; i++) { for (int i = 0, n = input.ReadInt(true); i < n; i++) {
Skin skin = skeletonData.skins.Items[input.ReadInt(true)]; Skin skin = skeletonData.skins.Items[input.ReadInt(true)];
for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
int slotIndex = input.ReadInt(true); int slotIndex = input.ReadInt(true);
for (int iii = 0, nnn = input.ReadInt(true); iii < nnn; iii++) { for (int iii = 0, nnn = input.ReadInt(true); iii < nnn; iii++) {
String attachmentName = input.ReadStringRef(); String attachmentName = input.ReadStringRef();
VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, attachmentName); Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
if (attachment == null) throw new SerializationException("Vertex attachment not found: " + attachmentName); if (attachment == null) throw new SerializationException("Timeline attachment not found: " + attachmentName);
bool weighted = attachment.Bones != null;
float[] vertices = attachment.Vertices;
int deformLength = weighted ? (vertices.Length / 3) << 1 : vertices.Length;
int frameCount = input.ReadInt(true), frameLast = frameCount - 1; int timelineType = input.ReadByte(), frameCount = input.ReadInt(true), frameLast = frameCount - 1;
DeformTimeline timeline = new DeformTimeline(frameCount, input.ReadInt(true), slotIndex, attachment); switch (timelineType) {
case ATTACHMENT_DEFORM: {
VertexAttachment vertexAttachment = (VertexAttachment)attachment;
bool weighted = vertexAttachment.Bones != null;
float[] vertices = vertexAttachment.Vertices;
int deformLength = weighted ? (vertices.Length / 3) << 1 : vertices.Length;
float time = input.ReadFloat(); DeformTimeline timeline = new DeformTimeline(frameCount, input.ReadInt(true), slotIndex, vertexAttachment);
for (int frame = 0, bezier = 0; ; frame++) {
float[] deform; float time = input.ReadFloat();
int end = input.ReadInt(true); for (int frame = 0, bezier = 0; ; frame++) {
if (end == 0) float[] deform;
deform = weighted ? new float[deformLength] : vertices; int end = input.ReadInt(true);
else { if (end == 0)
deform = new float[deformLength]; deform = weighted ? new float[deformLength] : vertices;
int start = input.ReadInt(true); else {
end += start; deform = new float[deformLength];
if (scale == 1) { int start = input.ReadInt(true);
for (int v = start; v < end; v++) end += start;
deform[v] = input.ReadFloat(); if (scale == 1) {
} else { for (int v = start; v < end; v++)
for (int v = start; v < end; v++) deform[v] = input.ReadFloat();
deform[v] = input.ReadFloat() * scale; } else {
for (int v = start; v < end; v++)
deform[v] = input.ReadFloat() * scale;
}
if (!weighted) {
for (int v = 0, vn = deform.Length; v < vn; v++)
deform[v] += vertices[v];
}
} }
if (!weighted) { timeline.SetFrame(frame, time, deform);
for (int v = 0, vn = deform.Length; v < vn; v++) if (frame == frameLast) break;
deform[v] += vertices[v]; float time2 = input.ReadFloat();
switch (input.ReadByte()) {
case CURVE_STEPPED:
timeline.SetStepped(frame);
break;
case CURVE_BEZIER:
SetBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
break;
} }
time = time2;
} }
timeline.SetFrame(frame, time, deform); timelines.Add(timeline);
if (frame == frameLast) break; break;
float time2 = input.ReadFloat();
switch (input.ReadByte()) {
case CURVE_STEPPED:
timeline.SetStepped(frame);
break;
case CURVE_BEZIER:
SetBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
break;
}
time = time2;
} }
timelines.Add(timeline); case ATTACHMENT_SEQUENCE: {
SequenceTimeline timeline = new SequenceTimeline(frameCount, slotIndex, attachment);
for (int frame = 0; frame < frameCount; frame++) {
float time = input.ReadFloat();
int modeAndIndex = input.ReadInt();
timeline.SetFrame(frame, time, (SequenceMode)(modeAndIndex & 0xf), modeAndIndex >> 4,
input.ReadFloat());
}
timelines.Add(timeline);
break;
} // end case
} // end switch
} }
} }
} }

View File

@ -43,6 +43,7 @@ namespace Spine {
internal ExposedList<IkConstraintData> ikConstraints = new ExposedList<IkConstraintData>(); internal ExposedList<IkConstraintData> ikConstraints = new ExposedList<IkConstraintData>();
internal ExposedList<TransformConstraintData> transformConstraints = new ExposedList<TransformConstraintData>(); internal ExposedList<TransformConstraintData> transformConstraints = new ExposedList<TransformConstraintData>();
internal ExposedList<PathConstraintData> pathConstraints = new ExposedList<PathConstraintData>(); internal ExposedList<PathConstraintData> pathConstraints = new ExposedList<PathConstraintData>();
internal ExposedList<SpringConstraintData> springConstraints = new ExposedList<SpringConstraintData>();
internal float x, y, width, height; internal float x, y, width, height;
internal string version, hash; internal string version, hash;
@ -95,7 +96,7 @@ namespace Spine {
/// <summary>The dopesheet FPS in Spine, or zero if nonessential data was not exported.</summary> /// <summary>The dopesheet FPS in Spine, or zero if nonessential data was not exported.</summary>
public float Fps { get { return fps; } set { fps = value; } } public float Fps { get { return fps; } set { fps = value; } }
// --- Bones. // --- Bones
/// <summary> /// <summary>
/// Finds a bone by comparing each bone's name. /// Finds a bone by comparing each bone's name.
@ -111,7 +112,7 @@ namespace Spine {
return null; return null;
} }
// --- Slots. // --- Slots
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public SlotData FindSlot (string slotName) { public SlotData FindSlot (string slotName) {
@ -124,7 +125,7 @@ namespace Spine {
return null; return null;
} }
// --- Skins. // --- Skins
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public Skin FindSkin (string skinName) { public Skin FindSkin (string skinName) {
@ -134,7 +135,7 @@ namespace Spine {
return null; return null;
} }
// --- Events. // --- Events
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public EventData FindEvent (string eventDataName) { public EventData FindEvent (string eventDataName) {
@ -144,7 +145,7 @@ namespace Spine {
return null; return null;
} }
// --- Animations. // --- Animations
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public Animation FindAnimation (string animationName) { public Animation FindAnimation (string animationName) {
@ -157,7 +158,7 @@ namespace Spine {
return null; return null;
} }
// --- IK constraints. // --- IK constraints
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public IkConstraintData FindIkConstraint (string constraintName) { public IkConstraintData FindIkConstraint (string constraintName) {
@ -170,7 +171,7 @@ namespace Spine {
return null; return null;
} }
// --- Transform constraints. // --- Transform constraints
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public TransformConstraintData FindTransformConstraint (string constraintName) { public TransformConstraintData FindTransformConstraint (string constraintName) {
@ -183,8 +184,12 @@ namespace Spine {
return null; return null;
} }
// --- Path constraints. // --- Path constraints
/// <summary>
/// Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
/// than to call it multiple times.
/// </summary>
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public PathConstraintData FindPathConstraint (string constraintName) { public PathConstraintData FindPathConstraint (string constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
@ -196,6 +201,23 @@ namespace Spine {
return null; return null;
} }
// --- Spring constraints
/// <summary>
/// Finds a spring constraint by comparing each spring constraint's name. It is more efficient to cache the results of this
/// method than to call it multiple times.
/// </summary>
/// <returns>May be null.</returns>
public SpringConstraintData FindSpringConstraint (String constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
Object[] springConstraints = this.springConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) {
SpringConstraintData constraint = (SpringConstraintData)springConstraints[i];
if (constraint.name.Equals(constraintName)) return constraint;
}
return null;
}
// --- // ---
override public string ToString () { override public string ToString () {

View File

@ -336,9 +336,9 @@ namespace Spine {
if (skin == null) throw new Exception("Slot not found: " + linkedMesh.skin); if (skin == null) throw new Exception("Slot not found: " + linkedMesh.skin);
Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent);
if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent);
linkedMesh.mesh.DeformAttachment = linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh; linkedMesh.mesh.TimelineAttachment = linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh;
linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.ParentMesh = (MeshAttachment)parent;
linkedMesh.mesh.UpdateUVs(); if (linkedMesh.mesh.Region != null) linkedMesh.mesh.UpdateRegion();
} }
linkedMeshes.Clear(); linkedMeshes.Clear();
@ -386,11 +386,13 @@ namespace Spine {
var typeName = GetString(map, "type", "region"); var typeName = GetString(map, "type", "region");
var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true); var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true);
string path = GetString(map, "path", name);
switch (type) { switch (type) {
case AttachmentType.Region: case AttachmentType.Region: {
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); string path = GetString(map, "path", name);
object sequenceJson;
map.TryGetValue("sequence", out sequenceJson);
Sequence sequence = ReadSequence(sequenceJson);
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path, sequence);
if (region == null) return null; if (region == null) return null;
region.Path = path; region.Path = path;
region.x = GetFloat(map, "x", 0) * scale; region.x = GetFloat(map, "x", 0) * scale;
@ -400,6 +402,7 @@ namespace Spine {
region.rotation = GetFloat(map, "rotation", 0); region.rotation = GetFloat(map, "rotation", 0);
region.width = GetFloat(map, "width", 32) * scale; region.width = GetFloat(map, "width", 32) * scale;
region.height = GetFloat(map, "height", 32) * scale; region.height = GetFloat(map, "height", 32) * scale;
region.sequence = sequence;
if (map.ContainsKey("color")) { if (map.ContainsKey("color")) {
var color = (string)map["color"]; var color = (string)map["color"];
@ -409,8 +412,9 @@ namespace Spine {
region.a = ToColor(color, 3); region.a = ToColor(color, 3);
} }
region.UpdateOffset(); if (region.Region != null) region.UpdateRegion();
return region; return region;
}
case AttachmentType.Boundingbox: case AttachmentType.Boundingbox:
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name); BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
if (box == null) return null; if (box == null) return null;
@ -418,7 +422,11 @@ namespace Spine {
return box; return box;
case AttachmentType.Mesh: case AttachmentType.Mesh:
case AttachmentType.Linkedmesh: { case AttachmentType.Linkedmesh: {
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); string path = GetString(map, "path", name);
object sequenceJson;
map.TryGetValue("sequence", out sequenceJson);
Sequence sequence = ReadSequence(sequenceJson);
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path, sequence);
if (mesh == null) return null; if (mesh == null) return null;
mesh.Path = path; mesh.Path = path;
@ -432,10 +440,11 @@ namespace Spine {
mesh.Width = GetFloat(map, "width", 0) * scale; mesh.Width = GetFloat(map, "width", 0) * scale;
mesh.Height = GetFloat(map, "height", 0) * scale; mesh.Height = GetFloat(map, "height", 0) * scale;
mesh.Sequence = sequence;
string parent = GetString(map, "parent", null); string parent = GetString(map, "parent", null);
if (parent != null) { if (parent != null) {
linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent, GetBoolean(map, "deform", true))); linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent, GetBoolean(map, "timelines", true)));
return mesh; return mesh;
} }
@ -443,7 +452,7 @@ namespace Spine {
ReadVertices(map, mesh, uvs.Length); ReadVertices(map, mesh, uvs.Length);
mesh.triangles = GetIntArray(map, "triangles"); mesh.triangles = GetIntArray(map, "triangles");
mesh.regionUVs = uvs; mesh.regionUVs = uvs;
mesh.UpdateUVs(); if (mesh.Region != null) mesh.UpdateRegion();
if (map.ContainsKey("hull")) mesh.HullLength = GetInt(map, "hull", 0) << 1; if (map.ContainsKey("hull")) mesh.HullLength = GetInt(map, "hull", 0) << 1;
if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges"); if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
@ -494,6 +503,16 @@ namespace Spine {
return null; return null;
} }
public static Sequence ReadSequence (object sequenceJson) {
var map = sequenceJson as Dictionary<string, Object>;
if (map == null) return null;
Sequence sequence = new Sequence(GetInt(map, "count"));
sequence.start = GetInt(map, "start", 1);
sequence.digits = GetInt(map, "digits", 0);
sequence.setupIndex = GetInt(map, "setup", 0);
return sequence;
}
private void ReadVertices (Dictionary<string, Object> map, VertexAttachment attachment, int verticesLength) { private void ReadVertices (Dictionary<string, Object> map, VertexAttachment attachment, int verticesLength) {
attachment.WorldVerticesLength = verticesLength; attachment.WorldVerticesLength = verticesLength;
float[] vertices = GetFloatArray(map, "vertices", 1); float[] vertices = GetFloatArray(map, "vertices", 1);
@ -549,7 +568,7 @@ namespace Spine {
var timeline = new AttachmentTimeline(frames, slotIndex); var timeline = new AttachmentTimeline(frames, slotIndex);
int frame = 0; int frame = 0;
foreach (Dictionary<string, Object> keyMap in values) { foreach (Dictionary<string, Object> keyMap in values) {
timeline.SetFrame(frame++, GetFloat(keyMap, "time", 0), (string)keyMap["name"]); timeline.SetFrame(frame++, GetFloat(keyMap, "time", 0), GetString(keyMap, "name", null));
} }
timelines.Add(timeline); timelines.Add(timeline);
@ -945,59 +964,82 @@ namespace Spine {
} }
} }
// Deform timelines. // Attachment timelines.
if (map.ContainsKey("deform")) { if (map.ContainsKey("attachments")) {
foreach (KeyValuePair<string, Object> deformMap in (Dictionary<string, Object>)map["deform"]) { foreach (KeyValuePair<string, Object> attachmentsMap in (Dictionary<string, Object>)map["attachments"]) {
Skin skin = skeletonData.FindSkin(deformMap.Key); Skin skin = skeletonData.FindSkin(attachmentsMap.Key);
foreach (KeyValuePair<string, Object> slotMap in (Dictionary<string, Object>)deformMap.Value) { foreach (KeyValuePair<string, Object> slotMap in (Dictionary<string, Object>)attachmentsMap.Value) {
int slotIndex = FindSlotIndex(skeletonData, slotMap.Key); SlotData slot = skeletonData.FindSlot(slotMap.Key);
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)slotMap.Value) { if (slot == null) throw new Exception("Slot not found: " + slotMap.Key);
var values = (List<Object>)timelineMap.Value; foreach (KeyValuePair<string, Object> attachmentMap in (Dictionary<string, Object>)slotMap.Value) {
var keyMapEnumerator = values.GetEnumerator(); Attachment attachment = skin.GetAttachment(slot.index, attachmentMap.Key);
if (!keyMapEnumerator.MoveNext()) continue; if (attachment == null) throw new Exception("Timeline attachment not found: " + attachmentMap.Key);
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current; foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)attachmentMap.Value) {
VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key); var values = (List<Object>)timelineMap.Value;
if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key); var keyMapEnumerator = values.GetEnumerator();
bool weighted = attachment.bones != null; if (!keyMapEnumerator.MoveNext()) continue;
float[] vertices = attachment.vertices; var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
int deformLength = weighted ? (vertices.Length / 3) << 1 : vertices.Length; int frames = values.Count;
DeformTimeline timeline = new DeformTimeline(values.Count, values.Count, slotIndex, attachment); string timelineName = timelineMap.Key;
float time = GetFloat(keyMap, "time", 0); if (timelineName == "deform") {
for (int frame = 0, bezier = 0; ; frame++) { VertexAttachment vertexAttachment = (VertexAttachment)attachment;
float[] deform; bool weighted = vertexAttachment.bones != null;
if (!keyMap.ContainsKey("vertices")) { float[] vertices = vertexAttachment.vertices;
deform = weighted ? new float[deformLength] : vertices; int deformLength = weighted ? (vertices.Length / 3) << 1 : vertices.Length;
} else {
deform = new float[deformLength];
int start = GetInt(keyMap, "offset", 0);
float[] verticesValue = GetFloatArray(keyMap, "vertices", 1);
Array.Copy(verticesValue, 0, deform, start, verticesValue.Length);
if (scale != 1) {
for (int i = start, n = i + verticesValue.Length; i < n; i++)
deform[i] *= scale;
}
if (!weighted) { DeformTimeline timeline = new DeformTimeline(frames, frames, slot.Index, vertexAttachment);
for (int i = 0; i < deformLength; i++) float time = GetFloat(keyMap, "time", 0);
deform[i] += vertices[i]; for (int frame = 0, bezier = 0; ; frame++) {
} float[] deform;
} if (!keyMap.ContainsKey("vertices")) {
deform = weighted ? new float[deformLength] : vertices;
} else {
deform = new float[deformLength];
int start = GetInt(keyMap, "offset", 0);
float[] verticesValue = GetFloatArray(keyMap, "vertices", 1);
Array.Copy(verticesValue, 0, deform, start, verticesValue.Length);
if (scale != 1) {
for (int i = start, n = i + verticesValue.Length; i < n; i++)
deform[i] *= scale;
}
timeline.SetFrame(frame, time, deform); if (!weighted) {
if (!keyMapEnumerator.MoveNext()) { for (int i = 0; i < deformLength; i++)
timeline.Shrink(bezier); deform[i] += vertices[i];
break; }
}
timeline.SetFrame(frame, time, deform);
if (!keyMapEnumerator.MoveNext()) {
timeline.Shrink(bezier);
break;
}
var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
float time2 = GetFloat(nextMap, "time", 0);
if (keyMap.ContainsKey("curve")) {
object curve = keyMap["curve"];
bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
keyMap = nextMap;
}
timelines.Add(timeline);
} else if (timelineName == "sequence") {
SequenceTimeline timeline = new SequenceTimeline(frames, slot.index, attachment);
float lastDelay = 0;
for (int frame = 0; keyMap != null;
keyMapEnumerator.MoveNext(), keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current, frame++) {
float delay = GetFloat(keyMap, "delay", lastDelay);
SequenceMode sequenceMode = (SequenceMode)Enum.Parse(typeof(SequenceMode),
GetString(keyMap, "mode", "hold"), true);
timeline.SetFrame(frame, GetFloat(keyMap, "time", 0),
sequenceMode, GetInt(keyMap, "index", 0), delay);
lastDelay = delay;
}
timelines.Add(timeline);
} }
var nextMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
float time2 = GetFloat(nextMap, "time", 0);
if (keyMap.ContainsKey("curve")) {
object curve = keyMap["curve"];
bezier = ReadCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
keyMap = nextMap;
} }
timelines.Add(timeline);
} }
} }
} }
@ -1174,6 +1216,11 @@ namespace Spine {
return (int)(float)map[name]; return (int)(float)map[name];
} }
static int GetInt (Dictionary<string, Object> map, string name) {
if (!map.ContainsKey(name)) throw new ArgumentException("Named value not found: " + name);
return (int)(float)map[name];
}
static bool GetBoolean (Dictionary<string, Object> map, string name, bool defaultValue) { static bool GetBoolean (Dictionary<string, Object> map, string name, bool defaultValue) {
if (!map.ContainsKey(name)) return defaultValue; if (!map.ContainsKey(name)) return defaultValue;
return (bool)map[name]; return (bool)map[name];

View File

@ -77,14 +77,14 @@ namespace Spine {
internal string parent, skin; internal string parent, skin;
internal int slotIndex; internal int slotIndex;
internal MeshAttachment mesh; internal MeshAttachment mesh;
internal bool inheritDeform; internal bool inheritTimelines;
public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent, bool inheritDeform) { public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent, bool inheritTimelines) {
this.mesh = mesh; this.mesh = mesh;
this.skin = skin; this.skin = skin;
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
this.parent = parent; this.parent = parent;
this.inheritDeform = inheritDeform; this.inheritTimelines = inheritTimelines;
} }
} }

View File

@ -43,7 +43,7 @@ namespace Spine {
internal float r2, g2, b2; internal float r2, g2, b2;
internal bool hasSecondColor; internal bool hasSecondColor;
internal Attachment attachment; internal Attachment attachment;
internal float attachmentTime; internal int sequenceIndex;
internal ExposedList<float> deform = new ExposedList<float>(); internal ExposedList<float> deform = new ExposedList<float>();
internal int attachmentState; internal int attachmentState;
@ -83,7 +83,7 @@ namespace Spine {
hasSecondColor = slot.hasSecondColor; hasSecondColor = slot.hasSecondColor;
attachment = slot.attachment; attachment = slot.attachment;
attachmentTime = slot.attachmentTime; sequenceIndex = slot.sequenceIndex;
deform.AddRange(slot.deform); deform.AddRange(slot.deform);
} }
@ -135,27 +135,26 @@ namespace Spine {
/// <summary>The current attachment for the slot, or null if the slot has no attachment.</summary> /// <summary>The current attachment for the slot, or null if the slot has no attachment.</summary>
get { return attachment; } get { return attachment; }
/// <summary> /// <summary>
/// Sets the slot's attachment and, if the attachment changed, resets <see cref="AttachmentTime"/> and clears the <see cref="Deform"/>. /// Sets the slot's attachment and, if the attachment changed, resets <see cref="SequenceIndex"/> and clears the <see cref="Deform"/>.
/// The deform is not cleared if the old attachment has the same <see cref="VertexAttachment.DeformAttachment"/> as the specified /// The deform is not cleared if the old attachment has the same <see cref="VertexAttachment.TimelineAttachment"/> as the
/// attachment.</summary> /// specified attachment.</summary>
/// <param name="value">May be null.</param> /// <param name="value">May be null.</param>
set { set {
if (attachment == value) return; if (attachment == value) return;
if (!(value is VertexAttachment) || !(this.attachment is VertexAttachment) if (!(value is VertexAttachment) || !(this.attachment is VertexAttachment)
|| ((VertexAttachment)value).DeformAttachment != ((VertexAttachment)this.attachment).DeformAttachment) { || ((VertexAttachment)value).TimelineAttachment != ((VertexAttachment)this.attachment).TimelineAttachment) {
deform.Clear(); deform.Clear();
} }
this.attachment = value; this.attachment = value;
attachmentTime = bone.skeleton.time; sequenceIndex = -1;
} }
} }
/// <summary> The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton /// <summary>
/// <see cref="Skeleton.Time"/></summary> /// The index of the texture region to display when the slot's attachment has a <see cref="Sequence"/>. -1 represents the
public float AttachmentTime { /// <see cref="Sequence.SetupIndex"/>.
get { return bone.skeleton.time - attachmentTime; } /// </summary>
set { attachmentTime = bone.skeleton.time - value; } public int SequenceIndex { get { return sequenceIndex; } set { sequenceIndex = value; } }
}
/// <summary> Vertices to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a /// <summary> Vertices to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
/// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. /// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.

View File

@ -0,0 +1,105 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
/// <summary>
/// Stores the current pose for a spring constraint. A spring constraint applies physics to bones.
/// <para>
/// See <a href="http://esotericsoftware.com/spine-spring-constraints">Spring constraints</a> in the Spine User Guide.</para>
/// </summary>
public class SpringConstraint : IUpdatable {
internal readonly SpringConstraintData data;
internal readonly ExposedList<Bone> bones;
// BOZO! - stiffness -> strength. stiffness, damping, rope, stretch -> move to spring.
internal float mix, friction, gravity, wind, stiffness, damping;
internal bool rope, stretch;
internal bool active;
public SpringConstraint (SpringConstraintData data, Skeleton skeleton) {
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;
mix = data.mix;
friction = data.friction;
gravity = data.gravity;
wind = data.wind;
stiffness = data.stiffness;
damping = data.damping;
rope = data.rope;
stretch = data.stretch;
bones = new ExposedList<Bone>(data.Bones.Count);
foreach (BoneData boneData in data.bones)
bones.Add(skeleton.bones.Items[boneData.index]);
}
/// <summary>Copy constructor.</summary>
public SpringConstraint (SpringConstraint constraint, Skeleton skeleton) {
if (constraint == null) throw new ArgumentNullException("constraint", "constraint cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
data = constraint.data;
bones = new ExposedList<Bone>(constraint.bones.Count);
foreach (Bone bone in constraint.bones)
bones.Add(skeleton.bones.Items[bone.data.index]);
mix = constraint.mix;
friction = constraint.friction;
gravity = constraint.gravity;
wind = constraint.wind;
stiffness = constraint.stiffness;
damping = constraint.damping;
rope = constraint.rope;
stretch = constraint.stretch;
}
/// <summary>Applies the constraint to the constrained bones.</summary>
public void Update () {
}
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary>
public float Mix { get { return mix; } set { mix = value; } }
public float Friction { get { return friction; } set { friction = value; } }
public float Gravity { get { return gravity; } set { gravity = value; } }
public float Wind { get { return wind; } set { wind = value; } }
public float Stiffness { get { return stiffness; } set { stiffness = value; } }
public float Damping { get { return damping; } set { damping = value; } }
public bool Rope { get { return rope; } set { rope = value; } }
public bool Stretch { get { return stretch; } set { stretch = value; } }
public bool Active { get { return active; } }
/// <summary>The spring constraint's setup pose data.</summary>
public SpringConstraintData Data { get { return data; } }
override public string ToString () {
return data.name;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2816491d178b3b4986920107586ce55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
/// <summary>
/// Stores the setup pose for a <see cref="SpringConstraint"/>.
/// <para>
/// See <a href="http://esotericsoftware.com/spine-spring-constraints">Spring constraints</a> in the Spine User Guide.</para>
/// </summary>
public class SpringConstraintData : ConstraintData {
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
internal float mix, friction, gravity, wind, stiffness, damping;
internal bool rope, stretch;
public SpringConstraintData (string name) : base(name) {
}
/// <summary>The bones that are constrained by this spring constraint.</summary>
public ExposedList<BoneData> Bones { get { return bones; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary>
public float Mix { get { return mix; } set { mix = value; } }
public float Friction { get { return friction; } set { friction = value; } }
public float Gravity { get { return gravity; } set { gravity = value; } }
public float Wind { get { return wind; } set { wind = value; } }
public float Stiffness { get { return stiffness; } set { stiffness = value; } }
public float Damping { get { return damping; } set { damping = value; } }
public bool Rope { get { return rope; } set { rope = value; } }
public bool Stretch { get { return stretch; } set { stretch = value; } }
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 438688f6194e6dc40953a23d05d48e1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,49 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated September 24, 2021. Replaces all prior versions.
*
* Copyright (c) 2013-2021, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#if (UNITY_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1)
#define IS_UNITY
#endif
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
namespace Spine {
public class TextureRegion {
public int width, height;
public float u, v, u2, v2;
virtual public int OriginalWidth { get { return width; } }
virtual public int OriginalHeight { get { return height; } }
}
}

View File

@ -38,8 +38,8 @@ namespace Spine {
/// 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 : IUpdatable { public class TransformConstraint : IUpdatable {
internal TransformConstraintData data; internal readonly TransformConstraintData data;
internal ExposedList<Bone> bones; internal readonly ExposedList<Bone> bones;
internal Bone target; internal Bone target;
internal float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; internal float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
@ -57,9 +57,9 @@ namespace Spine {
mixShearY = data.mixShearY; mixShearY = data.mixShearY;
bones = new ExposedList<Bone>(); bones = new ExposedList<Bone>();
foreach (BoneData boneData in data.bones) foreach (BoneData boneData in data.bones)
bones.Add(skeleton.FindBone(boneData.name)); bones.Add(skeleton.bones.Items[boneData.index]);
target = skeleton.FindBone(data.target.name); target = skeleton.bones.Items[data.target.index];
} }
/// <summary>Copy constructor.</summary> /// <summary>Copy constructor.</summary>

View File

@ -2,7 +2,7 @@
"name": "com.esotericsoftware.spine.spine-csharp", "name": "com.esotericsoftware.spine.spine-csharp",
"displayName": "spine-csharp Runtime", "displayName": "spine-csharp Runtime",
"description": "This plugin provides the spine-csharp core runtime.", "description": "This plugin provides the spine-csharp core runtime.",
"version": "4.0.0", "version": "4.1.0",
"unity": "2018.3", "unity": "2018.3",
"author": { "author": {
"name": "Esoteric Software", "name": "Esoteric Software",

View File

@ -44,11 +44,11 @@ namespace Spine {
} }
class NullAttachmentLoader : AttachmentLoader { class NullAttachmentLoader : AttachmentLoader {
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
return null; return null;
} }
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
return null; return null;
} }
@ -851,7 +851,6 @@ namespace Spine {
state.Apply(skeleton); state.Apply(skeleton);
while (time < endTime) { while (time < endTime) {
time += incr; time += incr;
skeleton.Update(incr);
state.Update(incr); state.Update(incr);
// Reduce float discrepancies for tests. // Reduce float discrepancies for tests.

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: e47cc991328826946a8c4efdd1885bf2 guid: 1e002a2e05cd8a441801b685e426f6c8
timeCreated: 1599066046 timeCreated: 1599066046
licenseType: Pro licenseType: Pro
MonoImporter: MonoImporter:

View File

@ -56,7 +56,6 @@ namespace Spine.Unity.Examples {
var skeleton = skeletonRenderer.skeleton; if (skeleton == null) return; var skeleton = skeletonRenderer.skeleton; if (skeleton == null) return;
fillAnimation.Animation.Apply(skeleton, 0, percent, false, null, 1f, MixBlend.Setup, MixDirection.In); fillAnimation.Animation.Apply(skeleton, 0, percent, false, null, 1f, MixBlend.Setup, MixDirection.In);
skeleton.Update(Time.deltaTime);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
} }
} }

View File

@ -3,110 +3,127 @@ dragon.png
filter: Linear, Linear filter: Linear, Linear
pma: true pma: true
back back
bounds: 2, 334, 190, 185 bounds: 564, 534, 190, 185
chest chest
bounds: 2, 697, 136, 122 bounds: 2, 645, 136, 122
chin chin
bounds: 611, 613, 214, 146 bounds: 140, 619, 214, 146
front-toe-a front-toe-a
bounds: 2, 914, 29, 50 bounds: 2, 862, 29, 50
rotate: 90 rotate: 90
front-toe-b front-toe-b
bounds: 467, 887, 56, 57 bounds: 467, 835, 56, 57
rotate: 90
head
bounds: 756, 398, 296, 260
rotate: 90 rotate: 90
left-front-leg left-front-leg
bounds: 599, 886, 84, 57 bounds: 599, 834, 84, 57
left-front-thigh left-front-thigh
bounds: 782, 871, 84, 72 bounds: 782, 819, 84, 72
left-rear-leg left-rear-leg
bounds: 465, 434, 206, 177 bounds: 356, 558, 206, 177
left-rear-thigh left-rear-thigh
bounds: 216, 819, 91, 149 bounds: 216, 767, 91, 149
rotate: 90 rotate: 90
left-wing01 left-wing01
bounds: 403, 241, 191, 256 bounds: 2, 268, 264, 589
rotate: 90 rotate: 90
left-wing02 left-wing02
bounds: 673, 401, 179, 269 bounds: 2, 2, 264, 589
rotate: 90 rotate: 90
left-wing03
bounds: 194, 286, 186, 207
rotate: 90
left-wing04
bounds: 140, 682, 188, 135
left-wing06
bounds: 661, 207, 192, 331
rotate: 90
left-wing07
bounds: 2, 521, 159, 255
rotate: 90
left-wing08
bounds: 827, 582, 164, 181
rotate: 90
left-wing09
bounds: 259, 474, 204, 167
right-front-leg right-front-leg
bounds: 113, 821, 101, 89 bounds: 113, 769, 101, 89
right-front-thigh right-front-thigh
bounds: 758, 761, 108, 108 bounds: 758, 709, 108, 108
right-rear-leg right-rear-leg
bounds: 640, 773, 116, 100 bounds: 640, 721, 116, 100
right-rear-thigh right-rear-thigh
bounds: 367, 794, 91, 149 bounds: 367, 742, 91, 149
rotate: 90 rotate: 90
right-rear-toe right-rear-toe
bounds: 2, 833, 109, 77 bounds: 2, 781, 109, 77
right-wing02
bounds: 635, 2, 203, 305
rotate: 90
right-wing04
bounds: 330, 643, 279, 144
right-wing06
bounds: 2, 84, 200, 366
rotate: 90
right-wing07
bounds: 370, 39, 200, 263
rotate: 90
tail01 tail01
bounds: 868, 748, 120, 153 bounds: 868, 696, 120, 153
rotate: 90 rotate: 90
tail02 tail02
bounds: 518, 789, 95, 120 bounds: 518, 737, 95, 120
rotate: 90 rotate: 90
tail03 tail03
bounds: 868, 870, 73, 92 bounds: 868, 818, 73, 92
rotate: 90 rotate: 90
tail04 tail04
bounds: 526, 887, 56, 71 bounds: 526, 835, 56, 71
rotate: 90 rotate: 90
tail05 tail05
bounds: 406, 891, 52, 59 bounds: 406, 839, 52, 59
rotate: 90 rotate: 90
tail06 tail06
bounds: 685, 875, 95, 68 bounds: 685, 823, 95, 68
thiagobrayner thiagobrayner
bounds: 54, 912, 350, 31 bounds: 54, 860, 350, 31
dragon2.png dragon2.png
size: 1024, 512 size: 1024, 1024
filter: Linear, Linear filter: Linear, Linear
pma: true pma: true
head left-wing03
bounds: 2, 214, 296, 260 bounds: 2, 534, 264, 589
rotate: 90
left-wing04
bounds: 2, 268, 264, 589
rotate: 90 rotate: 90
left-wing05 left-wing05
bounds: 741, 39, 218, 213 bounds: 593, 209, 264, 589
left-wing06
bounds: 2, 2, 264, 589
rotate: 90 rotate: 90
dragon3.png
size: 1024, 1024
filter: Linear, Linear
pma: true
left-wing07
bounds: 2, 694, 264, 589
rotate: 90
left-wing08
bounds: 2, 428, 264, 589
rotate: 90
left-wing09
bounds: 593, 369, 264, 589
right-wing01 right-wing01
bounds: 264, 200, 219, 310 bounds: 2, 2, 365, 643
rotate: 90
dragon4.png
size: 1024, 1024
filter: Linear, Linear
pma: true
right-wing02
bounds: 2, 369, 365, 643
right-wing03 right-wing03
bounds: 485, 238, 272, 247 bounds: 369, 369, 365, 643
right-wing04
bounds: 2, 2, 365, 643
rotate: 90 rotate: 90
dragon5.png
size: 1024, 1024
filter: Linear, Linear
pma: true
right-wing05 right-wing05
bounds: 734, 259, 251, 229 bounds: 2, 369, 365, 643
right-wing06
bounds: 369, 369, 365, 643
right-wing07
bounds: 2, 2, 365, 643
rotate: 90 rotate: 90
dragon6.png
size: 1024, 1024
filter: Linear, Linear
pma: true
right-wing08 right-wing08
bounds: 485, 2, 234, 254 bounds: 2, 2, 365, 643
rotate: 90
right-wing09 right-wing09
bounds: 2, 8, 248, 204 bounds: 369, 2, 365, 643

View File

@ -1,13 +1,13 @@
{ {
"skeleton": { "skeleton": {
"hash": "UIFpNNbbcQI", "hash": "aPoA1GjXkVI",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -366.31, "x": -366.31,
"y": -286.62, "y": -327.81,
"width": 660.39, "width": 660.39,
"height": 604.09, "height": 643,
"images": "./images/", "images": "./images/",
"audio": "" "audio": "././"
}, },
"bones": [ "bones": [
{ "name": "root", "y": -176.12 }, { "name": "root", "y": -176.12 },
@ -297,7 +297,7 @@
"slots": [ "slots": [
{ "name": "left-rear-leg", "bone": "left-rear-leg", "attachment": "left-rear-leg" }, { "name": "left-rear-leg", "bone": "left-rear-leg", "attachment": "left-rear-leg" },
{ "name": "left-rear-thigh", "bone": "left-rear-thigh", "attachment": "left-rear-thigh" }, { "name": "left-rear-thigh", "bone": "left-rear-thigh", "attachment": "left-rear-thigh" },
{ "name": "left-wing", "bone": "left-wing", "attachment": "left-wing01" }, { "name": "left-wing", "bone": "left-wing", "attachment": "left-wing" },
{ "name": "tail6", "bone": "tail6", "attachment": "tail06" }, { "name": "tail6", "bone": "tail6", "attachment": "tail06" },
{ "name": "tail5", "bone": "tail5", "attachment": "tail05" }, { "name": "tail5", "bone": "tail5", "attachment": "tail05" },
{ "name": "tail4", "bone": "tail4", "attachment": "tail04" }, { "name": "tail4", "bone": "tail4", "attachment": "tail04" },
@ -323,7 +323,7 @@
{ "name": "right-front-toe2", "bone": "right-front-toe2", "attachment": "front-toe-b" }, { "name": "right-front-toe2", "bone": "right-front-toe2", "attachment": "front-toe-b" },
{ "name": "right-front-toe3", "bone": "right-front-toe3", "attachment": "front-toe-b" }, { "name": "right-front-toe3", "bone": "right-front-toe3", "attachment": "front-toe-b" },
{ "name": "chin", "bone": "chin", "attachment": "chin" }, { "name": "chin", "bone": "chin", "attachment": "chin" },
{ "name": "right-wing", "bone": "right-wing", "attachment": "right-wing01" }, { "name": "right-wing", "bone": "right-wing", "attachment": "right-wing" },
{ "name": "head", "bone": "head", "attachment": "head" }, { "name": "head", "bone": "head", "attachment": "head" },
{ "name": "thiagobrayner", "bone": "root", "attachment": "thiagobrayner" } { "name": "thiagobrayner", "bone": "root", "attachment": "thiagobrayner" }
], ],
@ -376,15 +376,14 @@
"left-rear-thigh": { "x": 56.03, "y": 27.39, "rotation": 74.94, "width": 91, "height": 149 } "left-rear-thigh": { "x": 56.03, "y": 27.39, "rotation": 74.94, "width": 91, "height": 149 }
}, },
"left-wing": { "left-wing": {
"left-wing01": { "x": 129.21, "y": -45.49, "rotation": -83.7, "width": 191, "height": 256 }, "left-wing": {
"left-wing02": { "x": 126.38, "y": -31.69, "rotation": -86.19, "width": 179, "height": 269 }, "x": -36.32,
"left-wing03": { "x": 110.27, "y": -90.89, "rotation": -86.19, "width": 186, "height": 207 }, "y": -44.53,
"left-wing04": { "x": -61.62, "y": -83.27, "rotation": -86.19, "width": 188, "height": 135 }, "rotation": -83.7,
"left-wing05": { "x": -90.02, "y": -78.14, "rotation": -86.19, "width": 218, "height": 213 }, "width": 264,
"left-wing06": { "x": -143.77, "y": -83.72, "rotation": -86.19, "width": 192, "height": 331 }, "height": 589,
"left-wing07": { "x": -133.05, "y": -33.9, "rotation": -86.19, "width": 159, "height": 255 }, "sequence": { "count": 9, "digits": 2 }
"left-wing08": { "x": 50.15, "y": -15.71, "rotation": -86.19, "width": 164, "height": 181 }, }
"left-wing09": { "x": 85.94, "y": -11.33, "rotation": -86.19, "width": 204, "height": 167 }
}, },
"right-front-leg": { "right-front-leg": {
"right-front-leg": { "x": 17.8, "y": 4.23, "rotation": 37.63, "width": 101, "height": 89 } "right-front-leg": { "x": 17.8, "y": 4.23, "rotation": 37.63, "width": 101, "height": 89 }
@ -417,15 +416,14 @@
"right-rear-toe": { "x": 47.46, "y": -7.64, "rotation": 134.34, "width": 109, "height": 77 } "right-rear-toe": { "x": 47.46, "y": -7.64, "rotation": 134.34, "width": 109, "height": 77 }
}, },
"right-wing": { "right-wing": {
"right-wing01": { "x": 170.08, "y": -23.68, "rotation": -130.34, "width": 219, "height": 310 }, "right-wing": {
"right-wing02": { "x": 171.15, "y": -19.33, "rotation": -130.34, "width": 203, "height": 305 }, "x": 35.09,
"right-wing03": { "x": 166.46, "y": 29.24, "rotation": -130.34, "width": 272, "height": 247 }, "y": 78.11,
"right-wing04": { "x": 42.94, "y": 134.06, "rotation": -130.34, "width": 279, "height": 144 }, "rotation": -130.34,
"right-wing05": { "x": -8.84, "y": 142.59, "rotation": -130.34, "width": 251, "height": 229 }, "width": 365,
"right-wing06": { "x": -123.33, "y": 111.22, "rotation": -130.34, "width": 200, "height": 366 }, "height": 643,
"right-wing07": { "x": -40.17, "y": 118.03, "rotation": -130.34, "width": 200, "height": 263 }, "sequence": { "count": 9, "digits": 2 }
"right-wing08": { "x": 48.02, "y": 28.76, "rotation": -130.34, "width": 234, "height": 254 }, }
"right-wing09": { "x": 128.1, "y": 21.13, "rotation": -130.34, "width": 248, "height": 204 }
}, },
"tail1": { "tail1": {
"tail01": { "x": 22.6, "y": -4.5, "rotation": 163.85, "width": 120, "height": 153 } "tail01": { "x": 22.6, "y": -4.5, "rotation": 163.85, "width": 120, "height": 153 }
@ -453,50 +451,6 @@
], ],
"animations": { "animations": {
"flying": { "flying": {
"slots": {
"left-wing": {
"attachment": [
{ "time": 0.0667, "name": "left-wing02" },
{ "time": 0.1333, "name": "left-wing03" },
{ "time": 0.2, "name": "left-wing04" },
{ "time": 0.2667, "name": "left-wing05" },
{ "time": 0.3333, "name": "left-wing06" },
{ "time": 0.4, "name": "left-wing07" },
{ "time": 0.4667, "name": "left-wing08" },
{ "time": 0.5333, "name": "left-wing09" },
{ "time": 0.6, "name": "left-wing01" },
{ "time": 0.7333, "name": "left-wing02" },
{ "time": 0.8, "name": "left-wing03" },
{ "time": 0.8333, "name": "left-wing04" },
{ "time": 0.8667, "name": "left-wing05" },
{ "time": 0.9, "name": "left-wing06" },
{ "time": 0.9333, "name": "left-wing07" },
{ "time": 0.9667, "name": "left-wing08" },
{ "time": 1, "name": "left-wing01" }
]
},
"right-wing": {
"attachment": [
{ "time": 0.0667, "name": "right-wing02" },
{ "time": 0.1333, "name": "right-wing03" },
{ "time": 0.2, "name": "right-wing04" },
{ "time": 0.2667, "name": "right-wing05" },
{ "time": 0.3333, "name": "right-wing06" },
{ "time": 0.4, "name": "right-wing07" },
{ "time": 0.4667, "name": "right-wing08" },
{ "time": 0.5333, "name": "right-wing09" },
{ "time": 0.6, "name": "right-wing01" },
{ "time": 0.7333, "name": "right-wing02" },
{ "time": 0.8, "name": "right-wing03" },
{ "time": 0.8333, "name": "right-wing04" },
{ "time": 0.8667, "name": "right-wing05" },
{ "time": 0.9, "name": "right-wing06" },
{ "time": 0.9333, "name": "right-wing07" },
{ "time": 0.9667, "name": "right-wing08" },
{ "time": 1, "name": "right-wing01" }
]
}
},
"bones": { "bones": {
"back": { "back": {
"rotate": [ "rotate": [
@ -1093,6 +1047,32 @@
{ "time": 1 } { "time": 1 }
] ]
} }
},
"attachments": {
"default": {
"left-wing": {
"left-wing": {
"sequence": [
{ "mode": "loop", "delay": 0.0667 },
{ "time": 0.6 },
{ "time": 0.7333, "mode": "loop", "index": 1 },
{ "time": 0.8, "mode": "loop", "index": 2, "delay": 0.0333 },
{ "time": 0.9667, "index": 7 }
]
}
},
"right-wing": {
"right-wing": {
"sequence": [
{ "mode": "loop", "delay": 0.0667 },
{ "time": 0.6 },
{ "time": 0.7333, "mode": "loop", "index": 1 },
{ "time": 0.8, "mode": "loop", "index": 2, "delay": 0.0333 },
{ "time": 0.9667, "index": 7 }
]
}
}
}
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 KiB

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -0,0 +1,108 @@
fileFormatVersion: 2
guid: 9a960996718ee9a4a9872c1a38fc3946
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

View File

@ -0,0 +1,108 @@
fileFormatVersion: 2
guid: 390eb45b86ad95d40855f1cedc5ebe86
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1,108 @@
fileFormatVersion: 2
guid: d3a3452c852fdd84ea122c9533745866
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -0,0 +1,108 @@
fileFormatVersion: 2
guid: a87fe78b999f42f459397732f7c75303
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 1
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: dragon_dragon3
m_Shader: {fileID: 4800000, guid: 1e8a610c9e01c3648bac42585e5fc676, type: 3}
m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 9a960996718ee9a4a9872c1a38fc3946, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _Cutoff: 0.1
- _OutlineMipLevel: 0
- _OutlineReferenceTexWidth: 1024
- _OutlineSmoothness: 1
- _OutlineWidth: 3
- _StencilComp: 8
- _StencilRef: 1
- _StraightAlphaInput: 0
- _ThresholdEnd: 0.25
- _Use8Neighbourhood: 1
m_Colors:
- _OutlineColor: {r: 1, g: 1, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 46ebf60e37c48414f90b2f53f8ce4ea0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: dragon_dragon4
m_Shader: {fileID: 4800000, guid: 1e8a610c9e01c3648bac42585e5fc676, type: 3}
m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 390eb45b86ad95d40855f1cedc5ebe86, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _Cutoff: 0.1
- _OutlineMipLevel: 0
- _OutlineReferenceTexWidth: 1024
- _OutlineSmoothness: 1
- _OutlineWidth: 3
- _StencilComp: 8
- _StencilRef: 1
- _StraightAlphaInput: 0
- _ThresholdEnd: 0.25
- _Use8Neighbourhood: 1
m_Colors:
- _OutlineColor: {r: 1, g: 1, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1cb51a81cfe737549beec4fdb1f16360
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: dragon_dragon5
m_Shader: {fileID: 4800000, guid: 1e8a610c9e01c3648bac42585e5fc676, type: 3}
m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: d3a3452c852fdd84ea122c9533745866, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _Cutoff: 0.1
- _OutlineMipLevel: 0
- _OutlineReferenceTexWidth: 1024
- _OutlineSmoothness: 1
- _OutlineWidth: 3
- _StencilComp: 8
- _StencilRef: 1
- _StraightAlphaInput: 0
- _ThresholdEnd: 0.25
- _Use8Neighbourhood: 1
m_Colors:
- _OutlineColor: {r: 1, g: 1, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bd1fb273f898c1e4482466fbdfdbd01e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: dragon_dragon6
m_Shader: {fileID: 4800000, guid: 1e8a610c9e01c3648bac42585e5fc676, type: 3}
m_ShaderKeywords: _USE8NEIGHBOURHOOD_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: a87fe78b999f42f459397732f7c75303, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _Cutoff: 0.1
- _OutlineMipLevel: 0
- _OutlineReferenceTexWidth: 1024
- _OutlineSmoothness: 1
- _OutlineWidth: 3
- _StencilComp: 8
- _StencilRef: 1
- _StraightAlphaInput: 0
- _ThresholdEnd: 0.25
- _Use8Neighbourhood: 1
m_Colors:
- _OutlineColor: {r: 1, g: 1, b: 0, a: 1}
m_BuildTextureStacks: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: df19a30178772d14895780e0cbd7c25c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "twyVt4LWmOY", "hash": "3Ru4PsHnfWE",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -434, "x": -434,
"y": -133, "y": -133,
"width": 868, "width": 868,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "t48AsgsO/fQ", "hash": "RGdJecpcnMU",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -79.83, "x": -79.83,
"y": -0.99, "y": -0.99,
"width": 147.64, "width": 147.64,

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "mUQaGw4LIww", "hash": "Sz0QhWD6Eyg",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -125, "x": -125,
"y": -30, "y": -30,
"width": 250, "width": 250,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "PtTAK+zF95I", "hash": "5+0u5UUVwqA",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -134.12, "x": -134.12,
"y": -3.28, "y": -3.28,
"width": 266.94, "width": 266.94,
@ -571,7 +571,7 @@
"eyes": { "eyes": {
"attachment": [ "attachment": [
{ "time": 0.7, "name": "eyes-closed" }, { "time": 0.7, "name": "eyes-closed" },
{ "time": 0.8, "name": null } { "time": 0.8 }
] ]
} }
}, },
@ -899,309 +899,331 @@
] ]
} }
}, },
"deform": { "attachments": {
"default": { "default": {
"right-hand-item": { "right-hand-item": {
"dagger": [ "dagger": {
{ "deform": [
"offset": 26, {
"vertices": [ 2.34755, 0.1447 ], "offset": 26,
"curve": [ 0.125, 0, 0.375, 1 ] "vertices": [ 2.34755, 0.1447 ],
}, "curve": [ 0.125, 0, 0.375, 1 ]
{ },
"time": 0.5, {
"offset": 8, "time": 0.5,
"vertices": [ -1.19415, 4.31532, 0.07279, 6.41351, 1.66048, 6.18883, 1.75233, 3.59555 ], "offset": 8,
"curve": [ 0.625, 0, 0.875, 1 ] "vertices": [ -1.19415, 4.31532, 0.07279, 6.41351, 1.66048, 6.18883, 1.75233, 3.59555 ],
}, "curve": [ 0.625, 0, 0.875, 1 ]
{ },
"time": 1, {
"offset": 26, "time": 1,
"vertices": [ 2.34755, 0.1447 ] "offset": 26,
} "vertices": [ 2.34755, 0.1447 ]
] }
]
}
} }
}, },
"goblin": { "goblin": {
"head": { "head": {
"head": [ "head": {
{ "deform": [
"curve": [ 0.127, 0, 0.15, 1 ] {
}, "curve": [ 0.127, 0, 0.15, 1 ]
{ },
"time": 0.2, {
"vertices": [ -10.97827, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08392, -1.08534, 0.08392, -1.08534, 0.08392, 0, 0, -2.22325, 2.66465, -4.83295, 2.70085, -5.70553, -0.51941, -3.15962, -1.61502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64742, 0.81612, -11.82286, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08392 ], "time": 0.2,
"curve": [ 0.242, 0, 0.325, 1 ] "vertices": [ -10.97827, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08392, -1.08534, 0.08392, -1.08534, 0.08392, 0, 0, -2.22325, 2.66465, -4.83295, 2.70085, -5.70553, -0.51941, -3.15962, -1.61502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64742, 0.81612, -11.82286, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.08534, 0.08392 ],
}, "curve": [ 0.242, 0, 0.325, 1 ]
{ },
"time": 0.3667, {
"vertices": [ 10.69276, 4.05949, 3.66373, 1.85427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09018, 1.47305, 0.09018, 1.47305, 0.09018, 0, 0, 2.69653, -0.22738, 3.77135, 0.11418, 3.6893, 1.55352, 2.49595, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.45881, -3.9113, 9.19594, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09018 ], "time": 0.3667,
"curve": [ 0.574, 0, 0.617, 1 ] "vertices": [ 10.69276, 4.05949, 3.66373, 1.85427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09018, 1.47305, 0.09018, 1.47305, 0.09018, 0, 0, 2.69653, -0.22738, 3.77135, 0.11418, 3.6893, 1.55352, 2.49595, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.45881, -3.9113, 9.19594, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.47305, 0.09018 ],
}, "curve": [ 0.574, 0, 0.617, 1 ]
{ },
"time": 0.7, {
"vertices": [ -10.97827, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.17551, -0.17183, -1.17551, -0.17183, -1.17551, -0.17183, 0, 0, -2.22325, 2.66465, -4.83295, 2.70085, -5.70553, -0.51941, -3.15962, -1.61502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64742, 0.81612, -11.82286, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.17551, -0.17183 ], "time": 0.7,
"curve": [ 0.742, 0, 0.825, 1 ] "vertices": [ -10.97827, -6.68962, -4.68015, -2.46175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.17551, -0.17183, -1.17551, -0.17183, -1.17551, -0.17183, 0, 0, -2.22325, 2.66465, -4.83295, 2.70085, -5.70553, -0.51941, -3.15962, -1.61502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.64742, 0.81612, -11.82286, -1.34955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.17551, -0.17183 ],
}, "curve": [ 0.742, 0, 0.825, 1 ]
{ },
"time": 0.8667, {
"vertices": [ 10.69276, 4.05949, 3.66373, 1.85427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446, 0.38687, 0.08446, 0.38687, 0.08446, 0, 0, 2.69653, -0.22738, 3.77135, 0.11418, 3.6893, 1.55352, 2.49595, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.45881, -3.9113, 9.19594, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446 ], "time": 0.8667,
"curve": [ 0.9, 0, 0.967, 1 ] "vertices": [ 10.69276, 4.05949, 3.66373, 1.85427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446, 0.38687, 0.08446, 0.38687, 0.08446, 0, 0, 2.69653, -0.22738, 3.77135, 0.11418, 3.6893, 1.55352, 2.49595, 1.65501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.45881, -3.9113, 9.19594, -1.66854, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.38687, 0.08446 ],
}, "curve": [ 0.9, 0, 0.967, 1 ]
{ "time": 1 } },
] { "time": 1 }
]
}
}, },
"left-foot": { "left-foot": {
"left-foot": [ "left-foot": {
{ "deform": [
"offset": 8, {
"vertices": [ 3.69298, 2.37573, -7.16969, 18.79733, -12.78162, 14.7778, -12.75776, 6.50514, -3.13476, 1.98906, -0.44402, 0.36629, 0, 0, -3.80085, 2.98474 ] "offset": 8,
}, "vertices": [ 3.69298, 2.37573, -7.16969, 18.79733, -12.78162, 14.7778, -12.75776, 6.50514, -3.13476, 1.98906, -0.44402, 0.36629, 0, 0, -3.80085, 2.98474 ]
{ "time": 0.1333 }, },
{ { "time": 0.1333 },
"time": 0.2333, {
"offset": 8, "time": 0.2333,
"vertices": [ -3.96073, -2.34594, -5.80446, -12.47629, -2.2313, -12.99038, 2.02942, -9.1036, 0, 0, 0, 0, 0, 0, -1.35254, -5.2883 ] "offset": 8,
}, "vertices": [ -3.96073, -2.34594, -5.80446, -12.47629, -2.2313, -12.99038, 2.02942, -9.1036, 0, 0, 0, 0, 0, 0, -1.35254, -5.2883 ]
{ },
"time": 0.3667, {
"offset": 8, "time": 0.3667,
"vertices": [ 0.66505, 0.33548, 0.33902, 2.69014, -0.48171, 2.54524, -1.13593, 1.38562, 0, 0, 0, 0, 0, 0, -0.11908, 0.79273 ] "offset": 8,
}, "vertices": [ 0.66505, 0.33548, 0.33902, 2.69014, -0.48171, 2.54524, -1.13593, 1.38562, 0, 0, 0, 0, 0, 0, -0.11908, 0.79273 ]
{ "time": 0.5, "curve": "stepped" }, },
{ "time": 0.6333 }, { "time": 0.5, "curve": "stepped" },
{ { "time": 0.6333 },
"time": 0.7333, {
"offset": 8, "time": 0.7333,
"vertices": [ -2.97738, 9.40254, -6.91661, 19.92794, -10.55287, 18.41085, -12.37161, 12.38473, -4.72607, 6.30799, 0, 0, -1.48902, 4.88944, -7.06773, 10.70102 ] "offset": 8,
}, "vertices": [ -2.97738, 9.40254, -6.91661, 19.92794, -10.55287, 18.41085, -12.37161, 12.38473, -4.72607, 6.30799, 0, 0, -1.48902, 4.88944, -7.06773, 10.70102 ]
{ },
"time": 0.8333, {
"offset": 6, "time": 0.8333,
"vertices": [ 1.05319, 1.56362, -2.52723, 7.9974, -5.52031, 17.14137, -8.93317, 15.79635, -10.73748, 10.22056, -4.23801, 5.36992, 0, 0, 0, 0, -5.83148, 8.55532 ] "offset": 6,
}, "vertices": [ 1.05319, 1.56362, -2.52723, 7.9974, -5.52031, 17.14137, -8.93317, 15.79635, -10.73748, 10.22056, -4.23801, 5.36992, 0, 0, 0, 0, -5.83148, 8.55532 ]
{ },
"time": 1, {
"offset": 8, "time": 1,
"vertices": [ 3.69298, 2.37573, -7.16969, 18.79733, -12.78162, 14.7778, -12.75776, 6.50514, -3.13476, 1.98906, -0.44402, 0.36629, 0, 0, -3.80085, 2.98474 ] "offset": 8,
} "vertices": [ 3.69298, 2.37573, -7.16969, 18.79733, -12.78162, 14.7778, -12.75776, 6.50514, -3.13476, 1.98906, -0.44402, 0.36629, 0, 0, -3.80085, 2.98474 ]
] }
]
}
}, },
"pelvis": { "pelvis": {
"pelvis": [ "pelvis": {
{}, "deform": [
{ {},
"time": 0.1333, {
"offset": 6, "time": 0.1333,
"vertices": [ -0.6899, -4.13284 ] "offset": 6,
}, "vertices": [ -0.6899, -4.13284 ]
{ },
"time": 0.3333, {
"offset": 6, "time": 0.3333,
"vertices": [ -1.04945, -3.10477 ] "offset": 6,
}, "vertices": [ -1.04945, -3.10477 ]
{ },
"time": 0.7, {
"offset": 6, "time": 0.7,
"vertices": [ -1.4245, -6.30617 ] "offset": 6,
}, "vertices": [ -1.4245, -6.30617 ]
{ },
"time": 0.8667, {
"offset": 6, "time": 0.8667,
"vertices": [ -1.13542, -1.79036 ] "offset": 6,
}, "vertices": [ -1.13542, -1.79036 ]
{ "time": 1 } },
] { "time": 1 }
]
}
}, },
"right-foot": { "right-foot": {
"right-foot": [ "right-foot": {
{}, "deform": [
{ {},
"time": 0.1333, {
"offset": 2, "time": 0.1333,
"vertices": [ -2.81259, 2.63115, -2.35238, 3.89441, -1.99921, 4.8639, -0.93273, 5.57982, -0.48886, 5.09855, -0.34813, 3.42912, -0.17446, 1.36899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.31305, 1.91372, -1.32986, 3.65703 ] "offset": 2,
}, "vertices": [ -2.81259, 2.63115, -2.35238, 3.89441, -1.99921, 4.8639, -0.93273, 5.57982, -0.48886, 5.09855, -0.34813, 3.42912, -0.17446, 1.36899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.31305, 1.91372, -1.32986, 3.65703 ]
{ },
"time": 0.2333, {
"offset": 2, "time": 0.2333,
"vertices": [ -6.39088, 6.41246, -7.74575, 8.27192, -7.02471, 11.35894, -4.03471, 13.93454, -2.50399, 12.62963, -1.46125, 7.58915, -0.17446, 1.36899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.84766, 2.61216, -4.53956, 7.92358 ] "offset": 2,
}, "vertices": [ -6.39088, 6.41246, -7.74575, 8.27192, -7.02471, 11.35894, -4.03471, 13.93454, -2.50399, 12.62963, -1.46125, 7.58915, -0.17446, 1.36899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.84766, 2.61216, -4.53956, 7.92358 ]
{ },
"time": 0.3, {
"offset": 2, "time": 0.3,
"vertices": [ -8.27185, 6.68822, -9.29764, 10.13797, -8.62231, 14.7134, -4.5863, 18.81939, -2.20304, 17.10709, -0.07795, 9.9046, 2.54452, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.94625, 2.38008, -4.59399, 10.01888 ] "offset": 2,
}, "vertices": [ -8.27185, 6.68822, -9.29764, 10.13797, -8.62231, 14.7134, -4.5863, 18.81939, -2.20304, 17.10709, -0.07795, 9.9046, 2.54452, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.94625, 2.38008, -4.59399, 10.01888 ]
{ },
"time": 0.3667, {
"offset": 2, "time": 0.3667,
"vertices": [ -10.47684, 9.44176, -13.36883, 12.40983, -14.32569, 16.94392, -9.24463, 23.55674, -5.51712, 21.51378, -1.19582, 11.53193, 2.54452, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.14848, 2.29389, -6.63419, 11.37127 ] "offset": 2,
}, "vertices": [ -10.47684, 9.44176, -13.36883, 12.40983, -14.32569, 16.94392, -9.24463, 23.55674, -5.51712, 21.51378, -1.19582, 11.53193, 2.54452, 1.01642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.14848, 2.29389, -6.63419, 11.37127 ]
{ },
"time": 0.5, {
"offset": 2, "time": 0.5,
"vertices": [ -5.42474, 4.36854, -10.59004, 7.04468, -11.64251, 11.55845, -6.19665, 20.12806, -1.45498, 18.05411, 4.8662, 6.41679, 2.81463, 0.27601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.96412, 4.9483 ] "offset": 2,
}, "vertices": [ -5.42474, 4.36854, -10.59004, 7.04468, -11.64251, 11.55845, -6.19665, 20.12806, -1.45498, 18.05411, 4.8662, 6.41679, 2.81463, 0.27601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.96412, 4.9483 ]
{ "time": 0.6333 }, },
{ { "time": 0.6333 },
"time": 0.7333, {
"offset": 4, "time": 0.7333,
"vertices": [ 1.31462, -6.84099, -0.87905, -12.54479, -5.9851, -14.08368, -7.15892, -11.63194, -5.6792, -4.83545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.06164, -6.93844 ] "offset": 4,
}, "vertices": [ 1.31462, -6.84099, -0.87905, -12.54479, -5.9851, -14.08368, -7.15892, -11.63194, -5.6792, -4.83545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.06164, -6.93844 ]
{ },
"time": 0.8, {
"offset": 4, "time": 0.8,
"vertices": [ 0.65731, -3.4205, -0.43953, -6.2724, -2.99255, -7.04184, -3.57946, -5.81597, -2.8396, -2.41772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.79688, -1.28021, 0, 0, 0, 0, -1.03082, -3.46922 ] "offset": 4,
}, "vertices": [ 0.65731, -3.4205, -0.43953, -6.2724, -2.99255, -7.04184, -3.57946, -5.81597, -2.8396, -2.41772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.79688, -1.28021, 0, 0, 0, 0, -1.03082, -3.46922 ]
{ "time": 0.8667 } },
] { "time": 0.8667 }
]
}
}, },
"right-hand": { "right-hand": {
"right-hand": [ "right-hand": {
{ "deform": [
"offset": 4, {
"vertices": [ -1.48417, 0.34736, 0, 0, 1.31152, 0.08085, 1.60296, 0.09882, 0.13673, 0.15471, 0, 0, 0, 0, -0.72862, -0.0449 ] "offset": 4,
}, "vertices": [ -1.48417, 0.34736, 0, 0, 1.31152, 0.08085, 1.60296, 0.09882, 0.13673, 0.15471, 0, 0, 0, 0, -0.72862, -0.0449 ]
{ "time": 0.5 }, },
{ { "time": 0.5 },
"time": 1, {
"offset": 4, "time": 1,
"vertices": [ -1.48417, 0.34736, 0, 0, 1.31152, 0.08085, 1.60296, 0.09882, 0.13673, 0.15471, 0, 0, 0, 0, -0.72862, -0.0449 ] "offset": 4,
} "vertices": [ -1.48417, 0.34736, 0, 0, 1.31152, 0.08085, 1.60296, 0.09882, 0.13673, 0.15471, 0, 0, 0, 0, -0.72862, -0.0449 ]
] }
]
}
}, },
"right-lower-leg": { "right-lower-leg": {
"right-lower-leg": [ "right-lower-leg": {
{}, "deform": [
{ {},
"time": 0.6, {
"offset": 6, "time": 0.6,
"vertices": [ 1.80396, -1.56553 ] "offset": 6,
}, "vertices": [ 1.80396, -1.56553 ]
{ "time": 1 } },
] { "time": 1 }
]
}
}, },
"right-upper-leg": { "right-upper-leg": {
"right-upper-leg": [ "right-upper-leg": {
{ "deform": [
"vertices": [ -6.03857, -1.46325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34685, -1.93102, -1.86047, -5.05266, -2.5014, -3.09985 ] {
}, "vertices": [ -6.03857, -1.46325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34685, -1.93102, -1.86047, -5.05266, -2.5014, -3.09985 ]
{ "time": 0.3333 }, },
{ { "time": 0.3333 },
"time": 0.8667, {
"offset": 14, "time": 0.8667,
"vertices": [ 0.13425, -2.35378, -1.33318, -5.99573, -1.35862, -4.43324 ] "offset": 14,
}, "vertices": [ 0.13425, -2.35378, -1.33318, -5.99573, -1.35862, -4.43324 ]
{ },
"time": 1, {
"vertices": [ -6.03857, -1.46325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34685, -1.93102, -1.86047, -5.05266, -2.5014, -3.09985 ] "time": 1,
} "vertices": [ -6.03857, -1.46325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34685, -1.93102, -1.86047, -5.05266, -2.5014, -3.09985 ]
] }
]
}
}, },
"torso": { "torso": {
"torso": [ "torso": {
{ "deform": [
"offset": 2, {
"vertices": [ 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, -1.24131, 2.62652, -2.47492, 0.71183, -0.26363, -0.5308, 0.24821, 2.86673, 0.24821, 2.86673, 0, 0, 0, 0, 0, 0, 0, 0, 1.34461, 0.25215, 0.24821, 2.86673, 0.82507, 1.61798, 0.24821, 2.86673, 0, 0, -1.86431, -0.4326, 0.24821, 2.86673 ] "offset": 2,
}, "vertices": [ 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, 0.24821, 2.86673, -1.24131, 2.62652, -2.47492, 0.71183, -0.26363, -0.5308, 0.24821, 2.86673, 0.24821, 2.86673, 0, 0, 0, 0, 0, 0, 0, 0, 1.34461, 0.25215, 0.24821, 2.86673, 0.82507, 1.61798, 0.24821, 2.86673, 0, 0, -1.86431, -0.4326, 0.24821, 2.86673 ]
{ },
"time": 0.1333, {
"offset": 2, "time": 0.1333,
"vertices": [ 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 1.66908, 3.51187, -0.62355, 2.47979, 1.1045, 3.49684, -1.09009, 6.08429, 0.35589, 4.10914, 0, 0, 0, 0, 0, 0, 0, 0, 3.01291, 0.15693, 0.35589, 4.10914, -1.11398, 3.7954, 0.35589, 4.10914, 0, 0, -2.96167, 0.55563, -2.20741, 4.40587 ] "offset": 2,
}, "vertices": [ 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 0.35589, 4.10914, 1.66908, 3.51187, -0.62355, 2.47979, 1.1045, 3.49684, -1.09009, 6.08429, 0.35589, 4.10914, 0, 0, 0, 0, 0, 0, 0, 0, 3.01291, 0.15693, 0.35589, 4.10914, -1.11398, 3.7954, 0.35589, 4.10914, 0, 0, -2.96167, 0.55563, -2.20741, 4.40587 ]
{ },
"time": 0.3, {
"offset": 2, "time": 0.3,
"vertices": [ 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 6.32601, 0.19387, 7.84315, 1.94837, 7.08587, 3.64119, 4.52343, 4.46961, 0.2884, 3.32948, 0, 0, 0, 0, 0, 0, 0, 0, 4.36416, -1.83876, 0.2884, 3.32948, 4.2925, 3.60194, 0.2884, 3.32948, 0, 0, 3.72601, -0.19338, 0.2884, 3.32948 ] "offset": 2,
}, "vertices": [ 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 0.2884, 3.32948, 6.32601, 0.19387, 7.84315, 1.94837, 7.08587, 3.64119, 4.52343, 4.46961, 0.2884, 3.32948, 0, 0, 0, 0, 0, 0, 0, 0, 4.36416, -1.83876, 0.2884, 3.32948, 4.2925, 3.60194, 0.2884, 3.32948, 0, 0, 3.72601, -0.19338, 0.2884, 3.32948 ]
{ },
"time": 0.5, {
"offset": 2, "time": 0.5,
"vertices": [ 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 2.57273, 2.74457, 2.88831, 3.04797, 3.48442, 3.04655, 1.80035, 4.609, 0.3133, 3.61659, 0, 0, 0, 0, 0, 0, 0, 0, 3.53782, -0.82203, 0.3133, 3.61659, 1.80022, 3.63246, 0.3133, 3.61659, 0, 0, 0.62718, 0.33564, -1.22467, 3.79463 ] "offset": 2,
}, "vertices": [ 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 0.3133, 3.61659, 2.57273, 2.74457, 2.88831, 3.04797, 3.48442, 3.04655, 1.80035, 4.609, 0.3133, 3.61659, 0, 0, 0, 0, 0, 0, 0, 0, 3.53782, -0.82203, 0.3133, 3.61659, 1.80022, 3.63246, 0.3133, 3.61659, 0, 0, 0.62718, 0.33564, -1.22467, 3.79463 ]
{ },
"time": 0.6333, {
"offset": 2, "time": 0.6333,
"vertices": [ 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 1.19401, 3.60798, -0.53546, 3.49565, 1.1926, 4.5127, -1.002, 7.10015, 0.44398, 5.125, 0, 0, 0, 0, 0, 0, 0, 0, 3.101, 1.17278, 0.44398, 5.125, -1.02589, 4.81126, 0.44398, 5.125, 0, 0, -2.87358, 1.57149, -2.11931, 5.42173 ] "offset": 2,
}, "vertices": [ 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 0.44398, 5.125, 1.19401, 3.60798, -0.53546, 3.49565, 1.1926, 4.5127, -1.002, 7.10015, 0.44398, 5.125, 0, 0, 0, 0, 0, 0, 0, 0, 3.101, 1.17278, 0.44398, 5.125, -1.02589, 4.81126, 0.44398, 5.125, 0, 0, -2.87358, 1.57149, -2.11931, 5.42173 ]
{ },
"time": 0.8667, {
"offset": 2, "time": 0.8667,
"vertices": [ 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.92587, 2.24385, 0.68874, 1.29945, 3.55433, 3.00604, 2.71494, 5.89962, 0.30385, 3.50647, 0, 0, 0, 0, 0, 0, 0, 0, 1.96775, 0.40548, 0.30385, 3.50647, 2.6104, 2.3545, 0.30385, 3.50647, 0, 0, 0.22709, -0.12851, -0.62826, 3.61437 ] "offset": 2,
}, "vertices": [ 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.30385, 3.50647, 0.92587, 2.24385, 0.68874, 1.29945, 3.55433, 3.00604, 2.71494, 5.89962, 0.30385, 3.50647, 0, 0, 0, 0, 0, 0, 0, 0, 1.96775, 0.40548, 0.30385, 3.50647, 2.6104, 2.3545, 0.30385, 3.50647, 0, 0, 0.22709, -0.12851, -0.62826, 3.61437 ]
{ },
"time": 1, {
"offset": 2, "time": 1,
"vertices": [ 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, -1.1615, 3.54805, -2.39511, 1.63336, -0.18382, 0.39073, 0.32802, 3.78826, 0.32802, 3.78826, 0, 0, 0, 0, 0, 0, 0, 0, 1.42442, 1.17368, 0.32802, 3.78826, 0.90488, 2.53951, 0.32802, 3.78826, 0, 0, -1.7845, 0.48894, 0.32802, 3.78826 ] "offset": 2,
} "vertices": [ 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, 0.32802, 3.78826, -1.1615, 3.54805, -2.39511, 1.63336, -0.18382, 0.39073, 0.32802, 3.78826, 0.32802, 3.78826, 0, 0, 0, 0, 0, 0, 0, 0, 1.42442, 1.17368, 0.32802, 3.78826, 0.90488, 2.53951, 0.32802, 3.78826, 0, 0, -1.7845, 0.48894, 0.32802, 3.78826 ]
] }
]
}
}, },
"undie-straps": { "undie-straps": {
"undie-straps": [ "undie-straps": {
{ "deform": [
"offset": 2, {
"vertices": [ -1.77697, 0.5476, -0.96145, -1.03793, -0.39148, -0.24072, -1.77697, 0.5476 ] "offset": 2,
}, "vertices": [ -1.77697, 0.5476, -0.96145, -1.03793, -0.39148, -0.24072, -1.77697, 0.5476 ]
{ },
"time": 0.1333, {
"offset": 2, "time": 0.1333,
"vertices": [ -2.25684, -1.03177, -1.49719, -4.23862, -0.7447, -2.84907, -1.90072, 0.54478 ] "offset": 2,
}, "vertices": [ -2.25684, -1.03177, -1.49719, -4.23862, -0.7447, -2.84907, -1.90072, 0.54478 ]
{ },
"time": 0.3333, {
"offset": 2, "time": 0.3333,
"vertices": [ -2.37974, -0.05432, -0.49433, 0.19437, -0.90861, 1.16519, -1.60956, 2.70799, 0.96186, 0.80615 ] "offset": 2,
}, "vertices": [ -2.37974, -0.05432, -0.49433, 0.19437, -0.90861, 1.16519, -1.60956, 2.70799, 0.96186, 0.80615 ]
{ },
"time": 0.7, {
"offset": 2, "time": 0.7,
"vertices": [ -0.91715, -2.76567, -0.62215, -3.63489, -0.84941, -2.26772, -2.56077, 0.52971 ] "offset": 2,
}, "vertices": [ -0.91715, -2.76567, -0.62215, -3.63489, -0.84941, -2.26772, -2.56077, 0.52971 ]
{ },
"time": 0.8667, {
"offset": 2, "time": 0.8667,
"vertices": [ -2.56077, 0.52971, -1.58065, 0.32031, -1.3847, 0.32476, -2.56077, 0.52971 ] "offset": 2,
}, "vertices": [ -2.56077, 0.52971, -1.58065, 0.32031, -1.3847, 0.32476, -2.56077, 0.52971 ]
{ },
"time": 1, {
"offset": 2, "time": 1,
"vertices": [ -1.77697, 0.5476, -0.80128, 0.53413, -0.80128, 0.53413, -1.77697, 0.5476 ] "offset": 2,
} "vertices": [ -1.77697, 0.5476, -0.80128, 0.53413, -0.80128, 0.53413, -1.77697, 0.5476 ]
] }
]
}
}, },
"undies": { "undies": {
"undies": [ "undies": {
{ "deform": [
"vertices": [ 0.43099, 0.722, 10.60295, -0.117, 2.29599, 0, 2.29599, 0, 2.29599, 0, 0.58799, 0.244, -2.40018, -0.65335, -2.2782, -0.77534, 2.29599, 0, 0.58799, -0.488, 4.98698, -0.117, 6.50797, -0.23399 ] {
}, "vertices": [ 0.43099, 0.722, 10.60295, -0.117, 2.29599, 0, 2.29599, 0, 2.29599, 0, 0.58799, 0.244, -2.40018, -0.65335, -2.2782, -0.77534, 2.29599, 0, 0.58799, -0.488, 4.98698, -0.117, 6.50797, -0.23399 ]
{ },
"time": 0.1333, {
"vertices": [ 0.72659, 0.4332, 7.20417, -0.1638, 1.37759, 0, 1.37759, 0, 1.37759, 0, 1.25279, 0.0464, -0.99862, -2.95085, -1.37543, -3.07404, 1.37759, 0, 0.35279, -0.2928, 2.99219, -0.0702, 3.90478, -0.1404 ] "time": 0.1333,
}, "vertices": [ 0.72659, 0.4332, 7.20417, -0.1638, 1.37759, 0, 1.37759, 0, 1.37759, 0, 1.25279, 0.0464, -0.99862, -2.95085, -1.37543, -3.07404, 1.37759, 0, 0.35279, -0.2928, 2.99219, -0.0702, 3.90478, -0.1404 ]
{ },
"time": 0.3333, {
"vertices": [ 1.16999, 0, 2.10599, -0.23401, 0, 0, 0, 0, 0, 0, 2.24999, -0.24999, -0.4344, 0.60551, -1.55939, 0.48051 ] "time": 0.3333,
}, "vertices": [ 1.16999, 0, 2.10599, -0.23401, 0, 0, 0, 0, 0, 0, 2.24999, -0.24999, -0.4344, 0.60551, -1.55939, 0.48051 ]
{ },
"time": 0.5333, {
"vertices": [ 1.16999, 0, -0.234, -0.936, -2.92499, 0.351, 0, 0, 0, 0, 0.5, -0.24999, -0.64079, -2.07915, -0.64079, -2.07915 ] "time": 0.5333,
}, "vertices": [ 1.16999, 0, -0.234, -0.936, -2.92499, 0.351, 0, 0, 0, 0, 0.5, -0.24999, -0.64079, -2.07915, -0.64079, -2.07915 ]
{ },
"time": 0.7, {
"vertices": [ 1.86271, -0.11514, 4.66327, -0.091, -1.76428, 0.21171, 0, 0, -0.56833, 0.32833, -1.13833, -1.15111, -2.19996, -3.47068, -1.29719, -3.47068, 0, 0, 0, 0, 1.58785, -0.04643, 2.65942, 0.16715 ] "time": 0.7,
}, "vertices": [ 1.86271, -0.11514, 4.66327, -0.091, -1.76428, 0.21171, 0, 0, -0.56833, 0.32833, -1.13833, -1.15111, -2.19996, -3.47068, -1.29719, -3.47068, 0, 0, 0, 0, 1.58785, -0.04643, 2.65942, 0.16715 ]
{ },
"time": 0.8333, {
"vertices": [ 2.41688, -0.20726, 8.58108, 0.585, -0.83571, 0.10029, 0, 0, -1.02299, 0.59099, -2.449, -1.872, -1.625, 0, 0, 0, 0, 0, 0, 0, 2.85813, -0.08357, 4.78695, 0.30086 ] "time": 0.8333,
}, "vertices": [ 2.41688, -0.20726, 8.58108, 0.585, -0.83571, 0.10029, 0, 0, -1.02299, 0.59099, -2.449, -1.872, -1.625, 0, 0, 0, 0, 0, 0, 0, 2.85813, -0.08357, 4.78695, 0.30086 ]
{ },
"time": 0.8667, {
"vertices": [ 2.0197, -0.02141, 8.98546, 0.4446, -0.20937, 0.08023, 0.4592, 0, -0.3592, 0.47279, -1.8416, -1.4488, -0.79153, 1.26421, 0.53286, 1.23981, 0.4592, 0, 0.1176, -0.0976, 3.2839, -0.09025, 5.13116, 0.19389 ] "time": 0.8667,
}, "vertices": [ 2.0197, -0.02141, 8.98546, 0.4446, -0.20937, 0.08023, 0.4592, 0, -0.3592, 0.47279, -1.8416, -1.4488, -0.79153, 1.26421, 0.53286, 1.23981, 0.4592, 0, 0.1176, -0.0976, 3.2839, -0.09025, 5.13116, 0.19389 ]
{ },
"time": 1, {
"vertices": [ 0.43099, 0.722, 10.60295, -0.117, 2.29599, 0, 2.29599, 0, 2.29599, 0, 0.58799, 0.244, -2.40018, -0.65335, -2.2782, -0.77534, 2.29599, 0, 0.58799, -0.488, 4.98698, -0.117, 6.50797, -0.23399 ] "time": 1,
} "vertices": [ 0.43099, 0.722, 10.60295, -0.117, 2.29599, 0, 2.29599, 0, 2.29599, 0, 0.58799, 0.244, -2.40018, -0.65335, -2.2782, -0.77534, 2.29599, 0, 0.58799, -0.488, 4.98698, -0.117, 6.50797, -0.23399 ]
] }
]
}
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "pCpU7tdx0Yk", "hash": "ukmbgK+14T0",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -78.45, "x": -78.45,
"y": -9.66, "y": -9.66,
"width": 157.48, "width": 157.48,

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "1+TtfhbEFt8", "hash": "oPVc6FExiik",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -402.84, "x": -402.84,
"y": -35.99, "y": -35.99,
"width": 611.87, "width": 611.87,
@ -1248,7 +1248,7 @@
}, },
"gun": { "gun": {
"attachment": [ "attachment": [
{ "time": 0.1667, "name": null } { "time": 0.1667 }
] ]
} }
}, },
@ -1326,7 +1326,7 @@
}, },
"gun": { "gun": {
"attachment": [ "attachment": [
{ "name": null }, {},
{ "time": 0.4, "name": "gun_nohand" } { "time": 0.4, "name": "gun_nohand" }
] ]
} }
@ -2051,45 +2051,49 @@
] ]
} }
}, },
"deform": { "attachments": {
"default": { "default": {
"raptor_body": { "raptor_body": {
"raptor_body": [ "raptor_body": {
{}, "deform": [
{ {},
"time": 0.2667, {
"offset": 452, "time": 0.2667,
"vertices": [ 9.66226, 6.07712, -8.39342, 7.73739, -0.31512, 11.41041, 9.05756, 6.94628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, 0, 0, -1.62274, 0.40576 ] "offset": 452,
}, "vertices": [ 9.66226, 6.07712, -8.39342, 7.73739, -0.31512, 11.41041, 9.05756, 6.94628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, 0, 0, -1.62274, 0.40576 ]
{ "time": 0.5333 }, },
{ { "time": 0.5333 },
"time": 0.8, {
"offset": 452, "time": 0.8,
"vertices": [ 9.66226, 6.07712, -8.39342, 7.73739, -0.31512, 11.41041, 9.05756, 6.94628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, 0, 0, -1.62274, 0.40576 ] "offset": 452,
}, "vertices": [ 9.66226, 6.07712, -8.39342, 7.73739, -0.31512, 11.41041, 9.05756, 6.94628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, -1.62274, 0.40576, 0, 0, 0, 0, 0, 0, -1.62274, 0.40576, 0, 0, -1.62274, 0.40576 ]
{ "time": 1.0667 } },
] { "time": 1.0667 }
]
}
}, },
"raptor_front_leg": { "raptor_front_leg": {
"raptor_front_leg": [ "raptor_front_leg": {
{ "time": 0.2667 }, "deform": [
{ { "time": 0.2667 },
"time": 0.5333, {
"offset": 206, "time": 0.5333,
"vertices": [ -1.11804, 10.97701, -10.52314, 3.3174, 10.77458, -2.3777 ] "offset": 206,
}, "vertices": [ -1.11804, 10.97701, -10.52314, 3.3174, 10.77458, -2.3777 ]
{ },
"time": 0.6, {
"offset": 206, "time": 0.6,
"vertices": [ 3.58981, 7.57179, -8.37008, -0.40027, 7.63262, -3.45871 ] "offset": 206,
}, "vertices": [ 3.58981, 7.57179, -8.37008, -0.40027, 7.63262, -3.45871 ]
{ },
"time": 0.7333, {
"offset": 160, "time": 0.7333,
"vertices": [ -0.41243, 0.36704, -0.00642, -0.55221, -0.13748, 0.53003, -0.64028, 0.19816, 0, 0, 0, 0, 0, 0, 0, 0, 0.7433, -1.29713, 0.49036, 1.41172, -0.05063, -1.49312, 1.47504, -1.05834, 1.3683, -5.24968, 3.06253, 4.47641, -1.44046, -5.17512, -1.30437, -1.14192, 1.71709, -0.23523, -1.14153, -2.38019, 2.54447, 0.70039, -2.29261, -1.30733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.68984, -0.87758, -1.06615, -0.32834, -1.4312, -0.38682, 1.22995, -0.8266, -1.25796, 0.43206 ] "offset": 160,
}, "vertices": [ -0.41243, 0.36704, -0.00642, -0.55221, -0.13748, 0.53003, -0.64028, 0.19816, 0, 0, 0, 0, 0, 0, 0, 0, 0.7433, -1.29713, 0.49036, 1.41172, -0.05063, -1.49312, 1.47504, -1.05834, 1.3683, -5.24968, 3.06253, 4.47641, -1.44046, -5.17512, -1.30437, -1.14192, 1.71709, -0.23523, -1.14153, -2.38019, 2.54447, 0.70039, -2.29261, -1.30733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.68984, -0.87758, -1.06615, -0.32834, -1.4312, -0.38682, 1.22995, -0.8266, -1.25796, 0.43206 ]
{ "time": 0.8 } },
] { "time": 0.8 }
]
}
} }
} }
}, },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

After

Width:  |  Height:  |  Size: 408 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "dGMI1oAkl8o", "hash": "8oWe7nDoZEk",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -214.04, "x": -214.04,
"y": -80.91, "y": -80.91,
"width": 519.95, "width": 519.95,
@ -650,7 +650,7 @@
"eyelids closed": { "eyelids closed": {
"attachment": [ "attachment": [
{ "name": "eyelids closed" }, { "name": "eyelids closed" },
{ "time": 0.0667, "name": null } { "time": 0.0667 }
] ]
} }
}, },
@ -2115,255 +2115,287 @@
] ]
} }
}, },
"deform": { "attachments": {
"default": { "default": {
"armL": { "armL": {
"armL": [ "armL": {
{ "deform": [
"time": 0.9, {
"curve": [ 1.029, 0, 1.14, 1 ] "time": 0.9,
}, "curve": [ 1.029, 0, 1.14, 1 ]
{ },
"time": 1.2667, {
"offset": 28, "time": 1.2667,
"vertices": [ -1.51086, 0.71941, -1.20222, -0.99176, -1.74438, -0.55032, -1.74438, -0.55032, -5.4474, -2.71472, -6.01334, -5.1203, -6.01334, -5.1203, -8.01959, 2.939, -6.01334, -5.1203, -6.01334, -5.1203, -6.01334, -5.1203, -8.01959, 2.939, -6.01334, -5.1203, -3.22636, -2.41086, -3.92453, 0.9055, -2.31032, -2.9559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.92453, 0.9055, -2.31032, -2.9559, -6.81499, -7.15472, 0, 0, 0, 0, 0, 0, -8.9516, 4.12372, -7.38049, -5.44019, -4.89615, -4.35225 ], "offset": 28,
"curve": [ 1.526, 0, 1.747, 1 ] "vertices": [ -1.51086, 0.71941, -1.20222, -0.99176, -1.74438, -0.55032, -1.74438, -0.55032, -5.4474, -2.71472, -6.01334, -5.1203, -6.01334, -5.1203, -8.01959, 2.939, -6.01334, -5.1203, -6.01334, -5.1203, -6.01334, -5.1203, -8.01959, 2.939, -6.01334, -5.1203, -3.22636, -2.41086, -3.92453, 0.9055, -2.31032, -2.9559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.92453, 0.9055, -2.31032, -2.9559, -6.81499, -7.15472, 0, 0, 0, 0, 0, 0, -8.9516, 4.12372, -7.38049, -5.44019, -4.89615, -4.35225 ],
}, "curve": [ 1.526, 0, 1.747, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"armR": { "armR": {
"armR": [ "armR": {
{ "deform": [
"curve": [ 0.79, 0, 0.635, 1 ] {
}, "curve": [ 0.79, 0, 0.635, 1 ]
{ },
"time": 1, {
"vertices": [ 3.29417, 7.54852, 7.38307, 4.59549, 3.70951, 3.69086, 3.10799, 4.21008, 2.62421, 2.72685, 2.18121, 3.0929, -2.82712, 1.84239, -3.07339, 1.39288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.41486, -0.02728, 0.41422, 0.03586, 0.41486, -0.02728, 0.41422, 0.03586, 0, 0, 0, 0, -2.70642, -0.02931, -7.84895, 0.7765, -6.89497, 4.14276, -6.60889, 5.26572, -3.56116, 5.85962, -1.18237, 5.82011, 3.62317, 4.25227, 2.84126, 2.91956, 2.36634, 3.31624, -0.12074, 1.8717, -0.40276, 1.8318, 0.84898, 0.3584, 0.78494, 0.48286, 0, 0, 0, 0, -2.5412, 3.44402, -0.37629, 0.85307, 0, 0, 1.2253, -0.49471, 1.28616, -0.30338 ], "time": 1,
"curve": [ 1.79, 0, 1.635, 1 ] "vertices": [ 3.29417, 7.54852, 7.38307, 4.59549, 3.70951, 3.69086, 3.10799, 4.21008, 2.62421, 2.72685, 2.18121, 3.0929, -2.82712, 1.84239, -3.07339, 1.39288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.41486, -0.02728, 0.41422, 0.03586, 0.41486, -0.02728, 0.41422, 0.03586, 0, 0, 0, 0, -2.70642, -0.02931, -7.84895, 0.7765, -6.89497, 4.14276, -6.60889, 5.26572, -3.56116, 5.85962, -1.18237, 5.82011, 3.62317, 4.25227, 2.84126, 2.91956, 2.36634, 3.31624, -0.12074, 1.8717, -0.40276, 1.8318, 0.84898, 0.3584, 0.78494, 0.48286, 0, 0, 0, 0, -2.5412, 3.44402, -0.37629, 0.85307, 0, 0, 1.2253, -0.49471, 1.28616, -0.30338 ],
}, "curve": [ 1.79, 0, 1.635, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"bootR": { "bootR": {
"bootR": [ "bootR": {
{ "deform": [
"curve": [ 0.294, 0, 0.546, 1 ] {
}, "curve": [ 0.294, 0, 0.546, 1 ]
{ },
"time": 0.8333, {
"offset": 2, "time": 0.8333,
"vertices": [ 5.22825, -1.73952, 4.71846, 0.2213, 5.62447, 6.47461, 1.50863, 7.97215, -4.47059, 2.31835, 0, 0, 0, 0, -4.4706, 2.31835, -4.4706, 2.31835, -4.4706, 2.31835, -4.4706, 2.31835 ], "offset": 2,
"curve": [ 1.245, 0, 1.598, 1 ] "vertices": [ 5.22825, -1.73952, 4.71846, 0.2213, 5.62447, 6.47461, 1.50863, 7.97215, -4.47059, 2.31835, 0, 0, 0, 0, -4.4706, 2.31835, -4.4706, 2.31835, -4.4706, 2.31835, -4.4706, 2.31835 ],
}, "curve": [ 1.245, 0, 1.598, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"hairM blob": { "hairM blob": {
"hairM blob": [ "hairM blob": {
{ "deform": [
"curve": [ 0.542, 0, 0.483, 1 ] {
}, "curve": [ 0.542, 0, 0.483, 1 ]
{ },
"time": 1, {
"vertices": [ -1.08211, 8.65523, -1.11434, 7.5247, -2.24056, 6.26955, -3.82799, 5.99094, -3.91438, 7.22203, -2.67052, 9.0497, -1.38165, 9.20383 ], "time": 1,
"curve": [ 1.542, 0, 1.483, 1 ] "vertices": [ -1.08211, 8.65523, -1.11434, 7.5247, -2.24056, 6.26955, -3.82799, 5.99094, -3.91438, 7.22203, -2.67052, 9.0497, -1.38165, 9.20383 ],
}, "curve": [ 1.542, 0, 1.483, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"hairM blobS": { "hairM blobS": {
"hairM blobS": [ "hairM blobS": {
{ "deform": [
"curve": [ 0.542, 0, 0.483, 1 ] {
}, "curve": [ 0.542, 0, 0.483, 1 ]
{ },
"time": 1, {
"vertices": [ -5.04186, 4.96768, -4.67044, 7.01031, -4.93049, 10.27776, -5.31269, 10.78222, -5.59053, 8.83483, -5.32308, 5.60685 ], "time": 1,
"curve": [ 1.542, 0, 1.483, 1 ] "vertices": [ -5.04186, 4.96768, -4.67044, 7.01031, -4.93049, 10.27776, -5.31269, 10.78222, -5.59053, 8.83483, -5.32308, 5.60685 ],
}, "curve": [ 1.542, 0, 1.483, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"hairSide": { "hairSide": {
"hairSide": [ "hairSide": {
{}, "deform": [
{ {},
"time": 0.6, {
"vertices": [ -1.60584, 0.69799, -2.39742, 5.14579, 1.78111, 10.4846, -1.31722, -1.77717 ] "time": 0.6,
}, "vertices": [ -1.60584, 0.69799, -2.39742, 5.14579, 1.78111, 10.4846, -1.31722, -1.77717 ]
{ "time": 1.1 }, },
{ { "time": 1.1 },
"time": 1.6667, {
"vertices": [ -1.60584, 0.69799, -2.39742, 5.14579, 1.78111, 10.4846, -1.31722, -1.77717 ] "time": 1.6667,
}, "vertices": [ -1.60584, 0.69799, -2.39742, 5.14579, 1.78111, 10.4846, -1.31722, -1.77717 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"indexL": { "indexL": {
"indexL": [ "indexL": {
{ "curve": "stepped" }, "deform": [
{ { "curve": "stepped" },
"time": 0.3333, {
"curve": [ 0.497, 0, 0.649, 0.49 ] "time": 0.3333,
}, "curve": [ 0.497, 0, 0.649, 0.49 ]
{ },
"time": 0.8, {
"vertices": [ 0.3316, -0.01168, 0.33158, -0.01167, 0.33158, -0.01169, 0.32023, -0.02302, -1.0E-5, 1.0E-5, 1.0E-5, 1.0E-5, -4.0E-5, 3.0E-5, 0.32023, -0.02301, 0.33155, -0.01169, 0.3316, -0.01167, 0.3316, -0.01167 ], "time": 0.8,
"curve": [ 0.953, 0.49, 1.105, 1 ] "vertices": [ 0.3316, -0.01168, 0.33158, -0.01167, 0.33158, -0.01169, 0.32023, -0.02302, -1.0E-5, 1.0E-5, 1.0E-5, 1.0E-5, -4.0E-5, 3.0E-5, 0.32023, -0.02301, 0.33155, -0.01169, 0.3316, -0.01167, 0.3316, -0.01167 ],
}, "curve": [ 0.953, 0.49, 1.105, 1 ]
{ },
"time": 1.2667, {
"vertices": [ -7.78268, -0.32068, -7.7827, -0.32067, -7.7827, -0.32069, -1.72646, -0.27644, -1.0E-5, 1.0E-5, 1.0E-5, 1.0E-5, -4.0E-5, 3.0E-5, -1.72646, -0.27643, -7.78273, -0.32069, -7.78268, -0.32067, -7.78268, -0.32067 ], "time": 1.2667,
"curve": [ 1.526, 0, 1.747, 1 ] "vertices": [ -7.78268, -0.32068, -7.7827, -0.32067, -7.7827, -0.32069, -1.72646, -0.27644, -1.0E-5, 1.0E-5, 1.0E-5, 1.0E-5, -4.0E-5, 3.0E-5, -1.72646, -0.27643, -7.78273, -0.32069, -7.78268, -0.32067, -7.78268, -0.32067 ],
}, "curve": [ 1.526, 0, 1.747, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"indexR": { "indexR": {
"indexR": [ "indexR": {
{ "deform": [
"curve": [ 0.353, 0, 0.655, 1 ] {
}, "curve": [ 0.353, 0, 0.655, 1 ]
{ },
"time": 1, {
"vertices": [ -3.70744, 2.07258, -3.56297, 1.70496, -4.31731, -0.57099, -3.25647, -3.29185, -2.18936, -5.81705, 0.70666, -5.57201, 1.93816, -3.54265, 1.80319, 0.17362, 0.49382, -1.71758, 0.49383, -1.71758, 1.0E-5, -1.0E-5, 0, 0, -4.19104, 3.05999, -1.06691, -0.08681 ], "time": 1,
"curve": [ 1.353, 0, 1.655, 1 ] "vertices": [ -3.70744, 2.07258, -3.56297, 1.70496, -4.31731, -0.57099, -3.25647, -3.29185, -2.18936, -5.81705, 0.70666, -5.57201, 1.93816, -3.54265, 1.80319, 0.17362, 0.49382, -1.71758, 0.49383, -1.71758, 1.0E-5, -1.0E-5, 0, 0, -4.19104, 3.05999, -1.06691, -0.08681 ],
}, "curve": [ 1.353, 0, 1.655, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"irisL flatspec": { "irisL flatspec": {
"irisL flatspec": [ "irisL flatspec": {
{}, "deform": [
{ {},
"time": 0.5, {
"vertices": [ 0.61252, -0.47808, -0.34621, -0.26418, -0.95872, 0.2139 ] "time": 0.5,
}, "vertices": [ 0.61252, -0.47808, -0.34621, -0.26418, -0.95872, 0.2139 ]
{ "time": 1 }, },
{ { "time": 1 },
"time": 1.5667, {
"vertices": [ 0.61252, -0.47808, -0.34621, -0.26418, -1.41387, 0.64572, 1.69759, 0.84319 ] "time": 1.5667,
}, "vertices": [ 0.61252, -0.47808, -0.34621, -0.26418, -1.41387, 0.64572, 1.69759, 0.84319 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"irisL spec": { "irisL spec": {
"irisL spec": [ "irisL spec": {
{}, "deform": [
{ {},
"time": 0.5, {
"vertices": [ 2.66561, -1.34321, -0.62155, -1.4382, 2.1585, -0.04376, 3.15285, -1.17854 ] "time": 0.5,
}, "vertices": [ 2.66561, -1.34321, -0.62155, -1.4382, 2.1585, -0.04376, 3.15285, -1.17854 ]
{ },
"time": 1, {
"vertices": [ 0.98535, -1.29693, -1.2431, -2.87638, -2.16038, -1.52057 ] "time": 1,
}, "vertices": [ 0.98535, -1.29693, -1.2431, -2.87638, -2.16038, -1.52057 ]
{ },
"time": 1.5667, {
"vertices": [ 2.93274, 1.38345, 1.4911, -0.79594, -0.93617, -0.65891 ] "time": 1.5667,
}, "vertices": [ 2.93274, 1.38345, 1.4911, -0.79594, -0.93617, -0.65891 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"irisR flatspec": { "irisR flatspec": {
"irisR flatspec": [ "irisR flatspec": {
{}, "deform": [
{ {},
"time": 0.4667, {
"offset": 2, "time": 0.4667,
"vertices": [ -1.70543, 0.46474, -1.2566, -0.32218, 1.71141, 0.20524 ] "offset": 2,
}, "vertices": [ -1.70543, 0.46474, -1.2566, -0.32218, 1.71141, 0.20524 ]
{ "time": 0.9667 }, },
{ { "time": 0.9667 },
"time": 1.5667, {
"vertices": [ 0.42843, -0.47367, -1.277, -0.00896, -1.2566, -0.32218, 1.71141, 0.20524 ] "time": 1.5667,
}, "vertices": [ 0.42843, -0.47367, -1.277, -0.00896, -1.2566, -0.32218, 1.71141, 0.20524 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"irisR spec": { "irisR spec": {
"irisR spec": [ "irisR spec": {
{}, "deform": [
{ {},
"time": 0.4, {
"vertices": [ 1.33019, 0.3099, -0.7722, -1.58121, -0.93541, -2.05612, -0.31694, 1.15223 ] "time": 0.4,
}, "vertices": [ 1.33019, 0.3099, -0.7722, -1.58121, -0.93541, -2.05612, -0.31694, 1.15223 ]
{ },
"time": 0.9667, {
"vertices": [ -1.23871, -0.17238, -2.84217, 0.45327, 1.84367, 0.5128, 1.38389, 0.67142 ] "time": 0.9667,
}, "vertices": [ -1.23871, -0.17238, -2.84217, 0.45327, 1.84367, 0.5128, 1.38389, 0.67142 ]
{ },
"time": 1.5, {
"vertices": [ -0.55319, 2.56626, -1.37525, 0.21934, -0.90461, 0.64045, -1.50449, -0.12951 ] "time": 1.5,
}, "vertices": [ -0.55319, 2.56626, -1.37525, 0.21934, -0.90461, 0.64045, -1.50449, -0.12951 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"middleL": { "middleL": {
"middleL": [ "middleL": {
{ "deform": [
"curve": [ 0.379, 0, 0.338, 1 ] {
}, "curve": [ 0.379, 0, 0.338, 1 ]
{ },
"time": 0.7, {
"vertices": [ 1.87502, -1.17947, 2.27197, -0.96694, 2.27365, -1.0802, -0.73205, -0.10651, 0, 0, 0, -1.0E-5, 0, 0, -0.55559, -0.01207, 2.27369, -1.08022, 1.79739, -1.19242, 1.78682, -1.2267 ], "time": 0.7,
"curve": [ 1.061, 0, 1.022, 1 ] "vertices": [ 1.87502, -1.17947, 2.27197, -0.96694, 2.27365, -1.0802, -0.73205, -0.10651, 0, 0, 0, -1.0E-5, 0, 0, -0.55559, -0.01207, 2.27369, -1.08022, 1.79739, -1.19242, 1.78682, -1.2267 ],
}, "curve": [ 1.061, 0, 1.022, 1 ]
{ },
"time": 1.3667, {
"vertices": [ -6.16218, -0.21533, -4.73239, 0.55014, -4.72634, 0.14221, -2.6366, -0.38359, 0, 0, 0, -1.0E-5, 0, 0, -2.00113, -0.04347, -4.7263, 0.14219, -6.44176, -0.26199, -6.47987, -0.38544 ], "time": 1.3667,
"curve": [ 1.59, 0, 1.782, 1 ] "vertices": [ -6.16218, -0.21533, -4.73239, 0.55014, -4.72634, 0.14221, -2.6366, -0.38359, 0, 0, 0, -1.0E-5, 0, 0, -2.00113, -0.04347, -4.7263, 0.14219, -6.44176, -0.26199, -6.47987, -0.38544 ],
}, "curve": [ 1.59, 0, 1.782, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"ringL": { "ringL": {
"ringL": [ "ringL": {
{ "deform": [
"curve": [ 0.614, 0, 0.547, 1 ] {
}, "curve": [ 0.614, 0, 0.547, 1 ]
{ },
"time": 1.1333, {
"vertices": [ 2.29756, -2.1041, 2.29753, -2.10409, 2.29757, -2.1041, 0, 0, 0, 0, -0.61601, -0.2029 ], "time": 1.1333,
"curve": [ 1.35, 0, 1.327, 1 ] "vertices": [ 2.29756, -2.1041, 2.29753, -2.10409, 2.29757, -2.1041, 0, 0, 0, 0, -0.61601, -0.2029 ],
}, "curve": [ 1.35, 0, 1.327, 1 ]
{ },
"time": 1.5333, {
"vertices": [ -3.41745, -0.94554, -3.41747, -0.94553, -3.41744, -0.94554, 0, 0, 0, 0, -1.24409, -0.40979 ], "time": 1.5333,
"curve": [ 1.786, 0, 1.759, 1 ] "vertices": [ -3.41745, -0.94554, -3.41747, -0.94553, -3.41744, -0.94554, 0, 0, 0, 0, -1.24409, -0.40979 ],
}, "curve": [ 1.786, 0, 1.759, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"thumbL": { "thumbL": {
"thumbL": [ "thumbL": {
{ "curve": "stepped" }, "deform": [
{ { "curve": "stepped" },
"time": 0.4667, {
"curve": [ 0.714, 0, 0.925, 1 ] "time": 0.4667,
}, "curve": [ 0.714, 0, 0.925, 1 ]
{ },
"time": 1.1667, {
"vertices": [ -2.29185, -3.98124, -0.2334, -3.13461, 0.49543, -1.60927, 1.06945, 0.67771, -0.11907, -0.5765, -0.11912, -0.57646, -1.0E-5, 0, -1.0E-5, 2.0E-5, -1.80242, 1.16175, -2.5097, 0.70314, -3.87533, 0.49874, -4.51916, -1.38056, -4.28195, -2.70174, -3.59239, -3.16153, -3.25915, -3.82949, -1.17744, -0.89034, 0.3796, 0.01583 ], "time": 1.1667,
"curve": [ 1.461, 0, 1.713, 1 ] "vertices": [ -2.29185, -3.98124, -0.2334, -3.13461, 0.49543, -1.60927, 1.06945, 0.67771, -0.11907, -0.5765, -0.11912, -0.57646, -1.0E-5, 0, -1.0E-5, 2.0E-5, -1.80242, 1.16175, -2.5097, 0.70314, -3.87533, 0.49874, -4.51916, -1.38056, -4.28195, -2.70174, -3.59239, -3.16153, -3.25915, -3.82949, -1.17744, -0.89034, 0.3796, 0.01583 ],
}, "curve": [ 1.461, 0, 1.713, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
}, },
"thumbR": { "thumbR": {
"thumbR": [ "thumbR": {
{ "deform": [
"curve": [ 0.353, 0, 0.655, 1 ] {
}, "curve": [ 0.353, 0, 0.655, 1 ]
{ },
"time": 1, {
"offset": 2, "time": 1,
"vertices": [ 4.24296, 0.26622, 5.3837, 4.83061, 3.73976, 9.41351, -1.18715, 11.81196, -5.39824, 10.30256, -6.95535, 4.73572, -3.19517, -0.32295, -1.31602, 0.11442, 0, 1.0E-5, 0, -1.0E-5, -1.0E-5, 1.0E-5, -0.93784, 2.97592 ], "offset": 2,
"curve": [ 1.353, 0, 1.655, 1 ] "vertices": [ 4.24296, 0.26622, 5.3837, 4.83061, 3.73976, 9.41351, -1.18715, 11.81196, -5.39824, 10.30256, -6.95535, 4.73572, -3.19517, -0.32295, -1.31602, 0.11442, 0, 1.0E-5, 0, -1.0E-5, -1.0E-5, 1.0E-5, -0.93784, 2.97592 ],
}, "curve": [ 1.353, 0, 1.655, 1 ]
{ "time": 2 } },
] { "time": 2 }
]
}
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "F+EPhClYhR8", "hash": "NNUiOwCxKWo",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -100.47, "x": -100.47,
"y": -9.21, "y": -9.21,
"width": 260.65, "width": 260.65,
@ -1966,144 +1966,148 @@
{ "mix": 0 } { "mix": 0 }
] ]
}, },
"deform": { "attachments": {
"default": { "default": {
"back-leg-path": { "back-leg-path": {
"back-leg-path": [ "back-leg-path": {
{ "deform": [
"curve": [ 0.158, 0, 0.475, 1 ] {
}, "curve": [ 0.158, 0, 0.475, 1 ]
{ },
"time": 0.6333, {
"offset": 6, "time": 0.6333,
"vertices": [ 7.58212, 6.44012, -6.24036, 7.74866, 0, 0, 0, 0, -8.65305, -6.0506, 5.82422, -8.80603 ], "offset": 6,
"curve": [ 0.771, 0, 1.005, 0.48 ] "vertices": [ 7.58212, 6.44012, -6.24036, 7.74866, 0, 0, 0, 0, -8.65305, -6.0506, 5.82422, -8.80603 ],
}, "curve": [ 0.771, 0, 1.005, 0.48 ]
{ },
"time": 1.2, {
"offset": 6, "time": 1.2,
"vertices": [ 1.75757, 1.49285, -1.44654, 1.79617, 0, 0, 0, 0, -2.00581, -1.40255, 1.35008, -2.04128 ], "offset": 6,
"curve": [ 1.215, 0, 1.225, 0.03 ] "vertices": [ 1.75757, 1.49285, -1.44654, 1.79617, 0, 0, 0, 0, -2.00581, -1.40255, 1.35008, -2.04128 ],
}, "curve": [ 1.215, 0, 1.225, 0.03 ]
{ },
"time": 1.2333, {
"offset": 6, "time": 1.2333,
"vertices": [ 11.07889, 9.19726, -3.09299, 13.71402, 9.39429, 7.76639, -1.7065, 11.99242, 7.47175, 6.42206, -0.41247, 10.03589 ], "offset": 6,
"curve": [ 1.246, 0.12, 1.254, 0.27 ] "vertices": [ 11.07889, 9.19726, -3.09299, 13.71402, 9.39429, 7.76639, -1.7065, 11.99242, 7.47175, 6.42206, -0.41247, 10.03589 ],
}, "curve": [ 1.246, 0.12, 1.254, 0.27 ]
{ },
"time": 1.2667, {
"offset": 6, "time": 1.2667,
"vertices": [ 10.10474, 8.7463, -2.36874, 12.63447, 8.81438, 7.65029, -1.30674, 11.31577, 7.34177, 6.62058, -0.31555, 9.81713 ], "offset": 6,
"curve": [ 1.275, 0.62, 1.286, 0.79 ] "vertices": [ 10.10474, 8.7463, -2.36874, 12.63447, 8.81438, 7.65029, -1.30674, 11.31577, 7.34177, 6.62058, -0.31555, 9.81713 ],
}, "curve": [ 1.275, 0.62, 1.286, 0.79 ]
{ },
"time": 1.3, {
"offset": 6, "time": 1.3,
"vertices": [ 3.4599, -0.42859, 1.07778, 1.47922, 2.60141, -1.15778, 1.78435, 0.60187, 1.62166, -1.84286, 2.4438, -0.3952 ], "offset": 6,
"curve": [ 1.354, 0.76, 1.414, 1 ] "vertices": [ 3.4599, -0.42859, 1.07778, 1.47922, 2.60141, -1.15778, 1.78435, 0.60187, 1.62166, -1.84286, 2.4438, -0.3952 ],
}, "curve": [ 1.354, 0.76, 1.414, 1 ]
{ },
"time": 1.4333, {
"offset": 6, "time": 1.4333,
"vertices": [ -4.08505, -24.14874, 13.996, -20.09798, -4.08505, -24.14874, 13.996, -20.09798, -4.08505, -24.14874, 13.996, -20.09798 ] "offset": 6,
}, "vertices": [ -4.08505, -24.14874, 13.996, -20.09798, -4.08505, -24.14874, 13.996, -20.09798, -4.08505, -24.14874, 13.996, -20.09798 ]
{ },
"time": 1.5, {
"vertices": [ 4.67719, -35.44354, 0, 0, -11.37146, 49.53738, 17.39343, -2.33365, 4.23248, 5.68374, -9.56653, -24.74756, 11.45203, -23.93552, -27.49841, -64.4725, 35.55432, -56.67893, 34.69244, -51.5341, 0, 0, 13.30164, -100.17206 ] "time": 1.5,
}, "vertices": [ 4.67719, -35.44354, 0, 0, -11.37146, 49.53738, 17.39343, -2.33365, 4.23248, 5.68374, -9.56653, -24.74756, 11.45203, -23.93552, -27.49841, -64.4725, 35.55432, -56.67893, 34.69244, -51.5341, 0, 0, 13.30164, -100.17206 ]
{ },
"time": 1.5333, {
"vertices": [ 1.85684, -28.94159, 0, 0, -12.58768, 38.57599, 11.30969, 16.17496, -13.13428, 1.4907, -12.13364, -13.87851, 4.3075, -20.49398, -34.95135, -45.73811, 21.12878, -45.5335, 30.62613, -45.13649, 0, 0, -0.15961, -190.51059 ] "time": 1.5333,
}, "vertices": [ 1.85684, -28.94159, 0, 0, -12.58768, 38.57599, 11.30969, 16.17496, -13.13428, 1.4907, -12.13364, -13.87851, 4.3075, -20.49398, -34.95135, -45.73811, 21.12878, -45.5335, 30.62613, -45.13649, 0, 0, -0.15961, -190.51059 ]
{ },
"time": 1.5667, {
"vertices": [ -0.9635, -22.43964, 0, 0, -13.80389, 27.61459, 1.79449, 28.22318, -27.06714, -9.07224, -6.2052, -1.21002, 1.34003, -9.39124, -24.41541, -19.97638, 12.56061, -16.52356, 26.55981, -38.73888, 0, 0, -13.62085, -280.84912 ] "time": 1.5667,
}, "vertices": [ -0.9635, -22.43964, 0, 0, -13.80389, 27.61459, 1.79449, 28.22318, -27.06714, -9.07224, -6.2052, -1.21002, 1.34003, -9.39124, -24.41541, -19.97638, 12.56061, -16.52356, 26.55981, -38.73888, 0, 0, -13.62085, -280.84912 ]
{ },
"time": 1.6, {
"vertices": [ -0.64233, -14.95974, 0, 0, -9.20259, 18.40971, 13.73107, 41.19725, -42.90586, -9.10037, 4.13583, -3.71808, 4.12607, -1.04554, -17.52923, -15.07591, 15.79826, -11.47559, 17.70652, -25.82589, 0, 0, -9.08056, -187.23253 ] "time": 1.6,
}, "vertices": [ -0.64233, -14.95974, 0, 0, -9.20259, 18.40971, 13.73107, 41.19725, -42.90586, -9.10037, 4.13583, -3.71808, 4.12607, -1.04554, -17.52923, -15.07591, 15.79826, -11.47559, 17.70652, -25.82589, 0, 0, -9.08056, -187.23253 ]
{ },
"time": 1.6333, {
"vertices": [ -0.32117, -7.47987, 0, 0, -4.60129, 9.20485, 3.14877, 52.3598, -63.25818, -29.05335, -8.042, -8.03761, 2.39843, -12.62472, -33.16191, -11.98693, 14.52224, -26.35249, 8.85326, -12.91294, 0, 0, -4.54028, -93.61627 ] "time": 1.6333,
}, "vertices": [ -0.32117, -7.47987, 0, 0, -4.60129, 9.20485, 3.14877, 52.3598, -63.25818, -29.05335, -8.042, -8.03761, 2.39843, -12.62472, -33.16191, -11.98693, 14.52224, -26.35249, 8.85326, -12.91294, 0, 0, -4.54028, -93.61627 ]
{ "time": 1.6667 } },
] { "time": 1.6667 }
]
}
}, },
"front-leg-path": { "front-leg-path": {
"front-leg-path": [ "front-leg-path": {
{ "deform": [
"curve": [ 0.075, 0, 0.189, 0.28 ] {
}, "curve": [ 0.075, 0, 0.189, 0.28 ]
{ },
"time": 0.3, {
"vertices": [ 0.05087, -3.38688, 0, 0, 1.38452, 5.97834, -14.9041, 2.01206, 1.44487, -6.80281, -14.9041, 2.01206, 1.44487, -6.80281, -14.9041, 2.01206, 1.44487, -6.80281 ], "time": 0.3,
"curve": [ 0.323, 0.2, 0.345, 0.35 ] "vertices": [ 0.05087, -3.38688, 0, 0, 1.38452, 5.97834, -14.9041, 2.01206, 1.44487, -6.80281, -14.9041, 2.01206, 1.44487, -6.80281, -14.9041, 2.01206, 1.44487, -6.80281 ],
}, "curve": [ 0.323, 0.2, 0.345, 0.35 ]
{ },
"time": 0.3667, {
"vertices": [ 0.07139, -4.75271, 0, 0, 1.94286, 8.38924, 4.65956, 20.90988, -6.00341, 18.98861, -0.14155, 20.92476, -9.36768, 15.5653, -12.20349, 23.97896, -19.98153, 9.06929 ], "time": 0.3667,
"curve": [ 0.39, 0.31, 0.412, 0.53 ] "vertices": [ 0.07139, -4.75271, 0, 0, 1.94286, 8.38924, 4.65956, 20.90988, -6.00341, 18.98861, -0.14155, 20.92476, -9.36768, 15.5653, -12.20349, 23.97896, -19.98153, 9.06929 ],
}, "curve": [ 0.39, 0.31, 0.412, 0.53 ]
{ },
"time": 0.4333, {
"vertices": [ 0.08487, -5.65058, 0, 0, 2.3099, 9.97411, 6.09287, 20.58425, -8.39331, 19.11554, -1.86437, 20.6089, -13.96917, 13.44183, -21.85559, 25.6709, -31.56034, 2.67548 ], "time": 0.4333,
"curve": [ 0.438, 0.32, 0.451, 0.54 ] "vertices": [ 0.08487, -5.65058, 0, 0, 2.3099, 9.97411, 6.09287, 20.58425, -8.39331, 19.11554, -1.86437, 20.6089, -13.96917, 13.44183, -21.85559, 25.6709, -31.56034, 2.67548 ],
}, "curve": [ 0.438, 0.32, 0.451, 0.54 ]
{ },
"time": 0.4667, {
"vertices": [ 0.09099, -6.05806, 0, 0, 2.47648, 10.69338, 6.80647, 9.95062, -1.39596, 12.12401, -2.58313, 9.97971, -7.97551, 5.429, -26.17287, 15.95288, -28.7332, -7.27536 ], "time": 0.4667,
"curve": [ 0.491, 0.92, 0.521, 0.99 ] "vertices": [ 0.09099, -6.05806, 0, 0, 2.47648, 10.69338, 6.80647, 9.95062, -1.39596, 12.12401, -2.58313, 9.97971, -7.97551, 5.429, -26.17287, 15.95288, -28.7332, -7.27536 ],
}, "curve": [ 0.491, 0.92, 0.521, 0.99 ]
{ },
"time": 0.5333, {
"vertices": [ 0.0938, -6.24474, 0, 0, 2.55279, 11.0229, 3.37726, -9.77658, 9.35123, -4.41786, -6.66855, -9.74546, 2.31187, -11.58077, -31.90691, -3.35485, -19.89651, -25.173 ], "time": 0.5333,
"curve": [ 0.54, 0.52, 0.553, 0.77 ] "vertices": [ 0.0938, -6.24474, 0, 0, 2.55279, 11.0229, 3.37726, -9.77658, 9.35123, -4.41786, -6.66855, -9.74546, 2.31187, -11.58077, -31.90691, -3.35485, -19.89651, -25.173 ],
}, "curve": [ 0.54, 0.52, 0.553, 0.77 ]
{ },
"time": 0.5667, {
"vertices": [ 0.12554, -7.9214, 0, 0, 0.6047, 13.76218, 28.2061, -4.72442, -24.72498, -10.04851, -1.08998, -15.00371, 3.89968, -14.73675, -45.72995, -9.44002, -7.51602, -33.5578, 22.59846, -13.40422, 0, 0, -21.81488, -287.65363 ], "time": 0.5667,
"curve": [ 0.579, 1, 0.592, 1 ] "vertices": [ 0.12554, -7.9214, 0, 0, 0.6047, 13.76218, 28.2061, -4.72442, -24.72498, -10.04851, -1.08998, -15.00371, 3.89968, -14.73675, -45.72995, -9.44002, -7.51602, -33.5578, 22.59846, -13.40422, 0, 0, -21.81488, -287.65363 ],
}, "curve": [ 0.579, 1, 0.592, 1 ]
{ },
"time": 0.6, {
"vertices": [ 0.12969, -8.14021, 0, 0, 0.35046, 14.11967, 49.51149, 65.25623, -80.01971, 39.68078, -0.36196, -15.68993, 4.10689, -15.14861, -62.03986, -28.71517, 2.78595, -56.47927, 41.45007, -31.91446, 0, 0, -19.75009, -6.99966 ] "time": 0.6,
}, "vertices": [ 0.12969, -8.14021, 0, 0, 0.35046, 14.11967, 49.51149, 65.25623, -80.01971, 39.68078, -0.36196, -15.68993, 4.10689, -15.14861, -62.03986, -28.71517, 2.78595, -56.47927, 41.45007, -31.91446, 0, 0, -19.75009, -6.99966 ]
{ },
"time": 0.6333, {
"vertices": [ 0.16366, -9.90768, 0, 0, -1.90419, 16.9905, 99.3634, 33.16509, -81.26534, 35.35141, -0.72391, -31.37989, 8.2138, -30.29725, -84.11658, -22.14578, -6.24997, -61.22949, 46.91129, -33.41971, 0, 0, -31.98465, -262.01813 ] "time": 0.6333,
}, "vertices": [ 0.16366, -9.90768, 0, 0, -1.90419, 16.9905, 99.3634, 33.16509, -81.26534, 35.35141, -0.72391, -31.37989, 8.2138, -30.29725, -84.11658, -22.14578, -6.24997, -61.22949, 46.91129, -33.41971, 0, 0, -31.98465, -262.01813 ]
{ },
"time": 0.6667, {
"vertices": [ 0.18382, -11.1283, 0, 0, -2.13879, 19.08371, 85.97569, 24.69115, -94.39235, -5.64914, 3.63728, -14.95789, -10.54588, -27.66409, -78.76755, -2.82176, -20.92926, -42.81331, 26.18336, -20.74105, 0, 0, -159.67368, -300.67038 ] "time": 0.6667,
}, "vertices": [ 0.18382, -11.1283, 0, 0, -2.13879, 19.08371, 85.97569, 24.69115, -94.39235, -5.64914, 3.63728, -14.95789, -10.54588, -27.66409, -78.76755, -2.82176, -20.92926, -42.81331, 26.18336, -20.74105, 0, 0, -159.67368, -300.67038 ]
{ },
"time": 0.7, {
"vertices": [ 0.20398, -12.34892, 0, 0, -2.37338, 21.17692, 70.14705, -52.80042, -51.24022, -73.25025, 20.8386, -23.27967, -12.66359, -23.66, -39.22493, -9.41795, -5.46658, 10.6813, 1.18861, 10.38911, 0, 0, -400.93036, -315.42963 ] "time": 0.7,
}, "vertices": [ 0.20398, -12.34892, 0, 0, -2.37338, 21.17692, 70.14705, -52.80042, -51.24022, -73.25025, 20.8386, -23.27967, -12.66359, -23.66, -39.22493, -9.41795, -5.46658, 10.6813, 1.18861, 10.38911, 0, 0, -400.93036, -315.42963 ]
{ },
"time": 0.7333, {
"vertices": [ 0.13599, -8.23261, 0, 0, -1.58226, 14.11795, 46.76473, -35.2003, -34.16017, -48.83353, 13.89241, -15.51979, -8.4424, -15.77335, -26.14997, -6.27864, -3.64439, 7.12087, 0.8908, 26.32127, 0, 0, -439.48523, -177.52177 ] "time": 0.7333,
}, "vertices": [ 0.13599, -8.23261, 0, 0, -1.58226, 14.11795, 46.76473, -35.2003, -34.16017, -48.83353, 13.89241, -15.51979, -8.4424, -15.77335, -26.14997, -6.27864, -3.64439, 7.12087, 0.8908, 26.32127, 0, 0, -439.48523, -177.52177 ]
{ },
"time": 0.7667, {
"vertices": [ 0.06799, -4.11631, 0, 0, -0.79113, 7.05898, 23.38236, -17.60015, -17.08008, -24.41677, 6.94621, -7.7599, -4.2212, -7.88667, -13.07498, -3.13932, -1.8222, 3.56044, 6.0198, 23.00182, 0, 0, -365.68442, -226.89883 ] "time": 0.7667,
}, "vertices": [ 0.06799, -4.11631, 0, 0, -0.79113, 7.05898, 23.38236, -17.60015, -17.08008, -24.41677, 6.94621, -7.7599, -4.2212, -7.88667, -13.07498, -3.13932, -1.8222, 3.56044, 6.0198, 23.00182, 0, 0, -365.68442, -226.89883 ]
{ "time": 0.8, "curve": "stepped" }, },
{ "time": 1.1 }, { "time": 0.8, "curve": "stepped" },
{ { "time": 1.1 },
"time": 1.3, {
"offset": 6, "time": 1.3,
"vertices": [ 22.24737, 20.71245, -17.43828, 31.85296, 22.24737, 20.71245, -17.43828, 31.85296, 22.24737, 20.71245, -17.43828, 31.85296 ] "offset": 6,
}, "vertices": [ 22.24737, 20.71245, -17.43828, 31.85296, 22.24737, 20.71245, -17.43828, 31.85296, 22.24737, 20.71245, -17.43828, 31.85296 ]
{ },
"time": 1.4333, {
"offset": 6, "time": 1.4333,
"vertices": [ 50.92273, 30.30164, -15.21045, 57.26978, 50.92273, 30.30164, -15.21045, 57.26978, 50.92273, 30.30164, -15.21045, 57.26978 ] "offset": 6,
}, "vertices": [ 50.92273, 30.30164, -15.21045, 57.26978, 50.92273, 30.30164, -15.21045, 57.26978, 50.92273, 30.30164, -15.21045, 57.26978 ]
{ "time": 1.8 } },
] { "time": 1.8 }
]
}
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 366 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "bR3EmyUwO+g", "hash": "mFaJu+5zxGE",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -240.58, "x": -240.58,
"y": -3.38, "y": -3.38,
"width": 410.36, "width": 410.36,
@ -5263,37 +5263,37 @@
"slots": { "slots": {
"eye-back-iris": { "eye-back-iris": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-back-iris" } { "time": 0.0732, "name": "eye-back-iris" }
] ]
}, },
"eye-back-pupil": { "eye-back-pupil": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-back-pupil" } { "time": 0.0732, "name": "eye-back-pupil" }
] ]
}, },
"eye-back-white": { "eye-back-white": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-back-white" } { "time": 0.0732, "name": "eye-back-white" }
] ]
}, },
"eye-front-iris": { "eye-front-iris": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-front-iris" } { "time": 0.0732, "name": "eye-front-iris" }
] ]
}, },
"eye-front-pupil": { "eye-front-pupil": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-front-pupil" } { "time": 0.0732, "name": "eye-front-pupil" }
] ]
}, },
"eye-front-white": { "eye-front-white": {
"attachment": [ "attachment": [
{ "time": 0.0333, "name": null }, { "time": 0.0333 },
{ "time": 0.0732, "name": "eye-front-white" } { "time": 0.0732, "name": "eye-front-white" }
] ]
} }
@ -6028,49 +6028,49 @@
"slots": { "slots": {
"eye-back-iris": { "eye-back-iris": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-back-iris" }, { "time": 0.1732, "name": "eye-back-iris" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-back-iris" } { "time": 2.3, "name": "eye-back-iris" }
] ]
}, },
"eye-back-pupil": { "eye-back-pupil": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-back-pupil" }, { "time": 0.1732, "name": "eye-back-pupil" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-back-pupil" } { "time": 2.3, "name": "eye-back-pupil" }
] ]
}, },
"eye-back-white": { "eye-back-white": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-back-white" }, { "time": 0.1732, "name": "eye-back-white" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-back-white" } { "time": 2.3, "name": "eye-back-white" }
] ]
}, },
"eye-front-iris": { "eye-front-iris": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-front-iris" }, { "time": 0.1732, "name": "eye-front-iris" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-front-iris" } { "time": 2.3, "name": "eye-front-iris" }
] ]
}, },
"eye-front-pupil": { "eye-front-pupil": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-front-pupil" }, { "time": 0.1732, "name": "eye-front-pupil" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-front-pupil" } { "time": 2.3, "name": "eye-front-pupil" }
] ]
}, },
"eye-front-white": { "eye-front-white": {
"attachment": [ "attachment": [
{ "time": 0.1333, "name": null }, { "time": 0.1333 },
{ "time": 0.1732, "name": "eye-front-white" }, { "time": 0.1732, "name": "eye-front-white" },
{ "time": 2.2667, "name": null }, { "time": 2.2667 },
{ "time": 2.3, "name": "eye-front-white" } { "time": 2.3, "name": "eye-front-white" }
] ]
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

After

Width:  |  Height:  |  Size: 409 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "c1+xCfJH+TE", "hash": "cDRfwRDrCkA",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -809.16, "x": -809.16,
"y": -73.54, "y": -73.54,
"width": 1287.65, "width": 1287.65,
@ -879,7 +879,7 @@
}, },
"gun": { "gun": {
"attachment": [ "attachment": [
{ "time": 0.2333, "name": null } { "time": 0.2333 }
] ]
} }
}, },
@ -1006,7 +1006,7 @@
}, },
"gun": { "gun": {
"attachment": [ "attachment": [
{ "name": null }, {},
{ "time": 0.3, "name": "gun-nohand" } { "time": 0.3, "name": "gun-nohand" }
] ]
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "AN/kz0MkBAg", "hash": "fJ3tj/bl3Iw",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -221.22, "x": -221.22,
"y": -8.55, "y": -8.55,
"width": 371.09, "width": 371.09,
@ -887,19 +887,19 @@
"gun2": { "gun2": {
"attachment": [ "attachment": [
{ "time": 0.6333, "name": "gun" }, { "time": 0.6333, "name": "gun" },
{ "time": 1.6667, "name": null } { "time": 1.6667 }
] ]
}, },
"gun3": { "gun3": {
"attachment": [ "attachment": [
{ "time": 0.6333, "name": "gun" }, { "time": 0.6333, "name": "gun" },
{ "time": 1.6667, "name": null } { "time": 1.6667 }
] ]
}, },
"gun4": { "gun4": {
"attachment": [ "attachment": [
{ "time": 0.6333, "name": "gun" }, { "time": 0.6333, "name": "gun" },
{ "time": 1.6667, "name": null } { "time": 1.6667 }
] ]
}, },
"muzzle": { "muzzle": {
@ -922,39 +922,39 @@
], ],
"attachment": [ "attachment": [
{ "time": 0.7667, "name": "muzzle" }, { "time": 0.7667, "name": "muzzle" },
{ "time": 1.3333, "name": null } { "time": 1.3333 }
] ]
}, },
"muzzle2": { "muzzle2": {
"attachment": [ "attachment": [
{ "time": 0.7667, "name": "muzzle" }, { "time": 0.7667, "name": "muzzle" },
{ "time": 0.8333, "name": null }, { "time": 0.8333 },
{ "time": 0.8667, "name": "muzzle" }, { "time": 0.8667, "name": "muzzle" },
{ "time": 0.9333, "name": null }, { "time": 0.9333 },
{ "time": 0.9667, "name": "muzzle" }, { "time": 0.9667, "name": "muzzle" },
{ "time": 1.0333, "name": null }, { "time": 1.0333 },
{ "time": 1.0667, "name": "muzzle" }, { "time": 1.0667, "name": "muzzle" },
{ "time": 1.1333, "name": null }, { "time": 1.1333 },
{ "time": 1.1667, "name": "muzzle" }, { "time": 1.1667, "name": "muzzle" },
{ "time": 1.2333, "name": null }, { "time": 1.2333 },
{ "time": 1.2667, "name": "muzzle" }, { "time": 1.2667, "name": "muzzle" },
{ "time": 1.3333, "name": null } { "time": 1.3333 }
] ]
}, },
"muzzle3": { "muzzle3": {
"attachment": [ "attachment": [
{ "time": 0.8333, "name": "muzzle" }, { "time": 0.8333, "name": "muzzle" },
{ "time": 0.9, "name": null }, { "time": 0.9 },
{ "time": 0.9333, "name": "muzzle" }, { "time": 0.9333, "name": "muzzle" },
{ "time": 1, "name": null }, { "time": 1 },
{ "time": 1.0333, "name": "muzzle" }, { "time": 1.0333, "name": "muzzle" },
{ "time": 1.1, "name": null }, { "time": 1.1 },
{ "time": 1.1333, "name": "muzzle" }, { "time": 1.1333, "name": "muzzle" },
{ "time": 1.2, "name": null }, { "time": 1.2 },
{ "time": 1.2333, "name": "muzzle" }, { "time": 1.2333, "name": "muzzle" },
{ "time": 1.3, "name": null }, { "time": 1.3 },
{ "time": 1.3333, "name": "muzzle" }, { "time": 1.3333, "name": "muzzle" },
{ "time": 1.4, "name": null } { "time": 1.4 }
] ]
} }
}, },
@ -5232,7 +5232,7 @@
], ],
"attachment": [ "attachment": [
{ "time": 0.0333, "name": "muzzle" }, { "time": 0.0333, "name": "muzzle" },
{ "time": 0.1667, "name": null } { "time": 0.1667 }
] ]
}, },
"muzzle2": { "muzzle2": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 KiB

After

Width:  |  Height:  |  Size: 524 KiB

View File

@ -1,7 +1,7 @@
{ {
"skeleton": { "skeleton": {
"hash": "wOLCjLyjs9E", "hash": "d53R1Ina68Q",
"spine": "4.0.31", "spine": "4.1.04-beta",
"x": -252.71, "x": -252.71,
"y": -232.55, "y": -232.55,
"width": 456.71, "width": 456.71,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -2,7 +2,7 @@
"name": "com.esotericsoftware.spine.spine-unity-examples", "name": "com.esotericsoftware.spine.spine-unity-examples",
"displayName": "spine-unity Runtime Examples", "displayName": "spine-unity Runtime Examples",
"description": "This plugin provides example scenes and scripts for the spine-unity runtime.", "description": "This plugin provides example scenes and scripts for the spine-unity runtime.",
"version": "4.0.0", "version": "4.1.0",
"unity": "2018.3", "unity": "2018.3",
"author": { "author": {
"name": "Esoteric Software", "name": "Esoteric Software",
@ -10,7 +10,7 @@
"url": "http://esotericsoftware.com/" "url": "http://esotericsoftware.com/"
}, },
"dependencies": { "dependencies": {
"com.esotericsoftware.spine.spine-unity": "4.0.0" "com.esotericsoftware.spine.spine-unity": "4.1.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -176,6 +176,14 @@ namespace Spine.Unity.Editor {
requiredPaths.Add((string)data["path"]); requiredPaths.Add((string)data["path"]);
else if (data.ContainsKey("name")) else if (data.ContainsKey("name"))
requiredPaths.Add((string)data["name"]); requiredPaths.Add((string)data["name"]);
else if (data.ContainsKey("sequence")) {
Sequence sequence = SkeletonJson.ReadSequence(data["sequence"]);
if (sequence != null)
for (int index = 0; index < sequence.Regions.Length; ++index)
requiredPaths.Add(sequence.GetPath(attachment.Key, index));
else
requiredPaths.Add(attachment.Key);
}
else else
requiredPaths.Add(attachment.Key); requiredPaths.Add(attachment.Key);
} }
@ -234,14 +242,26 @@ namespace Spine.Unity.Editor {
this.requirementList = requirementList; this.requirementList = requirementList;
} }
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
requirementList.Add(path); var regionAttachment = new RegionAttachment(name);
return new RegionAttachment(name); if (sequence != null)
LoadSequence(path, sequence);
else {
requirementList.Add(path);
AssignDummyRegion(regionAttachment);
}
return regionAttachment;
} }
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
requirementList.Add(path); var meshAttachment = new MeshAttachment(name);
return new MeshAttachment(name); if (sequence != null)
LoadSequence(path, sequence);
else {
requirementList.Add(path);
AssignDummyRegion(meshAttachment);
}
return meshAttachment;
} }
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) { public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
@ -259,6 +279,18 @@ namespace Spine.Unity.Editor {
public ClippingAttachment NewClippingAttachment (Skin skin, string name) { public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
return new ClippingAttachment(name); return new ClippingAttachment(name);
} }
private void LoadSequence (string basePath, Sequence sequence) {
TextureRegion[] regions = sequence.Regions;
for (int i = 0, n = regions.Length; i < n; i++) {
string path = sequence.GetPath(basePath, i);
requirementList.Add(path);
}
}
private static void AssignDummyRegion (IHasTextureRegion attachment) {
attachment.Region = new AtlasRegion();
}
} }
#endregion #endregion
@ -1215,7 +1247,6 @@ namespace Spine.Unity.Editor {
} }
newSkeletonAnimation.loop = SpineEditorUtilities.Preferences.defaultInstantiateLoop; newSkeletonAnimation.loop = SpineEditorUtilities.Preferences.defaultInstantiateLoop;
newSkeletonAnimation.skeleton.Update(0);
newSkeletonAnimation.state.Update(0); newSkeletonAnimation.state.Update(0);
newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton); newSkeletonAnimation.state.Apply(newSkeletonAnimation.skeleton);
newSkeletonAnimation.skeleton.UpdateWorldTransform(); newSkeletonAnimation.skeleton.UpdateWorldTransform();
@ -1301,7 +1332,6 @@ namespace Spine.Unity.Editor {
throw e; throw e;
} }
newSkeletonMecanim.skeleton.Update(0);
newSkeletonMecanim.skeleton.UpdateWorldTransform(); newSkeletonMecanim.skeleton.UpdateWorldTransform();
newSkeletonMecanim.LateUpdate(); newSkeletonMecanim.LateUpdate();

View File

@ -200,9 +200,9 @@ namespace Spine.Unity.Editor {
skin.GetAttachments(slotIndex, skinEntries); skin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) { foreach (var entry in skinEntries) {
var renderableAttachment = entry.Attachment as IHasRendererObject; var renderableAttachment = entry.Attachment as IHasTextureRegion;
if (renderableAttachment != null) { if (renderableAttachment != null) {
var originalRegion = (AtlasRegion)renderableAttachment.RendererObject; var originalRegion = (AtlasRegion)renderableAttachment.Region;
bool replacementExists = replacementMaterials.Exists( bool replacementExists = replacementMaterials.Exists(
replacement => replacement.pageName == originalRegion.page.name); replacement => replacement.pageName == originalRegion.page.name);
if (!replacementExists) { if (!replacementExists) {

View File

@ -501,7 +501,8 @@ namespace Spine.Unity.Editor {
} }
internal static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null, bool centered = true) { internal static Mesh ExtractRegionAttachment (string name, RegionAttachment attachment, Mesh mesh = null, bool centered = true) {
var bone = GetDummyBone(); var slot = GetDummySlot();
var bone = slot.Bone;
if (centered) { if (centered) {
bone.X = -attachment.X; bone.X = -attachment.X;
@ -512,7 +513,7 @@ namespace Spine.Unity.Editor {
Vector2[] uvs = ExtractUV(attachment.UVs); Vector2[] uvs = ExtractUV(attachment.UVs);
float[] floatVerts = new float[8]; float[] floatVerts = new float[8];
attachment.ComputeWorldVertices(bone, floatVerts, 0); attachment.ComputeWorldVertices(slot, floatVerts, 0);
Vector3[] verts = ExtractVerts(floatVerts); Vector3[] verts = ExtractVerts(floatVerts);
//unrotate verts now that they're centered //unrotate verts now that they're centered

View File

@ -70,7 +70,7 @@ namespace Spine.Unity {
public bool UpdateBlendmodeMaterialsRequiredState (SkeletonData skeletonData) { public bool UpdateBlendmodeMaterialsRequiredState (SkeletonData skeletonData) {
requiresBlendModeMaterials = false; requiresBlendModeMaterials = false;
if (skeletonData == null) throw new ArgumentNullException("skeletonData"); if (skeletonData == null) return false;
var skinEntries = new List<Skin.SkinEntry>(); var skinEntries = new List<Skin.SkinEntry>();
var slotsItems = skeletonData.Slots.Items; var slotsItems = skeletonData.Slots.Items;
@ -84,7 +84,7 @@ namespace Spine.Unity {
skin.GetAttachments(slotIndex, skinEntries); skin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) { foreach (var entry in skinEntries) {
if (entry.Attachment is IHasRendererObject) { if (entry.Attachment is IHasTextureRegion) {
requiresBlendModeMaterials = true; requiresBlendModeMaterials = true;
return true; return true;
} }
@ -125,10 +125,10 @@ namespace Spine.Unity {
skin.GetAttachments(slotIndex, skinEntries); skin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) { foreach (var entry in skinEntries) {
var renderableAttachment = entry.Attachment as IHasRendererObject; var renderableAttachment = entry.Attachment as IHasTextureRegion;
if (renderableAttachment != null) { if (renderableAttachment != null) {
renderableAttachment.RendererObject = CloneAtlasRegionWithMaterial( renderableAttachment.Region = CloneAtlasRegionWithMaterial(
(AtlasRegion)renderableAttachment.RendererObject, replacementMaterials); (AtlasRegion)renderableAttachment.Region, replacementMaterials);
} }
} }
} }

View File

@ -50,16 +50,16 @@ namespace Spine.Unity {
} }
} }
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) { public RegionAttachment NewRegionAttachment (Skin skin, string name, string path, Sequence sequence) {
RegionAttachment attachment = new RegionAttachment(name) { RegionAttachment attachment = new RegionAttachment(name) {
RendererObject = EmptyRegion Region = EmptyRegion
}; };
return attachment; return attachment;
} }
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) { public MeshAttachment NewMeshAttachment (Skin skin, string name, string path, Sequence sequence) {
MeshAttachment attachment = new MeshAttachment(name) { MeshAttachment attachment = new MeshAttachment(name) {
RendererObject = EmptyRegion Region = EmptyRegion
}; };
return attachment; return attachment;
} }

View File

@ -41,8 +41,8 @@ namespace Spine.Unity {
public static class SkeletonDataCompatibility { public static class SkeletonDataCompatibility {
#if UNITY_EDITOR #if UNITY_EDITOR
static readonly int[][] compatibleBinaryVersions = { new[] { 4, 0, 0 } }; static readonly int[][] compatibleBinaryVersions = { new[] { 4, 1, 0 } };
static readonly int[][] compatibleJsonVersions = { new[] { 4, 0, 0 } }; static readonly int[][] compatibleJsonVersions = { new[] { 4, 1, 0 } };
static bool wasVersionDialogShown = false; static bool wasVersionDialogShown = false;
static readonly Regex jsonVersionRegex = new Regex(@"""spine""\s*:\s*""([^""]+)""", RegexOptions.CultureInvariant); static readonly Regex jsonVersionRegex = new Regex(@"""spine""\s*:\s*""([^""]+)""", RegexOptions.CultureInvariant);

View File

@ -215,7 +215,6 @@ namespace Spine.Unity {
protected void UpdateAnimationStatus (float deltaTime) { protected void UpdateAnimationStatus (float deltaTime) {
deltaTime *= timeScale; deltaTime *= timeScale;
skeleton.Update(deltaTime);
state.Update(deltaTime); state.Update(deltaTime);
} }

View File

@ -295,7 +295,6 @@ namespace Spine.Unity {
protected void UpdateAnimationStatus (float deltaTime) { protected void UpdateAnimationStatus (float deltaTime) {
deltaTime *= timeScale; deltaTime *= timeScale;
skeleton.Update(deltaTime);
state.Update(deltaTime); state.Update(deltaTime);
} }

View File

@ -191,13 +191,15 @@ namespace Spine.Unity {
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
rendererObject = regionAttachment.RendererObject; if (regionAttachment.Sequence != null) regionAttachment.Sequence.Apply(slot, regionAttachment);
rendererObject = regionAttachment.Region;
attachmentVertexCount = 4; attachmentVertexCount = 4;
attachmentTriangleCount = 6; attachmentTriangleCount = 6;
} else { } else {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
rendererObject = meshAttachment.RendererObject; if (meshAttachment.Sequence != null) meshAttachment.Sequence.Apply(slot, meshAttachment);
rendererObject = meshAttachment.Region;
attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1; attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
attachmentTriangleCount = meshAttachment.Triangles.Length; attachmentTriangleCount = meshAttachment.Triangles.Length;
} else { } else {
@ -249,9 +251,10 @@ namespace Spine.Unity {
Slot slot = drawOrderItems[i]; Slot slot = drawOrderItems[i];
if (!slot.Bone.Active) continue; if (!slot.Bone.Active) continue;
Attachment attachment = slot.Attachment; Attachment attachment = slot.Attachment;
var rendererAttachment = attachment as IHasRendererObject; var rendererAttachment = attachment as IHasTextureRegion;
if (rendererAttachment != null) { if (rendererAttachment != null) {
AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.RendererObject; if (rendererAttachment.Sequence != null) rendererAttachment.Sequence.Apply(slot, rendererAttachment);
AtlasRegion atlasRegion = (AtlasRegion)rendererAttachment.Region;
Material material = (Material)atlasRegion.page.rendererObject; Material material = (Material)atlasRegion.page.rendererObject;
if (lastRendererMaterial != material) { if (lastRendererMaterial != material) {
if (lastRendererMaterial != null) if (lastRendererMaterial != null)
@ -308,12 +311,13 @@ namespace Spine.Unity {
int attachmentVertexCount = 0, attachmentTriangleCount = 0; int attachmentVertexCount = 0, attachmentTriangleCount = 0;
#endif #endif
object rendererObject = null; // An AtlasRegion in plain Spine-Unity. Spine-TK2D hooks into TK2D's system. eventual source of Material object. object region = null;
bool noRender = false; // Using this allows empty slots as separators, and keeps separated parts more stable despite slots being reordered bool noRender = false; // Using this allows empty slots as separators, and keeps separated parts more stable despite slots being reordered
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
rendererObject = regionAttachment.RendererObject; if (regionAttachment.Sequence != null) regionAttachment.Sequence.Apply(slot, regionAttachment);
region = regionAttachment.Region;
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
attachmentVertexCount = 4; attachmentVertexCount = 4;
attachmentTriangleCount = 6; attachmentTriangleCount = 6;
@ -321,7 +325,8 @@ namespace Spine.Unity {
} else { } else {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
rendererObject = meshAttachment.RendererObject; if (meshAttachment.Sequence != null) meshAttachment.Sequence.Apply(slot, meshAttachment);
region = meshAttachment.Region;
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1; attachmentVertexCount = meshAttachment.WorldVerticesLength >> 1;
attachmentTriangleCount = meshAttachment.Triangles.Length; attachmentTriangleCount = meshAttachment.Triangles.Length;
@ -378,12 +383,13 @@ namespace Spine.Unity {
Material material; Material material;
if (isCustomSlotMaterialsPopulated) { if (isCustomSlotMaterialsPopulated) {
if (!customSlotMaterials.TryGetValue(slot, out material)) if (!customSlotMaterials.TryGetValue(slot, out material))
material = (Material)((AtlasRegion)rendererObject).page.rendererObject; material = (Material)((AtlasRegion)region).page.rendererObject;
} else { } else {
material = (Material)((AtlasRegion)rendererObject).page.rendererObject; material = (Material)((AtlasRegion)region).page.rendererObject;
} }
#else #else
Material material = (rendererObject is Material) ? (Material)rendererObject : (Material)((AtlasRegion)rendererObject).page.rendererObject; // An AtlasRegion in plain spine-unity, spine-TK2D hooks into TK2D's system. eventual source of Material object.
Material material = (region is Material) ? (Material)region : (Material)((AtlasRegion)region).page.rendererObject;
#endif #endif
if (current.forceSeparate || (current.rawVertexCount > 0 && !System.Object.ReferenceEquals(current.material, material))) { // Material changed. Add the previous submesh. if (current.forceSeparate || (current.rawVertexCount > 0 && !System.Object.ReferenceEquals(current.material, material))) { // Material changed. Add the previous submesh.
@ -531,7 +537,7 @@ namespace Spine.Unity {
// Identify and prepare values. // Identify and prepare values.
var region = attachment as RegionAttachment; var region = attachment as RegionAttachment;
if (region != null) { if (region != null) {
region.ComputeWorldVertices(slot.Bone, workingVerts, 0); region.ComputeWorldVertices(slot, workingVerts, 0);
uvs = region.UVs; uvs = region.UVs;
attachmentTriangleIndices = regionTriangles; attachmentTriangleIndices = regionTriangles;
c.r = region.R; c.g = region.G; c.b = region.B; c.a = region.A; c.r = region.R; c.g = region.G; c.b = region.B; c.a = region.A;
@ -821,7 +827,7 @@ namespace Spine.Unity {
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
regionAttachment.ComputeWorldVertices(slot.Bone, tempVerts, 0); regionAttachment.ComputeWorldVertices(slot, tempVerts, 0);
float x1 = tempVerts[RegionAttachment.BLX], y1 = tempVerts[RegionAttachment.BLY]; float x1 = tempVerts[RegionAttachment.BLX], y1 = tempVerts[RegionAttachment.BLY];
float x2 = tempVerts[RegionAttachment.ULX], y2 = tempVerts[RegionAttachment.ULY]; float x2 = tempVerts[RegionAttachment.ULX], y2 = tempVerts[RegionAttachment.ULY];

View File

@ -77,9 +77,10 @@ namespace Spine.Unity {
if (templateMaterial == null) continue; if (templateMaterial == null) continue;
foreach (var entry in entryBuffer) { foreach (var entry in entryBuffer) {
var renderableAttachment = entry.Attachment as IHasRendererObject; var renderableAttachment = entry.Attachment as IHasTextureRegion;
if (renderableAttachment != null) { if (renderableAttachment != null) {
renderableAttachment.RendererObject = materialCache.CloneAtlasRegionWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial); renderableAttachment.Region = materialCache.CloneAtlasRegionWithMaterial(
(AtlasRegion)renderableAttachment.Region, templateMaterial);
} }
} }
} }

View File

@ -351,10 +351,10 @@ namespace Spine.Unity.AttachmentTools {
for (int attachmentIndex = 0, n = sourceAttachments.Count; attachmentIndex < n; attachmentIndex++) { for (int attachmentIndex = 0, n = sourceAttachments.Count; attachmentIndex < n; attachmentIndex++) {
var originalAttachment = sourceAttachments[attachmentIndex]; var originalAttachment = sourceAttachments[attachmentIndex];
if (originalAttachment is IHasRendererObject) { if (originalAttachment is IHasTextureRegion) {
var originalMeshAttachment = originalAttachment as MeshAttachment; var originalMeshAttachment = originalAttachment as MeshAttachment;
Attachment newAttachment = (originalMeshAttachment != null) ? originalMeshAttachment.NewLinkedMesh() : originalAttachment.Copy(); Attachment newAttachment = (originalMeshAttachment != null) ? originalMeshAttachment.NewLinkedMesh() : originalAttachment.Copy();
var region = ((IHasRendererObject)newAttachment).RendererObject as AtlasRegion; var region = ((IHasTextureRegion)newAttachment).Region as AtlasRegion;
int existingIndex; int existingIndex;
if (existingRegions.TryGetValue(region, out existingIndex)) { if (existingRegions.TryGetValue(region, out existingIndex)) {
regionIndices.Add(existingIndex); regionIndices.Add(existingIndex);
@ -428,9 +428,12 @@ namespace Spine.Unity.AttachmentTools {
// Map the cloned attachments to the repacked atlas. // Map the cloned attachments to the repacked atlas.
for (int i = 0, n = outputAttachments.Count; i < n; i++) { for (int i = 0, n = outputAttachments.Count; i < n; i++) {
var a = outputAttachments[i]; Attachment attachment = outputAttachments[i];
if (a is IHasRendererObject) var iHasRegion = attachment as IHasTextureRegion;
a.SetRegion(repackedRegions[regionIndices[i]]); if (iHasRegion != null) {
iHasRegion.Region = repackedRegions[regionIndices[i]];
iHasRegion.UpdateRegion();
}
} }
// Clean up. // Clean up.
@ -650,7 +653,7 @@ namespace Spine.Unity.AttachmentTools {
} }
static bool IsRenderable (Attachment a) { static bool IsRenderable (Attachment a) {
return a is IHasRendererObject; return a is IHasTextureRegion;
} }
/// <summary> /// <summary>
@ -676,10 +679,7 @@ namespace Spine.Unity.AttachmentTools {
/// <summary> /// <summary>
/// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down)</summary> /// Returns a Rect of the AtlasRegion according to Spine texture coordinates. (x-right, y-down)</summary>
static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) { static Rect GetSpineAtlasRect (this AtlasRegion region, bool includeRotate = true) {
if (includeRotate && (region.degrees == 90 || region.degrees == 270)) return new Rect(region.x, region.y, region.packedWidth, region.packedHeight);
return new Rect(region.x, region.y, region.height, region.width);
else
return new Rect(region.x, region.y, region.width, region.height);
} }
/// <summary> /// <summary>
@ -708,26 +708,18 @@ namespace Spine.Unity.AttachmentTools {
var tr = UVRectToTextureRect(uvRect, page.width, page.height); var tr = UVRectToTextureRect(uvRect, page.width, page.height);
var rr = tr.SpineUnityFlipRect(page.height); var rr = tr.SpineUnityFlipRect(page.height);
int x = (int)rr.x, y = (int)rr.y; int x = (int)rr.x;
int w, h; int y = (int)rr.y;
if (referenceRegion.degrees == 90 || referenceRegion.degrees == 270) { int w = (int)rr.width;
w = (int)rr.height; int h = (int)rr.height;
h = (int)rr.width; // Note: originalW and originalH need to be scaled according to the
} else { // repacked width and height, repacking can mess with aspect ratio, etc.
w = (int)rr.width;
h = (int)rr.height;
}
int originalW = Mathf.RoundToInt((float)w * ((float)referenceRegion.originalWidth / (float)referenceRegion.width)); int originalW = Mathf.RoundToInt((float)w * ((float)referenceRegion.originalWidth / (float)referenceRegion.width));
int originalH = Mathf.RoundToInt((float)h * ((float)referenceRegion.originalHeight / (float)referenceRegion.height)); int originalH = Mathf.RoundToInt((float)h * ((float)referenceRegion.originalHeight / (float)referenceRegion.height));
int offsetX = Mathf.RoundToInt((float)referenceRegion.offsetX * ((float)w / (float)referenceRegion.width)); int offsetX = Mathf.RoundToInt((float)referenceRegion.offsetX * ((float)w / (float)referenceRegion.width));
int offsetY = Mathf.RoundToInt((float)referenceRegion.offsetY * ((float)h / (float)referenceRegion.height)); int offsetY = Mathf.RoundToInt((float)referenceRegion.offsetY * ((float)h / (float)referenceRegion.height));
if (referenceRegion.degrees == 270) {
w = (int)rr.width;
h = (int)rr.height;
}
float u = uvRect.xMin; float u = uvRect.xMin;
float u2 = uvRect.xMax; float u2 = uvRect.xMax;
float v = uvRect.yMax; float v = uvRect.yMax;

View File

@ -68,8 +68,8 @@ namespace Spine.Unity.AttachmentTools {
float scale = 1f / sprite.pixelsPerUnit; float scale = 1f / sprite.pixelsPerUnit;
if (useOriginalRegionScale) { if (useOriginalRegionScale) {
var regionAttachment = o as RegionAttachment; var regionAttachment = o as RegionAttachment;
if (regionAttachment != null) if (regionAttachment != null )
scale = regionAttachment.Width / regionAttachment.RegionOriginalWidth; scale = regionAttachment.Width / regionAttachment.Region.OriginalWidth;
} }
return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, scale); return o.GetRemappedClone(atlasRegion, cloneMeshAsLinked, useOriginalRegionSize, scale);
} }
@ -86,18 +86,19 @@ namespace Spine.Unity.AttachmentTools {
var regionAttachment = o as RegionAttachment; var regionAttachment = o as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy(); RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy();
newAttachment.SetRegion(atlasRegion, false); newAttachment.Region = atlasRegion;
if (!useOriginalRegionSize) { if (!useOriginalRegionSize) {
newAttachment.Width = atlasRegion.width * scale; newAttachment.Width = atlasRegion.width * scale;
newAttachment.Height = atlasRegion.height * scale; newAttachment.Height = atlasRegion.height * scale;
} }
newAttachment.UpdateOffset(); newAttachment.UpdateRegion();
return newAttachment; return newAttachment;
} else { } else {
var meshAttachment = o as MeshAttachment; var meshAttachment = o as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy(); MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy();
newAttachment.SetRegion(atlasRegion); newAttachment.Region = atlasRegion;
newAttachment.UpdateRegion();
return newAttachment; return newAttachment;
} }
} }

View File

@ -33,58 +33,6 @@ using UnityEngine;
namespace Spine.Unity.AttachmentTools { namespace Spine.Unity.AttachmentTools {
public static class AttachmentRegionExtensions { public static class AttachmentRegionExtensions {
#region SetRegion
/// <summary>
/// Tries to set the region (image) of a renderable attachment. If the attachment is not renderable, nothing is applied.</summary>
public static void SetRegion (this Attachment attachment, AtlasRegion region, bool updateOffset = true) {
var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null)
regionAttachment.SetRegion(region, updateOffset);
var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null)
meshAttachment.SetRegion(region, updateOffset);
}
/// <summary>Sets the region (image) of a RegionAttachment</summary>
public static void SetRegion (this RegionAttachment attachment, AtlasRegion region, bool updateOffset = true) {
if (region == null) throw new System.ArgumentNullException("region");
// (AtlasAttachmentLoader.cs)
attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment.RegionOffsetX = region.offsetX;
attachment.RegionOffsetY = region.offsetY;
attachment.RegionWidth = region.width;
attachment.RegionHeight = region.height;
attachment.RegionOriginalWidth = region.originalWidth;
attachment.RegionOriginalHeight = region.originalHeight;
if (updateOffset) attachment.UpdateOffset();
}
/// <summary>Sets the region (image) of a MeshAttachment</summary>
public static void SetRegion (this MeshAttachment attachment, AtlasRegion region, bool updateUVs = true) {
if (region == null) throw new System.ArgumentNullException("region");
// (AtlasAttachmentLoader.cs)
attachment.RendererObject = region;
attachment.RegionU = region.u;
attachment.RegionV = region.v;
attachment.RegionU2 = region.u2;
attachment.RegionV2 = region.v2;
attachment.RegionDegrees = region.degrees;
attachment.RegionOffsetX = region.offsetX;
attachment.RegionOffsetY = region.offsetY;
attachment.RegionWidth = region.width;
attachment.RegionHeight = region.height;
attachment.RegionOriginalWidth = region.originalWidth;
attachment.RegionOriginalHeight = region.originalHeight;
if (updateUVs) attachment.UpdateUVs();
}
#endregion
#region Runtime RegionAttachments #region Runtime RegionAttachments
/// <summary> /// <summary>
/// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses a new AtlasPage with the Material provided./// </summary> /// Creates a RegionAttachment based on a sprite. This method creates a real, usable AtlasRegion. That AtlasRegion uses a new AtlasPage with the Material provided./// </summary>
@ -128,15 +76,7 @@ namespace Spine.Unity.AttachmentTools {
// (AtlasAttachmentLoader.cs) // (AtlasAttachmentLoader.cs)
var attachment = new RegionAttachment(attachmentName); var attachment = new RegionAttachment(attachmentName);
attachment.RendererObject = region; attachment.Region = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment.RegionOffsetX = region.offsetX;
attachment.RegionOffsetY = region.offsetY;
attachment.RegionWidth = region.width;
attachment.RegionHeight = region.height;
attachment.RegionOriginalWidth = region.originalWidth;
attachment.RegionOriginalHeight = region.originalHeight;
attachment.Path = region.name; attachment.Path = region.name;
attachment.ScaleX = 1; attachment.ScaleX = 1;
attachment.ScaleY = 1; attachment.ScaleY = 1;
@ -148,11 +88,15 @@ namespace Spine.Unity.AttachmentTools {
attachment.A = 1; attachment.A = 1;
// pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation. // pass OriginalWidth and OriginalHeight because UpdateOffset uses it in its calculation.
attachment.Width = attachment.RegionOriginalWidth * scale; var textreRegion = attachment.Region;
attachment.Height = attachment.RegionOriginalHeight * scale; var atlasRegion = textreRegion as AtlasRegion;
float originalWidth = atlasRegion != null ? atlasRegion.originalWidth : textreRegion.width;
float originalHeight = atlasRegion != null ? atlasRegion.originalHeight : textreRegion.height;
attachment.Width = originalWidth * scale;
attachment.Height = originalHeight * scale;
attachment.SetColor(Color.white); attachment.SetColor(Color.white);
attachment.UpdateOffset(); attachment.UpdateRegion();
return attachment; return attachment;
} }

View File

@ -209,9 +209,9 @@ namespace Spine.Unity {
#region Attachments #region Attachments
public static Material GetMaterial (this Attachment a) { public static Material GetMaterial (this Attachment a) {
object rendererObject = null; object rendererObject = null;
var renderableAttachment = a as IHasRendererObject; var renderableAttachment = a as IHasTextureRegion;
if (renderableAttachment != null) if (renderableAttachment != null)
rendererObject = renderableAttachment.RendererObject; rendererObject = renderableAttachment.Region;
if (rendererObject == null) if (rendererObject == null)
return null; return null;

Some files were not shown because too many files have changed in this diff Show More