package com.uwsoft.editor.view.ui.widget.actors; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.utils.Array; import com.esotericsoftware.spine.*; import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.WeightedMeshAttachment; import com.uwsoft.editor.renderer.resources.IResourceRetriever; public class SpineActor extends Actor { private String animationName; public SkeletonData skeletonData; private SkeletonRenderer renderer; private Skeleton skeleton; private AnimationState state; private IResourceRetriever irr; private SkeletonJson skeletonJson; private float minX = 0; private float minY = 0; public SpineActor(String animationName, IResourceRetriever irr) { this.irr = irr; this.renderer = new SkeletonRenderer(); this.animationName = animationName; initSkeletonData(); initSpine(); } private void computeBoundBox() { skeleton.updateWorldTransform(); minX = Float.MAX_VALUE; minY = Float.MAX_VALUE; float maxX = Float.MIN_VALUE, maxY = Float.MIN_VALUE; for (int i = 0, n = skeleton.getSlots().size; i < n; i++) { Slot slot = skeleton.getSlots().get(i); Attachment attachment = slot.getAttachment(); if (attachment == null) continue; if (!((attachment instanceof RegionAttachment) || (attachment instanceof MeshAttachment) || (attachment instanceof WeightedMeshAttachment))) continue; float[] vertices = new float[0]; if ((attachment instanceof RegionAttachment)) { RegionAttachment region = (RegionAttachment) attachment; region.updateWorldVertices(slot, false); vertices = region.getWorldVertices(); } if ((attachment instanceof MeshAttachment)) { MeshAttachment region = (MeshAttachment) attachment; region.updateWorldVertices(slot, false); vertices = region.getWorldVertices(); } if ((attachment instanceof WeightedMeshAttachment)) { WeightedMeshAttachment region = (WeightedMeshAttachment) attachment; region.updateWorldVertices(slot, false); vertices = region.getWorldVertices(); } for (int ii = 0, nn = vertices.length; ii < nn; ii += 5) { minX = Math.min(minX, vertices[ii]); minY = Math.min(minY, vertices[ii + 1]); maxX = Math.max(maxX, vertices[ii]); maxY = Math.max(maxY, vertices[ii + 1]); } } setWidth(maxX - minX); setHeight(maxY - minY); } private void initSkeletonData() { skeletonJson = new SkeletonJson(irr.getSkeletonAtlas(animationName)); skeletonData = skeletonJson.readSkeletonData((irr.getSkeletonJSON(animationName))); } private void initSpine() { BoneData root = skeletonData.getBones().get(0); root.setScale(getScaleX(), getScaleY()); skeleton = new Skeleton(skeletonData); AnimationStateData stateData = new AnimationStateData(skeletonData); state = new AnimationState(stateData); computeBoundBox(); setAnimation(skeletonData.getAnimations().get(0).getName()); } public Array<Animation> getAnimations() { return skeletonData.getAnimations(); } public void setAnimation(String animName) { state.setAnimation(0, animName, true); } public AnimationState getState() { return state; } @Override public void setScale(float scale) { super.setScale(scale); initSpine(); } @Override public void draw(Batch batch, float parentAlpha) { renderer.draw((PolygonSpriteBatch)batch, skeleton); super.draw(batch, parentAlpha); } @Override public void act(float delta) { skeleton.updateWorldTransform(); // state.update(delta); state.apply(skeleton); skeleton.setPosition(getX() - minX, getY() - minY); super.act(delta); } }