From 41f2e206d676fe428787050e74caddd93437504d Mon Sep 17 00:00:00 2001 From: badlogic Date: Wed, 19 Apr 2017 16:35:26 +0200 Subject: [PATCH] [xna] Added clipping to SkeletonMeshRenderer, doesn't quite work yet --- spine-csharp/src/ConvexDecomposer.cs | 26 +++++++++++++------------- spine-csharp/src/SkeletonClipping.cs | 22 +++++++++++----------- spine-xna/src/SkeletonMeshRenderer.cs | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/spine-csharp/src/ConvexDecomposer.cs b/spine-csharp/src/ConvexDecomposer.cs index f4ed36721..250d2b26e 100644 --- a/spine-csharp/src/ConvexDecomposer.cs +++ b/spine-csharp/src/ConvexDecomposer.cs @@ -33,14 +33,14 @@ using System; namespace Spine { internal class ConvexDecomposer { private readonly ExposedList> convexPolygons = new ExposedList>(); - private readonly ExposedList> convexPolygonsIndices = new ExposedList>(); + private readonly ExposedList> convexPolygonsIndices = new ExposedList>(); - private readonly ExposedList indicesArray = new ExposedList(); + private readonly ExposedList indicesArray = new ExposedList(); private readonly ExposedList isConcaveArray = new ExposedList(); - private readonly ExposedList triangles = new ExposedList(); + private readonly ExposedList triangles = new ExposedList(); private readonly Pool> polygonPool = new Pool>(); - private readonly Pool> polygonIndicesPool = new Pool>(); + private readonly Pool> polygonIndicesPool = new Pool>(); public ExposedList> Decompose(ExposedList input) { var vertices = input.Items; @@ -48,8 +48,8 @@ namespace Spine { var indicesArray = this.indicesArray; indicesArray.Clear(); - short[] indices = indicesArray.Resize(vertexCount).Items; - for (short i = 0; i < vertexCount; i++) + int[] indices = indicesArray.Resize(vertexCount).Items; + for (int i = 0; i < vertexCount; i++) indices[i] = i; var isConcaveArray = this.isConcaveArray; @@ -137,7 +137,7 @@ namespace Spine { // Merge subsequent triangles if they form a triangle fan. int fanBaseIndex = -1, lastWinding = 0; - short[] trianglesItems = triangles.Items; + int[] trianglesItems = triangles.Items; for (int i = 0, n = triangles.Count; i < n; i += 3) { int t1 = trianglesItems[i] << 1, t2 = trianglesItems[i + 1] << 1, t3 = trianglesItems[i + 2] << 1; float x1 = vertices[t1], y1 = vertices[t1 + 1]; @@ -154,7 +154,7 @@ namespace Spine { if (winding1 == lastWinding && winding2 == lastWinding) { polygon.Add(x3); polygon.Add(y3); - polygonIndices.Add((short)t3); + polygonIndices.Add(t3); merged = true; } } @@ -175,9 +175,9 @@ namespace Spine { polygon.Add(y3); polygonIndices = polygonIndicesPool.Obtain(); polygonIndices.Clear(); - polygonIndices.Add((short)t1); - polygonIndices.Add((short)t2); - polygonIndices.Add((short)t3); + polygonIndices.Add(t1); + polygonIndices.Add(t2); + polygonIndices.Add(t3); lastWinding = Winding(x1, y1, x2, y2, x3, y3); fanBaseIndex = t1; } @@ -223,7 +223,7 @@ namespace Spine { otherIndices.Clear(); polygon.Add(x3); polygon.Add(y3); - polygonIndices.Add((short)otherLastIndex); + polygonIndices.Add(otherLastIndex); prevPrevX = prevX; prevPrevY = prevY; prevX = x3; @@ -245,7 +245,7 @@ namespace Spine { return convexPolygons; } - static private bool IsConcave(int index, int vertexCount, float[] vertices, short[] indices) { + static private bool IsConcave(int index, int vertexCount, float[] vertices, int[] indices) { int previous = indices[(vertexCount + index - 1) % vertexCount] << 1; int current = indices[index] << 1; int next = indices[(index + 1) % vertexCount] << 1; diff --git a/spine-csharp/src/SkeletonClipping.cs b/spine-csharp/src/SkeletonClipping.cs index bf4ba6e8c..3b1a4a9e9 100644 --- a/spine-csharp/src/SkeletonClipping.cs +++ b/spine-csharp/src/SkeletonClipping.cs @@ -36,7 +36,7 @@ namespace Spine { private readonly ExposedList clippingPolygon = new ExposedList(); private readonly ExposedList clipOutput = new ExposedList(128); private readonly ExposedList clippedVertices = new ExposedList(128); - private readonly ExposedList clippedTriangles = new ExposedList(128); + private readonly ExposedList clippedTriangles = new ExposedList(128); private readonly ExposedList clippedUVs = new ExposedList(128); private readonly ExposedList scratch = new ExposedList(); @@ -44,7 +44,7 @@ namespace Spine { private ExposedList> clippingPolygons; public ExposedList ClippedVertices { get { return clippedVertices; } } - public ExposedList ClippedTriangles { get { return clippedTriangles; } } + public ExposedList ClippedTriangles { get { return clippedTriangles; } } public ExposedList ClippedUVs { get { return clippedUVs; } } public void ClipStart(Slot slot, ClippingAttachment clip) { @@ -80,14 +80,14 @@ namespace Spine { return clipAttachment != null; } - public void ClipTriangles(float[] vertices, int verticesLength, short[] triangles, int trianglesLength, float[] uvs) { + public void ClipTriangles(float[] vertices, int verticesLength, int[] triangles, int trianglesLength, float[] uvs) { ExposedList clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; var clippedTriangles = this.clippedTriangles; var polygons = clippingPolygons.Items; int polygonsCount = clippingPolygons.Count; - short index = 0; + int index = 0; clippedVertices.Clear(); clippedUVs.Clear(); clippedTriangles.Clear(); @@ -131,15 +131,15 @@ namespace Spine { } s = clippedTriangles.Count; - short[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items; + int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items; clipOutputCount--; for (int ii = 1; ii < clipOutputCount; ii++) { clippedTrianglesItems[s] = index; - clippedTrianglesItems[s + 1] = (short)(index + ii); - clippedTrianglesItems[s + 2] = (short)(index + ii + 1); + clippedTrianglesItems[s + 1] = index + ii; + clippedTrianglesItems[s + 2] = index + ii + 1; s += 3; } - index += (short)(clipOutputCount + 1); + index += clipOutputCount + 1; } else { @@ -160,10 +160,10 @@ namespace Spine { clippedUVsItems[s + 5] = v3; s = clippedTriangles.Count; - short[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items; + int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items; clippedTrianglesItems[s] = index; - clippedTrianglesItems[s + 1] = (short)(index + 1); - clippedTrianglesItems[s + 2] = (short)(index + 2); + clippedTrianglesItems[s + 1] = index + 1; + clippedTrianglesItems[s + 2] = index + 2; index += 3; goto outer; } diff --git a/spine-xna/src/SkeletonMeshRenderer.cs b/spine-xna/src/SkeletonMeshRenderer.cs index 9a719d942..751c02d5b 100644 --- a/spine-xna/src/SkeletonMeshRenderer.cs +++ b/spine-xna/src/SkeletonMeshRenderer.cs @@ -42,6 +42,7 @@ namespace Spine { private const int BL = 2; private const int BR = 3; + SkeletonClipping clipper = new SkeletonClipping(); GraphicsDevice device; MeshBatcher batcher; RasterizerState rasterizerState; @@ -131,6 +132,8 @@ namespace Spine { uvs = mesh.UVs; } else if (attachment is ClippingAttachment) { + ClippingAttachment clip = (ClippingAttachment)attachment; + clipper.ClipStart(slot, clip); continue; } else { @@ -159,6 +162,19 @@ namespace Spine { skeletonB * slot.B * attachmentColorB, a); } + // clip + if (clipper.IsClipping()) { + clipper.ClipTriangles(vertices, verticesCount << 1, indices, indicesCount, uvs); + vertices = clipper.ClippedVertices.Items; + verticesCount = clipper.ClippedVertices.Count; + indices = clipper.ClippedTriangles.Items; + indicesCount = clipper.ClippedTriangles.Count; + uvs = clipper.ClippedUVs.Items; + } + + if (verticesCount == 0 || indicesCount == 0) + continue; + // submit to batch MeshItem item = batcher.NextItem(verticesCount, indicesCount); item.texture = texture; @@ -172,7 +188,10 @@ namespace Spine { itemVertices[ii].TextureCoordinate.X = uvs[v]; itemVertices[ii].TextureCoordinate.Y = uvs[v + 1]; } + + clipper.ClipEnd(slot); } + clipper.ClipEnd(); } } }