mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
replaced List<T> with ExposedList<T> to avoid indexer overhead
This commit is contained in:
parent
67a639d12a
commit
9ae48c2aac
@ -233,7 +233,7 @@ namespace Spine {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
Bone bone = skeleton.bones.Items[boneIndex];
|
||||
|
||||
float amount;
|
||||
|
||||
@ -296,7 +296,7 @@ namespace Spine {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
Bone bone = skeleton.bones.Items[boneIndex];
|
||||
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
bone.x += (bone.data.x + frames[frames.Length - 2] - bone.x) * alpha;
|
||||
@ -326,7 +326,7 @@ namespace Spine {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
Bone bone = skeleton.bones.Items[boneIndex];
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
bone.scaleX += (bone.data.scaleX * frames[frames.Length - 2] - bone.scaleX) * alpha;
|
||||
bone.scaleY += (bone.data.scaleY * frames[frames.Length - 1] - bone.scaleY) * alpha;
|
||||
@ -402,7 +402,7 @@ namespace Spine {
|
||||
b = prevFrameB + (frames[frameIndex + FRAME_B] - prevFrameB) * percent;
|
||||
a = prevFrameA + (frames[frameIndex + FRAME_A] - prevFrameA) * percent;
|
||||
}
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
Slot slot = skeleton.slots.Items[slotIndex];
|
||||
if (alpha < 1) {
|
||||
slot.r += (r - slot.r) * alpha;
|
||||
slot.g += (g - slot.g) * alpha;
|
||||
@ -450,7 +450,7 @@ namespace Spine {
|
||||
if (frames[frameIndex] < lastTime) return;
|
||||
|
||||
String attachmentName = attachmentNames[frameIndex];
|
||||
skeleton.slots[slotIndex].Attachment =
|
||||
skeleton.slots.Items[slotIndex].Attachment =
|
||||
attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName);
|
||||
}
|
||||
}
|
||||
@ -533,15 +533,16 @@ namespace Spine {
|
||||
else
|
||||
frameIndex = Animation.binarySearch(frames, time) - 1;
|
||||
|
||||
List<Slot> drawOrder = skeleton.drawOrder;
|
||||
List<Slot> slots = skeleton.slots;
|
||||
ExposedList<Slot> drawOrder = skeleton.drawOrder;
|
||||
ExposedList<Slot> slots = skeleton.slots;
|
||||
int[] drawOrderToSetupIndex = drawOrders[frameIndex];
|
||||
if (drawOrderToSetupIndex == null) {
|
||||
drawOrder.Clear();
|
||||
drawOrder.AddRange(slots);
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
drawOrder.Add(slots.Items[i]);
|
||||
} else {
|
||||
for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++)
|
||||
drawOrder[i] = slots[drawOrderToSetupIndex[i]];
|
||||
drawOrder.Items[i] = slots.Items[drawOrderToSetupIndex[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -570,7 +571,7 @@ namespace Spine {
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
Slot slot = skeleton.slots.Items[slotIndex];
|
||||
if (slot.attachment != attachment) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
@ -652,7 +653,7 @@ namespace Spine {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
IkConstraint ikConstraint = skeleton.ikConstraints[ikConstraintIndex];
|
||||
IkConstraint ikConstraint = skeleton.ikConstraints.Items[ikConstraintIndex];
|
||||
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
ikConstraint.mix += (frames[frames.Length - 2] - ikConstraint.mix) * alpha;
|
||||
@ -703,7 +704,7 @@ namespace Spine {
|
||||
int frameIndex = (time >= frames[frames.Length - 2] ? frames.Length : Animation.binarySearch(frames, time, 2)) - 2;
|
||||
if (frames[frameIndex] < lastTime) return;
|
||||
|
||||
SetFlip(skeleton.bones[boneIndex], frames[frameIndex + 1] != 0);
|
||||
SetFlip(skeleton.bones.Items[boneIndex], frames[frameIndex + 1] != 0);
|
||||
}
|
||||
|
||||
virtual protected void SetFlip (Bone bone, bool flip) {
|
||||
|
||||
@ -95,7 +95,7 @@ namespace Spine {
|
||||
|
||||
public void ComputeWorldVertices (Slot slot, float[] worldVertices) {
|
||||
Skeleton skeleton = slot.bone.skeleton;
|
||||
List<Bone> skeletonBones = skeleton.bones;
|
||||
ExposedList<Bone> skeletonBones = skeleton.bones;
|
||||
float x = skeleton.x, y = skeleton.y;
|
||||
float[] weights = this.weights;
|
||||
int[] bones = this.bones;
|
||||
@ -104,7 +104,7 @@ namespace Spine {
|
||||
float wx = 0, wy = 0;
|
||||
int nn = bones[v++] + v;
|
||||
for (; v < nn; v++, b += 3) {
|
||||
Bone bone = skeletonBones[bones[v]];
|
||||
Bone bone = skeletonBones.Items[bones[v]];
|
||||
float vx = weights[b], vy = weights[b + 1], weight = weights[b + 2];
|
||||
wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
|
||||
wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
|
||||
@ -118,7 +118,7 @@ namespace Spine {
|
||||
float wx = 0, wy = 0;
|
||||
int nn = bones[v++] + v;
|
||||
for (; v < nn; v++, b += 3, f += 2) {
|
||||
Bone bone = skeletonBones[bones[v]];
|
||||
Bone bone = skeletonBones.Items[bones[v]];
|
||||
float vx = weights[b] + ffd[f], vy = weights[b + 1] + ffd[f + 1], weight = weights[b + 2];
|
||||
wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
|
||||
wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
internal BoneData data;
|
||||
internal Skeleton skeleton;
|
||||
internal Bone parent;
|
||||
internal List<Bone> children = new List<Bone>();
|
||||
internal ExposedList<Bone> children = new ExposedList<Bone>();
|
||||
internal float x, y, rotation, rotationIK, scaleX, scaleY;
|
||||
internal bool flipX, flipY;
|
||||
internal float m00, m01, m10, m11;
|
||||
@ -48,7 +48,7 @@ namespace Spine {
|
||||
public BoneData Data { get { return data; } }
|
||||
public Skeleton Skeleton { get { return skeleton; } }
|
||||
public Bone Parent { get { return parent; } }
|
||||
public List<Bone> Children { get { return children; } }
|
||||
public ExposedList<Bone> Children { get { return children; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
/// <summary>The forward kinetics rotation.</summary>
|
||||
|
||||
667
spine-csharp/src/ExposedList.cs
Normal file
667
spine-csharp/src/ExposedList.cs
Normal file
@ -0,0 +1,667 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>
|
||||
/// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search and manipulate lists.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of elements in the list.</typeparam>
|
||||
public class ExposedList<T> : IEnumerable<T> {
|
||||
private const int _defaultCapacity = 4;
|
||||
private static readonly T[] _emptyArray = new T[0];
|
||||
public T[] Items;
|
||||
|
||||
private int _size;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1" /> class that is empty and has the default initial capacity.
|
||||
/// </summary>
|
||||
public ExposedList() {
|
||||
Items = _emptyArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1" /> class that is empty and has the specified initial capacity.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The number of elements that the new list can initially store.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="capacity" /> is less than 0.
|
||||
/// </exception>
|
||||
public ExposedList(int capacity) {
|
||||
if (capacity < 0) {
|
||||
throw new ArgumentOutOfRangeException("capacity");
|
||||
}
|
||||
Items = new T[capacity];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of elements the internal data structure can hold without resizing.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The number of elements that the <see cref="T:System.Collections.Generic.List`1" /> can contain before resizing is required.
|
||||
/// </returns>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <see cref="P:System.Collections.Generic.List`1.Capacity" /> is set to a value that is less than
|
||||
/// <see
|
||||
/// cref="P:System.Collections.Generic.List`1.Count" />
|
||||
/// .
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.OutOfMemoryException">There is not enough memory available on the system.</exception>
|
||||
public int Capacity {
|
||||
get {
|
||||
return Items.Length;
|
||||
}
|
||||
set {
|
||||
if (value == Items.Length) {
|
||||
return;
|
||||
}
|
||||
if (value < _size) {
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
}
|
||||
if (value > 0) {
|
||||
var objArray = new T[value];
|
||||
if (_size > 0) {
|
||||
Array.Copy(Items, 0, objArray, 0, _size);
|
||||
}
|
||||
Items = objArray;
|
||||
} else {
|
||||
Items = _emptyArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements actually contained in the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The number of elements actually contained in the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </returns>
|
||||
public int Count {
|
||||
get {
|
||||
return _size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an object to the end of the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <param name="item">
|
||||
/// The object to be added to the end of the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
public void Add(T item) {
|
||||
if (_size == Items.Length) {
|
||||
EnsureCapacity(_size + 1);
|
||||
}
|
||||
Items[_size++] = item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all elements from the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
public void Clear() {
|
||||
if (_size > 0) {
|
||||
Array.Clear(Items, 0, _size);
|
||||
_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether an element is in the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.List`1" />; otherwise, false.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
public bool Contains(T item) {
|
||||
if (item == null) {
|
||||
for (int index = 0; index < _size; ++index) {
|
||||
if (Items[index] == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
EqualityComparer<T> @default = EqualityComparer<T>.Default;
|
||||
for (int index = 0; index < _size; ++index) {
|
||||
if (@default.Equals(Items[index], item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the entire <see cref="T:System.Collections.Generic.List`1" /> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
/// </summary>
|
||||
/// <param name="array">
|
||||
/// The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// . The <see cref="T:System.Array" /> must have zero-based indexing.
|
||||
/// </param>
|
||||
/// <param name="arrayIndex">
|
||||
/// The zero-based index in <paramref name="array" /> at which copying begins.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="array" /> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="arrayIndex" /> is less than 0.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// The number of elements in the source <see cref="T:System.Collections.Generic.List`1" /> is greater than the available space from
|
||||
/// <paramref
|
||||
/// name="arrayIndex" />
|
||||
/// to the end of the destination <paramref name="array" />.
|
||||
/// </exception>
|
||||
public void CopyTo(T[] array, int arrayIndex) {
|
||||
Array.Copy(Items, 0, array, arrayIndex, _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the first occurrence within the entire
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the first occurrence of <paramref name="item" /> within the entire
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// , if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
public int IndexOf(T item) {
|
||||
return Array.IndexOf(Items, item, 0, _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an element into the <see cref="T:System.Collections.Generic.List`1" /> at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The zero-based index at which <paramref name="item" /> should be inserted.
|
||||
/// </param>
|
||||
/// <param name="item">The object to insert. The value can be null for reference types.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is greater than
|
||||
/// <see
|
||||
/// cref="P:System.Collections.Generic.List`1.Count" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public void Insert(int index, T item) {
|
||||
if ((uint) index > (uint) _size) {
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
if (_size == Items.Length) {
|
||||
EnsureCapacity(_size + 1);
|
||||
}
|
||||
if (index < _size) {
|
||||
Array.Copy(Items, index, Items, index + 1, _size - index);
|
||||
}
|
||||
Items[index] = item;
|
||||
++_size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item" /> is successfully removed; otherwise, false. This method also returns false if
|
||||
/// <paramref
|
||||
/// name="item" />
|
||||
/// was not found in the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to remove from the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
public bool Remove(T item) {
|
||||
int index = IndexOf(item);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
RemoveAt(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the element at the specified index of the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the element to remove.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than
|
||||
/// <see
|
||||
/// cref="P:System.Collections.Generic.List`1.Count" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public void RemoveAt(int index) {
|
||||
if ((uint) index >= (uint) _size) {
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
--_size;
|
||||
if (index < _size) {
|
||||
Array.Copy(Items, index + 1, Items, index, _size - index);
|
||||
}
|
||||
Items[_size] = default (T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the entire <see cref="T:System.Collections.Generic.List`1" /> to a compatible one-dimensional array, starting at the beginning of the target array.
|
||||
/// </summary>
|
||||
/// <param name="array">
|
||||
/// The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// . The <see cref="T:System.Array" /> must have zero-based indexing.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="array" /> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// The number of elements in the source <see cref="T:System.Collections.Generic.List`1" /> is greater than the number of elements that the destination
|
||||
/// <paramref
|
||||
/// name="array" />
|
||||
/// can contain.
|
||||
/// </exception>
|
||||
public void CopyTo(T[] array) {
|
||||
CopyTo(array, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a range of elements from the <see cref="T:System.Collections.Generic.List`1" /> to a compatible one-dimensional array, starting at the specified index of the target array.
|
||||
/// </summary>
|
||||
/// <param name="index">
|
||||
/// The zero-based index in the source <see cref="T:System.Collections.Generic.List`1" /> at which copying begins.
|
||||
/// </param>
|
||||
/// <param name="array">
|
||||
/// The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// . The <see cref="T:System.Array" /> must have zero-based indexing.
|
||||
/// </param>
|
||||
/// <param name="arrayIndex">
|
||||
/// The zero-based index in <paramref name="array" /> at which copying begins.
|
||||
/// </param>
|
||||
/// <param name="count">The number of elements to copy.</param>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="array" /> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="arrayIndex" /> is less than 0.-or-
|
||||
/// <paramref
|
||||
/// name="count" />
|
||||
/// is less than 0.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// <paramref name="index" /> is equal to or greater than the <see cref="P:System.Collections.Generic.List`1.Count" /> of the source
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .-or-The number of elements from <paramref name="index" /> to the end of the source
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// is greater than the available space from
|
||||
/// <paramref
|
||||
/// name="arrayIndex" />
|
||||
/// to the end of the destination <paramref name="array" />.
|
||||
/// </exception>
|
||||
public void CopyTo(int index, T[] array, int arrayIndex, int count) {
|
||||
if (_size - index < count) {
|
||||
throw new ArgumentException("Invalid length");
|
||||
}
|
||||
Array.Copy(Items, index, array, arrayIndex, count);
|
||||
}
|
||||
|
||||
private void EnsureCapacity(int min) {
|
||||
if (Items.Length >= min) {
|
||||
return;
|
||||
}
|
||||
int num = Items.Length == 0 ? 4 : Items.Length * 2;
|
||||
if (num < min) {
|
||||
num = min;
|
||||
}
|
||||
Capacity = num;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow copy of a range of elements in the source <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A shallow copy of a range of elements in the source <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </returns>
|
||||
/// <param name="index">
|
||||
/// The zero-based <see cref="T:System.Collections.Generic.List`1" /> index at which the range starts.
|
||||
/// </param>
|
||||
/// <param name="count">The number of elements in the range.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="count" /> is less than 0.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// <paramref name="index" /> and <paramref name="count" /> do not denote a valid range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public ExposedList<T> GetRange(int index, int count) {
|
||||
if (index < 0 || count < 0) {
|
||||
throw new ArgumentOutOfRangeException("index || count");
|
||||
}
|
||||
if (_size - index < count) {
|
||||
throw new ArgumentException("Invalid length");
|
||||
}
|
||||
var list = new ExposedList<T>(count);
|
||||
Array.Copy(Items, index, list.Items, 0, count);
|
||||
list._size = count;
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that extends from the specified index to the last element.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the first occurrence of <paramref name="item" /> within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that extends from <paramref name="index" /> to the last element, if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
/// <param name="index">The zero-based starting index of the search. 0 (zero) is valid in an empty list.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is outside the range of valid indexes for the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public int IndexOf(T item, int index) {
|
||||
if (index > _size) {
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
return Array.IndexOf(Items, item, index, _size - index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that starts at the specified index and contains the specified number of elements.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the first occurrence of <paramref name="item" /> within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that starts at <paramref name="index" /> and contains
|
||||
/// <paramref
|
||||
/// name="count" />
|
||||
/// number of elements, if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
/// <param name="index">The zero-based starting index of the search. 0 (zero) is valid in an empty list.</param>
|
||||
/// <param name="count">The number of elements in the section to search.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is outside the range of valid indexes for the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .-or-<paramref name="count" /> is less than 0.-or-
|
||||
/// <paramref
|
||||
/// name="index" />
|
||||
/// and <paramref name="count" /> do not specify a valid section in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public int IndexOf(T item, int index, int count) {
|
||||
if (index > _size) {
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
if (count < 0 || index > _size - count) {
|
||||
throw new ArgumentOutOfRangeException("count");
|
||||
}
|
||||
return Array.IndexOf(Items, item, index, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the last occurrence within the entire
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the last occurrence of <paramref name="item" /> within the entire the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// , if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
public int LastIndexOf(T item) {
|
||||
return LastIndexOf(item, _size - 1, _size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that extends from the first element to the specified index.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the last occurrence of <paramref name="item" /> within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that extends from the first element to <paramref name="index" />, if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
/// <param name="index">The zero-based starting index of the backward search.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is outside the range of valid indexes for the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public int LastIndexOf(T item, int index) {
|
||||
if (index >= _size) {
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
return LastIndexOf(item, index, index + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that contains the specified number of elements and ends at the specified index.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The zero-based index of the last occurrence of <paramref name="item" /> within the range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// that contains <paramref name="count" /> number of elements and ends at
|
||||
/// <paramref
|
||||
/// name="index" />
|
||||
/// , if found; otherwise, –1.
|
||||
/// </returns>
|
||||
/// <param name="item">
|
||||
/// The object to locate in the <see cref="T:System.Collections.Generic.List`1" />. The value can be null for reference types.
|
||||
/// </param>
|
||||
/// <param name="index">The zero-based starting index of the backward search.</param>
|
||||
/// <param name="count">The number of elements in the section to search.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is outside the range of valid indexes for the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .-or-<paramref name="count" /> is less than 0.-or-
|
||||
/// <paramref
|
||||
/// name="index" />
|
||||
/// and <paramref name="count" /> do not specify a valid section in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public int LastIndexOf(T item, int index, int count) {
|
||||
if (_size == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (index < 0 || count < 0) {
|
||||
throw new ArgumentOutOfRangeException("index || count");
|
||||
}
|
||||
if (index >= _size || count > index + 1) {
|
||||
throw new ArgumentOutOfRangeException("size || count");
|
||||
}
|
||||
return Array.LastIndexOf(Items, item, index, count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a range of elements from the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based starting index of the range of elements to remove.</param>
|
||||
/// <param name="count">The number of elements to remove.</param>
|
||||
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="count" /> is less than 0.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// <paramref name="index" /> and <paramref name="count" /> do not denote a valid range of elements in the
|
||||
/// <see
|
||||
/// cref="T:System.Collections.Generic.List`1" />
|
||||
/// .
|
||||
/// </exception>
|
||||
public void RemoveRange(int index, int count) {
|
||||
if (index < 0 || count < 0) {
|
||||
throw new ArgumentOutOfRangeException("index || count");
|
||||
}
|
||||
if (_size - index < count) {
|
||||
throw new ArgumentException("Invalid length");
|
||||
}
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
_size -= count;
|
||||
if (index < _size) {
|
||||
Array.Copy(Items, index + count, Items, index, _size - index);
|
||||
}
|
||||
Array.Clear(Items, _size, count);
|
||||
}
|
||||
|
||||
//public void Sort(Comparison<T> comparison)
|
||||
//{
|
||||
// if (comparison == null)
|
||||
// ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
|
||||
// if (this._size <= 0)
|
||||
// return;
|
||||
// Array.Sort<T>(this._items, 0, this._size, (IComparer<T>) new Array.FunctorComparer<T>(comparison));
|
||||
//}
|
||||
/// <summary>
|
||||
/// Sorts the elements in the entire <see cref="T:System.Collections.Generic.List`1" /> using the specified
|
||||
/// <see
|
||||
/// cref="T:System.Comparison`1" />
|
||||
/// .
|
||||
/// </summary>
|
||||
/// <param name="comparison">
|
||||
/// The <see cref="T:System.Comparison`1" /> to use when comparing elements.
|
||||
/// </param>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="comparison" /> is null.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.ArgumentException">
|
||||
/// The implementation of <paramref name="comparison" /> caused an error during the sort. For example,
|
||||
/// <paramref
|
||||
/// name="comparison" />
|
||||
/// might not return 0 when comparing an item with itself.
|
||||
/// </exception>
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="T:System.Collections.Generic.List`1" /> to a new array.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An array containing copies of the elements of the <see cref="T:System.Collections.Generic.List`1" />.
|
||||
/// </returns>
|
||||
public T[] ToArray() {
|
||||
var objArray = new T[_size];
|
||||
Array.Copy(Items, 0, objArray, 0, _size);
|
||||
return objArray;
|
||||
}
|
||||
|
||||
// Returns an enumerator for this list with the given
|
||||
// permission for removal of elements. If modifications made to the list
|
||||
// while an enumeration is in progress, the MoveNext and
|
||||
// GetObject methods of the enumerator will throw an exception.
|
||||
//
|
||||
public Enumerator GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
/// <internalonly/>
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
[Serializable()]
|
||||
public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
|
||||
{
|
||||
private readonly ExposedList<T> _list;
|
||||
private int _index;
|
||||
private T _current;
|
||||
|
||||
internal Enumerator(ExposedList<T> list) {
|
||||
_list = list;
|
||||
_index = 0;
|
||||
_current = default(T);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
ExposedList<T> localList = _list;
|
||||
|
||||
if (((uint)_index < (uint)localList._size)) {
|
||||
_current = localList.Items[_index];
|
||||
_index++;
|
||||
return true;
|
||||
}
|
||||
return MoveNextRare();
|
||||
}
|
||||
|
||||
private bool MoveNextRare()
|
||||
{
|
||||
_index = _list._size + 1;
|
||||
_current = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
public T Current {
|
||||
get {
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
|
||||
Object System.Collections.IEnumerator.Current {
|
||||
get {
|
||||
if( _index == 0 || _index == _list._size + 1)
|
||||
throw new InvalidOperationException();
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void System.Collections.IEnumerator.Reset() {
|
||||
_index = 0;
|
||||
_current = default(T);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
8
spine-csharp/src/ExposedList.cs.meta
Normal file
8
spine-csharp/src/ExposedList.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 540cf6a03c85e284e83831880e3f25a8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -36,13 +36,13 @@ namespace Spine {
|
||||
private const float radDeg = 180 / (float)Math.PI;
|
||||
|
||||
internal IkConstraintData data;
|
||||
internal List<Bone> bones = new List<Bone>();
|
||||
internal ExposedList<Bone> bones = new ExposedList<Bone>();
|
||||
internal Bone target;
|
||||
internal int bendDirection;
|
||||
internal float mix;
|
||||
|
||||
public IkConstraintData Data { get { return data; } }
|
||||
public List<Bone> Bones { get { return bones; } }
|
||||
public ExposedList<Bone> Bones { get { return bones; } }
|
||||
public Bone Target { get { return target; } set { target = value; } }
|
||||
public int BendDirection { get { return bendDirection; } set { bendDirection = value; } }
|
||||
public float Mix { get { return mix; } set { mix = value; } }
|
||||
@ -54,7 +54,7 @@ namespace Spine {
|
||||
mix = data.mix;
|
||||
bendDirection = data.bendDirection;
|
||||
|
||||
bones = new List<Bone>(data.bones.Count);
|
||||
bones = new ExposedList<Bone>(data.bones.Count);
|
||||
foreach (BoneData boneData in data.bones)
|
||||
bones.Add(skeleton.FindBone(boneData.name));
|
||||
target = skeleton.FindBone(data.target.name);
|
||||
@ -62,13 +62,13 @@ namespace Spine {
|
||||
|
||||
public void apply () {
|
||||
Bone target = this.target;
|
||||
List<Bone> bones = this.bones;
|
||||
ExposedList<Bone> bones = this.bones;
|
||||
switch (bones.Count) {
|
||||
case 1:
|
||||
apply(bones[0], target.worldX, target.worldY, mix);
|
||||
apply(bones.Items[0], target.worldX, target.worldY, mix);
|
||||
break;
|
||||
case 2:
|
||||
apply(bones[0], bones[1], target.worldX, target.worldY, bendDirection, mix);
|
||||
apply(bones.Items[0], bones.Items[1], target.worldX, target.worldY, bendDirection, mix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,11 +34,11 @@ using System.Collections.Generic;
|
||||
namespace Spine {
|
||||
public class Skeleton {
|
||||
internal SkeletonData data;
|
||||
internal List<Bone> bones;
|
||||
internal List<Slot> slots;
|
||||
internal List<Slot> drawOrder;
|
||||
internal List<IkConstraint> ikConstraints;
|
||||
private List<List<Bone>> boneCache = new List<List<Bone>>();
|
||||
internal ExposedList<Bone> bones;
|
||||
internal ExposedList<Slot> slots;
|
||||
internal ExposedList<Slot> drawOrder;
|
||||
internal ExposedList<IkConstraint> ikConstraints;
|
||||
private ExposedList<ExposedList<Bone>> boneCache = new ExposedList<ExposedList<Bone>>();
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
@ -46,10 +46,10 @@ namespace Spine {
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public List<Bone> Bones { get { return bones; } }
|
||||
public List<Slot> Slots { get { return slots; } }
|
||||
public List<Slot> DrawOrder { get { return drawOrder; } }
|
||||
public List<IkConstraint> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
|
||||
public ExposedList<Bone> Bones { get { return bones; } }
|
||||
public ExposedList<Slot> Slots { get { return slots; } }
|
||||
public ExposedList<Slot> DrawOrder { get { return drawOrder; } }
|
||||
public ExposedList<IkConstraint> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
|
||||
public Skin Skin { get { return skin; } set { skin = value; } }
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
@ -63,7 +63,7 @@ namespace Spine {
|
||||
|
||||
public Bone RootBone {
|
||||
get {
|
||||
return bones.Count == 0 ? null : bones[0];
|
||||
return bones.Count == 0 ? null : bones.Items[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,24 +71,24 @@ namespace Spine {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
this.data = data;
|
||||
|
||||
bones = new List<Bone>(data.bones.Count);
|
||||
bones = new ExposedList<Bone>(data.bones.Count);
|
||||
foreach (BoneData boneData in data.bones) {
|
||||
Bone parent = boneData.parent == null ? null : bones[data.bones.IndexOf(boneData.parent)];
|
||||
Bone parent = boneData.parent == null ? null : bones.Items[data.bones.IndexOf(boneData.parent)];
|
||||
Bone bone = new Bone(boneData, this, parent);
|
||||
if (parent != null) parent.children.Add(bone);
|
||||
bones.Add(bone);
|
||||
}
|
||||
|
||||
slots = new List<Slot>(data.slots.Count);
|
||||
drawOrder = new List<Slot>(data.slots.Count);
|
||||
slots = new ExposedList<Slot>(data.slots.Count);
|
||||
drawOrder = new ExposedList<Slot>(data.slots.Count);
|
||||
foreach (SlotData slotData in data.slots) {
|
||||
Bone bone = bones[data.bones.IndexOf(slotData.boneData)];
|
||||
Bone bone = bones.Items[data.bones.IndexOf(slotData.boneData)];
|
||||
Slot slot = new Slot(slotData, bone);
|
||||
slots.Add(slot);
|
||||
drawOrder.Add(slot);
|
||||
}
|
||||
|
||||
ikConstraints = new List<IkConstraint>(data.ikConstraints.Count);
|
||||
ikConstraints = new ExposedList<IkConstraint>(data.ikConstraints.Count);
|
||||
foreach (IkConstraintData ikConstraintData in data.ikConstraints)
|
||||
ikConstraints.Add(new IkConstraint(ikConstraintData, this));
|
||||
|
||||
@ -98,31 +98,31 @@ namespace Spine {
|
||||
/// <summary>Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or
|
||||
/// removed.</summary>
|
||||
public void UpdateCache () {
|
||||
List<List<Bone>> boneCache = this.boneCache;
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
ExposedList<ExposedList<Bone>> boneCache = this.boneCache;
|
||||
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
int ikConstraintsCount = ikConstraints.Count;
|
||||
|
||||
int arrayCount = ikConstraintsCount + 1;
|
||||
if (boneCache.Count > arrayCount) boneCache.RemoveRange(arrayCount, boneCache.Count - arrayCount);
|
||||
for (int i = 0, n = boneCache.Count; i < n; i++)
|
||||
boneCache[i].Clear();
|
||||
boneCache.Items[i].Clear();
|
||||
while (boneCache.Count < arrayCount)
|
||||
boneCache.Add(new List<Bone>());
|
||||
boneCache.Add(new ExposedList<Bone>());
|
||||
|
||||
List<Bone> nonIkBones = boneCache[0];
|
||||
ExposedList<Bone> nonIkBones = boneCache.Items[0];
|
||||
|
||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||
Bone bone = bones[i];
|
||||
Bone bone = bones.Items[i];
|
||||
Bone current = bone;
|
||||
do {
|
||||
for (int ii = 0; ii < ikConstraintsCount; ii++) {
|
||||
IkConstraint ikConstraint = ikConstraints[ii];
|
||||
Bone parent = ikConstraint.bones[0];
|
||||
Bone child = ikConstraint.bones[ikConstraint.bones.Count - 1];
|
||||
IkConstraint ikConstraint = ikConstraints.Items[ii];
|
||||
Bone parent = ikConstraint.bones.Items[0];
|
||||
Bone child = ikConstraint.bones.Items[ikConstraint.bones.Count - 1];
|
||||
while (true) {
|
||||
if (current == child) {
|
||||
boneCache[ii].Add(bone);
|
||||
boneCache[ii + 1].Add(bone);
|
||||
boneCache.Items[ii].Add(bone);
|
||||
boneCache.Items[ii + 1].Add(bone);
|
||||
goto outer;
|
||||
}
|
||||
if (child == parent) break;
|
||||
@ -138,20 +138,20 @@ namespace Spine {
|
||||
|
||||
/// <summary>Updates the world transform for each bone and applies IK constraints.</summary>
|
||||
public void UpdateWorldTransform () {
|
||||
List<Bone> bones = this.bones;
|
||||
ExposedList<Bone> bones = this.bones;
|
||||
for (int ii = 0, nn = bones.Count; ii < nn; ii++) {
|
||||
Bone bone = bones[ii];
|
||||
Bone bone = bones.Items[ii];
|
||||
bone.rotationIK = bone.rotation;
|
||||
}
|
||||
List<List<Bone>> boneCache = this.boneCache;
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
ExposedList<ExposedList<Bone>> boneCache = this.boneCache;
|
||||
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
int i = 0, last = boneCache.Count - 1;
|
||||
while (true) {
|
||||
List<Bone> updateBones = boneCache[i];
|
||||
ExposedList<Bone> updateBones = boneCache.Items[i];
|
||||
for (int ii = 0, nn = updateBones.Count; ii < nn; ii++)
|
||||
updateBones[ii].UpdateWorldTransform();
|
||||
updateBones.Items[ii].UpdateWorldTransform();
|
||||
if (i == last) break;
|
||||
ikConstraints[i].apply();
|
||||
ikConstraints.Items[i].apply();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@ -163,32 +163,34 @@ namespace Spine {
|
||||
}
|
||||
|
||||
public void SetBonesToSetupPose () {
|
||||
List<Bone> bones = this.bones;
|
||||
ExposedList<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++)
|
||||
bones[i].SetToSetupPose();
|
||||
bones.Items[i].SetToSetupPose();
|
||||
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
|
||||
IkConstraint ikConstraint = ikConstraints[i];
|
||||
IkConstraint ikConstraint = ikConstraints.Items[i];
|
||||
ikConstraint.bendDirection = ikConstraint.data.bendDirection;
|
||||
ikConstraint.mix = ikConstraint.data.mix;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSlotsToSetupPose () {
|
||||
List<Slot> slots = this.slots;
|
||||
ExposedList<Slot> slots = this.slots;
|
||||
drawOrder.Clear();
|
||||
drawOrder.AddRange(slots);
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
drawOrder.Add(slots.Items[i]);
|
||||
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
slots[i].SetToSetupPose(i);
|
||||
slots.Items[i].SetToSetupPose(i);
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Bone FindBone (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<Bone> bones = this.bones;
|
||||
ExposedList<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||
Bone bone = bones[i];
|
||||
Bone bone = bones.Items[i];
|
||||
if (bone.data.name == boneName) return bone;
|
||||
}
|
||||
return null;
|
||||
@ -197,18 +199,18 @@ namespace Spine {
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindBoneIndex (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<Bone> bones = this.bones;
|
||||
ExposedList<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++)
|
||||
if (bones[i].data.name == boneName) return i;
|
||||
if (bones.Items[i].data.name == boneName) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Slot FindSlot (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
ExposedList<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
Slot slot = slots.Items[i];
|
||||
if (slot.data.name == slotName) return slot;
|
||||
}
|
||||
return null;
|
||||
@ -217,9 +219,9 @@ namespace Spine {
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindSlotIndex (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
ExposedList<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
if (slots[i].data.name.Equals(slotName)) return i;
|
||||
if (slots.Items[i].data.name.Equals(slotName)) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -239,9 +241,9 @@ namespace Spine {
|
||||
if (skin != null)
|
||||
newSkin.AttachAll(this, skin);
|
||||
else {
|
||||
List<Slot> slots = this.slots;
|
||||
ExposedList<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
Slot slot = slots.Items[i];
|
||||
String name = slot.data.attachmentName;
|
||||
if (name != null) {
|
||||
Attachment attachment = newSkin.GetAttachment(i, name);
|
||||
@ -272,9 +274,9 @@ namespace Spine {
|
||||
/// <param name="attachmentName">May be null.</param>
|
||||
public void SetAttachment (String slotName, String attachmentName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
ExposedList<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
Slot slot = slots.Items[i];
|
||||
if (slot.data.name == slotName) {
|
||||
Attachment attachment = null;
|
||||
if (attachmentName != null) {
|
||||
@ -291,9 +293,9 @@ namespace Spine {
|
||||
/** @return May be null. */
|
||||
public IkConstraint FindIkConstraint (String ikConstraintName) {
|
||||
if (ikConstraintName == null) throw new ArgumentNullException("ikConstraintName cannot be null.");
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
ExposedList<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
|
||||
IkConstraint ikConstraint = ikConstraints[i];
|
||||
IkConstraint ikConstraint = ikConstraints.Items[i];
|
||||
if (ikConstraint.data.name == ikConstraintName) return ikConstraint;
|
||||
}
|
||||
return null;
|
||||
|
||||
@ -33,11 +33,11 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Spine {
|
||||
public class SkeletonBounds {
|
||||
private List<Polygon> polygonPool = new List<Polygon>();
|
||||
private ExposedList<Polygon> polygonPool = new ExposedList<Polygon>();
|
||||
private float minX, minY, maxX, maxY;
|
||||
|
||||
public List<BoundingBoxAttachment> BoundingBoxes { get; private set; }
|
||||
public List<Polygon> Polygons { get; private set; }
|
||||
public ExposedList<BoundingBoxAttachment> BoundingBoxes { get; private set; }
|
||||
public ExposedList<Polygon> Polygons { get; private set; }
|
||||
public float MinX { get { return minX; } set { minX = value; } }
|
||||
public float MinY { get { return minY; } set { minY = value; } }
|
||||
public float MaxX { get { return maxX; } set { maxX = value; } }
|
||||
@ -46,23 +46,23 @@ namespace Spine {
|
||||
public float Height { get { return maxY - minY; } }
|
||||
|
||||
public SkeletonBounds () {
|
||||
BoundingBoxes = new List<BoundingBoxAttachment>();
|
||||
Polygons = new List<Polygon>();
|
||||
BoundingBoxes = new ExposedList<BoundingBoxAttachment>();
|
||||
Polygons = new ExposedList<Polygon>();
|
||||
}
|
||||
|
||||
public void Update (Skeleton skeleton, bool updateAabb) {
|
||||
List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
|
||||
List<Polygon> polygons = Polygons;
|
||||
List<Slot> slots = skeleton.slots;
|
||||
ExposedList<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
|
||||
ExposedList<Polygon> polygons = Polygons;
|
||||
ExposedList<Slot> slots = skeleton.slots;
|
||||
int slotCount = slots.Count;
|
||||
|
||||
boundingBoxes.Clear();
|
||||
foreach (Polygon polygon in polygons)
|
||||
polygonPool.Add(polygon);
|
||||
for (int i = 0, n = polygons.Count; i < n; i++)
|
||||
polygonPool.Add(polygons.Items[n]);
|
||||
polygons.Clear();
|
||||
|
||||
for (int i = 0; i < slotCount; i++) {
|
||||
Slot slot = slots[i];
|
||||
Slot slot = slots.Items[i];
|
||||
BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
|
||||
if (boundingBox == null) continue;
|
||||
boundingBoxes.Add(boundingBox);
|
||||
@ -70,7 +70,7 @@ namespace Spine {
|
||||
Polygon polygon = null;
|
||||
int poolCount = polygonPool.Count;
|
||||
if (poolCount > 0) {
|
||||
polygon = polygonPool[poolCount - 1];
|
||||
polygon = polygonPool.Items[poolCount - 1];
|
||||
polygonPool.RemoveAt(poolCount - 1);
|
||||
} else
|
||||
polygon = new Polygon();
|
||||
@ -87,9 +87,9 @@ namespace Spine {
|
||||
|
||||
private void aabbCompute () {
|
||||
float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
|
||||
List<Polygon> polygons = Polygons;
|
||||
ExposedList<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++) {
|
||||
Polygon polygon = polygons[i];
|
||||
Polygon polygon = polygons.Items[i];
|
||||
float[] vertices = polygon.Vertices;
|
||||
for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) {
|
||||
float x = vertices[ii];
|
||||
@ -159,18 +159,18 @@ namespace Spine {
|
||||
/// <summary>Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
|
||||
/// efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true.</summary>
|
||||
public BoundingBoxAttachment ContainsPoint (float x, float y) {
|
||||
List<Polygon> polygons = Polygons;
|
||||
ExposedList<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++)
|
||||
if (ContainsPoint(polygons[i], x, y)) return BoundingBoxes[i];
|
||||
if (ContainsPoint(polygons.Items[i], x, y)) return BoundingBoxes.Items[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
|
||||
/// more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true.</summary>
|
||||
public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) {
|
||||
List<Polygon> polygons = Polygons;
|
||||
ExposedList<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++)
|
||||
if (IntersectsSegment(polygons[i], x1, y1, x2, y2)) return BoundingBoxes[i];
|
||||
if (IntersectsSegment(polygons.Items[i], x1, y1, x2, y2)) return BoundingBoxes.Items[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -200,7 +200,7 @@ namespace Spine {
|
||||
|
||||
public Polygon getPolygon (BoundingBoxAttachment attachment) {
|
||||
int index = BoundingBoxes.IndexOf(attachment);
|
||||
return index == -1 ? null : Polygons[index];
|
||||
return index == -1 ? null : Polygons.Items[index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +77,7 @@ namespace Spine {
|
||||
internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
|
||||
foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in oldSkin.attachments) {
|
||||
int slotIndex = entry.Key.Key;
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
Slot slot = skeleton.slots.Items[slotIndex];
|
||||
if (slot.attachment == entry.Value) {
|
||||
Attachment attachment = GetAttachment(slotIndex, entry.Key.Value);
|
||||
if (attachment != null) slot.Attachment = attachment;
|
||||
|
||||
@ -640,7 +640,7 @@ public static class SkeletonBaker {
|
||||
skeleton.UpdateWorldTransform();
|
||||
|
||||
float[] floatVerts = new float[attachment.UVs.Length];
|
||||
attachment.ComputeWorldVertices(skeleton.Slots[slotIndex], floatVerts);
|
||||
attachment.ComputeWorldVertices(skeleton.Slots.Items[slotIndex], floatVerts);
|
||||
|
||||
Vector2[] uvs = ExtractUV(attachment.UVs);
|
||||
Vector3[] verts = ExtractVerts(floatVerts);
|
||||
@ -807,26 +807,26 @@ public static class SkeletonBaker {
|
||||
|
||||
List<int> ignoreRotateTimelineIndexes = new List<int>();
|
||||
|
||||
if (bakeIK) {
|
||||
foreach (IkConstraint i in skeleton.IkConstraints) {
|
||||
foreach (Bone b in i.Bones) {
|
||||
int index = skeleton.FindBoneIndex(b.Data.Name);
|
||||
ignoreRotateTimelineIndexes.Add(index);
|
||||
BakeBone(b, animation, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (bakeIK) {
|
||||
// foreach (IkConstraint i in skeleton.IkConstraints) {
|
||||
// foreach (Bone b in i.Bones) {
|
||||
// int index = skeleton.FindBoneIndex(b.Data.Name);
|
||||
// ignoreRotateTimelineIndexes.Add(index);
|
||||
// BakeBone(b, animation, clip);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
foreach (Bone b in skeleton.Bones) {
|
||||
if (b.Data.InheritRotation == false) {
|
||||
int index = skeleton.FindBoneIndex(b.Data.Name);
|
||||
//foreach (Bone b in skeleton.Bones) {
|
||||
// if (b.Data.InheritRotation == false) {
|
||||
// int index = skeleton.FindBoneIndex(b.Data.Name);
|
||||
|
||||
if (ignoreRotateTimelineIndexes.Contains(index) == false) {
|
||||
ignoreRotateTimelineIndexes.Add(index);
|
||||
BakeBone(b, animation, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (ignoreRotateTimelineIndexes.Contains(index) == false) {
|
||||
// ignoreRotateTimelineIndexes.Add(index);
|
||||
// BakeBone(b, animation, clip);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
foreach (Timeline t in timelines) {
|
||||
skeleton.SetToSetupPose();
|
||||
@ -911,8 +911,8 @@ public static class SkeletonBaker {
|
||||
static void ParseAttachmentTimeline (Skeleton skeleton, AttachmentTimeline timeline, Dictionary<int, List<string>> slotLookup, AnimationClip clip) {
|
||||
var attachmentNames = slotLookup[timeline.SlotIndex];
|
||||
|
||||
string bonePath = GetPath(skeleton.Slots[timeline.SlotIndex].Bone.Data);
|
||||
string slotPath = bonePath + "/" + skeleton.Slots[timeline.SlotIndex].Data.Name;
|
||||
string bonePath = GetPath(skeleton.Slots.Items[timeline.SlotIndex].Bone.Data);
|
||||
string slotPath = bonePath + "/" + skeleton.Slots.Items[timeline.SlotIndex].Data.Name;
|
||||
|
||||
Dictionary<string, AnimationCurve> curveTable = new Dictionary<string, AnimationCurve>();
|
||||
|
||||
@ -923,7 +923,7 @@ public static class SkeletonBaker {
|
||||
float[] frames = timeline.Frames;
|
||||
|
||||
if (frames[0] != 0) {
|
||||
string startingName = skeleton.Slots[timeline.SlotIndex].Data.AttachmentName;
|
||||
string startingName = skeleton.Slots.Items[timeline.SlotIndex].Data.AttachmentName;
|
||||
foreach (var pair in curveTable) {
|
||||
if (startingName == "" || startingName == null) {
|
||||
pair.Value.AddKey(new Keyframe(0, 0, float.PositiveInfinity, float.PositiveInfinity));
|
||||
@ -1062,7 +1062,7 @@ public static class SkeletonBaker {
|
||||
|
||||
static void ParseTranslateTimeline (Skeleton skeleton, TranslateTimeline timeline, AnimationClip clip) {
|
||||
var boneData = skeleton.Data.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
||||
|
||||
AnimationCurve xCurve = new AnimationCurve();
|
||||
AnimationCurve yCurve = new AnimationCurve();
|
||||
@ -1208,7 +1208,7 @@ public static class SkeletonBaker {
|
||||
|
||||
static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) {
|
||||
var boneData = skeleton.Data.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
||||
|
||||
AnimationCurve xCurve = new AnimationCurve();
|
||||
AnimationCurve yCurve = new AnimationCurve();
|
||||
@ -1341,7 +1341,7 @@ public static class SkeletonBaker {
|
||||
|
||||
static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) {
|
||||
var boneData = skeleton.Data.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones[timeline.BoneIndex];
|
||||
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
||||
|
||||
AnimationCurve curve = new AnimationCurve();
|
||||
|
||||
|
||||
@ -357,7 +357,7 @@ public class SkeletonDataAssetInspector : Editor {
|
||||
}
|
||||
|
||||
for (int i = m_skeletonAnimation.skeleton.Slots.Count - 1; i >= 0; i--) {
|
||||
Slot slot = m_skeletonAnimation.skeleton.Slots[i];
|
||||
Slot slot = m_skeletonAnimation.skeleton.Slots.Items[i];
|
||||
EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.Icons.slot));
|
||||
if (showAttachments) {
|
||||
|
||||
|
||||
@ -173,11 +173,11 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
|
||||
Material lastMaterial = null;
|
||||
submeshMaterials.Clear();
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
ExposedList<Slot> drawOrder = skeleton.DrawOrder;
|
||||
int drawOrderCount = drawOrder.Count;
|
||||
bool renderMeshes = this.renderMeshes;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Slot slot = drawOrder[i];
|
||||
Slot slot = drawOrder.Items[i];
|
||||
Attachment attachment = slot.attachment;
|
||||
|
||||
object rendererObject;
|
||||
@ -254,7 +254,7 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
float zSpacing = this.zSpacing;
|
||||
float a = skeleton.a * 255, r = skeleton.r, g = skeleton.g, b = skeleton.b;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
Slot slot = drawOrder[i];
|
||||
Slot slot = drawOrder.Items[i];
|
||||
Attachment attachment = slot.attachment;
|
||||
if (attachment is RegionAttachment) {
|
||||
RegionAttachment regionAttachment = (RegionAttachment)attachment;
|
||||
@ -413,9 +413,9 @@ public class SkeletonRenderer : MonoBehaviour {
|
||||
}
|
||||
|
||||
// Store triangles.
|
||||
List<Slot> drawOrder = skeleton.DrawOrder;
|
||||
ExposedList<Slot> drawOrder = skeleton.DrawOrder;
|
||||
for (int i = startSlot, triangleIndex = 0; i < endSlot; i++) {
|
||||
Slot slot = drawOrder[i];
|
||||
Slot slot = drawOrder.Items[i];
|
||||
Attachment attachment = slot.attachment;
|
||||
Bone bone = slot.bone;
|
||||
bool flip = frontFacing && ((bone.WorldFlipX != bone.WorldFlipY) != (Mathf.Sign(bone.WorldScaleX) != Mathf.Sign(bone.WorldScaleY)));
|
||||
|
||||
@ -190,14 +190,14 @@ public class SkeletonUtilityBoneInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
void BoneSelectorContextMenu (string current, List<Bone> bones, string topValue, GenericMenu.MenuFunction2 callback) {
|
||||
void BoneSelectorContextMenu (string current, ExposedList<Bone> bones, string topValue, GenericMenu.MenuFunction2 callback) {
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
if (topValue != "")
|
||||
menu.AddItem(new GUIContent(topValue), current == topValue, callback, null);
|
||||
|
||||
for (int i = 0; i < bones.Count; i++) {
|
||||
menu.AddItem(new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i]);
|
||||
menu.AddItem(new GUIContent(bones.Items[i].Data.Name), bones.Items[i].Data.Name == current, callback, bones.Items[i]);
|
||||
}
|
||||
|
||||
menu.ShowAsContext();
|
||||
|
||||
@ -160,7 +160,7 @@ public class SkeletonUtilityInspector : Editor {
|
||||
List<Attachment> attachments = new List<Attachment>();
|
||||
skin.FindAttachmentsForSlot(i, attachments);
|
||||
|
||||
attachmentTable.Add(skeleton.Slots[i], attachments);
|
||||
attachmentTable.Add(skeleton.Slots.Items[i], attachments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -170,9 +170,9 @@ public class SkeletonUtility : MonoBehaviour {
|
||||
if (boneRoot != null) {
|
||||
List<string> constraintTargetNames = new List<string>();
|
||||
|
||||
foreach (IkConstraint c in skeletonRenderer.skeleton.IkConstraints) {
|
||||
constraintTargetNames.Add(c.Target.Data.Name);
|
||||
}
|
||||
ExposedList<IkConstraint> ikConstraints = skeletonRenderer.skeleton.IkConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++)
|
||||
constraintTargetNames.Add(ikConstraints.Items[n].Target.Data.Name);
|
||||
|
||||
foreach (var b in utilityBones) {
|
||||
if (b.bone == null) {
|
||||
@ -289,7 +289,9 @@ public class SkeletonUtility : MonoBehaviour {
|
||||
public GameObject SpawnBoneRecursively (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
|
||||
GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca);
|
||||
|
||||
foreach (Bone child in bone.Children) {
|
||||
ExposedList<Bone> childrenBones = bone.Children;
|
||||
for (int i = 0, n = childrenBones.Count; i < n; i++) {
|
||||
Bone child = childrenBones.Items[i];
|
||||
SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user