Merge branch 'skin-bones' of https://github.com/EsotericSoftware/spine-runtimes into skin-bones

This commit is contained in:
badlogic 2019-06-03 17:00:40 +02:00
commit 995cfa0d0a
5 changed files with 140 additions and 108 deletions

View File

@ -164,8 +164,7 @@ namespace Spine {
copy.g = g; copy.g = g;
copy.b = b; copy.b = b;
copy.a = a; copy.a = a;
copy.deformAttachment = deformAttachment;
CopyTo(copy); CopyTo(copy);
copy.regionUVs = new float[regionUVs.Length]; copy.regionUVs = new float[regionUVs.Length];
Array.Copy(regionUVs, 0, copy.regionUVs, 0, regionUVs.Length); Array.Copy(regionUVs, 0, copy.regionUVs, 0, regionUVs.Length);

View File

@ -150,6 +150,7 @@ namespace Spine {
attachment.vertices = null; attachment.vertices = null;
attachment.worldVerticesLength = worldVerticesLength; attachment.worldVerticesLength = worldVerticesLength;
attachment.deformAttachment = deformAttachment;
} }
} }
} }

View File

@ -83,9 +83,10 @@ namespace Spine {
foreach (SkinEntry entry in skin.attachments.Keys) { foreach (SkinEntry entry in skin.attachments.Keys) {
if (entry.Attachment is MeshAttachment) if (entry.Attachment is MeshAttachment)
SetAttachment(entry.SlotIndex, entry.Name, ((MeshAttachment)entry.Attachment).NewLinkedMesh()); SetAttachment(entry.SlotIndex, entry.Name,
entry.Attachment != null ? ((MeshAttachment)entry.Attachment).NewLinkedMesh() : null);
else else
SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment.Copy()); SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment != null ? entry.Attachment.Copy() : null);
} }
} }

View File

@ -40,6 +40,7 @@ import com.badlogic.gdx.utils.DataInput;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.IntArray; import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.SerializationException; import com.badlogic.gdx.utils.SerializationException;
import com.esotericsoftware.spine.Animation.AttachmentTimeline; import com.esotericsoftware.spine.Animation.AttachmentTimeline;
import com.esotericsoftware.spine.Animation.ColorTimeline; import com.esotericsoftware.spine.Animation.ColorTimeline;
import com.esotericsoftware.spine.Animation.CurveTimeline; import com.esotericsoftware.spine.Animation.CurveTimeline;
@ -132,43 +133,7 @@ public class SkeletonBinary {
SkeletonData skeletonData = new SkeletonData(); SkeletonData skeletonData = new SkeletonData();
skeletonData.name = file.nameWithoutExtension(); skeletonData.name = file.nameWithoutExtension();
DataInput input = new DataInput(file.read(512)) { SkeletonInput input = new SkeletonInput(file);
private char[] chars = new char[32];
public String readString () throws IOException {
int byteCount = readInt(true);
switch (byteCount) {
case 0:
return null;
case 1:
return "";
}
byteCount--;
if (chars.length < byteCount) chars = new char[byteCount];
char[] chars = this.chars;
int charCount = 0;
for (int i = 0; i < byteCount;) {
int b = read();
switch (b >> 4) {
case -1:
throw new EOFException();
case 12:
case 13:
chars[charCount++] = (char)((b & 0x1F) << 6 | read() & 0x3F);
i += 2;
break;
case 14:
chars[charCount++] = (char)((b & 0x0F) << 12 | (read() & 0x3F) << 6 | read() & 0x3F);
i += 3;
break;
default:
chars[charCount++] = (char)b;
i++;
}
}
return new String(chars, 0, charCount);
}
};
try { try {
skeletonData.hash = input.readString(); skeletonData.hash = input.readString();
if (skeletonData.hash.isEmpty()) skeletonData.hash = null; if (skeletonData.hash.isEmpty()) skeletonData.hash = null;
@ -180,7 +145,6 @@ public class SkeletonBinary {
skeletonData.height = input.readFloat(); skeletonData.height = input.readFloat();
boolean nonessential = input.readBoolean(); boolean nonessential = input.readBoolean();
if (nonessential) { if (nonessential) {
skeletonData.fps = input.readFloat(); skeletonData.fps = input.readFloat();
@ -191,8 +155,18 @@ public class SkeletonBinary {
if (skeletonData.audioPath.isEmpty()) skeletonData.audioPath = null; if (skeletonData.audioPath.isEmpty()) skeletonData.audioPath = null;
} }
int n;
Object[] o;
// Strings.
input.strings = new Array(n = input.readInt(true));
o = input.strings.setSize(n);
for (int i = 0; i < n; i++)
o[i] = input.readString();
// Bones. // Bones.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.bones.setSize(n = input.readInt(true));
for (int i = 0; i < n; i++) {
String name = input.readString(); String name = input.readString();
BoneData parent = i == 0 ? null : skeletonData.bones.get(input.readInt(true)); BoneData parent = i == 0 ? null : skeletonData.bones.get(input.readInt(true));
BoneData data = new BoneData(i, name, parent); BoneData data = new BoneData(i, name, parent);
@ -207,11 +181,12 @@ public class SkeletonBinary {
data.transformMode = TransformMode.values[input.readInt(true)]; data.transformMode = TransformMode.values[input.readInt(true)];
data.skinRequired = input.readBoolean(); data.skinRequired = input.readBoolean();
if (nonessential) Color.rgba8888ToColor(data.color, input.readInt()); if (nonessential) Color.rgba8888ToColor(data.color, input.readInt());
skeletonData.bones.add(data); o[i] = data;
} }
// Slots. // Slots.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.slots.setSize(n = input.readInt(true));
for (int i = 0; i < n; i++) {
String slotName = input.readString(); String slotName = input.readString();
BoneData boneData = skeletonData.bones.get(input.readInt(true)); BoneData boneData = skeletonData.bones.get(input.readInt(true));
SlotData data = new SlotData(i, slotName, boneData); SlotData data = new SlotData(i, slotName, boneData);
@ -220,34 +195,38 @@ public class SkeletonBinary {
int darkColor = input.readInt(); int darkColor = input.readInt();
if (darkColor != -1) Color.rgb888ToColor(data.darkColor = new Color(), darkColor); if (darkColor != -1) Color.rgb888ToColor(data.darkColor = new Color(), darkColor);
data.attachmentName = input.readString(); data.attachmentName = input.readStringRef();
data.blendMode = BlendMode.values[input.readInt(true)]; data.blendMode = BlendMode.values[input.readInt(true)];
skeletonData.slots.add(data); o[i] = data;
} }
// IK constraints. // IK constraints.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.ikConstraints.setSize(n = input.readInt(true));
for (int i = 0, nn; i < n; i++) {
IkConstraintData data = new IkConstraintData(input.readString()); IkConstraintData data = new IkConstraintData(input.readString());
data.order = input.readInt(true); data.order = input.readInt(true);
data.skinRequired = input.readBoolean(); data.skinRequired = input.readBoolean();
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) Object[] bones = data.bones.setSize(nn = input.readInt(true));
data.bones.add(skeletonData.bones.get(input.readInt(true))); for (int ii = 0; ii < nn; ii++)
bones[ii] = skeletonData.bones.get(input.readInt(true));
data.target = skeletonData.bones.get(input.readInt(true)); data.target = skeletonData.bones.get(input.readInt(true));
data.mix = input.readFloat(); data.mix = input.readFloat();
data.bendDirection = input.readByte(); data.bendDirection = input.readByte();
data.compress = input.readBoolean(); data.compress = input.readBoolean();
data.stretch = input.readBoolean(); data.stretch = input.readBoolean();
data.uniform = input.readBoolean(); data.uniform = input.readBoolean();
skeletonData.ikConstraints.add(data); o[i] = data;
} }
// Transform constraints. // Transform constraints.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.transformConstraints.setSize(n = input.readInt(true));
for (int i = 0, nn; i < n; i++) {
TransformConstraintData data = new TransformConstraintData(input.readString()); TransformConstraintData data = new TransformConstraintData(input.readString());
data.order = input.readInt(true); data.order = input.readInt(true);
data.skinRequired = input.readBoolean(); data.skinRequired = input.readBoolean();
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) Object[] bones = data.bones.setSize(nn = input.readInt(true));
data.bones.add(skeletonData.bones.get(input.readInt(true))); for (int ii = 0; ii < nn; ii++)
bones[ii] = skeletonData.bones.get(input.readInt(true));
data.target = skeletonData.bones.get(input.readInt(true)); data.target = skeletonData.bones.get(input.readInt(true));
data.local = input.readBoolean(); data.local = input.readBoolean();
data.relative = input.readBoolean(); data.relative = input.readBoolean();
@ -261,16 +240,18 @@ public class SkeletonBinary {
data.translateMix = input.readFloat(); data.translateMix = input.readFloat();
data.scaleMix = input.readFloat(); data.scaleMix = input.readFloat();
data.shearMix = input.readFloat(); data.shearMix = input.readFloat();
skeletonData.transformConstraints.add(data); o[i] = data;
} }
// Path constraints. // Path constraints.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.pathConstraints.setSize(n = input.readInt(true));
for (int i = 0, nn; i < n; i++) {
PathConstraintData data = new PathConstraintData(input.readString()); PathConstraintData data = new PathConstraintData(input.readString());
data.order = input.readInt(true); data.order = input.readInt(true);
data.skinRequired = input.readBoolean(); data.skinRequired = input.readBoolean();
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) Object[] bones = data.bones.setSize(nn = input.readInt(true));
data.bones.add(skeletonData.bones.get(input.readInt(true))); for (int ii = 0; ii < nn; ii++)
bones[ii] = skeletonData.bones.get(input.readInt(true));
data.target = skeletonData.slots.get(input.readInt(true)); data.target = skeletonData.slots.get(input.readInt(true));
data.positionMode = PositionMode.values[input.readInt(true)]; data.positionMode = PositionMode.values[input.readInt(true)];
data.spacingMode = SpacingMode.values[input.readInt(true)]; data.spacingMode = SpacingMode.values[input.readInt(true)];
@ -282,7 +263,7 @@ public class SkeletonBinary {
if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) data.spacing *= scale; if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) data.spacing *= scale;
data.rotateMix = input.readFloat(); data.rotateMix = input.readFloat();
data.translateMix = input.readFloat(); data.translateMix = input.readFloat();
skeletonData.pathConstraints.add(data); o[i] = data;
} }
// Default skin. // Default skin.
@ -293,11 +274,16 @@ public class SkeletonBinary {
} }
// Skins. // Skins.
for (int i = 0, n = input.readInt(true); i < n; i++) {
skeletonData.skins.add(readSkin(input, skeletonData, false, nonessential)); int i = skeletonData.skins.size;
o = skeletonData.skins.setSize(n = i + input.readInt(true));
for (; i < n; i++)
o[i] = readSkin(input, skeletonData, false, nonessential);
}
// Linked meshes. // Linked meshes.
for (int i = 0, n = linkedMeshes.size; i < n; i++) { n = linkedMeshes.size;
for (int i = 0; i < n; i++) {
LinkedMesh linkedMesh = linkedMeshes.get(i); LinkedMesh linkedMesh = linkedMeshes.get(i);
Skin skin = linkedMesh.skin == null ? skeletonData.getDefaultSkin() : skeletonData.findSkin(linkedMesh.skin); Skin skin = linkedMesh.skin == null ? skeletonData.getDefaultSkin() : skeletonData.findSkin(linkedMesh.skin);
if (skin == null) throw new SerializationException("Skin not found: " + linkedMesh.skin); if (skin == null) throw new SerializationException("Skin not found: " + linkedMesh.skin);
@ -310,8 +296,9 @@ public class SkeletonBinary {
linkedMeshes.clear(); linkedMeshes.clear();
// Events. // Events.
for (int i = 0, n = input.readInt(true); i < n; i++) { o = skeletonData.events.setSize(n = input.readInt(true));
EventData data = new EventData(input.readString()); for (int i = 0; i < n; i++) {
EventData data = new EventData(input.readStringRef());
data.intValue = input.readInt(false); data.intValue = input.readInt(false);
data.floatValue = input.readFloat(); data.floatValue = input.readFloat();
data.stringValue = input.readString(); data.stringValue = input.readString();
@ -320,12 +307,13 @@ public class SkeletonBinary {
data.volume = input.readFloat(); data.volume = input.readFloat();
data.balance = input.readFloat(); data.balance = input.readFloat();
} }
skeletonData.events.add(data); o[i] = data;
} }
// Animations. // Animations.
for (int i = 0, n = input.readInt(true); i < n; i++) o = skeletonData.animations.setSize(n = input.readInt(true));
readAnimation(input, input.readString(), skeletonData); for (int i = 0; i < n; i++)
o[i] = readAnimation(input, input.readString(), skeletonData);
} catch (IOException ex) { } catch (IOException ex) {
throw new SerializationException("Error reading skeleton file.", ex); throw new SerializationException("Error reading skeleton file.", ex);
@ -335,33 +323,32 @@ public class SkeletonBinary {
} catch (IOException ignored) { } catch (IOException ignored) {
} }
} }
skeletonData.bones.shrink();
skeletonData.slots.shrink();
skeletonData.skins.shrink();
skeletonData.events.shrink();
skeletonData.animations.shrink();
skeletonData.ikConstraints.shrink();
return skeletonData; return skeletonData;
} }
private Skin readSkin (DataInput input, SkeletonData skeletonData, boolean defaultSkin, boolean nonessential) private Skin readSkin (SkeletonInput input, SkeletonData skeletonData, boolean defaultSkin, boolean nonessential)
throws IOException { throws IOException {
Skin skin = new Skin(defaultSkin ? "default" : input.readString());
Skin skin = new Skin(defaultSkin ? "default" : input.readStringRef());
if (!defaultSkin) { if (!defaultSkin) {
for (int i = 0, n = input.readInt(true); i < n; i++) Object[] bones = skeletonData.bones.setSize(input.readInt(true));
skin.bones.add(skeletonData.bones.get(input.readInt(true))); for (int i = 0, n = skeletonData.bones.size; i < n; i++)
bones[i] = skeletonData.bones.get(input.readInt(true));
for (int i = 0, n = input.readInt(true); i < n; i++) for (int i = 0, n = input.readInt(true); i < n; i++)
skin.constraints.add(skeletonData.ikConstraints.get(input.readInt(true))); skin.constraints.add(skeletonData.ikConstraints.get(input.readInt(true)));
for (int i = 0, n = input.readInt(true); i < n; i++) for (int i = 0, n = input.readInt(true); i < n; i++)
skin.constraints.add(skeletonData.transformConstraints.get(input.readInt(true))); skin.constraints.add(skeletonData.transformConstraints.get(input.readInt(true)));
for (int i = 0, n = input.readInt(true); i < n; i++) for (int i = 0, n = input.readInt(true); i < n; i++)
skin.constraints.add(skeletonData.pathConstraints.get(input.readInt(true))); skin.constraints.add(skeletonData.pathConstraints.get(input.readInt(true)));
skin.constraints.shrink();
} }
for (int i = 0, n = input.readInt(true); i < n; i++) { for (int i = 0, n = input.readInt(true); i < n; i++) {
int slotIndex = input.readInt(true); int slotIndex = input.readInt(true);
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
String name = input.readString(); String name = input.readStringRef();
Attachment attachment = readAttachment(input, skeletonData, skin, slotIndex, name, nonessential); Attachment attachment = readAttachment(input, skeletonData, skin, slotIndex, name, nonessential);
if (attachment != null) skin.setAttachment(slotIndex, name, attachment); if (attachment != null) skin.setAttachment(slotIndex, name, attachment);
} }
@ -369,17 +356,17 @@ public class SkeletonBinary {
return skin; return skin;
} }
private Attachment readAttachment (DataInput input, SkeletonData skeletonData, Skin skin, int slotIndex, String attachmentName, private Attachment readAttachment (SkeletonInput input, SkeletonData skeletonData, Skin skin, int slotIndex,
boolean nonessential) throws IOException { String attachmentName, boolean nonessential) throws IOException {
float scale = this.scale; float scale = this.scale;
String name = input.readString(); String name = input.readStringRef();
if (name == null) name = attachmentName; if (name == null) name = attachmentName;
AttachmentType type = AttachmentType.values[input.readByte()]; AttachmentType type = AttachmentType.values[input.readByte()];
switch (type) { switch (type) {
case region: { case region: {
String path = input.readString(); String path = input.readStringRef();
float rotation = input.readFloat(); float rotation = input.readFloat();
float x = input.readFloat(); float x = input.readFloat();
float y = input.readFloat(); float y = input.readFloat();
@ -418,7 +405,7 @@ public class SkeletonBinary {
return box; return box;
} }
case mesh: { case mesh: {
String path = input.readString(); String path = input.readStringRef();
int color = input.readInt(); int color = input.readInt();
int vertexCount = input.readInt(true); int vertexCount = input.readInt(true);
float[] uvs = readFloatArray(input, vertexCount << 1, 1); float[] uvs = readFloatArray(input, vertexCount << 1, 1);
@ -453,10 +440,10 @@ public class SkeletonBinary {
return mesh; return mesh;
} }
case linkedmesh: { case linkedmesh: {
String path = input.readString(); String path = input.readStringRef();
int color = input.readInt(); int color = input.readInt();
String skinName = input.readString(); String skinName = input.readStringRef();
String parent = input.readString(); String parent = input.readStringRef();
boolean inheritDeform = input.readBoolean(); boolean inheritDeform = input.readBoolean();
float width = 0, height = 0; float width = 0, height = 0;
if (nonessential) { if (nonessential) {
@ -530,7 +517,7 @@ public class SkeletonBinary {
return null; return null;
} }
private Vertices readVertices (DataInput input, int vertexCount) throws IOException { private Vertices readVertices (SkeletonInput input, int vertexCount) throws IOException {
int verticesLength = vertexCount << 1; int verticesLength = vertexCount << 1;
Vertices vertices = new Vertices(); Vertices vertices = new Vertices();
if (!input.readBoolean()) { if (!input.readBoolean()) {
@ -554,7 +541,7 @@ public class SkeletonBinary {
return vertices; return vertices;
} }
private float[] readFloatArray (DataInput input, int n, float scale) throws IOException { private float[] readFloatArray (SkeletonInput input, int n, float scale) throws IOException {
float[] array = new float[n]; float[] array = new float[n];
if (scale == 1) { if (scale == 1) {
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
@ -566,7 +553,7 @@ public class SkeletonBinary {
return array; return array;
} }
private short[] readShortArray (DataInput input) throws IOException { private short[] readShortArray (SkeletonInput input) throws IOException {
int n = input.readInt(true); int n = input.readInt(true);
short[] array = new short[n]; short[] array = new short[n];
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
@ -574,8 +561,8 @@ public class SkeletonBinary {
return array; return array;
} }
private void readAnimation (DataInput input, String name, SkeletonData skeletonData) { private Animation readAnimation (SkeletonInput input, String name, SkeletonData skeletonData) {
Array<Timeline> timelines = new Array(); Array<Timeline> timelines = new Array(32);
float scale = this.scale; float scale = this.scale;
float duration = 0; float duration = 0;
@ -591,7 +578,7 @@ public class SkeletonBinary {
AttachmentTimeline timeline = new AttachmentTimeline(frameCount); AttachmentTimeline timeline = new AttachmentTimeline(frameCount);
timeline.slotIndex = slotIndex; timeline.slotIndex = slotIndex;
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
timeline.setFrame(frameIndex, input.readFloat(), input.readString()); timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
timelines.add(timeline); timelines.add(timeline);
duration = Math.max(duration, timeline.getFrames()[frameCount - 1]); duration = Math.max(duration, timeline.getFrames()[frameCount - 1]);
break; break;
@ -752,7 +739,7 @@ public class SkeletonBinary {
for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (int ii = 0, nn = input.readInt(true); ii < nn; ii++) {
int slotIndex = input.readInt(true); int slotIndex = input.readInt(true);
for (int iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { for (int iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slotIndex, input.readString()); VertexAttachment attachment = (VertexAttachment)skin.getAttachment(slotIndex, input.readStringRef());
boolean weighted = attachment.getBones() != null; boolean weighted = attachment.getBones() != null;
float[] vertices = attachment.getVertices(); float[] vertices = attachment.getVertices();
int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; int deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
@ -852,11 +839,10 @@ public class SkeletonBinary {
} }
timelines.shrink(); timelines.shrink();
skeletonData.animations.add(new Animation(name, timelines, duration)); return new Animation(name, timelines, duration);
} }
private void readCurve (DataInput input, int frameIndex, CurveTimeline timeline) throws IOException { private void readCurve (SkeletonInput input, int frameIndex, CurveTimeline timeline) throws IOException {
switch (input.readByte()) { switch (input.readByte()) {
case CURVE_STEPPED: case CURVE_STEPPED:
timeline.setStepped(frameIndex); timeline.setStepped(frameIndex);
@ -875,4 +861,53 @@ public class SkeletonBinary {
int[] bones; int[] bones;
float[] vertices; float[] vertices;
} }
static class SkeletonInput extends DataInput {
private char[] chars = new char[32];
Array<String> strings;
public SkeletonInput (FileHandle file) {
super(file.read(512));
}
/** @return May be null. */
public String readStringRef () throws IOException {
int index = readInt(true);
return index == 0 ? null : strings.get(index - 1);
}
public String readString () throws IOException {
int byteCount = readInt(true);
switch (byteCount) {
case 0:
return null;
case 1:
return "";
}
byteCount--;
if (chars.length < byteCount) chars = new char[byteCount];
char[] chars = this.chars;
int charCount = 0;
for (int i = 0; i < byteCount;) {
int b = read();
switch (b >> 4) {
case -1:
throw new EOFException();
case 12:
case 13:
chars[charCount++] = (char)((b & 0x1F) << 6 | read() & 0x3F);
i += 2;
break;
case 14:
chars[charCount++] = (char)((b & 0x0F) << 12 | (read() & 0x3F) << 6 | read() & 0x3F);
i += 3;
break;
default:
chars[charCount++] = (char)b;
i++;
}
}
return new String(chars, 0, charCount);
}
}
} }

View File

@ -29,18 +29,9 @@
package com.esotericsoftware.spine; package com.esotericsoftware.spine;
import static com.badlogic.gdx.math.Interpolation.linear; import static com.badlogic.gdx.math.Interpolation.*;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.delay; import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.moveBy;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.parallel;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.removeActor;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Toolkit;
import java.io.File; import java.io.File;
import java.lang.Thread.UncaughtExceptionHandler; import java.lang.Thread.UncaughtExceptionHandler;
@ -88,11 +79,16 @@ import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.StringBuilder; import com.badlogic.gdx.utils.StringBuilder;
import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixBlend;
import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter; import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter;
import com.esotericsoftware.spine.AnimationState.TrackEntry; import com.esotericsoftware.spine.AnimationState.TrackEntry;
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Toolkit;
public class SkeletonViewer extends ApplicationAdapter { public class SkeletonViewer extends ApplicationAdapter {
static final float checkModifiedInterval = 0.250f; static final float checkModifiedInterval = 0.250f;
static final float reloadDelay = 1; static final float reloadDelay = 1;