diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java index eb7dc8b2c..210a3a4cf 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/ClippingTest.java @@ -105,7 +105,7 @@ public class ClippingTest extends ApplicationAdapter { // -140, 50, // // }); clip.setWorldVerticesLength(8); - clip.setEnd(skeleton.findSlot("front_hand")); + clip.setEndSlot(skeleton.findSlot("front_hand").data.index); SlotData clipSlotData = new SlotData(skeletonData.getSlots().size, "clip slot", skeletonData.getBones().first()); skeletonData.getSlots().add(clipSlotData); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java index 7523a115e..0965f95e6 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java @@ -42,7 +42,7 @@ public class BoneData { TransformMode transformMode = TransformMode.normal; // Nonessential. - final Color color = new Color(0.61f, 0.61f, 0.61f, 1); + final Color color = new Color(0.61f, 0.61f, 0.61f, 1); // 9b9b9bff /** @param parent May be null. */ public BoneData (int index, String name, BoneData parent) { diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index 556e44aa2..28d542e52 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -68,6 +68,7 @@ import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.AttachmentLoader; import com.esotericsoftware.spine.attachments.AttachmentType; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; +import com.esotericsoftware.spine.attachments.ClippingAttachment; import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.PathAttachment; import com.esotericsoftware.spine.attachments.PointAttachment; @@ -377,7 +378,6 @@ public class SkeletonBinary { region.updateOffset(); return region; } - // BOZO! - Binary clip export. case boundingbox: { int vertexCount = input.readInt(true); Vertices vertices = readVertices(input, vertexCount); @@ -486,6 +486,21 @@ public class SkeletonBinary { if (nonessential) Color.rgba8888ToColor(point.getColor(), color); return point; } + case clipping: { + int endSlotIndex = input.readInt(true); + int vertexCount = input.readInt(true); + Vertices vertices = readVertices(input, vertexCount); + int color = nonessential ? input.readInt() : 0; + + ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) return null; + clip.setEndSlot(endSlotIndex); + clip.setWorldVerticesLength(vertexCount << 1); + clip.setVertices(vertices.vertices); + clip.setBones(vertices.bones); + if (nonessential) Color.rgba8888ToColor(clip.getColor(), color); + return clip; + } } return null; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index cdd9fafab..94281598c 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -65,6 +65,7 @@ import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.AttachmentLoader; import com.esotericsoftware.spine.attachments.AttachmentType; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; +import com.esotericsoftware.spine.attachments.ClippingAttachment; import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.PathAttachment; import com.esotericsoftware.spine.attachments.PointAttachment; @@ -207,7 +208,7 @@ public class SkeletonJson { data.local = constraintMap.getBoolean("local", false); data.relative = constraintMap.getBoolean("relative", false); - + data.offsetRotation = constraintMap.getFloat("rotation", 0); data.offsetX = constraintMap.getFloat("x", 0) * scale; data.offsetY = constraintMap.getFloat("y", 0) * scale; @@ -261,7 +262,7 @@ public class SkeletonJson { if (slot == null) throw new SerializationException("Slot not found: " + slotEntry.name); for (JsonValue entry = slotEntry.child; entry != null; entry = entry.next) { try { - Attachment attachment = readAttachment(entry, skin, slot.index, entry.name); + Attachment attachment = readAttachment(entry, skin, slot.index, entry.name, skeletonData); if (attachment != null) skin.addAttachment(slot.index, entry.name, attachment); } catch (Exception ex) { throw new SerializationException("Error reading attachment: " + entry.name + ", skin: " + skin, ex); @@ -311,7 +312,7 @@ public class SkeletonJson { return skeletonData; } - private Attachment readAttachment (JsonValue map, Skin skin, int slotIndex, String name) { + private Attachment readAttachment (JsonValue map, Skin skin, int slotIndex, String name, SkeletonData skeletonData) { float scale = this.scale; name = map.getString("name", name); @@ -337,7 +338,6 @@ public class SkeletonJson { region.updateOffset(); return region; } - // BOZO! - JSON clip export. case boundingbox: { BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name); if (box == null) return null; @@ -407,6 +407,20 @@ public class SkeletonJson { if (color != null) point.getColor().set(Color.valueOf(color)); return point; } + case clipping: { + ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) return null; + + SlotData slot = skeletonData.findSlot(map.getString("end")); + if (slot == null) throw new SerializationException("Slot not found: " + map.getString("end")); + clip.setEndSlot(slot.index); + + readVertices(map, clip, map.getInt("vertexCount") << 1); + + String color = map.getString("color", null); + if (color != null) clip.getColor().set(Color.valueOf(color)); + return clip; + } } return null; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index 84f574591..f91d5203a 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -40,6 +40,7 @@ import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer; import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.NumberUtils; import com.badlogic.gdx.utils.ShortArray; @@ -51,8 +52,8 @@ import com.esotericsoftware.spine.attachments.SkeletonAttachment; import com.esotericsoftware.spine.utils.Clipper; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; -public class SkeletonRenderer { - static private final short[] quadTriangles = { 0, 1, 2, 2, 3, 0 }; +public class SkeletonRenderer implements Disposable { + static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0}; private boolean softwareClipping; private boolean premultipliedAlpha; @@ -60,16 +61,15 @@ public class SkeletonRenderer { private Clipper clipper = new Clipper(); private ClippingAttachment clipAttachment; - private Slot clipEnd; private FloatArray clippingArea = new FloatArray(); private boolean clippingAreaClockwise; private FloatArray clipOutput = new FloatArray(400); - private FloatArray clippedVertices = new FloatArray(400); + private FloatArray clippedVertices = new FloatArray(400); private ShortArray clippedTriangles = new ShortArray(400); private final Matrix4 combinedMatrix = new Matrix4(); - private ImmediateModeRenderer renderer; // BOZO! - Dispose. + private ImmediateModeRenderer renderer; - public void draw(Batch batch, Skeleton skeleton) { + public void draw (Batch batch, Skeleton skeleton) { boolean premultipliedAlpha = this.premultipliedAlpha; float[] vertices = this.vertices.items; Color skeletonColor = skeleton.color; @@ -79,14 +79,14 @@ public class SkeletonRenderer { Slot slot = drawOrder.get(i); Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { - RegionAttachment region = (RegionAttachment) attachment; + RegionAttachment region = (RegionAttachment)attachment; region.computeWorldVertices(slot.getBone(), vertices, 0, 5); Color color = region.getColor(), slotColor = slot.getColor(); float alpha = a * slotColor.a * color.a * 255; - float c = NumberUtils.intToFloatColor(((int) alpha << 24) // - | ((int) (b * slotColor.b * color.b * alpha) << 16) // - | ((int) (g * slotColor.g * color.g * alpha) << 8) // - | (int) (r * slotColor.r * color.r * alpha)); + float c = NumberUtils.intToFloatColor(((int)alpha << 24) // + | ((int)(b * slotColor.b * color.b * alpha) << 16) // + | ((int)(g * slotColor.g * color.g * alpha) << 8) // + | (int)(r * slotColor.r * color.r * alpha)); float[] uvs = region.getUVs(); for (int u = 0, v = 2; u < 8; u += 2, v += 5) { vertices[v] = c; @@ -99,7 +99,7 @@ public class SkeletonRenderer { batch.draw(region.getRegion().getTexture(), vertices, 0, 20); } else if (attachment instanceof ClippingAttachment) { - ClippingAttachment clip = (ClippingAttachment) attachment; + ClippingAttachment clip = (ClippingAttachment)attachment; if (!softwareClipping) batch.end(); clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); if (!softwareClipping) batch.begin(); @@ -109,7 +109,7 @@ public class SkeletonRenderer { throw new RuntimeException("SkeletonMeshRenderer is required to render meshes."); } else if (attachment instanceof SkeletonAttachment) { - Skeleton attachmentSkeleton = ((SkeletonAttachment) attachment).getSkeleton(); + Skeleton attachmentSkeleton = ((SkeletonAttachment)attachment).getSkeleton(); if (attachmentSkeleton != null) { Bone bone = slot.getBone(); Bone rootBone = attachmentSkeleton.getRootBone(); @@ -135,7 +135,7 @@ public class SkeletonRenderer { } } - if (slot == clipEnd) { + if (clipAttachment != null && i == clipAttachment.getEndSlot()) { batch.flush(); clipEnd(); } @@ -143,7 +143,7 @@ public class SkeletonRenderer { } @SuppressWarnings("null") - public void draw(PolygonSpriteBatch batch, Skeleton skeleton) { + public void draw (PolygonSpriteBatch batch, Skeleton skeleton) { boolean premultipliedAlpha = this.premultipliedAlpha; BlendMode blendMode = null; int verticesLength = 0; @@ -152,13 +152,13 @@ public class SkeletonRenderer { Texture texture = null; Color color = null, skeletonColor = skeleton.color; float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a; - Array drawOrder = skeleton.drawOrder; + Array drawOrder = skeleton.drawOrder; for (int i = 0, n = drawOrder.size; i < n; i++) { final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 5; Slot slot = drawOrder.get(i); - Attachment attachment = slot.attachment; + Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { - RegionAttachment region = (RegionAttachment) attachment; + RegionAttachment region = (RegionAttachment)attachment; verticesLength = vertexSize << 2; vertices = this.vertices.items; region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize); @@ -168,7 +168,7 @@ public class SkeletonRenderer { color = region.getColor(); } else if (attachment instanceof MeshAttachment) { - MeshAttachment mesh = (MeshAttachment) attachment; + MeshAttachment mesh = (MeshAttachment)attachment; int count = mesh.getWorldVerticesLength(); verticesLength = (count >> 1) * vertexSize; vertices = this.vertices.setSize(verticesLength); @@ -179,14 +179,14 @@ public class SkeletonRenderer { color = mesh.getColor(); } else if (attachment instanceof ClippingAttachment) { - ClippingAttachment clip = (ClippingAttachment) attachment; + ClippingAttachment clip = (ClippingAttachment)attachment; if (!softwareClipping) batch.end(); clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); if (!softwareClipping) batch.begin(); continue; } else if (attachment instanceof SkeletonAttachment) { - Skeleton attachmentSkeleton = ((SkeletonAttachment) attachment).getSkeleton(); + Skeleton attachmentSkeleton = ((SkeletonAttachment)attachment).getSkeleton(); if (attachmentSkeleton != null) { Bone bone = slot.getBone(); Bone rootBone = attachmentSkeleton.getRootBone(); @@ -214,10 +214,10 @@ public class SkeletonRenderer { if (texture != null) { Color slotColor = slot.getColor(); float alpha = a * slotColor.a * color.a * 255; - float c = NumberUtils.intToFloatColor(((int) alpha << 24) // - | ((int) (b * slotColor.b * color.b * alpha) << 16) // - | ((int) (g * slotColor.g * color.g * alpha) << 8) // - | (int) (r * slotColor.r * color.r * alpha)); + float c = NumberUtils.intToFloatColor(((int)alpha << 24) // + | ((int)(b * slotColor.b * color.b * alpha) << 16) // + | ((int)(g * slotColor.g * color.g * alpha) << 8) // + | (int)(r * slotColor.r * color.r * alpha)); BlendMode slotBlendMode = slot.data.getBlendMode(); if (slotBlendMode != blendMode) { @@ -226,8 +226,10 @@ public class SkeletonRenderer { } if (softwareClipping) { if (clipAttachment != null) { - clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, 0, c, false, clippedVertices, clippedTriangles); - batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size); + clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, 0, c, false, clippedVertices, + clippedTriangles); + batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, + clippedTriangles.size); } else { for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) { vertices[v] = c; @@ -246,7 +248,7 @@ public class SkeletonRenderer { } } - if (slot == clipEnd) { + if (clipAttachment != null && i == clipAttachment.getEndSlot()) { if (!softwareClipping) batch.flush(); clipEnd(); } @@ -254,7 +256,7 @@ public class SkeletonRenderer { } @SuppressWarnings("null") - public void draw(TwoColorPolygonBatch batch, Skeleton skeleton) { + public void draw (TwoColorPolygonBatch batch, Skeleton skeleton) { boolean premultipliedAlpha = this.premultipliedAlpha; BlendMode blendMode = null; int verticesLength = 0; @@ -263,13 +265,13 @@ public class SkeletonRenderer { Texture texture = null; Color color = null, skeletonColor = skeleton.color; float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a; - Array drawOrder = skeleton.drawOrder; + Array drawOrder = skeleton.drawOrder; for (int i = 0, n = drawOrder.size; i < n; i++) { final int vertexSize = (softwareClipping && clipAttachment != null) ? 2 : 6; Slot slot = drawOrder.get(i); Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { - RegionAttachment region = (RegionAttachment) attachment; + RegionAttachment region = (RegionAttachment)attachment; verticesLength = vertexSize << 2; vertices = this.vertices.items; region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize); @@ -279,7 +281,7 @@ public class SkeletonRenderer { color = region.getColor(); } else if (attachment instanceof MeshAttachment) { - MeshAttachment mesh = (MeshAttachment) attachment; + MeshAttachment mesh = (MeshAttachment)attachment; int count = mesh.getWorldVerticesLength(); verticesLength = count * (vertexSize >> 1); vertices = this.vertices.setSize(verticesLength); @@ -290,14 +292,14 @@ public class SkeletonRenderer { color = mesh.getColor(); } else if (attachment instanceof ClippingAttachment) { - ClippingAttachment clip = (ClippingAttachment) attachment; + ClippingAttachment clip = (ClippingAttachment)attachment; if (!softwareClipping) batch.end(); clipStart(batch.getProjectionMatrix(), batch.getTransformMatrix(), slot, clip); if (!softwareClipping) batch.begin(); continue; } else if (attachment instanceof SkeletonAttachment) { - Skeleton attachmentSkeleton = ((SkeletonAttachment) attachment).getSkeleton(); + Skeleton attachmentSkeleton = ((SkeletonAttachment)attachment).getSkeleton(); if (attachmentSkeleton != null) { Bone bone = slot.getBone(); Bone rootBone = attachmentSkeleton.getRootBone(); @@ -325,28 +327,29 @@ public class SkeletonRenderer { if (texture != null) { Color lightColor = slot.getColor(); float alpha = a * lightColor.a * color.a * 255; - float light = NumberUtils.intToFloatColor(((int) alpha << 24) // - | ((int) (b * lightColor.b * color.b * alpha) << 16) // - | ((int) (g * lightColor.g * color.g * alpha) << 8) // - | (int) (r * lightColor.r * color.r * alpha)); + float light = NumberUtils.intToFloatColor(((int)alpha << 24) // + | ((int)(b * lightColor.b * color.b * alpha) << 16) // + | ((int)(g * lightColor.g * color.g * alpha) << 8) // + | (int)(r * lightColor.r * color.r * alpha)); Color darkColor = slot.getDarkColor(); - if (darkColor == null) - darkColor = Color.BLACK; + if (darkColor == null) darkColor = Color.BLACK; float dark = NumberUtils.intToFloatColor( // - ((int) (b * darkColor.b * color.b * 255) << 16) // - | ((int) (g * darkColor.g * color.g * 255) << 8) // - | (int) (r * darkColor.r * color.r * 255)); + ((int)(b * darkColor.b * color.b * 255) << 16) // + | ((int)(g * darkColor.g * color.g * 255) << 8) // + | (int)(r * darkColor.r * color.r * 255)); BlendMode slotBlendMode = slot.data.getBlendMode(); if (slotBlendMode != blendMode) { blendMode = slotBlendMode; batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); } - + if (softwareClipping) { if (clipAttachment != null) { - clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, dark, light, true, clippedVertices, clippedTriangles); - batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size); + clipSoftware(vertices, 0, verticesLength, triangles, 0, triangles.length, uvs, dark, light, true, + clippedVertices, clippedTriangles); + batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, + clippedTriangles.size); } else { for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) { vertices[v] = light; @@ -367,17 +370,16 @@ public class SkeletonRenderer { } } - if (slot == clipEnd) { + if (clipAttachment != null && i == clipAttachment.getEndSlot()) { if (!softwareClipping) batch.flush(); clipEnd(); } } } - private void clipStart(Matrix4 transformMatrix, Matrix4 projectionMatrix, Slot slot, ClippingAttachment clip) { - if (clipEnd != null) return; + private void clipStart (Matrix4 transformMatrix, Matrix4 projectionMatrix, Slot slot, ClippingAttachment clip) { + if (clipAttachment != null) return; clipAttachment = clip; - clipEnd = clip.getEnd(); if (!softwareClipping) { int n = clip.getWorldVerticesLength(); @@ -400,7 +402,7 @@ public class SkeletonRenderer { renderer.end(); Gdx.gl.glColorMask(true, true, true, true); - Gdx.gl.glStencilFunc(clip.getInvert() ? GL20.GL_NOTEQUAL : GL20.GL_EQUAL, 1, 1); + Gdx.gl.glStencilFunc(false ? GL20.GL_NOTEQUAL : GL20.GL_EQUAL, 1, 1); Gdx.gl.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP); } else { int n = clip.getWorldVerticesLength(); @@ -415,35 +417,36 @@ public class SkeletonRenderer { } } - private void clipEnd() { + private void clipEnd () { clipAttachment = null; - clipEnd = null; if (!softwareClipping) Gdx.gl.glDisable(GL20.GL_STENCIL_TEST); } - - private void clipSoftware(final float[] vertices, final int offset, final int verticesLength, final short[] triangles, final int triangleOffset, final int trianglesLength, final float uvs[], final float dark, final float light, final boolean twoColor, final FloatArray clippedVertices, final ShortArray clippedTriangles) { + + private void clipSoftware (final float[] vertices, final int offset, final int verticesLength, final short[] triangles, + final int triangleOffset, final int trianglesLength, final float uvs[], final float dark, final float light, + final boolean twoColor, final FloatArray clippedVertices, final ShortArray clippedTriangles) { short idx = 0; clippedVertices.clear(); clippedTriangles.clear(); for (int i = 0; i < trianglesLength; i += 3) { int vertexOffset = triangles[i] << 1; float x1 = vertices[vertexOffset]; - float y1= vertices[vertexOffset + 1]; + float y1 = vertices[vertexOffset + 1]; float u1 = uvs[vertexOffset]; float v1 = uvs[vertexOffset + 1]; - + vertexOffset = triangles[i + 1] << 1; float x2 = vertices[vertexOffset]; float y2 = vertices[vertexOffset + 1]; float u2 = uvs[vertexOffset]; float v2 = uvs[vertexOffset + 1]; - + vertexOffset = triangles[i + 2] << 1; float x3 = vertices[vertexOffset]; float y3 = vertices[vertexOffset + 1]; float u3 = uvs[vertexOffset]; float v3 = uvs[vertexOffset + 1]; - + boolean clipped = clipper.clip(x1, y1, x2, y2, x3, y3, clippingArea, clipOutput); if (clipped) { if (clipOutput.size == 0) continue; @@ -452,24 +455,24 @@ public class SkeletonRenderer { float d2 = x1 - x3; float d3 = y1 - y3; float d4 = y3 - y1; - + float denom = 1 / (d0 * d2 + d1 * d3); - + float[] clipVertices = clipOutput.items; int s = clippedVertices.size; clippedVertices.setSize(s + (clipOutput.size >> 1) * (twoColor ? 6 : 5)); final float[] clippedVerticesArray = clippedVertices.items; - - for (int j = 0, n = clipOutput.size; j < n; j += 2) { + + for (int j = 0, n = clipOutput.size; j < n; j += 2) { float x = clipVertices[j]; float y = clipVertices[j + 1]; - + float c0 = x - x3; float c1 = y - y3; float a = (d0 * c0 + d1 * c1) * denom; float b = (d4 * c0 + d2 * c1) * denom; float c = 1.0f - a - b; - + float u = u1 * a + u2 * b + u3 * c; float v = v1 * a + v2 * b + v3 * c; clippedVerticesArray[s++] = x; @@ -479,36 +482,36 @@ public class SkeletonRenderer { clippedVerticesArray[s++] = u; clippedVerticesArray[s++] = v; } - + s = clippedTriangles.size; clippedTriangles.setSize(s + 3 * ((clipOutput.size >> 1) - 2)); final short[] clippedTrianglesArray = clippedTriangles.items; - + for (int j = 1, n = (clipOutput.size >> 1) - 1; j < n; j++) { clippedTrianglesArray[s++] = idx; clippedTrianglesArray[s++] = (short)(idx + j); clippedTrianglesArray[s++] = (short)(idx + j + 1); } - + idx += clipOutput.size >> 1; } else { int s = clippedVertices.size; clippedVertices.setSize(s + 3 * (twoColor ? 6 : 5)); final float[] clippedVerticesArray = clippedVertices.items; - - if (!twoColor) { + + if (!twoColor) { clippedVerticesArray[s] = x1; clippedVerticesArray[s + 1] = y1; clippedVerticesArray[s + 2] = light; clippedVerticesArray[s + 3] = u1; clippedVerticesArray[s + 4] = v1; - + clippedVerticesArray[s + 5] = x2; clippedVerticesArray[s + 6] = y2; clippedVerticesArray[s + 7] = light; clippedVerticesArray[s + 8] = u2; clippedVerticesArray[s + 9] = v2; - + clippedVerticesArray[s + 10] = x3; clippedVerticesArray[s + 11] = y3; clippedVerticesArray[s + 12] = light; @@ -521,14 +524,14 @@ public class SkeletonRenderer { clippedVerticesArray[s + 3] = dark; clippedVerticesArray[s + 4] = u1; clippedVerticesArray[s + 5] = v1; - + clippedVerticesArray[s + 6] = x2; clippedVerticesArray[s + 7] = y2; clippedVerticesArray[s + 8] = light; clippedVerticesArray[s + 9] = dark; clippedVerticesArray[s + 10] = u2; clippedVerticesArray[s + 11] = v2; - + clippedVerticesArray[s + 12] = x3; clippedVerticesArray[s + 13] = y3; clippedVerticesArray[s + 14] = light; @@ -536,7 +539,7 @@ public class SkeletonRenderer { clippedVerticesArray[s + 16] = u3; clippedVerticesArray[s + 17] = v3; } - + s = clippedTriangles.size; clippedTriangles.setSize(s + 3); final short[] clippedTrianglesArray = clippedTriangles.items; @@ -547,15 +550,19 @@ public class SkeletonRenderer { } } - public void setPremultipliedAlpha(boolean premultipliedAlpha) { + public void setPremultipliedAlpha (boolean premultipliedAlpha) { this.premultipliedAlpha = premultipliedAlpha; } - + + public void dispose () { + renderer.dispose(); + } + public boolean getSoftwareClipping () { return softwareClipping; } - public void setSoftwareClipping(boolean softwareClipping) { + public void setSoftwareClipping (boolean softwareClipping) { this.softwareClipping = softwareClipping; } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java index aa6b0a9ff..22f85c10b 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java @@ -50,9 +50,8 @@ public class SkeletonRendererDebug { static private final Color boneLineColor = Color.RED; static private final Color boneOriginColor = Color.GREEN; static private final Color attachmentLineColor = new Color(0, 0, 1, 0.5f); - static private final Color triangleLineColor = new Color(1, 0.64f, 0, 0.5f); + static private final Color triangleLineColor = new Color(1, 0.64f, 0, 0.5f); // ffa3007f static private final Color aabbColor = new Color(0, 1, 0, 0.5f); - static private final Color clippingLineColor = Color.MAGENTA; private final ShapeRenderer shapes; private boolean drawBones = true, drawRegionAttachments = true, drawBoundingBoxes = true, drawPoints = true; @@ -190,7 +189,7 @@ public class SkeletonRendererDebug { int nn = clip.getWorldVerticesLength(); float[] vertices = this.vertices.setSize(nn); clip.computeWorldVertices(slot, 0, nn, vertices, 0, 2); - shapes.setColor(clippingLineColor); + shapes.setColor(clip.getColor()); for (int ii = 2; ii < nn; ii += 2) shapes.line(vertices[ii - 2], vertices[ii - 1], vertices[ii], vertices[ii + 1]); shapes.line(vertices[0], vertices[1], vertices[nn - 2], vertices[nn - 1]); @@ -296,6 +295,10 @@ public class SkeletonRendererDebug { public void setPoints (boolean points) { this.drawPoints = points; } + + public void setClipping (boolean clipping) { + this.drawClipping = clipping; + } public void setPremultipliedAlpha (boolean premultipliedAlpha) { this.premultipliedAlpha = premultipliedAlpha; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java index 61c5522ee..2940163d9 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java @@ -31,7 +31,7 @@ package com.esotericsoftware.spine.attachments; public enum AttachmentType { - region, boundingbox, mesh, linkedmesh, path, point; + region, boundingbox, mesh, linkedmesh, path, point, clipping; static public AttachmentType[] values = values(); } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java index b8e8715c5..7e449edb3 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java @@ -40,7 +40,7 @@ import com.esotericsoftware.spine.SkeletonBounds; * Guide. */ public class BoundingBoxAttachment extends VertexAttachment { // Nonessential. - final Color color = new Color(0.38f, 0.94f, 0, 1); + final Color color = new Color(0.38f, 0.94f, 0, 1); // 60f000ff public BoundingBoxAttachment (String name) { super(name); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java index f1c719f98..3da1e3b80 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java @@ -31,37 +31,25 @@ package com.esotericsoftware.spine.attachments; import com.badlogic.gdx.graphics.Color; -import com.esotericsoftware.spine.Slot; /** An attachment with vertices that make up a polygon used for clipping the rendering of other attachments. */ public class ClippingAttachment extends VertexAttachment { - Slot end; - boolean invert; + int endSlot; // Nonessential. - final Color color = new Color(0.38f, 0.94f, 0, 1); + final Color color = new Color(0.2275f, 0.2275f, 0.8078f, 1); // ce3a3aff public ClippingAttachment (String name) { super(name); } /** Clipping is performed between the clipping polygon's slot and the end slot. */ - public Slot getEnd () { - return end; + public int getEndSlot () { + return endSlot; } - public void setEnd (Slot end) { - this.end = end; - } - - /** If false, attachments outside the clipping polygon will be drawn. If true, attachments inside the clipping polygon will be - * drawn. */ - public boolean getInvert () { - return invert; - } - - public void setInvert (boolean invert) { - this.invert = invert; + public void setEndSlot (int slotIndex) { + this.endSlot = slotIndex; } /** The color of the clipping polygon as it was in Spine. Available only when nonessential data was exported. Clipping polygons diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java index 348115e23..a1747c408 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java @@ -41,7 +41,7 @@ public class PathAttachment extends VertexAttachment { boolean closed, constantSpeed; // Nonessential. - final Color color = new Color(1, 0.5f, 0, 1); + final Color color = new Color(1, 0.5f, 0, 1); // ff7f00ff public PathAttachment (String name) { super(name); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java index b601866db..403aca66e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java @@ -45,7 +45,7 @@ public class PointAttachment extends Attachment { float x, y, rotation; // Nonessential. - final Color color = new Color(0.38f, 0.94f, 0, 1); + final Color color = new Color(0.9451f, 0.9451f, 0, 1); // f1f100ff public PointAttachment (String name) { super(name); diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java index b776dc98c..cc7f5bd10 100644 --- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java +++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java @@ -299,6 +299,7 @@ public class SkeletonViewer extends ApplicationAdapter { debugRenderer.setMeshTriangles(ui.debugMeshTrianglesCheckbox.isChecked()); debugRenderer.setPaths(ui.debugPathsCheckbox.isChecked()); debugRenderer.setPoints(ui.debugPointsCheckbox.isChecked()); + debugRenderer.setClipping(ui.debugClippingCheckbox.isChecked()); debugRenderer.draw(skeleton); } @@ -396,6 +397,7 @@ public class SkeletonViewer extends ApplicationAdapter { CheckBox debugMeshTrianglesCheckbox = new CheckBox("Triangles", skin); CheckBox debugPathsCheckbox = new CheckBox("Paths", skin); CheckBox debugPointsCheckbox = new CheckBox("Points", skin); + CheckBox debugClippingCheckbox = new CheckBox("Clipping", skin); Slider scaleSlider = new Slider(0.1f, 3, 0.01f, false, skin); Slider zoomSlider = new Slider(0.01f, 10, 0.01f, false, skin); Label scaleLabel = new Label("1.0", skin); @@ -452,7 +454,7 @@ public class SkeletonViewer extends ApplicationAdapter { window.setX(-3); window.setY(-2); - window.getTitleLabel().setColor(new Color(0.76f, 1, 1, 1)); + window.getTitleLabel().setColor(new Color(0xc1ffffff)); window.getTitleTable().add(openButton).space(3); window.getTitleTable().add(minimizeButton).width(20); @@ -486,7 +488,7 @@ public class SkeletonViewer extends ApplicationAdapter { root.add("Debug:"); root.add(table(debugBonesCheckbox, debugRegionsCheckbox, debugBoundingBoxesCheckbox)).row(); root.add(); - root.add(table(debugPathsCheckbox, debugPointsCheckbox)).row(); + root.add(table(debugPathsCheckbox, debugPointsCheckbox, debugClippingCheckbox)).row(); root.add(); root.add(table(debugMeshHullCheckbox, debugMeshTrianglesCheckbox)).row(); root.add("Atlas alpha:"); @@ -784,6 +786,7 @@ public class SkeletonViewer extends ApplicationAdapter { debugMeshTrianglesCheckbox.addListener(savePrefsListener); debugPathsCheckbox.addListener(savePrefsListener); debugPointsCheckbox.addListener(savePrefsListener); + debugClippingCheckbox.addListener(savePrefsListener); premultipliedCheckbox.addListener(savePrefsListener); loopCheckbox.addListener(savePrefsListener); multipleMixingCheckbox.addListener(savePrefsListener); @@ -848,6 +851,7 @@ public class SkeletonViewer extends ApplicationAdapter { prefs.putBoolean("debugMeshTriangles", debugMeshTrianglesCheckbox.isChecked()); prefs.putBoolean("debugPaths", debugPathsCheckbox.isChecked()); prefs.putBoolean("debugPoints", debugPointsCheckbox.isChecked()); + prefs.putBoolean("debugClipping", debugClippingCheckbox.isChecked()); prefs.putBoolean("premultiplied", premultipliedCheckbox.isChecked()); prefs.putBoolean("loop", loopCheckbox.isChecked()); prefs.putBoolean("multipleMixing", multipleMixingCheckbox.isChecked()); @@ -874,6 +878,7 @@ public class SkeletonViewer extends ApplicationAdapter { debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false)); debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true)); debugPointsCheckbox.setChecked(prefs.getBoolean("debugPoints", true)); + debugClippingCheckbox.setChecked(prefs.getBoolean("debugClipping", true)); premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true)); loopCheckbox.setChecked(prefs.getBoolean("loop", false)); multipleMixingCheckbox.setChecked(prefs.getBoolean("multipleMixing", false));