diff --git a/spine-csharp/src/AnimationStateData.cs b/spine-csharp/src/AnimationStateData.cs index 77250d4f7..5282d894c 100644 --- a/spine-csharp/src/AnimationStateData.cs +++ b/spine-csharp/src/AnimationStateData.cs @@ -32,13 +32,18 @@ using System; using System.Collections.Generic; namespace Spine { + + /// Stores mix (crossfade) durations to be applied when AnimationState animations are changed. public class AnimationStateData { internal SkeletonData skeletonData; - readonly Dictionary animationToMixTime = new Dictionary(AnimationPairComparer.Instance); internal float defaultMix; + /// The SkeletonData to look up animations when they are specified by name. public SkeletonData SkeletonData { get { return skeletonData; } } + + /// + /// The mix duration to use when no mix duration has been specifically defined between two animations. 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) { + /// Sets a mix duration by animation names. + 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); } + /// Sets a mix duration when changing from the specified animation to the other. + /// See TrackEntry.MixDuration. 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); } + /// + /// The mix duration to use when changing from the specified animation to the other, + /// or the DefaultMix if no mix duration has been set. + /// 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."); diff --git a/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs b/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs index 0fbebe13b..c96d05f5c 100644 --- a/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs +++ b/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs @@ -31,6 +31,11 @@ using System; namespace Spine { + + /// + /// An AttachmentLoader that configures attachments using texture regions from an Atlas. + /// See Loading Skeleton Data in the Spine Runtimes Guide. + /// 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; diff --git a/spine-csharp/src/Attachments/Attachment.cs b/spine-csharp/src/Attachments/Attachment.cs index defd71380..7f033187a 100644 --- a/spine-csharp/src/Attachments/Attachment.cs +++ b/spine-csharp/src/Attachments/Attachment.cs @@ -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; } } diff --git a/spine-csharp/src/Attachments/AttachmentLoader.cs b/spine-csharp/src/Attachments/AttachmentLoader.cs index d1695c4c9..8917dc626 100644 --- a/spine-csharp/src/Attachments/AttachmentLoader.cs +++ b/spine-csharp/src/Attachments/AttachmentLoader.cs @@ -28,15 +28,13 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -using System; - namespace Spine { public interface AttachmentLoader { /// May be null to not load any attachment. - RegionAttachment NewRegionAttachment (Skin skin, String name, string path); + RegionAttachment NewRegionAttachment (Skin skin, string name, string path); /// May be null to not load any attachment. - MeshAttachment NewMeshAttachment (Skin skin, String name, string path); + MeshAttachment NewMeshAttachment (Skin skin, string name, string path); /// May be null to not load any attachment. BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name); diff --git a/spine-csharp/src/Attachments/MeshAttachment.cs b/spine-csharp/src/Attachments/MeshAttachment.cs index 301fc1699..5d1ba4a34 100644 --- a/spine-csharp/src/Attachments/MeshAttachment.cs +++ b/spine-csharp/src/Attachments/MeshAttachment.cs @@ -34,11 +34,11 @@ namespace Spine { /// Attachment that displays a texture region using a mesh. 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; } } diff --git a/spine-csharp/src/Attachments/RegionAttachment.cs b/spine-csharp/src/Attachments/RegionAttachment.cs index 145ce486f..71b50a0c2 100644 --- a/spine-csharp/src/Attachments/RegionAttachment.cs +++ b/spine-csharp/src/Attachments/RegionAttachment.cs @@ -33,14 +33,14 @@ using System; namespace Spine { /// Attachment that displays a texture region. 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; +// } + + /// Transforms the attachment's four vertices to world coordinates. + /// The parent bone. + /// The output world vertices. Must have a length greater than or equal to offset + 8. + /// The worldVertices index to begin writing values. + /// The number of worldVertices entries between the value pairs written. + 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; } } } diff --git a/spine-csharp/src/Attachments/VertexAttachment.cs b/spine-csharp/src/Attachments/VertexAttachment.cs index ff20b04c8..1ffa33137 100644 --- a/spine-csharp/src/Attachments/VertexAttachment.cs +++ b/spine-csharp/src/Attachments/VertexAttachment.cs @@ -29,7 +29,6 @@ *****************************************************************************/ using System; -using System.Collections.Generic; namespace Spine { /// >An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices. @@ -57,7 +56,7 @@ namespace Spine { /// The index to begin writing values. /// The number of entries between the value pairs written. 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; diff --git a/spine-csharp/src/BlendMode.cs b/spine-csharp/src/BlendMode.cs index ae0c33761..2e933c33f 100644 --- a/spine-csharp/src/BlendMode.cs +++ b/spine-csharp/src/BlendMode.cs @@ -30,6 +30,6 @@ namespace Spine { public enum BlendMode { - normal, additive, multiply, screen + Normal, Additive, Multiply, Screen } } diff --git a/spine-csharp/src/Event.cs b/spine-csharp/src/Event.cs index 9d1df7497..a2478db28 100644 --- a/spine-csharp/src/Event.cs +++ b/spine-csharp/src/Event.cs @@ -31,6 +31,7 @@ using System; namespace Spine { + /// Stores the current pose values for an Event. 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; } } + /// The animation time this event was keyed. 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."); diff --git a/spine-csharp/src/EventData.cs b/spine-csharp/src/EventData.cs index 298e4a814..522cfe8a6 100644 --- a/spine-csharp/src/EventData.cs +++ b/spine-csharp/src/EventData.cs @@ -31,20 +31,22 @@ using System; namespace Spine { + /// Stores the setup pose values for an Event. public class EventData { - internal String name; + internal string name; - public String Name { get { return name; } } + /// The name of the event, which is unique within the skeleton. + 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; } } diff --git a/spine-csharp/src/IConstraint.cs b/spine-csharp/src/IConstraint.cs index 25f375049..445d0772e 100644 --- a/spine-csharp/src/IConstraint.cs +++ b/spine-csharp/src/IConstraint.cs @@ -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 { + + /// The interface for all constraints. public interface IConstraint : IUpdatable { + /// The ordinal for the order a skeleton's constraints will be applied. int Order { get; } + } + } \ No newline at end of file diff --git a/spine-csharp/src/IUpdatable.cs b/spine-csharp/src/IUpdatable.cs index a3d214b9c..8de974c00 100644 --- a/spine-csharp/src/IUpdatable.cs +++ b/spine-csharp/src/IUpdatable.cs @@ -28,8 +28,6 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -using System; - namespace Spine { public interface IUpdatable { void Update (); diff --git a/spine-csharp/src/IkConstraint.cs b/spine-csharp/src/IkConstraint.cs index a9822bfb6..c5ef77ea5 100644 --- a/spine-csharp/src/IkConstraint.cs +++ b/spine-csharp/src/IkConstraint.cs @@ -58,11 +58,12 @@ namespace Spine { target = skeleton.FindBone(data.target.name); } - public void Update () { - Apply(); + /// Applies the constraint to the constrained bones. + public void Apply () { + Update(); } - public void Apply () { + public void Update () { Bone target = this.target; ExposedList bones = this.bones; switch (bones.Count) { @@ -75,7 +76,7 @@ namespace Spine { } } - override public String ToString () { + override public string ToString () { return data.name; } diff --git a/spine-csharp/src/IkConstraintData.cs b/spine-csharp/src/IkConstraintData.cs index 52ae64664..b0b0cf0ce 100644 --- a/spine-csharp/src/IkConstraintData.cs +++ b/spine-csharp/src/IkConstraintData.cs @@ -32,27 +32,50 @@ using System; using System.Collections.Generic; namespace Spine { + /// Stores the setup pose for an IkConstraint. public class IkConstraintData { - internal String name; + internal string name; internal int order; internal List bones = new List(); 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 Bones { get { return bones; } } - public BoneData Target { get { return target; } set { target = value; } } - public int BendDirection { get { return bendDirection; } set { bendDirection = value; } } + /// The IK constraint's name, which is unique within the skeleton. + public string Name { + get { return name; } + } + + public int Order { + get { return order; } + set { order = value; } + } + + /// The bones that are constrained by this IK Constraint. + public List Bones { + get { return bones; } + } + + /// The bone that is the IK target. + public BoneData Target { + get { return target; } + set { target = value; } + } + + /// Controls the bend direction of the IK bones, either 1 or -1. + 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; } } diff --git a/spine-csharp/src/PathConstraint.cs b/spine-csharp/src/PathConstraint.cs index 462e42b0c..d028fee16 100644 --- a/spine-csharp/src/PathConstraint.cs +++ b/spine-csharp/src/PathConstraint.cs @@ -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 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 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; diff --git a/spine-csharp/src/SkeletonBounds.cs b/spine-csharp/src/SkeletonBounds.cs index 261cacfa6..01bb829ab 100644 --- a/spine-csharp/src/SkeletonBounds.cs +++ b/spine-csharp/src/SkeletonBounds.cs @@ -31,6 +31,11 @@ using System; namespace Spine { + + /// + /// 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. + /// public class SkeletonBounds { private ExposedList polygonPool = new ExposedList(); private float minX, minY, maxX, maxY; @@ -49,6 +54,14 @@ namespace Spine { Polygons = new ExposedList(); } + /// + /// Clears any previous polygons, finds all visible bounding box attachments, + /// and computes the world vertices for each bounding box's polygon. + /// The skeleton. + /// + /// If true, the axis aligned bounding box containing all the polygons is computed. + /// If false, the SkeletonBounds AABB methods will always return true. + /// public void Update (Skeleton skeleton, bool updateAabb) { ExposedList boundingBoxes = BoundingBoxes; ExposedList 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); diff --git a/spine-csharp/src/SkeletonData.cs b/spine-csharp/src/SkeletonData.cs index 6ddb34f87..f9b451640 100644 --- a/spine-csharp/src/SkeletonData.cs +++ b/spine-csharp/src/SkeletonData.cs @@ -31,10 +31,12 @@ using System; namespace Spine { + + /// Stores the setup pose and all of the stateless data for a skeleton. public class SkeletonData { internal string name; - internal ExposedList bones = new ExposedList(); - internal ExposedList slots = new ExposedList(); + internal ExposedList bones = new ExposedList(); // Ordered parents first + internal ExposedList slots = new ExposedList(); // Setup pose draw order. internal ExposedList skins = new ExposedList(); internal Skin defaultSkin; internal ExposedList events = new ExposedList(); @@ -49,12 +51,23 @@ namespace Spine { internal float fps; internal string imagesPath; - public String Name { get { return name; } set { name = value; } } - public ExposedList Bones { get { return bones; } } // Ordered parents first. - public ExposedList Slots { get { return slots; } } // Setup pose draw order. + public string Name { get { return name; } set { name = value; } } + + /// The skeleton's bones, sorted parent first. The root bone is always the first bone. + public ExposedList Bones { get { return bones; } } + + public ExposedList Slots { get { return slots; } } + + /// All skins, including the default skin. public ExposedList Skins { get { return skins; } set { skins = value; } } - /// May be null. + + /// + /// The skeleton's default skin. + /// By default this skin contains all attachments that were not in a skin in Spine. + /// + /// May be null. public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } } + public ExposedList Events { get { return events; } set { events = value; } } public ExposedList Animations { get { return animations; } set { animations = value; } } public ExposedList 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; } } + + /// + /// The dopesheet FPS in Spine. Available only when nonessential data was exported. public float Fps { get { return fps; } set { fps = value; } } // --- Bones. + /// + /// 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. /// May be null. - public BoneData FindBone (String boneName) { + public BoneData FindBone (string boneName) { if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); - ExposedList 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; } /// -1 if the bone was not found. - public int FindBoneIndex (String boneName) { + public int FindBoneIndex (string boneName) { if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null."); - ExposedList 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. /// May be null. - public SlotData FindSlot (String slotName) { + public SlotData FindSlot (string slotName) { if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) { @@ -105,7 +126,7 @@ namespace Spine { } /// -1 if the slot was not found. - public int FindSlotIndex (String slotName) { + public int FindSlotIndex (string slotName) { if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); ExposedList slots = this.slots; for (int i = 0, n = slots.Count; i < n; i++) @@ -116,7 +137,7 @@ namespace Spine { // --- Skins. /// May be null. - 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. /// May be null. - 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. /// May be null. - public Animation FindAnimation (String animationName) { + public Animation FindAnimation (string animationName) { if (animationName == null) throw new ArgumentNullException("animationName", "animationName cannot be null."); ExposedList animations = this.animations; for (int i = 0, n = animations.Count; i < n; i++) { @@ -149,7 +170,7 @@ namespace Spine { // --- IK constraints. /// May be null. - public IkConstraintData FindIkConstraint (String constraintName) { + public IkConstraintData FindIkConstraint (string constraintName) { if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); ExposedList ikConstraints = this.ikConstraints; for (int i = 0, n = ikConstraints.Count; i < n; i++) { @@ -162,7 +183,7 @@ namespace Spine { // --- Transform constraints. /// May be null. - public TransformConstraintData FindTransformConstraint (String constraintName) { + public TransformConstraintData FindTransformConstraint (string constraintName) { if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); ExposedList transformConstraints = this.transformConstraints; for (int i = 0, n = transformConstraints.Count; i < n; i++) { @@ -175,7 +196,7 @@ namespace Spine { // --- Path constraints. /// May be null. - public PathConstraintData FindPathConstraint (String constraintName) { + public PathConstraintData FindPathConstraint (string constraintName) { if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); ExposedList pathConstraints = this.pathConstraints; for (int i = 0, n = pathConstraints.Count; i < n; i++) { @@ -186,7 +207,7 @@ namespace Spine { } /// -1 if the path constraint was not found. - public int FindPathConstraintIndex (String pathConstraintName) { + public int FindPathConstraintIndex (string pathConstraintName) { if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null."); ExposedList 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(); } } diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index c0b96c44b..43e091ddf 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -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); } } diff --git a/spine-csharp/src/Slot.cs b/spine-csharp/src/Slot.cs index c4cff8b0c..66357caff 100644 --- a/spine-csharp/src/Slot.cs +++ b/spine-csharp/src/Slot.cs @@ -93,7 +93,7 @@ namespace Spine { } } - override public String ToString () { + override public string ToString () { return data.name; } } diff --git a/spine-csharp/src/SlotData.cs b/spine-csharp/src/SlotData.cs index 10eb5102d..8cd34b087 100644 --- a/spine-csharp/src/SlotData.cs +++ b/spine-csharp/src/SlotData.cs @@ -67,7 +67,7 @@ namespace Spine { this.boneData = boneData; } - override public String ToString () { + override public string ToString () { return name; } } diff --git a/spine-csharp/src/TransformConstraint.cs b/spine-csharp/src/TransformConstraint.cs index 401778cf2..395bd26da 100644 --- a/spine-csharp/src/TransformConstraint.cs +++ b/spine-csharp/src/TransformConstraint.cs @@ -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; } } diff --git a/spine-csharp/src/TransformConstraintData.cs b/spine-csharp/src/TransformConstraintData.cs index 248cb4c58..8073c6249 100644 --- a/spine-csharp/src/TransformConstraintData.cs +++ b/spine-csharp/src/TransformConstraintData.cs @@ -32,7 +32,7 @@ using System; namespace Spine { public class TransformConstraintData { - internal String name; + internal string name; internal int order; internal ExposedList bones = new ExposedList(); 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 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; } }