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.badlogic.gdx.utils.Null;
|
||||||
|
|
||||||
import com.esotericsoftware.spine.Skin.SkinEntry;
|
import com.esotericsoftware.spine.Skin.SkinEntry;
|
||||||
import com.esotericsoftware.spine.attachments.Attachment;
|
import com.esotericsoftware.spine.attachments.*;
|
||||||
import com.esotericsoftware.spine.attachments.MeshAttachment;
|
import com.esotericsoftware.spine.utils.SkeletonClipping;
|
||||||
import com.esotericsoftware.spine.attachments.PathAttachment;
|
|
||||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
|
||||||
|
|
||||||
/** Stores the current pose for a skeleton.
|
/** Stores the current pose for a skeleton.
|
||||||
* <p>
|
* <p>
|
||||||
* See <a href="http://esotericsoftware.com/spine-runtime-architecture#Instance-objects">Instance objects</a> in the Spine
|
* See <a href="http://esotericsoftware.com/spine-runtime-architecture#Instance-objects">Instance objects</a> in the Spine
|
||||||
* Runtimes Guide. */
|
* Runtimes Guide. */
|
||||||
public class Skeleton {
|
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 SkeletonData data;
|
||||||
final Array<Bone> bones;
|
final Array<Bone> bones;
|
||||||
final Array<Slot> slots;
|
final Array<Slot> slots;
|
||||||
@ -699,19 +699,31 @@ public class Skeleton {
|
|||||||
if (!slot.bone.active) continue;
|
if (!slot.bone.active) continue;
|
||||||
int verticesLength = 0;
|
int verticesLength = 0;
|
||||||
float[] vertices = null;
|
float[] vertices = null;
|
||||||
|
short[] triangles = null;
|
||||||
Attachment attachment = slot.attachment;
|
Attachment attachment = slot.attachment;
|
||||||
if (attachment instanceof RegionAttachment) {
|
if (attachment instanceof RegionAttachment) {
|
||||||
RegionAttachment region = (RegionAttachment)attachment;
|
RegionAttachment region = (RegionAttachment)attachment;
|
||||||
verticesLength = 8;
|
verticesLength = 8;
|
||||||
vertices = temp.setSize(8);
|
vertices = temp.setSize(8);
|
||||||
region.computeWorldVertices(slot, vertices, 0, 2);
|
region.computeWorldVertices(slot, vertices, 0, 2);
|
||||||
|
triangles = quadTriangles;
|
||||||
} else if (attachment instanceof MeshAttachment) {
|
} else if (attachment instanceof MeshAttachment) {
|
||||||
MeshAttachment mesh = (MeshAttachment)attachment;
|
MeshAttachment mesh = (MeshAttachment)attachment;
|
||||||
verticesLength = mesh.getWorldVerticesLength();
|
verticesLength = mesh.getWorldVerticesLength();
|
||||||
vertices = temp.setSize(verticesLength);
|
vertices = temp.setSize(verticesLength);
|
||||||
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
|
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 (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) {
|
for (int ii = 0; ii < verticesLength; ii += 2) {
|
||||||
float x = vertices[ii], y = vertices[ii + 1];
|
float x = vertices[ii], y = vertices[ii + 1];
|
||||||
minX = Math.min(minX, x);
|
minX = Math.min(minX, x);
|
||||||
@ -720,7 +732,9 @@ public class Skeleton {
|
|||||||
maxY = Math.max(maxY, y);
|
maxY = Math.max(maxY, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clipper.clipEnd(slot);
|
||||||
}
|
}
|
||||||
|
clipper.clipEnd();
|
||||||
offset.set(minX, minY);
|
offset.set(minX, minY);
|
||||||
size.set(maxX - minX, maxY - minY);
|
size.set(maxX - minX, maxY - minY);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,6 +82,78 @@ public class SkeletonClipping {
|
|||||||
return clipAttachment != null;
|
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,
|
public void clipTriangles (float[] vertices, int verticesLength, short[] triangles, int trianglesLength, float[] uvs,
|
||||||
float light, float dark, boolean twoColor) {
|
float light, float dark, boolean twoColor) {
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user