Merge branch '3.6' into 3.7-beta

This commit is contained in:
NathanSweet 2017-10-19 16:21:19 +02:00
commit ef798dafe3
6 changed files with 1399 additions and 1369 deletions

View File

@ -90,7 +90,18 @@ namespace Spine {
} }
public ExposedList<T> Resize (int newSize) { public ExposedList<T> Resize (int newSize) {
if (newSize > Items.Length) Array.Resize(ref Items, newSize); int itemsLength = Items.Length;
var oldItems = Items;
if (newSize > itemsLength) {
Array.Resize(ref Items, newSize);
// var newItems = new T[newSize];
// Array.Copy(oldItems, newItems, Count);
// Items = newItems;
} else if (newSize > itemsLength) {
// Allow nulling of T reference type to allow GC.
for (int i = Count; i < itemsLength; i++)
oldItems[i] = default(T);
}
Count = newSize; Count = newSize;
return this; return this;
} }

View File

@ -47,7 +47,7 @@ namespace Spine {
public ExposedList<int> ClippedTriangles { get { return clippedTriangles; } } public ExposedList<int> ClippedTriangles { get { return clippedTriangles; } }
public ExposedList<float> ClippedUVs { get { return clippedUVs; } } public ExposedList<float> ClippedUVs { get { return clippedUVs; } }
public bool IsClipping () { return clipAttachment != null; } public bool IsClipping { get { return clipAttachment != null; } }
public int ClipStart (Slot slot, ClippingAttachment clip) { public int ClipStart (Slot slot, ClippingAttachment clip) {
if (clipAttachment != null) return 0; if (clipAttachment != null) return 0;
@ -89,7 +89,7 @@ namespace Spine {
clippedVertices.Clear(); clippedVertices.Clear();
clippedUVs.Clear(); clippedUVs.Clear();
clippedTriangles.Clear(); clippedTriangles.Clear();
//outer: // libgdx //outer:
for (int i = 0; i < trianglesLength; i += 3) { for (int i = 0; i < trianglesLength; i += 3) {
int vertexOffset = triangles[i] << 1; int vertexOffset = triangles[i] << 1;
float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
@ -258,7 +258,7 @@ namespace Spine {
return clipped; return clipped;
} }
public static void MakeClockwise (ExposedList<float> polygon) { static void MakeClockwise (ExposedList<float> polygon) {
float[] vertices = polygon.Items; float[] vertices = polygon.Items;
int verticeslength = polygon.Count; int verticeslength = polygon.Count;

View File

@ -31,7 +31,7 @@
using System; using System;
namespace Spine { namespace Spine {
public class Triangulator { internal class Triangulator {
private readonly ExposedList<ExposedList<float>> convexPolygons = new ExposedList<ExposedList<float>>(); private readonly ExposedList<ExposedList<float>> convexPolygons = new ExposedList<ExposedList<float>>();
private readonly ExposedList<ExposedList<int>> convexPolygonsIndices = new ExposedList<ExposedList<int>>(); private readonly ExposedList<ExposedList<int>> convexPolygonsIndices = new ExposedList<ExposedList<int>>();

View File

@ -30,7 +30,6 @@
package com.esotericsoftware.spine; package com.esotericsoftware.spine;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import com.esotericsoftware.spine.PathConstraintData.PositionMode; import com.esotericsoftware.spine.PathConstraintData.PositionMode;
@ -46,6 +45,7 @@ import com.esotericsoftware.spine.utils.SpineUtils;
* See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */ * See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
public class PathConstraint implements Constraint { public class PathConstraint implements Constraint {
static private final int NONE = -1, BEFORE = -2, AFTER = -3; static private final int NONE = -1, BEFORE = -2, AFTER = -3;
static private final float epsilon = 0.00001f;
final PathConstraintData data; final PathConstraintData data;
final Array<Bone> bones; final Array<Bone> bones;
@ -113,11 +113,15 @@ public class PathConstraint implements Constraint {
for (int i = 0, n = spacesCount - 1; i < n;) { for (int i = 0, n = spacesCount - 1; i < n;) {
Bone bone = (Bone)bones[i]; Bone bone = (Bone)bones[i];
float setupLength = bone.data.length; float setupLength = bone.data.length;
if (setupLength == 0) setupLength = 0.000000001f; if (setupLength < epsilon) {
float x = setupLength * bone.a, y = setupLength * bone.c; if (scale) lengths[i] = 0;
float length = (float)Math.sqrt(x * x + y * y); spaces[++i] = 0;
if (scale) lengths[i] = length; } else {
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
}
} }
} else { } else {
for (int i = 1; i < spacesCount; i++) for (int i = 1; i < spacesCount; i++)
@ -142,7 +146,7 @@ public class PathConstraint implements Constraint {
float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
if (scale) { if (scale) {
float length = lengths[i]; float length = lengths[i];
if (length != 0) { if (length >= epsilon) {
float s = ((float)Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; float s = ((float)Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
bone.a *= s; bone.a *= s;
bone.c *= s; bone.c *= s;
@ -154,7 +158,7 @@ public class PathConstraint implements Constraint {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin; float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin;
if (tangents) if (tangents)
r = positions[p - 1]; r = positions[p - 1];
else if (spaces[i + 1] == 0) else if (spaces[i + 1] < epsilon)
r = positions[p + 2]; r = positions[p + 2];
else else
r = (float)Math.atan2(dy, dx); r = (float)Math.atan2(dy, dx);
@ -247,7 +251,7 @@ public class PathConstraint implements Constraint {
path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
} }
addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
tangents || (i > 0 && space == 0)); tangents || (i > 0 && space < epsilon));
} }
return out; return out;
} }
@ -395,7 +399,7 @@ public class PathConstraint implements Constraint {
} }
break; break;
} }
addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space < epsilon));
} }
return out; return out;
} }
@ -416,13 +420,14 @@ public class PathConstraint implements Constraint {
private void addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, private void addCurvePosition (float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2,
float[] out, int o, boolean tangents) { float[] out, int o, boolean tangents) {
if (p == 0 || Float.isNaN(p)) p = 0.0001f; if (p < epsilon || Float.isNaN(p)) p = epsilon;
float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; float tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
float ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; float ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
float x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; float x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
out[o] = x; out[o] = x;
out[o + 1] = y; out[o + 1] = y;
if (tangents) out[o + 2] = (float)Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); if (tangents)
out[o + 2] = (float)Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
} }
public int getOrder () { public int getOrder () {

View File

@ -71,6 +71,16 @@ namespace Spine.Unity {
/// <summary>The number of slots in this SubmeshInstruction's range. Not necessarily the number of attachments.</summary> /// <summary>The number of slots in this SubmeshInstruction's range. Not necessarily the number of attachments.</summary>
public int SlotCount { get { return endSlot - startSlot; } } public int SlotCount { get { return endSlot - startSlot; } }
public override string ToString () {
return
string.Format("[SubmeshInstruction: slots {0} to {1}. (Material){2}. preActiveClippingSlotSource:{3}]",
startSlot,
endSlot - 1,
material == null ? "<none>" : material.name,
preActiveClippingSlotSource
);
}
} }
public delegate void MeshGeneratorDelegate (MeshGeneratorBuffers buffers); public delegate void MeshGeneratorDelegate (MeshGeneratorBuffers buffers);
@ -196,35 +206,35 @@ namespace Spine.Unity {
bool skeletonHasClipping = false; bool skeletonHasClipping = false;
var drawOrderItems = drawOrder.Items; var drawOrderItems = drawOrder.Items;
for (int i = 0; i < drawOrderCount; i++) { for (int i = 0; i < drawOrderCount; i++) {
Slot slot = drawOrderItems[i]; Slot slot = drawOrderItems[i];
Attachment attachment = slot.attachment; Attachment attachment = slot.attachment;
workingAttachmentsItems[i] = attachment; workingAttachmentsItems[i] = attachment;
int attachmentTriangleCount; int attachmentTriangleCount;
int attachmentVertexCount; int attachmentVertexCount;
var regionAttachment = attachment as RegionAttachment; var regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
attachmentVertexCount = 4; attachmentVertexCount = 4;
attachmentTriangleCount = 6; attachmentTriangleCount = 6;
} else { } else {
var meshAttachment = attachment as MeshAttachment; var meshAttachment = attachment as MeshAttachment;
if (meshAttachment != null) { if (meshAttachment != null) {
attachmentVertexCount = meshAttachment.worldVerticesLength >> 1; attachmentVertexCount = meshAttachment.worldVerticesLength >> 1;
attachmentTriangleCount = meshAttachment.triangles.Length; attachmentTriangleCount = meshAttachment.triangles.Length;
} else { } else {
var clippingAttachment = attachment as ClippingAttachment; var clippingAttachment = attachment as ClippingAttachment;
if (clippingAttachment != null) { if (clippingAttachment != null) {
current.hasClipping = true; current.hasClipping = true;
skeletonHasClipping = true; skeletonHasClipping = true;
} }
attachmentVertexCount = 0; attachmentVertexCount = 0;
attachmentTriangleCount = 0; attachmentTriangleCount = 0;
} }
} }
current.rawTriangleCount += attachmentTriangleCount; current.rawTriangleCount += attachmentTriangleCount;
current.rawVertexCount += attachmentVertexCount; current.rawVertexCount += attachmentVertexCount;
totalRawVertexCount += attachmentVertexCount; totalRawVertexCount += attachmentVertexCount;
} }
@ -236,8 +246,8 @@ namespace Spine.Unity {
} }
public static void GenerateSkeletonRendererInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Dictionary<Slot, Material> customSlotMaterials, List<Slot> separatorSlots, bool generateMeshOverride, bool immutableTriangles = false) { public static void GenerateSkeletonRendererInstruction (SkeletonRendererInstruction instructionOutput, Skeleton skeleton, Dictionary<Slot, Material> customSlotMaterials, List<Slot> separatorSlots, bool generateMeshOverride, bool immutableTriangles = false) {
// if (skeleton == null) throw new ArgumentNullException("skeleton"); // if (skeleton == null) throw new ArgumentNullException("skeleton");
// if (instructionOutput == null) throw new ArgumentNullException("instructionOutput"); // if (instructionOutput == null) throw new ArgumentNullException("instructionOutput");
ExposedList<Slot> drawOrder = skeleton.drawOrder; ExposedList<Slot> drawOrder = skeleton.drawOrder;
int drawOrderCount = drawOrder.Count; int drawOrderCount = drawOrder.Count;
@ -299,17 +309,17 @@ namespace Spine.Unity {
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
var clippingAttachment = attachment as ClippingAttachment; var clippingAttachment = attachment as ClippingAttachment;
if (clippingAttachment != null) { if (clippingAttachment != null) {
clippingEndSlot = clippingAttachment.endSlot; clippingEndSlot = clippingAttachment.endSlot;
clippingAttachmentSource = i; clippingAttachmentSource = i;
current.hasClipping = true; current.hasClipping = true;
skeletonHasClipping = true; skeletonHasClipping = true;
} }
#endif #endif
noRender = true; noRender = true;
} }
} }
if (clippingEndSlot != null && slot.data == clippingEndSlot) { if (clippingEndSlot != null && slot.data == clippingEndSlot && i != clippingAttachmentSource) {
clippingEndSlot = null; clippingEndSlot = null;
clippingAttachmentSource = -1; clippingAttachmentSource = -1;
} }
@ -538,7 +548,7 @@ namespace Spine.Unity {
color.b = (byte)(skeletonB * slot.b * c.b * 255); color.b = (byte)(skeletonB * slot.b * c.b * 255);
} }
if (useClipping && clipper.IsClipping()) { if (useClipping && clipper.IsClipping) {
clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs); clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs);
workingVerts = clipper.clippedVertices.Items; workingVerts = clipper.clippedVertices.Items;
attachmentVertexCount = clipper.clippedVertices.Count >> 1; attachmentVertexCount = clipper.clippedVertices.Count >> 1;
@ -1236,6 +1246,10 @@ namespace Spine.Unity {
this.submeshInstructions.Clear(false); this.submeshInstructions.Clear(false);
} }
public void Dispose () {
attachments.Clear(true);
}
public void SetWithSubset (ExposedList<SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) { public void SetWithSubset (ExposedList<SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) {
#if SPINE_TRIANGLECHECK #if SPINE_TRIANGLECHECK
int runningVertexCount = 0; int runningVertexCount = 0;
@ -1270,7 +1284,7 @@ namespace Spine.Unity {
var drawOrder = instructionsItems[0].skeleton.drawOrder.Items; var drawOrder = instructionsItems[0].skeleton.drawOrder.Items;
for (int i = 0; i < attachmentCount; i++) for (int i = 0; i < attachmentCount; i++)
attachmentsItems[i] = drawOrder[startSlot + i].attachment; attachmentsItems[i] = drawOrder[startSlot + i].attachment;
#endif #endif
} }

View File

@ -176,7 +176,7 @@ namespace Spine {
darkColor.A = premultipliedAlpha ? (byte)255 : (byte)0; darkColor.A = premultipliedAlpha ? (byte)255 : (byte)0;
// clip // clip
if (clipper.IsClipping()) { if (clipper.IsClipping) {
clipper.ClipTriangles(vertices, verticesCount << 1, indices, indicesCount, uvs); clipper.ClipTriangles(vertices, verticesCount << 1, indices, indicesCount, uvs);
vertices = clipper.ClippedVertices.Items; vertices = clipper.ClippedVertices.Items;
verticesCount = clipper.ClippedVertices.Count >> 1; verticesCount = clipper.ClippedVertices.Count >> 1;