mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-10 00:58:43 +08:00
[csharp] Matching and cleanup. 1 of 2
This commit is contained in:
parent
29b1f5f192
commit
2c92a4689b
@ -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.");
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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; } }
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -30,6 +30,6 @@
|
||||
|
||||
namespace Spine {
|
||||
public enum BlendMode {
|
||||
normal, additive, multiply, screen
|
||||
Normal, Additive, Multiply, Screen
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -28,8 +28,6 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
public interface IUpdatable {
|
||||
void Update ();
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ namespace Spine {
|
||||
}
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
override public string ToString () {
|
||||
return data.name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ namespace Spine {
|
||||
this.boneData = boneData;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
override public string ToString () {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user