diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
index fca5f239f..2fadf1cd6 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java
@@ -38,16 +38,16 @@ import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.Skin.SkinEntry;
-import com.esotericsoftware.spine.attachments.Attachment;
-import com.esotericsoftware.spine.attachments.MeshAttachment;
-import com.esotericsoftware.spine.attachments.PathAttachment;
-import com.esotericsoftware.spine.attachments.RegionAttachment;
+import com.esotericsoftware.spine.attachments.*;
+import com.esotericsoftware.spine.utils.SkeletonClipping;
/** Stores the current pose for a skeleton.
*
* See Instance objects in the Spine
* Runtimes Guide. */
public class Skeleton {
+ static private final SkeletonClipping clipper = new SkeletonClipping();
+ static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0};
final SkeletonData data;
final Array bones;
final Array slots;
@@ -699,19 +699,31 @@ public class Skeleton {
if (!slot.bone.active) continue;
int verticesLength = 0;
float[] vertices = null;
+ short[] triangles = null;
Attachment attachment = slot.attachment;
if (attachment instanceof RegionAttachment) {
RegionAttachment region = (RegionAttachment)attachment;
verticesLength = 8;
vertices = temp.setSize(8);
region.computeWorldVertices(slot, vertices, 0, 2);
+ triangles = quadTriangles;
} else if (attachment instanceof MeshAttachment) {
MeshAttachment mesh = (MeshAttachment)attachment;
verticesLength = mesh.getWorldVerticesLength();
vertices = temp.setSize(verticesLength);
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+ triangles = mesh.getTriangles();
+ } else if (attachment instanceof ClippingAttachment) {
+ ClippingAttachment clip = (ClippingAttachment)attachment;
+ clipper.clipStart(slot, clip);
+ continue;
}
if (vertices != null) {
+ if (clipper.isClipping()) {
+ clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length);
+ vertices = clipper.getClippedVertices().items;
+ verticesLength = clipper.getClippedVertices().size;
+ }
for (int ii = 0; ii < verticesLength; ii += 2) {
float x = vertices[ii], y = vertices[ii + 1];
minX = Math.min(minX, x);
@@ -720,7 +732,9 @@ public class Skeleton {
maxY = Math.max(maxY, y);
}
}
+ clipper.clipEnd(slot);
}
+ clipper.clipEnd();
offset.set(minX, minY);
size.set(maxX - minX, maxY - minY);
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SkeletonClipping.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SkeletonClipping.java
index 2c9ad1afb..77bcfab56 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SkeletonClipping.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/utils/SkeletonClipping.java
@@ -82,6 +82,78 @@ public class SkeletonClipping {
return clipAttachment != null;
}
+ public void clipTriangles (float[] vertices, int verticesLength, short[] triangles, int trianglesLength) {
+
+ FloatArray clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+ ShortArray clippedTriangles = this.clippedTriangles;
+ Object[] polygons = clippingPolygons.items;
+ int polygonsCount = clippingPolygons.size;
+ int vertexSize = 2;
+
+ short index = 0;
+ clippedVertices.clear();
+ clippedTriangles.clear();
+ outer:
+ for (int i = 0; i < trianglesLength; i += 3) {
+ int vertexOffset = triangles[i] << 1;
+ float x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+
+ vertexOffset = triangles[i + 1] << 1;
+ float x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+
+ vertexOffset = triangles[i + 2] << 1;
+ float x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+
+ for (int p = 0; p < polygonsCount; p++) {
+ int s = clippedVertices.size;
+ if (clip(x1, y1, x2, y2, x3, y3, (FloatArray)polygons[p], clipOutput)) {
+ int clipOutputLength = clipOutput.size;
+ if (clipOutputLength == 0) continue;
+
+ int clipOutputCount = clipOutputLength >> 1;
+ float[] clipOutputItems = clipOutput.items;
+ float[] clippedVerticesItems = clippedVertices.setSize(s + clipOutputCount * vertexSize);
+ for (int ii = 0; ii < clipOutputLength; ii += 2) {
+ float x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+ clippedVerticesItems[s] = x;
+ clippedVerticesItems[s + 1] = y;
+ s += 2;
+ }
+
+ s = clippedTriangles.size;
+ short[] clippedTrianglesItems = clippedTriangles.setSize(s + 3 * (clipOutputCount - 2));
+ clipOutputCount--;
+ for (int ii = 1; ii < clipOutputCount; ii++) {
+ clippedTrianglesItems[s] = index;
+ clippedTrianglesItems[s + 1] = (short)(index + ii);
+ clippedTrianglesItems[s + 2] = (short)(index + ii + 1);
+ s += 3;
+ }
+ index += clipOutputCount + 1;
+
+ } else {
+ float[] clippedVerticesItems = clippedVertices.setSize(s + 3 * vertexSize);
+ clippedVerticesItems[s] = x1;
+ clippedVerticesItems[s + 1] = y1;
+
+ clippedVerticesItems[s + 2] = x2;
+ clippedVerticesItems[s + 3] = y2;
+
+ clippedVerticesItems[s + 4] = x3;
+ clippedVerticesItems[s + 5] = y3;
+
+ s = clippedTriangles.size;
+ short[] clippedTrianglesItems = clippedTriangles.setSize(s + 3);
+ clippedTrianglesItems[s] = index;
+ clippedTrianglesItems[s + 1] = (short)(index + 1);
+ clippedTrianglesItems[s + 2] = (short)(index + 2);
+ index += 3;
+ continue outer;
+ }
+ }
+ }
+ }
+
public void clipTriangles (float[] vertices, int verticesLength, short[] triangles, int trianglesLength, float[] uvs,
float light, float dark, boolean twoColor) {