mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 09:16:01 +08:00
[csharp][unity] Skeleton.getBounds() applies clipping, see #2515. Port of commits b043e5c, 637321a and 2049bed.
This commit is contained in:
parent
2049bed11e
commit
c6a01d7a5f
@ -31,6 +31,7 @@ using System;
|
||||
|
||||
namespace Spine {
|
||||
public class Skeleton {
|
||||
static private readonly int[] quadTriangles = { 0, 1, 2, 2, 3, 0 };
|
||||
internal SkeletonData data;
|
||||
internal ExposedList<Bone> bones;
|
||||
internal ExposedList<Slot> slots;
|
||||
@ -696,7 +697,9 @@ namespace Spine {
|
||||
/// <param name="width">The width of the AABB</param>
|
||||
/// <param name="height">The height of the AABB.</param>
|
||||
/// <param name="vertexBuffer">Reference to hold a float[]. May be a null reference. This method will assign it a new float[] with the appropriate size as needed.</param>
|
||||
public void GetBounds (out float x, out float y, out float width, out float height, ref float[] vertexBuffer) {
|
||||
public void GetBounds (out float x, out float y, out float width, out float height, ref float[] vertexBuffer,
|
||||
SkeletonClipping clipper = null) {
|
||||
|
||||
float[] temp = vertexBuffer;
|
||||
temp = temp ?? new float[8];
|
||||
Slot[] drawOrder = this.drawOrder.Items;
|
||||
@ -706,6 +709,7 @@ namespace Spine {
|
||||
if (!slot.bone.active) continue;
|
||||
int verticesLength = 0;
|
||||
float[] vertices = null;
|
||||
int[] triangles = null;
|
||||
Attachment attachment = slot.attachment;
|
||||
RegionAttachment region = attachment as RegionAttachment;
|
||||
if (region != null) {
|
||||
@ -713,6 +717,7 @@ namespace Spine {
|
||||
vertices = temp;
|
||||
if (vertices.Length < 8) vertices = temp = new float[8];
|
||||
region.ComputeWorldVertices(slot, temp, 0, 2);
|
||||
triangles = quadTriangles;
|
||||
} else {
|
||||
MeshAttachment mesh = attachment as MeshAttachment;
|
||||
if (mesh != null) {
|
||||
@ -720,10 +725,23 @@ namespace Spine {
|
||||
vertices = temp;
|
||||
if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength];
|
||||
mesh.ComputeWorldVertices(slot, 0, verticesLength, temp, 0, 2);
|
||||
triangles = mesh.Triangles;
|
||||
} else if (clipper != null) {
|
||||
ClippingAttachment clip = attachment as ClippingAttachment;
|
||||
if (clip != null) {
|
||||
clipper.ClipStart(slot, clip);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices != null) {
|
||||
if (clipper != null && clipper.IsClipping) {
|
||||
clipper.ClipTriangles(vertices, verticesLength, triangles, triangles.Length);
|
||||
vertices = clipper.ClippedVertices.Items;
|
||||
verticesLength = clipper.ClippedVertices.Count;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < verticesLength; ii += 2) {
|
||||
float vx = vertices[ii], vy = vertices[ii + 1];
|
||||
minX = Math.Min(minX, vx);
|
||||
@ -732,7 +750,9 @@ namespace Spine {
|
||||
maxY = Math.Max(maxY, vy);
|
||||
}
|
||||
}
|
||||
if (clipper != null) clipper.ClipEnd(slot);
|
||||
}
|
||||
if (clipper != null) clipper.ClipEnd();
|
||||
x = minX;
|
||||
y = minY;
|
||||
width = maxX - minX;
|
||||
|
||||
@ -78,6 +78,73 @@ namespace Spine {
|
||||
clippingPolygon.Clear();
|
||||
}
|
||||
|
||||
public void ClipTriangles (float[] vertices, int verticesLength, int[] triangles, int trianglesLength) {
|
||||
ExposedList<float> clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
|
||||
ExposedList<int> clippedTriangles = this.clippedTriangles;
|
||||
ExposedList<float>[] polygons = clippingPolygons.Items;
|
||||
int polygonsCount = clippingPolygons.Count;
|
||||
|
||||
int 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.Count;
|
||||
if (Clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
|
||||
int clipOutputLength = clipOutput.Count;
|
||||
if (clipOutputLength == 0) continue;
|
||||
|
||||
int clipOutputCount = clipOutputLength >> 1;
|
||||
float[] clipOutputItems = clipOutput.Items;
|
||||
float[] clippedVerticesItems = clippedVertices.Resize(s + clipOutputCount * 2).Items;
|
||||
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.Count;
|
||||
int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items;
|
||||
clipOutputCount--;
|
||||
for (int ii = 1; ii < clipOutputCount; ii++) {
|
||||
clippedTrianglesItems[s] = index;
|
||||
clippedTrianglesItems[s + 1] = index + ii;
|
||||
clippedTrianglesItems[s + 2] = index + ii + 1;
|
||||
s += 3;
|
||||
}
|
||||
index += clipOutputCount + 1;
|
||||
} else {
|
||||
float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items;
|
||||
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.Count;
|
||||
int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items;
|
||||
clippedTrianglesItems[s] = index;
|
||||
clippedTrianglesItems[s + 1] = index + 1;
|
||||
clippedTrianglesItems[s + 2] = index + 2;
|
||||
index += 3;
|
||||
break; //continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClipTriangles (float[] vertices, int verticesLength, int[] triangles, int trianglesLength, float[] uvs) {
|
||||
ExposedList<float> clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
|
||||
ExposedList<int> clippedTriangles = this.clippedTriangles;
|
||||
@ -164,11 +231,10 @@ namespace Spine {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
|
||||
* area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
|
||||
///<summary>Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
|
||||
/// area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list.</summary>
|
||||
internal bool Clip (float x1, float y1, float x2, float y2, float x3, float y3, ExposedList<float> clippingArea, ExposedList<float> output) {
|
||||
ExposedList<float> originalOutput = output;
|
||||
bool clipped = false;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "com.esotericsoftware.spine.spine-csharp",
|
||||
"displayName": "spine-csharp Runtime",
|
||||
"description": "This plugin provides the spine-csharp core runtime.",
|
||||
"version": "4.2.21",
|
||||
"version": "4.2.22",
|
||||
"unity": "2018.3",
|
||||
"author": {
|
||||
"name": "Esoteric Software",
|
||||
|
||||
@ -645,6 +645,11 @@ namespace Spine.Unity {
|
||||
readonly ExposedList<Material> usedMaterials = new ExposedList<Material>();
|
||||
readonly ExposedList<Texture> usedTextures = new ExposedList<Texture>();
|
||||
|
||||
/// <summary>Returns the <see cref="SkeletonClipping"/> used by this renderer for use with e.g.
|
||||
/// <see cref="Skeleton.GetBounds(out float, out float, out float, out float, ref float[], SkeletonClipping)"/>
|
||||
/// </summary>
|
||||
public SkeletonClipping SkeletonClipping { get { return meshGenerator.SkeletonClipping; } }
|
||||
|
||||
public ExposedList<Mesh> MeshesMultipleCanvasRenderers { get { return meshes; } }
|
||||
public ExposedList<Material> MaterialsMultipleCanvasRenderers { get { return usedMaterials; } }
|
||||
public ExposedList<Texture> TexturesMultipleCanvasRenderers { get { return usedTextures; } }
|
||||
|
||||
@ -270,6 +270,11 @@ namespace Spine.Unity {
|
||||
[System.NonSerialized] readonly SkeletonRendererInstruction currentInstructions = new SkeletonRendererInstruction();
|
||||
readonly MeshGenerator meshGenerator = new MeshGenerator();
|
||||
[System.NonSerialized] readonly MeshRendererBuffers rendererBuffers = new MeshRendererBuffers();
|
||||
|
||||
/// <summary>Returns the <see cref="SkeletonClipping"/> used by this renderer for use with e.g.
|
||||
/// <see cref="Skeleton.GetBounds(out float, out float, out float, out float, ref float[], SkeletonClipping)"/>
|
||||
/// </summary>
|
||||
public SkeletonClipping SkeletonClipping { get { return meshGenerator.SkeletonClipping; } }
|
||||
#endregion
|
||||
|
||||
#region Cached component references
|
||||
|
||||
@ -156,6 +156,11 @@ namespace Spine.Unity {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns the <see cref="SkeletonClipping"/> used by this mesh generator for use with e.g.
|
||||
/// <see cref="Skeleton.GetBounds(out float, out float, out float, out float, ref float[], SkeletonClipping)"/>
|
||||
/// </summary>
|
||||
public SkeletonClipping SkeletonClipping { get { return clipper; } }
|
||||
|
||||
public MeshGenerator () {
|
||||
submeshes.TrimExcess();
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "com.esotericsoftware.spine.spine-unity",
|
||||
"displayName": "spine-unity Runtime",
|
||||
"description": "This plugin provides the spine-unity runtime core.",
|
||||
"version": "4.2.61",
|
||||
"version": "4.2.62",
|
||||
"unity": "2018.3",
|
||||
"author": {
|
||||
"name": "Esoteric Software",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user