@SuppressWarnings("null") public void draw(PolygonSpriteBatch batch, Skeleton skeleton) { boolean premultipliedAlpha = this.premultipliedAlpha; BlendMode blendMode = null; float[] vertices = null; short[] triangles = null; Array<Slot> drawOrder = skeleton.drawOrder; for (int i = 0, n = drawOrder.size; i < n; i++) { Slot slot = drawOrder.get(i); Attachment attachment = slot.attachment; Texture texture = null; if (attachment instanceof RegionAttachment) { RegionAttachment region = (RegionAttachment) attachment; vertices = region.updateWorldVertices(slot, premultipliedAlpha); triangles = quadTriangles; texture = region.getRegion().getTexture(); } else if (attachment instanceof MeshAttachment) { MeshAttachment mesh = (MeshAttachment) attachment; vertices = mesh.updateWorldVertices(slot, premultipliedAlpha); triangles = mesh.getTriangles(); texture = mesh.getRegion().getTexture(); } else if (attachment instanceof SkeletonAttachment) { Skeleton attachmentSkeleton = ((SkeletonAttachment) attachment).getSkeleton(); if (attachmentSkeleton == null) continue; Bone bone = slot.getBone(); Bone rootBone = attachmentSkeleton.getRootBone(); float oldScaleX = rootBone.getScaleX(); float oldScaleY = rootBone.getScaleY(); float oldRotation = rootBone.getRotation(); attachmentSkeleton.setPosition(bone.getWorldX(), bone.getWorldY()); // rootBone.setScaleX(1 + bone.getWorldScaleX() - oldScaleX); // rootBone.setScaleY(1 + bone.getWorldScaleY() - oldScaleY); // Set shear. rootBone.setRotation(oldRotation + bone.getWorldRotationX()); attachmentSkeleton.updateWorldTransform(); draw(batch, attachmentSkeleton); attachmentSkeleton.setPosition(0, 0); rootBone.setScaleX(oldScaleX); rootBone.setScaleY(oldScaleY); rootBone.setRotation(oldRotation); } if (texture != null) { BlendMode slotBlendMode = slot.data.getBlendMode(); if (slotBlendMode != blendMode) { blendMode = slotBlendMode; batch.setBlendFunction(blendMode.getSource(premultipliedAlpha), blendMode.getDest()); } batch.draw(texture, vertices, 0, vertices.length, triangles, 0, triangles.length); } } }
/** * Returns the axis aligned bounding box (AABB) of the region, mesh, and skinned mesh attachments * for the current pose. * * @param offset The distance from the skeleton origin to the bottom left corner of the AABB. * @param size The width and height of the AABB. */ public void getBounds(Vector2 offset, Vector2 size) { Array<Slot> drawOrder = this.drawOrder; float minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; for (int i = 0, n = drawOrder.size; i < n; i++) { Slot slot = drawOrder.get(i); float[] vertices = null; Attachment attachment = slot.attachment; if (attachment instanceof RegionAttachment) { RegionAttachment region = (RegionAttachment) attachment; region.updateWorldVertices(slot, false); vertices = region.getWorldVertices(); } else if (attachment instanceof MeshAttachment) { MeshAttachment mesh = (MeshAttachment) attachment; mesh.updateWorldVertices(slot, true); vertices = mesh.getWorldVertices(); } else if (attachment instanceof SkinnedMeshAttachment) { SkinnedMeshAttachment mesh = (SkinnedMeshAttachment) attachment; mesh.updateWorldVertices(slot, true); vertices = mesh.getWorldVertices(); } if (vertices != null) { for (int ii = 0, nn = vertices.length; ii < nn; ii += 5) { float x = vertices[ii], y = vertices[ii + 1]; minX = Math.min(minX, x); minY = Math.min(minY, y); maxX = Math.max(maxX, x); maxY = Math.max(maxY, y); } } } offset.set(minX, minY); size.set(maxX - minX, maxY - minY); }