diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 63699b320..7791c13f5 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -273,7 +273,7 @@ public class Animation { float prevFrameValue = frames[frameIndex - 1]; float frameTime = frames[frameIndex]; float percent = MathUtils.clamp(1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime), 0, 1); - percent = getCurvePercent(frameIndex / 2 - 1, percent); + percent = getCurvePercent((frameIndex >> 1) - 1, percent); float amount = frames[frameIndex + FRAME_VALUE] - prevFrameValue; while (amount > 180) @@ -657,7 +657,7 @@ public class Animation { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. - + float[][] frameVertices = this.frameVertices; int vertexCount = frameVertices[0].length; @@ -700,4 +700,63 @@ public class Animation { } } } + + static public class IkConstraintTimeline extends CurveTimeline { + static private final int PREV_FRAME_TIME = -2; + static private final int FRAME_VALUE = 1; + + int ikConstraintIndex; + private final float[] frames; // time, mix, ... + private final int[] bendDirections; + + public IkConstraintTimeline (int frameCount) { + super(frameCount); + frames = new float[frameCount * 2]; + bendDirections = new int[frameCount]; + } + + public void setIkConstraintIndex (int ikConstraint) { + this.ikConstraintIndex = ikConstraint; + } + + public int getIkConstraintIndex () { + return ikConstraintIndex; + } + + public float[] getFrames () { + return frames; + } + + /** Sets the time and mix and bend direction of the specified keyframe. */ + public void setFrame (int frameIndex, float time, float mix, int bendDirection) { + bendDirections[frameIndex] = bendDirection; + frameIndex *= 2; + frames[frameIndex] = time; + frames[frameIndex + 1] = mix; + } + + public void apply (Skeleton skeleton, float lastTime, float time, Array events, float alpha) { + float[] frames = this.frames; + if (time < frames[0]) return; // Time is before first frame. + + IkConstraint ikConstraint = skeleton.ikConstraints.get(ikConstraintIndex); + + if (time >= frames[frames.length - 2]) { // Time is after last frame. + ikConstraint.mix += (frames[frames.length - 1] - ikConstraint.mix) * alpha; + ikConstraint.bendDirection = bendDirections[bendDirections.length - 1]; + return; + } + + // Interpolate between the previous frame and the current frame. + int frameIndex = binarySearch(frames, time, 2); + float prevFrameValue = frames[frameIndex - 1]; + float frameTime = frames[frameIndex]; + float percent = MathUtils.clamp(1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime), 0, 1); + percent = getCurvePercent((frameIndex >> 1) - 1, percent); + + float mix = prevFrameValue + (frames[frameIndex + FRAME_VALUE] - prevFrameValue) * percent; + ikConstraint.mix += (mix - ikConstraint.mix) * alpha; + ikConstraint.bendDirection = bendDirections[(frameIndex - 2) >> 1]; + } + } } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Bone.java b/spine-libgdx/src/com/esotericsoftware/spine/Bone.java index 167c6de51..1fe7a7081 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Bone.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Bone.java @@ -34,17 +34,18 @@ import static com.badlogic.gdx.math.Matrix3.*; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Matrix3; +import com.badlogic.gdx.math.Vector2; public class Bone { final BoneData data; final Bone parent; float x, y; - float rotation; + float rotation, rotationIK; float scaleX, scaleY; float m00, m01, worldX; // a b x float m10, m11, worldY; // c d y - float worldRotation; + float worldRotation, worldCos, worldSin; float worldScaleX, worldScaleY; /** @param parent May be null. */ @@ -64,6 +65,7 @@ public class Bone { x = bone.x; y = bone.y; rotation = bone.rotation; + rotationIK = bone.rotationIK; scaleX = bone.scaleX; scaleY = bone.scaleY; } @@ -71,6 +73,7 @@ public class Bone { /** Computes the world SRT using the parent bone and the local SRT. */ public void updateWorldTransform (boolean flipX, boolean flipY) { Bone parent = this.parent; + float x = this.x, y = this.y; if (parent != null) { worldX = x * parent.m00 + y * parent.m01 + parent.worldX; worldY = x * parent.m10 + y * parent.m11 + parent.worldY; @@ -81,16 +84,18 @@ public class Bone { worldScaleX = scaleX; worldScaleY = scaleY; } - worldRotation = data.inheritRotation ? parent.worldRotation + rotation : rotation; + worldRotation = data.inheritRotation ? parent.worldRotation + rotationIK : rotationIK; } else { worldX = flipX ? -x : x; worldY = flipY ? -y : y; worldScaleX = scaleX; worldScaleY = scaleY; - worldRotation = rotation; + worldRotation = rotationIK; } float cos = MathUtils.cosDeg(worldRotation); float sin = MathUtils.sinDeg(worldRotation); + worldCos = cos; + worldSin = sin; m00 = cos * worldScaleX; m10 = sin * worldScaleX; m01 = -sin * worldScaleY; @@ -110,6 +115,7 @@ public class Bone { x = data.x; y = data.y; rotation = data.rotation; + rotationIK = rotation; scaleX = data.scaleX; scaleY = data.scaleY; } @@ -143,6 +149,7 @@ public class Bone { this.y = y; } + /** Returns the forward kinetics rotation. */ public float getRotation () { return rotation; } @@ -151,6 +158,15 @@ public class Bone { this.rotation = rotation; } + /** Returns the inverse kinetics rotation, as calculated by any IK constraints. */ + public float getRotationIK () { + return rotationIK; + } + + public void setRotationIK (float rotationIK) { + this.rotationIK = rotationIK; + } + public float getScaleX () { return scaleX; } @@ -205,6 +221,14 @@ public class Bone { return worldRotation; } + public float getWorldCos () { + return worldCos; + } + + public float getWorldSin () { + return worldSin; + } + public float getWorldScaleX () { return worldScaleX; } @@ -228,6 +252,23 @@ public class Bone { return worldTransform; } + public Vector2 worldToLocal (Vector2 world) { + float x = world.x - worldX; + float y = world.y - worldY; + float cos = worldCos; + float sin = -worldSin; + world.x = (x * cos - y * sin) / worldScaleX; + world.y = (x * sin + y * cos) / worldScaleY; + return world; + } + + public Vector2 localToWorld (Vector2 local) { + float x = local.x, y = local.y; + local.x = x * m00 + y * m01 + worldX; + local.y = x * m10 + y * m11 + worldY; + return local; + } + public String toString () { return data.name; } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java b/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java index 734ee8cab..7ace0df16 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java @@ -98,6 +98,11 @@ public class BoneData { this.y = y; } + public void setPosition (float x, float y) { + this.x = x; + this.y = y; + } + public float getRotation () { return rotation; } @@ -122,6 +127,11 @@ public class BoneData { this.scaleY = scaleY; } + public void setScale (float scaleX, float scaleY) { + this.scaleX = scaleX; + this.scaleY = scaleY; + } + public boolean getInheritScale () { return inheritScale; } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java b/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java new file mode 100644 index 000000000..49aaef7c3 --- /dev/null +++ b/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java @@ -0,0 +1,132 @@ + +package com.esotericsoftware.spine; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Array; + +public class IkConstraint { + static private final Vector2 temp = new Vector2(); + + final IkConstraintData data; + final Array bones; + Bone target; + float mix = 1; + int bendDirection; + + public IkConstraint (IkConstraintData data, Skeleton skeleton) { + this.data = data; + mix = data.mix; + bendDirection = data.bendDirection; + + bones = new Array(data.bones.size); + if (skeleton != null) { + for (BoneData boneData : data.bones) + bones.add(skeleton.findBone(boneData.name)); + target = skeleton.findBone(data.target.name); + } + } + + /** Copy constructor. */ + public IkConstraint (IkConstraint ikConstraint) { + data = ikConstraint.data; + bones = new Array(ikConstraint.bones); + target = ikConstraint.target; + mix = ikConstraint.mix; + bendDirection = ikConstraint.bendDirection; + } + + public void apply () { + Bone target = this.target; + Array bones = this.bones; + apply(bones.first(), bones.get(1), target.worldX, target.worldY, bendDirection, mix); + } + + public Array getBones () { + return bones; + } + + public Bone getTarget () { + return target; + } + + public void setTarget (Bone target) { + this.target = target; + } + + public float getMix () { + return mix; + } + + public void setMix (float mix) { + this.mix = mix; + } + + public int getBendDirection () { + return bendDirection; + } + + public void setBendDirection (int bendDirection) { + this.bendDirection = bendDirection; + } + + public IkConstraintData getData () { + return data; + } + + public String toString () { + return data.name; + } + + /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The + * target is specified in the world coordinate system. + * @param child Any descendant bone of the parent. */ + static public void apply (Bone parent, Bone child, float targetX, float targetY, int bendDirection, float alpha) { + float childRotation = child.rotation, parentRotation = parent.rotation; + if (alpha == 0) { + child.rotationIK = childRotation; + parent.rotationIK = parentRotation; + return; + } + Vector2 position = temp; + Bone parentParent = parent.parent; + if (parentParent != null) { + parentParent.worldToLocal(position.set(targetX, targetY)); + targetX = (position.x - parent.x) * parentParent.worldScaleX; + targetY = (position.y - parent.y) * parentParent.worldScaleY; + } else { + targetX -= parent.x; + targetY -= parent.y; + } + if (child.parent == parent) + position.set(child.x, child.y); + else + parent.worldToLocal(child.parent.localToWorld(position.set(child.x, child.y))); + float childX = position.x * parent.worldScaleX, childY = position.y * parent.worldScaleY; + float offset = (float)Math.atan2(childY, childX); + float len1 = (float)Math.sqrt(childX * childX + childY * childY), len2 = child.data.length * child.worldScaleX; + // Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett, http://www.ryanjuckett.com/ + float cosDenom = 2 * len1 * len2; + if (cosDenom < 0.0001f) { + child.rotationIK = childRotation + + ((float)Math.atan2(targetY, targetX) * MathUtils.radDeg - parentRotation - childRotation) * alpha; + return; + } + float cos = MathUtils.clamp((targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom, -1, 1); + float childAngle = (float)Math.acos(cos) * bendDirection; + float adjacent = len1 + len2 * cos, opposite = len2 * MathUtils.sin(childAngle); + float parentAngle = (float)Math.atan2(targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite); + float rotation = (parentAngle - offset) * MathUtils.radDeg - parentRotation; + if (rotation > 180) + rotation -= 360; + else if (rotation < -180) // + rotation += 360; + parent.rotationIK = parentRotation + rotation * alpha; + rotation = (childAngle + offset) * MathUtils.radDeg - childRotation; + if (rotation > 180) + rotation -= 360; + else if (rotation < -180) // + rotation += 360; + child.rotationIK = childRotation + (rotation + parent.worldRotation - child.parent.worldRotation) * alpha; + } +} diff --git a/spine-libgdx/src/com/esotericsoftware/spine/IkConstraintData.java b/spine-libgdx/src/com/esotericsoftware/spine/IkConstraintData.java new file mode 100644 index 000000000..6031d2c81 --- /dev/null +++ b/spine-libgdx/src/com/esotericsoftware/spine/IkConstraintData.java @@ -0,0 +1,52 @@ + +package com.esotericsoftware.spine; + +import com.badlogic.gdx.utils.Array; + +public class IkConstraintData { + final String name; + final Array bones = new Array(); + BoneData target; + int bendDirection = 1; + float mix = 1; + + public IkConstraintData (String name) { + this.name = name; + } + + public String getName () { + return name; + } + + public Array getBones () { + return bones; + } + + public BoneData getTarget () { + return target; + } + + public void setTarget (BoneData target) { + this.target = target; + } + + public int getBendDirection () { + return bendDirection; + } + + public void setBendDirection (int bendDirection) { + this.bendDirection = bendDirection; + } + + public float getMix () { + return mix; + } + + public void setMix (float mix) { + this.mix = mix; + } + + public String toString () { + return name; + } +} diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java index 91d7070c6..814a18acf 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java @@ -39,6 +39,8 @@ public class Skeleton { final SkeletonData data; final Array bones; final Array slots; + final Array ikConstraints; + private final Array> updateBonesCache = new Array(); Array drawOrder; Skin skin; final Color color; @@ -65,7 +67,13 @@ public class Skeleton { drawOrder.add(slot); } + ikConstraints = new Array(data.ikConstraints.size); + for (IkConstraintData ikConstraintData : data.ikConstraints) + ikConstraints.add(new IkConstraint(ikConstraintData, this)); + color = new Color(1, 1, 1, 1); + + updateCache(); } /** Copy constructor. */ @@ -82,26 +90,84 @@ public class Skeleton { slots = new Array(skeleton.slots.size); for (Slot slot : skeleton.slots) { Bone bone = bones.get(skeleton.bones.indexOf(slot.bone, true)); - Slot newSlot = new Slot(slot, this, bone); - slots.add(newSlot); + slots.add(new Slot(slot, this, bone)); } drawOrder = new Array(slots.size); for (Slot slot : skeleton.drawOrder) drawOrder.add(slots.get(skeleton.slots.indexOf(slot, true))); + ikConstraints = new Array(skeleton.ikConstraints.size); + for (IkConstraint ikConstraint : skeleton.ikConstraints) + ikConstraints.add(new IkConstraint(ikConstraint)); + skin = skeleton.skin; color = new Color(skeleton.color); time = skeleton.time; + + updateCache(); } - /** Updates the world transform for each bone. */ + /** Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or removed. */ + public void updateCache () { + Array> updateBonesCache = this.updateBonesCache; + Array ikConstraints = this.ikConstraints; + int ikConstraintsCount = ikConstraints.size; + + int arrayCount = ikConstraintsCount + 1; + updateBonesCache.truncate(arrayCount); + for (int i = 0, n = updateBonesCache.size; i < n; i++) + updateBonesCache.get(i).clear(); + while (updateBonesCache.size < arrayCount) + updateBonesCache.add(new Array()); + + Array nonIkBones = updateBonesCache.first(); + + outer: + for (int i = 0, n = bones.size; i < n; i++) { + Bone bone = bones.get(i); + Bone current = bone; + do { + for (int ii = 0; ii < ikConstraintsCount; ii++) { + IkConstraint ikConstraint = ikConstraints.get(ii); + Bone parent = ikConstraint.bones.first(); + Bone child = ikConstraint.bones.peek(); + while (true) { + if (current == child) { + updateBonesCache.get(ii).add(bone); + updateBonesCache.get(ii + 1).add(bone); + continue outer; + } + if (child == parent) break; + child = child.parent; + } + } + current = current.parent; + } while (current != null); + nonIkBones.add(bone); + } + } + + /** Updates the world transform for each bone and applies IK constraints. */ public void updateWorldTransform () { + Array bones = this.bones; + for (int i = 0, nn = bones.size; i < nn; i++) { + Bone bone = bones.get(i); + bone.rotationIK = bone.rotation; + } boolean flipX = this.flipX; boolean flipY = this.flipY; - Array bones = this.bones; - for (int i = 0, n = bones.size; i < n; i++) - bones.get(i).updateWorldTransform(flipX, flipY); + Array> updateBonesCache = this.updateBonesCache; + Array ikConstraints = this.ikConstraints; + int i = 0, last = updateBonesCache.size - 1; + while (true) { + Array updateBones = updateBonesCache.get(i); + for (int ii = 0, nn = updateBones.size; ii < nn; ii++) + updateBones.get(ii).updateWorldTransform(flipX, flipY); + if (i == last) break; + ikConstraints.get(i).apply(); + i++; + } } /** Sets the bones and slots to their setup pose values. */ @@ -114,6 +180,13 @@ public class Skeleton { Array bones = this.bones; for (int i = 0, n = bones.size; i < n; i++) bones.get(i).setToSetupPose(); + + Array ikConstraints = this.ikConstraints; + for (int i = 0, n = ikConstraints.size; i < n; i++) { + IkConstraint ikConstraint = ikConstraints.get(i); + ikConstraint.bendDirection = ikConstraint.data.bendDirection; + ikConstraint.mix = ikConstraint.data.mix; + } } public void setSlotsToSetupPose () { @@ -263,6 +336,21 @@ public class Skeleton { throw new IllegalArgumentException("Slot not found: " + slotName); } + public Array getIkConstraints () { + return ikConstraints; + } + + /** @return May be null. */ + public IkConstraint findIkConstraint (String ikConstraintName) { + if (ikConstraintName == null) throw new IllegalArgumentException("ikConstraintName cannot be null."); + Array ikConstraints = this.ikConstraints; + for (int i = 0, n = ikConstraints.size; i < n; i++) { + IkConstraint ikConstraint = ikConstraints.get(i); + if (ikConstraint.data.name.equals(ikConstraintName)) return ikConstraint; + } + return null; + } + public Color getColor () { return color; } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index d171c1719..886f93978 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -69,6 +69,7 @@ public class SkeletonBinary { static public final int TIMELINE_EVENT = 5; static public final int TIMELINE_DRAWORDER = 6; static public final int TIMELINE_FFD = 7; + static public final int TIMELINE_IK = 8; static public final int CURVE_LINEAR = 0; static public final int CURVE_STEPPED = 1; @@ -123,7 +124,7 @@ public class SkeletonBinary { boneData.inheritScale = input.readBoolean(); boneData.inheritRotation = input.readBoolean(); if (nonessential) Color.rgba8888ToColor(boneData.getColor(), input.readInt()); - skeletonData.addBone(boneData); + skeletonData.getBones().add(boneData); } // Slots. @@ -134,19 +135,19 @@ public class SkeletonBinary { Color.rgba8888ToColor(slotData.getColor(), input.readInt()); slotData.attachmentName = input.readString(); slotData.additiveBlending = input.readBoolean(); - skeletonData.addSlot(slotData); + skeletonData.getSlots().add(slotData); } // Default skin. Skin defaultSkin = readSkin(input, "default", nonessential); if (defaultSkin != null) { skeletonData.defaultSkin = defaultSkin; - skeletonData.addSkin(defaultSkin); + skeletonData.getSkins().add(defaultSkin); } // Skins. for (int i = 0, n = input.readInt(true); i < n; i++) - skeletonData.addSkin(readSkin(input, input.readString(), nonessential)); + skeletonData.getSkins().add(readSkin(input, input.readString(), nonessential)); // Events. for (int i = 0, n = input.readInt(true); i < n; i++) { @@ -154,7 +155,7 @@ public class SkeletonBinary { eventData.intValue = input.readInt(false); eventData.floatValue = input.readFloat(); eventData.stringValue = input.readString(); - skeletonData.addEvent(eventData); + skeletonData.getEvents().add(eventData); } // Animations. @@ -497,7 +498,7 @@ public class SkeletonBinary { } timelines.shrink(); - skeletonData.addAnimation(new Animation(name, timelines, duration)); + skeletonData.getAnimations().add(new Animation(name, timelines, duration)); } private void readCurve (DataInput input, int frameIndex, CurveTimeline timeline) throws IOException { diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java index 12d823aa4..df840988d 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonData.java @@ -40,23 +40,10 @@ public class SkeletonData { Skin defaultSkin; final Array events = new Array(); final Array animations = new Array(); - - public void clear () { - bones.clear(); - slots.clear(); - skins.clear(); - defaultSkin = null; - events.clear(); - animations.clear(); - } + final Array ikConstraints = new Array(); // --- Bones. - public void addBone (BoneData bone) { - if (bone == null) throw new IllegalArgumentException("bone cannot be null."); - bones.add(bone); - } - public Array getBones () { return bones; } @@ -83,11 +70,6 @@ public class SkeletonData { // --- Slots. - public void addSlot (SlotData slot) { - if (slot == null) throw new IllegalArgumentException("slot cannot be null."); - slots.add(slot); - } - public Array getSlots () { return slots; } @@ -124,11 +106,6 @@ public class SkeletonData { this.defaultSkin = defaultSkin; } - public void addSkin (Skin skin) { - if (skin == null) throw new IllegalArgumentException("skin cannot be null."); - skins.add(skin); - } - /** @return May be null. */ public Skin findSkin (String skinName) { if (skinName == null) throw new IllegalArgumentException("skinName cannot be null."); @@ -144,11 +121,6 @@ public class SkeletonData { // --- Events. - public void addEvent (EventData eventData) { - if (eventData == null) throw new IllegalArgumentException("eventData cannot be null."); - events.add(eventData); - } - /** @return May be null. */ public EventData findEvent (String eventDataName) { if (eventDataName == null) throw new IllegalArgumentException("eventDataName cannot be null."); @@ -163,11 +135,6 @@ public class SkeletonData { // --- Animations. - public void addAnimation (Animation animation) { - if (animation == null) throw new IllegalArgumentException("animation cannot be null."); - animations.add(animation); - } - public Array getAnimations () { return animations; } @@ -183,6 +150,23 @@ public class SkeletonData { return null; } + // --- IK + + public Array getIkConstraints () { + return ikConstraints; + } + + /** @return May be null. */ + public IkConstraintData findIkConstraint (String ikConstraintName) { + if (ikConstraintName == null) throw new IllegalArgumentException("ikConstraintName cannot be null."); + Array ikConstraints = this.ikConstraints; + for (int i = 0, n = ikConstraints.size; i < n; i++) { + IkConstraintData ikConstraint = ikConstraints.get(i); + if (ikConstraint.name.equals(ikConstraintName)) return ikConstraint; + } + return null; + } + // --- /** @return May be null. */ diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index 0c50cc950..4a07858a9 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -111,7 +111,7 @@ public class SkeletonJson { String color = boneMap.getString("color", null); if (color != null) boneData.getColor().set(Color.valueOf(color)); - skeletonData.addBone(boneData); + skeletonData.getBones().add(boneData); } // Slots. @@ -129,7 +129,7 @@ public class SkeletonJson { slotData.additiveBlending = slotMap.getBoolean("additive", false); - skeletonData.addSlot(slotData); + skeletonData.getSlots().add(slotData); } // Skins. @@ -143,7 +143,7 @@ public class SkeletonJson { if (attachment != null) skin.addAttachment(slotIndex, entry.name, attachment); } } - skeletonData.addSkin(skin); + skeletonData.getSkins().add(skin); if (skin.name.equals("default")) skeletonData.defaultSkin = skin; } @@ -153,7 +153,7 @@ public class SkeletonJson { eventData.intValue = eventMap.getInt("int", 0); eventData.floatValue = eventMap.getFloat("float", 0f); eventData.stringValue = eventMap.getString("string", null); - skeletonData.addEvent(eventData); + skeletonData.getEvents().add(eventData); } // Animations. @@ -461,7 +461,7 @@ public class SkeletonJson { } timelines.shrink(); - skeletonData.addAnimation(new Animation(name, timelines, duration)); + skeletonData.getAnimations().add(new Animation(name, timelines, duration)); } void readCurve (CurveTimeline timeline, int frameIndex, JsonValue valueMap) { diff --git a/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java b/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java index 5284f6cd7..8a74cff3c 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java @@ -38,7 +38,7 @@ public interface AttachmentLoader { /** @return May be null to not load any attachment. */ public MeshAttachment newMeshAttachment (Skin skin, String name, String path); - + /** @return May be null to not load any attachment. */ public SkinnedMeshAttachment newSkinnedMeshAttachment (Skin skin, String name, String path); diff --git a/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java b/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java index c88ce773b..c2ce43570 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java @@ -34,7 +34,7 @@ import com.esotericsoftware.spine.Bone; import com.esotericsoftware.spine.Skeleton; import com.esotericsoftware.spine.Slot; -import static com.badlogic.gdx.graphics.g2d.SpriteBatch.*; +import static com.badlogic.gdx.graphics.g2d.Batch.*; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;