Skip to content

Commit

Permalink
[libgdx] Skeleton.getBounds() applies clipping, see #2515
Browse files Browse the repository at this point in the history
  • Loading branch information
badlogic committed May 2, 2024
1 parent a228adf commit b043e5c
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
Expand Up @@ -38,16 +38,16 @@
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.
* <p>
* See <a href="http://esotericsoftware.com/spine-runtime-architecture#Instance-objects">Instance objects</a> 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<Bone> bones;
final Array<Slot> slots;
Expand Down Expand Up @@ -699,19 +699,31 @@ public void getBounds (Vector2 offset, Vector2 size, FloatArray temp) {
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);
Expand All @@ -720,7 +732,9 @@ public void getBounds (Vector2 offset, Vector2 size, FloatArray temp) {
maxY = Math.max(maxY, y);
}
}
clipper.clipEnd(slot);
}
clipper.clipEnd();
offset.set(minX, minY);
size.set(maxX - minX, maxY - minY);
}
Expand Down
Expand Up @@ -82,6 +82,78 @@ public boolean isClipping () {
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) {

Expand Down

0 comments on commit b043e5c

Please sign in to comment.