mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[libgdx] Skeleton.getBounds() applies clipping, see #2515
This commit is contained in:
parent
a228adf684
commit
b043e5c978
@ -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.
|
||||
* <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;
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user