[csharp] Matching and cleanup. 1 of 2

This commit is contained in:
pharan 2017-02-24 16:56:35 +08:00
parent 29b1f5f192
commit 2c92a4689b
22 changed files with 279 additions and 131 deletions

View File

@ -32,13 +32,18 @@ using System;
using System.Collections.Generic;
namespace Spine {
/// <summary>Stores mix (crossfade) durations to be applied when AnimationState animations are changed.</summary>
public class AnimationStateData {
internal SkeletonData skeletonData;
readonly Dictionary<AnimationPair, float> animationToMixTime = new Dictionary<AnimationPair, float>(AnimationPairComparer.Instance);
internal float defaultMix;
/// <summary>The SkeletonData to look up animations when they are specified by name.</summary>
public SkeletonData SkeletonData { get { return skeletonData; } }
/// <summary>
/// The mix duration to use when no mix duration has been specifically defined between two animations.</summary>
public float DefaultMix { get { return defaultMix; } set { defaultMix = value; } }
public AnimationStateData (SkeletonData skeletonData) {
@ -46,7 +51,8 @@ namespace Spine {
this.skeletonData = skeletonData;
}
public void SetMix (String fromName, String toName, float duration) {
/// <summary>Sets a mix duration by animation names.</summary>
public void SetMix (string fromName, string toName, float duration) {
Animation from = skeletonData.FindAnimation(fromName);
if (from == null) throw new ArgumentException("Animation not found: " + fromName);
Animation to = skeletonData.FindAnimation(toName);
@ -54,6 +60,8 @@ namespace Spine {
SetMix(from, to, duration);
}
/// <summary>Sets a mix duration when changing from the specified animation to the other.
/// See TrackEntry.MixDuration.</summary>
public void SetMix (Animation from, Animation to, float duration) {
if (from == null) throw new ArgumentNullException("from", "from cannot be null.");
if (to == null) throw new ArgumentNullException("to", "to cannot be null.");
@ -62,6 +70,10 @@ namespace Spine {
animationToMixTime.Add(key, duration);
}
/// <summary>
/// The mix duration to use when changing from the specified animation to the other,
/// or the DefaultMix if no mix duration has been set.
/// </summary>
public float GetMix (Animation from, Animation to) {
if (from == null) throw new ArgumentNullException("from", "from cannot be null.");
if (to == null) throw new ArgumentNullException("to", "to cannot be null.");

View File

@ -31,6 +31,11 @@
using System;
namespace Spine {
/// <summary>
/// An AttachmentLoader that configures attachments using texture regions from an Atlas.
/// See <a href='http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data'>Loading Skeleton Data</a> in the Spine Runtimes Guide.
/// </summary>
public class AtlasAttachmentLoader : AttachmentLoader {
private Atlas[] atlasArray;
@ -41,7 +46,7 @@ namespace Spine {
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
AtlasRegion region = FindRegion(path);
if (region == null) throw new Exception("Region not found in atlas: " + path + " (region attachment: " + name + ")");
if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
RegionAttachment attachment = new RegionAttachment(name);
attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
@ -56,7 +61,7 @@ namespace Spine {
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
AtlasRegion region = FindRegion(path);
if (region == null) throw new Exception("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
if (region == null) throw new ArgumentException(string.Format("Region not found in atlas: {0} (region attachment: {1})", path, name));
MeshAttachment attachment = new MeshAttachment(name);
attachment.RendererObject = region;
attachment.RegionU = region.u;

View File

@ -32,14 +32,14 @@ using System;
namespace Spine {
abstract public class Attachment {
public String Name { get; private set; }
public string Name { get; private set; }
public Attachment (String name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null");
Name = name;
}
override public String ToString () {
override public string ToString () {
return Name;
}
}

View File

@ -28,15 +28,13 @@
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
public interface AttachmentLoader {
/// <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);
/// <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);
/// <return>May be null to not load any attachment.</return>
BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name);

View File

@ -34,11 +34,11 @@ namespace Spine {
/// <summary>Attachment that displays a texture region using a mesh.</summary>
public class MeshAttachment : VertexAttachment {
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
private MeshAttachment parentMesh;
internal float[] uvs, regionUVs;
internal int[] triangles;
internal float r = 1, g = 1, b = 1, a = 1;
internal int hulllength;
internal MeshAttachment parentMesh;
internal bool inheritDeform;
public int HullLength { get { return hulllength; } set { hulllength = value; } }

View File

@ -33,14 +33,14 @@ using System;
namespace Spine {
/// <summary>Attachment that displays a texture region.</summary>
public class RegionAttachment : Attachment {
public const int X1 = 0;
public const int Y1 = 1;
public const int X2 = 2;
public const int Y2 = 3;
public const int X3 = 4;
public const int Y3 = 5;
public const int X4 = 6;
public const int Y4 = 7;
public const int BLX = 0;
public const int BLY = 1;
public const int ULX = 2;
public const int ULY = 3;
public const int URX = 4;
public const int URY = 5;
public const int BRX = 6;
public const int BRY = 7;
internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
@ -60,8 +60,8 @@ namespace Spine {
public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } }
public String Path { get; set; }
public Object RendererObject { get; set; }
public string Path { get; set; }
public object RendererObject { 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; } }
@ -79,23 +79,23 @@ namespace Spine {
public void SetUVs (float u, float v, float u2, float v2, bool rotate) {
float[] uvs = this.uvs;
if (rotate) {
uvs[X2] = u;
uvs[Y2] = v2;
uvs[X3] = u;
uvs[Y3] = v;
uvs[X4] = u2;
uvs[Y4] = v;
uvs[X1] = u2;
uvs[Y1] = v2;
uvs[ULX] = u;
uvs[ULY] = v2;
uvs[URX] = u;
uvs[URY] = v;
uvs[BRX] = u2;
uvs[BRY] = v;
uvs[BLX] = u2;
uvs[BLY] = v2;
} else {
uvs[X1] = u;
uvs[Y1] = v2;
uvs[X2] = u;
uvs[Y2] = v;
uvs[X3] = u2;
uvs[Y3] = v;
uvs[X4] = u2;
uvs[Y4] = v2;
uvs[BLX] = u;
uvs[BLY] = v2;
uvs[ULX] = u;
uvs[ULY] = v;
uvs[URX] = u2;
uvs[URY] = v;
uvs[BRX] = u2;
uvs[BRY] = v2;
}
}
@ -124,28 +124,64 @@ namespace Spine {
float localY2Cos = localY2 * cos + y;
float localY2Sin = localY2 * sin;
float[] offset = this.offset;
offset[X1] = localXCos - localYSin;
offset[Y1] = localYCos + localXSin;
offset[X2] = localXCos - localY2Sin;
offset[Y2] = localY2Cos + localXSin;
offset[X3] = localX2Cos - localY2Sin;
offset[Y3] = localY2Cos + localX2Sin;
offset[X4] = localX2Cos - localYSin;
offset[Y4] = localYCos + localX2Sin;
offset[BLX] = localXCos - localYSin;
offset[BLY] = localYCos + localXSin;
offset[ULX] = localXCos - localY2Sin;
offset[ULY] = localY2Cos + localXSin;
offset[URX] = localX2Cos - localY2Sin;
offset[URY] = localY2Cos + localX2Sin;
offset[BRX] = localX2Cos - localYSin;
offset[BRY] = localYCos + localX2Sin;
}
public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
float x = bone.worldX, y = bone.worldY;
// [Obsolete("Please use the new ComputeWorldVertices that requires offset and stride parameters introduced in 3.6")]
// public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
// float x = bone.worldX, y = bone.worldY;
// float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
// float[] offset = this.offset;
// worldVertices[BLX] = offset[BLX] * a + offset[BLY] * b + x;
// worldVertices[BLY] = offset[BLX] * c + offset[BLY] * d + y;
// worldVertices[ULX] = offset[ULX] * a + offset[ULY] * b + x;
// worldVertices[ULY] = offset[ULX] * c + offset[ULY] * d + y;
// worldVertices[URX] = offset[URX] * a + offset[URY] * b + x;
// worldVertices[URY] = offset[URX] * c + offset[URY] * d + y;
// worldVertices[BRX] = offset[BRX] * a + offset[BRY] * b + x;
// worldVertices[BRY] = offset[BRX] * c + offset[BRY] * d + y;
// }
/// <summary>Transforms the attachment's four vertices to world coordinates.</summary>
/// <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="offset">The worldVertices index to begin writing values.</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) {
float[] vertexOffset = this.offset;
float bwx = bone.worldX, bwy = bone.worldY;
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
float[] offset = this.offset;
worldVertices[X1] = offset[X1] * a + offset[Y1] * b + x;
worldVertices[Y1] = offset[X1] * c + offset[Y1] * d + y;
worldVertices[X2] = offset[X2] * a + offset[Y2] * b + x;
worldVertices[Y2] = offset[X2] * c + offset[Y2] * d + y;
worldVertices[X3] = offset[X3] * a + offset[Y3] * b + x;
worldVertices[Y3] = offset[X3] * c + offset[Y3] * d + y;
worldVertices[X4] = offset[X4] * a + offset[Y4] * b + x;
worldVertices[Y4] = offset[X4] * c + offset[Y4] * d + y;
float offsetX, offsetY;
offsetX = vertexOffset[BRX];
offsetY = vertexOffset[BRY];
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
offset += stride;
offsetX = vertexOffset[BLX];
offsetY = vertexOffset[BLY];
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
offset += stride;
offsetX = vertexOffset[ULX];
offsetY = vertexOffset[ULY];
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
offset += stride;
offsetX = vertexOffset[URX];
offsetY = vertexOffset[URY];
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
}
}
}

View File

@ -29,7 +29,6 @@
*****************************************************************************/
using System;
using System.Collections.Generic;
namespace Spine {
/// <summary>>An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices.</summary>
@ -57,7 +56,7 @@ namespace Spine {
/// <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>
public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
count += offset;
count = offset + (count >> 1) * stride;
Skeleton skeleton = slot.Skeleton;
var deformArray = slot.attachmentVertices;
float[] vertices = this.vertices;
@ -80,7 +79,7 @@ namespace Spine {
v += n + 1;
skip += n;
}
Bone[] skeletonBones = skeleton.Bones.Items;
var skeletonBones = skeleton.bones.Items;
if (deformArray.Count == 0) {
for (int w = offset, b = skip * 3; w < count; w += stride) {
float wx = 0, wy = 0;

View File

@ -30,6 +30,6 @@
namespace Spine {
public enum BlendMode {
normal, additive, multiply, screen
Normal, Additive, Multiply, Screen
}
}

View File

@ -31,6 +31,7 @@
using System;
namespace Spine {
/// <summary>Stores the current pose values for an Event.</summary>
public class Event {
internal readonly EventData data;
internal readonly float time;
@ -39,10 +40,12 @@ namespace Spine {
internal string stringValue;
public EventData Data { get { return data; } }
/// <summary>The animation time this event was keyed.</summary>
public float Time { get { return time; } }
public int Int { get { return intValue; } set { intValue = value; } }
public float Float { get { return floatValue; } set { floatValue = value; } }
public String String { get { return stringValue; } set { stringValue = value; } }
public string String { get { return stringValue; } set { stringValue = value; } }
public Event (float time, EventData data) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null.");

View File

@ -31,20 +31,22 @@
using System;
namespace Spine {
/// <summary>Stores the setup pose values for an Event.</summary>
public class EventData {
internal String name;
internal string name;
public String Name { get { return name; } }
/// <summary>The name of the event, which is unique within the skeleton.</summary>
public string Name { get { return name; } }
public int Int { get; set; }
public float Float { get; set; }
public String String { get; set; }
public string String { get; set; }
public EventData (String name) {
public EventData (string name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
this.name = name;
}
override public String ToString () {
override public string ToString () {
return Name;
}
}

View File

@ -1,5 +1,40 @@
namespace Spine {
/******************************************************************************
* Spine Runtimes Software License v2.5
*
* Copyright (c) 2013-2016, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable, and
* non-transferable license to use, install, execute, and perform the Spine
* Runtimes software and derivative works solely for personal or internal
* use. Without the written permission of Esoteric Software (see Section 2 of
* the Spine Software License Agreement), you may not (a) modify, translate,
* adapt, or develop new applications using the Spine Runtimes or otherwise
* create derivative works or improvements of the Spine Runtimes or (b) remove,
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
* or other intellectual property or proprietary rights notices on or in the
* Software, including any copy thereof. Redistributions in binary or source
* form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
namespace Spine {
/// <summary>The interface for all constraints.</summary>
public interface IConstraint : IUpdatable {
/// <summary>The ordinal for the order a skeleton's constraints will be applied.</summary>
int Order { get; }
}
}

View File

@ -28,8 +28,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
namespace Spine {
public interface IUpdatable {
void Update ();

View File

@ -58,11 +58,12 @@ namespace Spine {
target = skeleton.FindBone(data.target.name);
}
public void Update () {
Apply();
/// <summary>Applies the constraint to the constrained bones.</summary>
public void Apply () {
Update();
}
public void Apply () {
public void Update () {
Bone target = this.target;
ExposedList<Bone> bones = this.bones;
switch (bones.Count) {
@ -75,7 +76,7 @@ namespace Spine {
}
}
override public String ToString () {
override public string ToString () {
return data.name;
}

View File

@ -32,27 +32,50 @@ using System;
using System.Collections.Generic;
namespace Spine {
/// <summary>Stores the setup pose for an IkConstraint.</summary>
public class IkConstraintData {
internal String name;
internal string name;
internal int order;
internal List<BoneData> bones = new List<BoneData>();
internal BoneData target;
internal int bendDirection = 1;
internal float mix = 1;
public String Name { get { return name; } }
public int Order { get { return order; } set { order = value; } }
public List<BoneData> Bones { get { return bones; } }
public BoneData Target { get { return target; } set { target = value; } }
public int BendDirection { get { return bendDirection; } set { bendDirection = value; } }
/// <summary>The IK constraint's name, which is unique within the skeleton.</summary>
public string Name {
get { return name; }
}
public int Order {
get { return order; }
set { order = value; }
}
/// <summary>The bones that are constrained by this IK Constraint.</summary>
public List<BoneData> Bones {
get { return bones; }
}
/// <summary>The bone that is the IK target.</summary>
public BoneData Target {
get { return target; }
set { target = value; }
}
/// <summary>Controls the bend direction of the IK bones, either 1 or -1.</summary>
public int BendDirection {
get { return bendDirection; }
set { bendDirection = value; }
}
public float Mix { get { return mix; } set { mix = value; } }
public IkConstraintData (String name) {
public IkConstraintData (string name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
this.name = name;
}
override public String ToString () {
override public string ToString () {
return name;
}
}

View File

@ -32,7 +32,7 @@ using System;
namespace Spine {
public class PathConstraint : IConstraint {
private const int NONE = -1, BEFORE = -2, AFTER = -3;
const int NONE = -1, BEFORE = -2, AFTER = -3;
internal PathConstraintData data;
internal ExposedList<Bone> bones;
@ -84,13 +84,13 @@ namespace Spine {
RotateMode rotateMode = data.rotateMode;
bool tangents = rotateMode == RotateMode.Tangent, scale = rotateMode == RotateMode.ChainScale;
int boneCount = this.bones.Count, spacesCount = tangents ? boneCount : boneCount + 1;
Bone[] bones = this.bones.Items;
Bone[] bonesItems = this.bones.Items;
ExposedList<float> spaces = this.spaces.Resize(spacesCount), lengths = null;
float spacing = this.spacing;
if (scale || lengthSpacing) {
if (scale) lengths = this.lengths.Resize(boneCount);
for (int i = 0, n = spacesCount - 1; i < n;) {
Bone bone = bones[i];
Bone bone = bonesItems[i];
float setupLength = bone.data.length, x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths.Items[i] = setupLength;
@ -113,7 +113,7 @@ namespace Spine {
offsetRotation *= p.a * p.d - p.b * p.c > 0 ? MathUtils.DegRad : -MathUtils.DegRad;
}
for (int i = 0, p = 3; i < boneCount; i++, p += 3) {
Bone bone = (Bone)bones[i];
Bone bone = bonesItems[i];
bone.worldX += (boneX - bone.worldX) * translateMix;
bone.worldY += (boneY - bone.worldY) * translateMix;
float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
@ -166,7 +166,7 @@ namespace Spine {
Slot target = this.target;
float position = this.position;
float[] spaces = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world;
float[] spacesItems = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world;
bool closed = path.Closed;
int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE;
@ -178,11 +178,11 @@ namespace Spine {
if (percentPosition) position *= pathLength;
if (percentSpacing) {
for (int i = 0; i < spacesCount; i++)
spaces[i] *= pathLength;
spacesItems[i] *= pathLength;
}
world = this.world.Resize(8).Items;
for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
float space = spaces[i];
float space = spacesItems[i];
position += space;
float p = position;
@ -286,13 +286,13 @@ namespace Spine {
if (percentPosition) position *= pathLength;
if (percentSpacing) {
for (int i = 0; i < spacesCount; i++)
spaces[i] *= pathLength;
spacesItems[i] *= pathLength;
}
float[] segments = this.segments;
float curveLength = 0;
for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
float space = spaces[i];
float space = spacesItems[i];
position += space;
float p = position;
@ -380,21 +380,21 @@ namespace Spine {
return output;
}
private void AddBeforePosition (float p, float[] temp, int i, float[] output, int o) {
static void AddBeforePosition (float p, float[] temp, int i, float[] output, int o) {
float x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = MathUtils.Atan2(dy, dx);
output[o] = x1 + p * MathUtils.Cos(r);
output[o + 1] = y1 + p * MathUtils.Sin(r);
output[o + 2] = r;
}
private void AddAfterPosition (float p, float[] temp, int i, float[] output, int o) {
static void AddAfterPosition (float p, float[] temp, int i, float[] output, int o) {
float x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = MathUtils.Atan2(dy, dx);
output[o] = x1 + p * MathUtils.Cos(r);
output[o + 1] = y1 + p * MathUtils.Sin(r);
output[o + 2] = r;
}
private void AddCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
static void AddCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
float[] output, int o, bool tangents) {
if (p == 0 || float.IsNaN(p)) p = 0.0001f;
float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;

View File

@ -31,6 +31,11 @@
using System;
namespace Spine {
/// <summary>
/// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon.
/// The polygon vertices are provided along with convenience methods for doing hit detection.
/// </summary>
public class SkeletonBounds {
private ExposedList<Polygon> polygonPool = new ExposedList<Polygon>();
private float minX, minY, maxX, maxY;
@ -49,6 +54,14 @@ namespace Spine {
Polygons = new ExposedList<Polygon>();
}
/// <summary>
/// Clears any previous polygons, finds all visible bounding box attachments,
/// and computes the world vertices for each bounding box's polygon.</summary>
/// <param name="skeleton">The skeleton.</param>
/// <param name="updateAabb">
/// If true, the axis aligned bounding box containing all the polygons is computed.
/// If false, the SkeletonBounds AABB methods will always return true.
/// </param>
public void Update (Skeleton skeleton, bool updateAabb) {
ExposedList<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
ExposedList<Polygon> polygons = Polygons;
@ -75,7 +88,7 @@ namespace Spine {
polygon = new Polygon();
polygons.Add(polygon);
int count = boundingBox.Vertices.Length;
int count = boundingBox.worldVerticesLength;
polygon.Count = count;
if (polygon.Vertices.Length < count) polygon.Vertices = new float[count];
boundingBox.ComputeWorldVertices(slot, polygon.Vertices);

View File

@ -31,10 +31,12 @@
using System;
namespace Spine {
/// <summary>Stores the setup pose and all of the stateless data for a skeleton.</summary>
public class SkeletonData {
internal string name;
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
internal ExposedList<SlotData> slots = new ExposedList<SlotData>();
internal ExposedList<BoneData> bones = new ExposedList<BoneData>(); // Ordered parents first
internal ExposedList<SlotData> slots = new ExposedList<SlotData>(); // Setup pose draw order.
internal ExposedList<Skin> skins = new ExposedList<Skin>();
internal Skin defaultSkin;
internal ExposedList<EventData> events = new ExposedList<EventData>();
@ -49,12 +51,23 @@ namespace Spine {
internal float fps;
internal string imagesPath;
public String Name { get { return name; } set { name = value; } }
public ExposedList<BoneData> Bones { get { return bones; } } // Ordered parents first.
public ExposedList<SlotData> Slots { get { return slots; } } // Setup pose draw order.
public string Name { get { return name; } set { name = value; } }
/// <summary>The skeleton's bones, sorted parent first. The root bone is always the first bone.</summary>
public ExposedList<BoneData> Bones { get { return bones; } }
public ExposedList<SlotData> Slots { get { return slots; } }
/// <summary>All skins, including the default skin.</summary>
public ExposedList<Skin> Skins { get { return skins; } set { skins = value; } }
/// <summary>May be null.</summary>
/// <summary>
/// The skeleton's default skin.
/// By default this skin contains all attachments that were not in a skin in Spine.
/// </summary>
/// <return>May be null.</return>
public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } }
public ExposedList<EventData> Events { get { return events; } set { events = value; } }
public ExposedList<Animation> Animations { get { return animations; } set { animations = value; } }
public ExposedList<IkConstraintData> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
@ -67,34 +80,42 @@ namespace Spine {
public string Version { get { return version; } set { version = value; } }
public string Hash { get { return hash; } set { hash = value; } }
public string ImagesPath { get { return imagesPath; } set { imagesPath = value; } }
/// <summary>
/// The dopesheet FPS in Spine. Available only when nonessential data was exported.</summary>
public float Fps { get { return fps; } set { fps = value; } }
// --- Bones.
/// <summary>
/// Finds a bone by comparing each bone'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 BoneData FindBone (String boneName) {
public BoneData FindBone (string boneName) {
if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null.");
ExposedList<BoneData> bones = this.bones;
var bones = this.bones;
var bonesItems = bones.Items;
for (int i = 0, n = bones.Count; i < n; i++) {
BoneData bone = bones.Items[i];
BoneData bone = bonesItems[i];
if (bone.name == boneName) return bone;
}
return null;
}
/// <returns>-1 if the bone was not found.</returns>
public int FindBoneIndex (String boneName) {
public int FindBoneIndex (string boneName) {
if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null.");
ExposedList<BoneData> bones = this.bones;
var bones = this.bones;
var bonesItems = bones.Items;
for (int i = 0, n = bones.Count; i < n; i++)
if (bones.Items[i].name == boneName) return i;
if (bonesItems[i].name == boneName) return i;
return -1;
}
// --- Slots.
/// <returns>May be null.</returns>
public SlotData FindSlot (String slotName) {
public SlotData FindSlot (string slotName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
ExposedList<SlotData> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) {
@ -105,7 +126,7 @@ namespace Spine {
}
/// <returns>-1 if the slot was not found.</returns>
public int FindSlotIndex (String slotName) {
public int FindSlotIndex (string slotName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
ExposedList<SlotData> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++)
@ -116,7 +137,7 @@ namespace Spine {
// --- Skins.
/// <returns>May be null.</returns>
public Skin FindSkin (String skinName) {
public Skin FindSkin (string skinName) {
if (skinName == null) throw new ArgumentNullException("skinName", "skinName cannot be null.");
foreach (Skin skin in skins)
if (skin.name == skinName) return skin;
@ -126,7 +147,7 @@ namespace Spine {
// --- Events.
/// <returns>May be null.</returns>
public EventData FindEvent (String eventDataName) {
public EventData FindEvent (string eventDataName) {
if (eventDataName == null) throw new ArgumentNullException("eventDataName", "eventDataName cannot be null.");
foreach (EventData eventData in events)
if (eventData.name == eventDataName) return eventData;
@ -136,7 +157,7 @@ namespace Spine {
// --- Animations.
/// <returns>May be null.</returns>
public Animation FindAnimation (String animationName) {
public Animation FindAnimation (string animationName) {
if (animationName == null) throw new ArgumentNullException("animationName", "animationName cannot be null.");
ExposedList<Animation> animations = this.animations;
for (int i = 0, n = animations.Count; i < n; i++) {
@ -149,7 +170,7 @@ namespace Spine {
// --- IK constraints.
/// <returns>May be null.</returns>
public IkConstraintData FindIkConstraint (String constraintName) {
public IkConstraintData FindIkConstraint (string constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
ExposedList<IkConstraintData> ikConstraints = this.ikConstraints;
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
@ -162,7 +183,7 @@ namespace Spine {
// --- Transform constraints.
/// <returns>May be null.</returns>
public TransformConstraintData FindTransformConstraint (String constraintName) {
public TransformConstraintData FindTransformConstraint (string constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
ExposedList<TransformConstraintData> transformConstraints = this.transformConstraints;
for (int i = 0, n = transformConstraints.Count; i < n; i++) {
@ -175,7 +196,7 @@ namespace Spine {
// --- Path constraints.
/// <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.");
ExposedList<PathConstraintData> pathConstraints = this.pathConstraints;
for (int i = 0, n = pathConstraints.Count; i < n; i++) {
@ -186,7 +207,7 @@ namespace Spine {
}
/// <returns>-1 if the path constraint was not found.</returns>
public int FindPathConstraintIndex (String pathConstraintName) {
public int FindPathConstraintIndex (string pathConstraintName) {
if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null.");
ExposedList<PathConstraintData> pathConstraints = this.pathConstraints;
for (int i = 0, n = pathConstraints.Count; i < n; i++)
@ -196,7 +217,7 @@ namespace Spine {
// ---
override public String ToString () {
override public string ToString () {
return name ?? base.ToString();
}
}

View File

@ -157,9 +157,9 @@ namespace Spine {
data.attachmentName = GetString(slotMap, "attachment", null);
if (slotMap.ContainsKey("blend"))
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false);
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], true);
else
data.blendMode = BlendMode.normal;
data.blendMode = BlendMode.Normal;
skeletonData.slots.Add(data);
}
}

View File

@ -93,7 +93,7 @@ namespace Spine {
}
}
override public String ToString () {
override public string ToString () {
return data.name;
}
}

View File

@ -67,7 +67,7 @@ namespace Spine {
this.boneData = boneData;
}
override public String ToString () {
override public string ToString () {
return name;
}
}

View File

@ -116,10 +116,12 @@ namespace Spine {
if (scaleMix > 0) {
float s = (float)Math.Sqrt(bone.a * bone.a + bone.c * bone.c);
//float ts = (float)Math.sqrt(ta * ta + tc * tc);
if (s > 0.00001f) s = (s + ((float)Math.Sqrt(ta * ta + tc * tc) - s + data.offsetScaleX) * scaleMix) / s;
bone.a *= s;
bone.c *= s;
s = (float)Math.Sqrt(bone.b * bone.b + bone.d * bone.d);
//ts = (float)Math.Sqrt(tb * tb + td * td);
if (s > 0.00001f) s = (s + ((float)Math.Sqrt(tb * tb + td * td) - s + data.offsetScaleY) * scaleMix) / s;
bone.b *= s;
bone.d *= s;
@ -209,9 +211,9 @@ namespace Spine {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
if (!target.appliedValid) target.UpdateAppliedTransform();
var bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bones.Items[i];
var bonesItems = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++) {
Bone bone = bonesItems[i];
if (!bone.appliedValid) bone.UpdateAppliedTransform();
float rotation = bone.arotation;
@ -248,9 +250,9 @@ namespace Spine {
float rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix;
Bone target = this.target;
if (!target.appliedValid) target.UpdateAppliedTransform();
var bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bones.Items[i];
var bonesItems = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++) {
Bone bone = bonesItems[i];
if (!bone.appliedValid) bone.UpdateAppliedTransform();
float rotation = bone.arotation;
@ -275,7 +277,7 @@ namespace Spine {
}
}
override public String ToString () {
override public string ToString () {
return data.name;
}
}

View File

@ -32,7 +32,7 @@ using System;
namespace Spine {
public class TransformConstraintData {
internal String name;
internal string name;
internal int order;
internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
internal BoneData target;
@ -40,7 +40,7 @@ namespace Spine {
internal float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
internal bool relative, local;
public String Name { get { return name; } }
public string Name { get { return name; } }
public int Order { get { return order; } set { order = value; } }
public ExposedList<BoneData> Bones { get { return bones; } }
public BoneData Target { get { return target; } set { target = value; } }
@ -59,12 +59,12 @@ namespace Spine {
public bool Relative { get { return relative; } set { relative = value; } }
public bool Local { get { return local; } set { local = value; } }
public TransformConstraintData (String name) {
public TransformConstraintData (string name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
this.name = name;
}
override public String ToString () {
override public string ToString () {
return name;
}
}