mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-16 20:11:47 +08:00
Merge branch '3.9-beta' of https://github.com/esotericsoftware/spine-runtimes into 3.9-beta
This commit is contained in:
commit
fa422fb1ce
@ -58,15 +58,11 @@ public class SimpleTest1 extends ApplicationAdapter {
|
|||||||
|
|
||||||
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
|
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
|
||||||
|
|
||||||
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
SkeletonLoader loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
||||||
|
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
|
||||||
loader.setScale(0.6f); // Load the skeleton at 60% the size it was in Spine.
|
loader.setScale(0.6f); // Load the skeleton at 60% the size it was in Spine.
|
||||||
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-pro.json"));
|
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-pro.json"));
|
||||||
|
|
||||||
// Binary would be loaded similarly:
|
|
||||||
// SkeletonBinary loader = new SkeletonBinary(atlas);
|
|
||||||
// loader.setScale(0.6f);
|
|
||||||
// SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-pro.skel"));
|
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
||||||
skeleton.setPosition(250, 20);
|
skeleton.setPosition(250, 20);
|
||||||
|
|
||||||
|
|||||||
@ -65,14 +65,10 @@ public class SimpleTest2 extends ApplicationAdapter {
|
|||||||
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
|
atlas = new TextureAtlas(Gdx.files.internal("spineboy/spineboy-pma.atlas"));
|
||||||
|
|
||||||
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
||||||
|
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
|
||||||
loader.setScale(0.6f); // Load the skeleton at 60% the size it was in Spine.
|
loader.setScale(0.6f); // Load the skeleton at 60% the size it was in Spine.
|
||||||
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-ess.json"));
|
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-ess.json"));
|
||||||
|
|
||||||
// Binary would be loaded similarly:
|
|
||||||
// SkeletonBinary loader = new SkeletonBinary(atlas);
|
|
||||||
// loader.setScale(0.6f);
|
|
||||||
// SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("spineboy/spineboy-ess.skel"));
|
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
||||||
skeleton.setPosition(250, 20);
|
skeleton.setPosition(250, 20);
|
||||||
skeleton.setAttachment("head-bb", "head"); // Attach "head" bounding box to "head-bb" slot.
|
skeleton.setAttachment("head-bb", "head"); // Attach "head" bounding box to "head-bb" slot.
|
||||||
|
|||||||
@ -60,14 +60,10 @@ public class SimpleTest3 extends ApplicationAdapter {
|
|||||||
atlas = new TextureAtlas(Gdx.files.internal("raptor/raptor-pma.atlas"));
|
atlas = new TextureAtlas(Gdx.files.internal("raptor/raptor-pma.atlas"));
|
||||||
|
|
||||||
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
||||||
loader.setScale(0.5f); // Load the skeleton at 50% the size it was in Spine.
|
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
|
||||||
|
loader.setScale(0.1f); // Load the skeleton at 50% the size it was in Spine.
|
||||||
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("raptor/raptor-pro.json"));
|
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("raptor/raptor-pro.json"));
|
||||||
|
|
||||||
// Binary would be loaded similarly:
|
|
||||||
// SkeletonBinary loader = new SkeletonBinary(atlas);
|
|
||||||
// loader.setScale(0.5f);
|
|
||||||
// SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("raptor/raptor-pro.skel"));
|
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
||||||
skeleton.setPosition(250, 20);
|
skeleton.setPosition(250, 20);
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,7 @@ import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
|||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
|
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
public class SimpleTest4 extends ApplicationAdapter {
|
public class SimpleTest4 extends ApplicationAdapter {
|
||||||
@ -59,7 +60,8 @@ public class SimpleTest4 extends ApplicationAdapter {
|
|||||||
atlas = new TextureAtlas(Gdx.files.internal("goblins/goblins-pma.atlas"));
|
atlas = new TextureAtlas(Gdx.files.internal("goblins/goblins-pma.atlas"));
|
||||||
|
|
||||||
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
SkeletonJson loader = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless.
|
||||||
loader.setScale(0.6f); // Load the skeleton at 60% the size it was in Spine.
|
// SkeletonLoader loader = new SkeletonBinary(atlas); // Or use SkeletonBinary to load binary data.
|
||||||
|
loader.setScale(1.3f); // Load the skeleton at 130% the size it was in Spine.
|
||||||
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("goblins/goblins-pro.json"));
|
SkeletonData skeletonData = loader.readSkeletonData(Gdx.files.internal("goblins/goblins-pro.json"));
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc).
|
||||||
|
|||||||
@ -66,7 +66,6 @@ import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
|||||||
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
||||||
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
||||||
import com.esotericsoftware.spine.SkeletonJson.LinkedMesh;
|
import com.esotericsoftware.spine.SkeletonJson.LinkedMesh;
|
||||||
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
|
|
||||||
import com.esotericsoftware.spine.attachments.Attachment;
|
import com.esotericsoftware.spine.attachments.Attachment;
|
||||||
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
||||||
import com.esotericsoftware.spine.attachments.AttachmentType;
|
import com.esotericsoftware.spine.attachments.AttachmentType;
|
||||||
@ -83,7 +82,7 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
|
|||||||
* See <a href="http://esotericsoftware.com/spine-binary-format">Spine binary format</a> and
|
* See <a href="http://esotericsoftware.com/spine-binary-format">Spine binary format</a> and
|
||||||
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
||||||
* Runtimes Guide. */
|
* Runtimes Guide. */
|
||||||
public class SkeletonBinary {
|
public class SkeletonBinary extends SkeletonLoader {
|
||||||
static public final int BONE_ROTATE = 0;
|
static public final int BONE_ROTATE = 0;
|
||||||
static public final int BONE_TRANSLATE = 1;
|
static public final int BONE_TRANSLATE = 1;
|
||||||
static public final int BONE_SCALE = 2;
|
static public final int BONE_SCALE = 2;
|
||||||
@ -101,30 +100,12 @@ public class SkeletonBinary {
|
|||||||
static public final int CURVE_STEPPED = 1;
|
static public final int CURVE_STEPPED = 1;
|
||||||
static public final int CURVE_BEZIER = 2;
|
static public final int CURVE_BEZIER = 2;
|
||||||
|
|
||||||
private final AttachmentLoader attachmentLoader;
|
public SkeletonBinary (AttachmentLoader attachmentLoader) {
|
||||||
private float scale = 1;
|
super(attachmentLoader);
|
||||||
private final Array<LinkedMesh> linkedMeshes = new Array();
|
}
|
||||||
|
|
||||||
public SkeletonBinary (TextureAtlas atlas) {
|
public SkeletonBinary (TextureAtlas atlas) {
|
||||||
attachmentLoader = new AtlasAttachmentLoader(atlas);
|
super(atlas);
|
||||||
}
|
|
||||||
|
|
||||||
public SkeletonBinary (AttachmentLoader attachmentLoader) {
|
|
||||||
if (attachmentLoader == null) throw new IllegalArgumentException("attachmentLoader cannot be null.");
|
|
||||||
this.attachmentLoader = attachmentLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
|
||||||
* runtime than were used in Spine.
|
|
||||||
* <p>
|
|
||||||
* See <a href="http://esotericsoftware.com/spine-loading-skeleton-data#Scaling">Scaling</a> in the Spine Runtimes Guide. */
|
|
||||||
public float getScale () {
|
|
||||||
return scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScale (float scale) {
|
|
||||||
if (scale == 0) throw new IllegalArgumentException("scale cannot be 0.");
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkeletonData readSkeletonData (FileHandle file) {
|
public SkeletonData readSkeletonData (FileHandle file) {
|
||||||
@ -610,10 +591,10 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2);
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2);
|
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2);
|
setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
r = r2;
|
r = r2;
|
||||||
@ -644,13 +625,13 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng);
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb);
|
setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na);
|
setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2);
|
setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2);
|
setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2);
|
setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
r = nr;
|
r = nr;
|
||||||
@ -703,8 +684,8 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2);
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
mix = mix2;
|
mix = mix2;
|
||||||
@ -729,10 +710,10 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, rotateMix, rotateMix2);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, rotateMix, rotateMix2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, translateMix, translateMix2);
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, translateMix, translateMix2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 2, time, time2, scaleMix, scaleMix2);
|
setBezier(input, timeline, bezier++, frame, 2, time, time2, scaleMix, scaleMix2, 1);
|
||||||
setBezier(input, timeline, bezier++, frame, 3, time, time2, shearMix, shearMix2);
|
setBezier(input, timeline, bezier++, frame, 3, time, time2, shearMix, shearMix2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
rotateMix = rotateMix2;
|
rotateMix = rotateMix2;
|
||||||
@ -812,7 +793,7 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
}
|
}
|
||||||
@ -891,7 +872,7 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
value = value2;
|
value = value2;
|
||||||
@ -910,8 +891,8 @@ public class SkeletonBinary {
|
|||||||
timeline.setStepped(frame);
|
timeline.setStepped(frame);
|
||||||
break;
|
break;
|
||||||
case CURVE_BEZIER:
|
case CURVE_BEZIER:
|
||||||
setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1);
|
setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale);
|
||||||
setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2);
|
setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
value1 = nvalue1;
|
value1 = nvalue1;
|
||||||
@ -921,9 +902,9 @@ public class SkeletonBinary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setBezier (SkeletonInput input, CurveTimeline timeline, int bezier, int frame, int value, float time1, float time2,
|
void setBezier (SkeletonInput input, CurveTimeline timeline, int bezier, int frame, int value, float time1, float time2,
|
||||||
float value1, float value2) throws IOException {
|
float value1, float value2, float scale) throws IOException {
|
||||||
timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat(), input.readFloat(),
|
timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(),
|
||||||
input.readFloat(), time2, value2);
|
input.readFloat() * scale, time2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Vertices {
|
static class Vertices {
|
||||||
|
|||||||
@ -64,7 +64,6 @@ import com.esotericsoftware.spine.BoneData.TransformMode;
|
|||||||
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
||||||
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
||||||
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
||||||
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
|
|
||||||
import com.esotericsoftware.spine.attachments.Attachment;
|
import com.esotericsoftware.spine.attachments.Attachment;
|
||||||
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
||||||
import com.esotericsoftware.spine.attachments.AttachmentType;
|
import com.esotericsoftware.spine.attachments.AttachmentType;
|
||||||
@ -77,35 +76,19 @@ import com.esotericsoftware.spine.attachments.RegionAttachment;
|
|||||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||||
|
|
||||||
/** Loads skeleton data in the Spine JSON format.
|
/** Loads skeleton data in the Spine JSON format.
|
||||||
|
* <p>
|
||||||
|
* JSON is human readable but the binary format is much smaller on disk and faster to load. See {@link SkeletonBinary}.
|
||||||
* <p>
|
* <p>
|
||||||
* See <a href="http://esotericsoftware.com/spine-json-format">Spine JSON format</a> and
|
* See <a href="http://esotericsoftware.com/spine-json-format">Spine JSON format</a> and
|
||||||
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
||||||
* Runtimes Guide. */
|
* Runtimes Guide. */
|
||||||
public class SkeletonJson {
|
public class SkeletonJson extends SkeletonLoader {
|
||||||
private final AttachmentLoader attachmentLoader;
|
public SkeletonJson (AttachmentLoader attachmentLoader) {
|
||||||
private float scale = 1;
|
super(attachmentLoader);
|
||||||
private final Array<LinkedMesh> linkedMeshes = new Array();
|
}
|
||||||
|
|
||||||
public SkeletonJson (TextureAtlas atlas) {
|
public SkeletonJson (TextureAtlas atlas) {
|
||||||
attachmentLoader = new AtlasAttachmentLoader(atlas);
|
super(atlas);
|
||||||
}
|
|
||||||
|
|
||||||
public SkeletonJson (AttachmentLoader attachmentLoader) {
|
|
||||||
if (attachmentLoader == null) throw new IllegalArgumentException("attachmentLoader cannot be null.");
|
|
||||||
this.attachmentLoader = attachmentLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
|
||||||
* runtime than were used in Spine.
|
|
||||||
* <p>
|
|
||||||
* See <a href="http://esotericsoftware.com/spine-loading-skeleton-data#Scaling">Scaling</a> in the Spine Runtimes Guide. */
|
|
||||||
public float getScale () {
|
|
||||||
return scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setScale (float scale) {
|
|
||||||
if (scale == 0) throw new IllegalArgumentException("scale cannot be 0.");
|
|
||||||
this.scale = scale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonValue parse (FileHandle file) {
|
protected JsonValue parse (FileHandle file) {
|
||||||
@ -128,8 +111,6 @@ public class SkeletonJson {
|
|||||||
if (skeletonMap != null) {
|
if (skeletonMap != null) {
|
||||||
skeletonData.hash = skeletonMap.getString("hash", null);
|
skeletonData.hash = skeletonMap.getString("hash", null);
|
||||||
skeletonData.version = skeletonMap.getString("spine", null);
|
skeletonData.version = skeletonMap.getString("spine", null);
|
||||||
if ("3.8.75".equals(skeletonData.version))
|
|
||||||
throw new RuntimeException("Unsupported skeleton data, please export with a newer version of Spine.");
|
|
||||||
skeletonData.x = skeletonMap.getFloat("x", 0);
|
skeletonData.x = skeletonMap.getFloat("x", 0);
|
||||||
skeletonData.y = skeletonMap.getFloat("y", 0);
|
skeletonData.y = skeletonMap.getFloat("y", 0);
|
||||||
skeletonData.width = skeletonMap.getFloat("width", 0);
|
skeletonData.width = skeletonMap.getFloat("width", 0);
|
||||||
@ -491,7 +472,7 @@ public class SkeletonJson {
|
|||||||
for (int i = 0, n = vertices.length; i < n;) {
|
for (int i = 0, n = vertices.length; i < n;) {
|
||||||
int boneCount = (int)vertices[i++];
|
int boneCount = (int)vertices[i++];
|
||||||
bones.add(boneCount);
|
bones.add(boneCount);
|
||||||
for (int nn = i + boneCount * 4; i < nn; i += 4) {
|
for (int nn = i + (boneCount << 2); i < nn; i += 4) {
|
||||||
bones.add((int)vertices[i]);
|
bones.add((int)vertices[i]);
|
||||||
weights.add(vertices[i + 1] * scale);
|
weights.add(vertices[i + 1] * scale);
|
||||||
weights.add(vertices[i + 2] * scale);
|
weights.add(vertices[i + 2] * scale);
|
||||||
@ -544,10 +525,10 @@ public class SkeletonJson {
|
|||||||
float na = Integer.parseInt(color.substring(6, 8), 16) / 255f;
|
float na = Integer.parseInt(color.substring(6, 8), 16) / 255f;
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr);
|
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng);
|
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb);
|
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, a, na);
|
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, a, na, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
r = nr;
|
r = nr;
|
||||||
@ -589,13 +570,13 @@ public class SkeletonJson {
|
|||||||
float nb2 = Integer.parseInt(color.substring(12, 14), 16) / 255f;
|
float nb2 = Integer.parseInt(color.substring(12, 14), 16) / 255f;
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr);
|
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, r, nr, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng);
|
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, g, ng, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb);
|
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, b, nb, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, a, na);
|
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, a, na, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, r2, nr2);
|
bezier = readCurve(curve, timeline, bezier, frame, 4, time, time2, r2, nr2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, g2, ng2);
|
bezier = readCurve(curve, timeline, bezier, frame, 5, time, time2, g2, ng2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, b2, nb2);
|
bezier = readCurve(curve, timeline, bezier, frame, 6, time, time2, b2, nb2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
r = nr;
|
r = nr;
|
||||||
@ -660,8 +641,8 @@ public class SkeletonJson {
|
|||||||
float mix2 = nextMap.getFloat("mix", 1), softness2 = nextMap.getFloat("softness", 0) * scale;
|
float mix2 = nextMap.getFloat("mix", 1), softness2 = nextMap.getFloat("softness", 0) * scale;
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2);
|
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2);
|
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
mix = mix2;
|
mix = mix2;
|
||||||
@ -693,10 +674,10 @@ public class SkeletonJson {
|
|||||||
float scaleMix2 = nextMap.getFloat("scaleMix", 1), shearMix2 = nextMap.getFloat("shearMix", 1);
|
float scaleMix2 = nextMap.getFloat("scaleMix", 1), shearMix2 = nextMap.getFloat("shearMix", 1);
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, rotateMix, rotateMix2);
|
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, rotateMix, rotateMix2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, translateMix, translateMix2);
|
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, translateMix, translateMix2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, scaleMix, scaleMix2);
|
bezier = readCurve(curve, timeline, bezier, frame, 2, time, time2, scaleMix, scaleMix2, 1);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, shearMix, shearMix2);
|
bezier = readCurve(curve, timeline, bezier, frame, 3, time, time2, shearMix, shearMix2, 1);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
rotateMix = rotateMix2;
|
rotateMix = rotateMix2;
|
||||||
@ -777,7 +758,7 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
float time2 = nextMap.getFloat("time", 0);
|
float time2 = nextMap.getFloat("time", 0);
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1);
|
if (curve != null) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
|
||||||
time = time2;
|
time = time2;
|
||||||
keyMap = nextMap;
|
keyMap = nextMap;
|
||||||
}
|
}
|
||||||
@ -853,16 +834,16 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Timeline readTimeline (JsonValue keyMap, CurveTimeline1 timeline, float defaultValue, float scale) {
|
private Timeline readTimeline (JsonValue keyMap, CurveTimeline1 timeline, float defaultValue, float scale) {
|
||||||
float time = keyMap.getFloat("time", 0), value = keyMap.getFloat("value", defaultValue);
|
float time = keyMap.getFloat("time", 0), value = keyMap.getFloat("value", defaultValue) * scale;
|
||||||
int bezier = 0;
|
int bezier = 0;
|
||||||
for (int frame = 0;; frame++) {
|
for (int frame = 0;; frame++) {
|
||||||
timeline.setFrame(frame, time, value);
|
timeline.setFrame(frame, time, value);
|
||||||
JsonValue nextMap = keyMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (nextMap == null) break;
|
if (nextMap == null) break;
|
||||||
float time2 = nextMap.getFloat("time", 0);
|
float time2 = nextMap.getFloat("time", 0);
|
||||||
float value2 = nextMap.getFloat("value", defaultValue);
|
float value2 = nextMap.getFloat("value", defaultValue) * scale;
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value, value2);
|
if (curve != null) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value, value2, scale);
|
||||||
time = time2;
|
time = time2;
|
||||||
value = value2;
|
value = value2;
|
||||||
keyMap = nextMap;
|
keyMap = nextMap;
|
||||||
@ -874,18 +855,18 @@ public class SkeletonJson {
|
|||||||
private Timeline readTimeline (JsonValue keyMap, CurveTimeline2 timeline, String name1, String name2, float defaultValue,
|
private Timeline readTimeline (JsonValue keyMap, CurveTimeline2 timeline, String name1, String name2, float defaultValue,
|
||||||
float scale) {
|
float scale) {
|
||||||
float time = keyMap.getFloat("time", 0);
|
float time = keyMap.getFloat("time", 0);
|
||||||
float value1 = keyMap.getFloat(name1, defaultValue), value2 = keyMap.getFloat(name2, defaultValue);
|
float value1 = keyMap.getFloat(name1, defaultValue) * scale, value2 = keyMap.getFloat(name2, defaultValue) * scale;
|
||||||
int bezier = 0;
|
int bezier = 0;
|
||||||
for (int frame = 0;; frame++) {
|
for (int frame = 0;; frame++) {
|
||||||
timeline.setFrame(frame, time, value1, value2);
|
timeline.setFrame(frame, time, value1, value2);
|
||||||
JsonValue nextMap = keyMap.next;
|
JsonValue nextMap = keyMap.next;
|
||||||
if (nextMap == null) break;
|
if (nextMap == null) break;
|
||||||
float time2 = nextMap.getFloat("time", 0);
|
float time2 = nextMap.getFloat("time", 0);
|
||||||
float nvalue1 = nextMap.getFloat(name1, defaultValue), nvalue2 = nextMap.getFloat(name2, defaultValue);
|
float nvalue1 = nextMap.getFloat(name1, defaultValue) * scale, nvalue2 = nextMap.getFloat(name2, defaultValue) * scale;
|
||||||
JsonValue curve = keyMap.get("curve");
|
JsonValue curve = keyMap.get("curve");
|
||||||
if (curve != null) {
|
if (curve != null) {
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1);
|
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);
|
||||||
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2);
|
bezier = readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);
|
||||||
}
|
}
|
||||||
time = time2;
|
time = time2;
|
||||||
value1 = nvalue1;
|
value1 = nvalue1;
|
||||||
@ -897,18 +878,18 @@ public class SkeletonJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int readCurve (JsonValue curve, CurveTimeline timeline, int bezier, int frame, int value, float time1, float time2,
|
int readCurve (JsonValue curve, CurveTimeline timeline, int bezier, int frame, int value, float time1, float time2,
|
||||||
float value1, float value2) {
|
float value1, float value2, float scale) {
|
||||||
if (curve.isString()) {
|
if (curve.isString()) {
|
||||||
if (value != 0) timeline.setStepped(frame);
|
if (value != 0) timeline.setStepped(frame);
|
||||||
} else {
|
} else {
|
||||||
curve = curve.get(value * 4);
|
curve = curve.get(value << 2);
|
||||||
float cx1 = curve.asFloat();
|
float cx1 = curve.asFloat();
|
||||||
curve = curve.next;
|
curve = curve.next;
|
||||||
float cy1 = curve.asFloat();
|
float cy1 = curve.asFloat() * scale;
|
||||||
curve = curve.next;
|
curve = curve.next;
|
||||||
float cx2 = curve.asFloat();
|
float cx2 = curve.asFloat();
|
||||||
curve = curve.next;
|
curve = curve.next;
|
||||||
float cy2 = curve.asFloat();
|
float cy2 = curve.asFloat() * scale;
|
||||||
setBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
|
setBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
|
||||||
}
|
}
|
||||||
return bezier;
|
return bezier;
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.SkeletonJson.LinkedMesh;
|
||||||
|
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
|
||||||
|
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
||||||
|
|
||||||
|
/** Base class for loading skeleton data from a file. */
|
||||||
|
abstract public class SkeletonLoader {
|
||||||
|
final AttachmentLoader attachmentLoader;
|
||||||
|
float scale = 1;
|
||||||
|
final Array<LinkedMesh> linkedMeshes = new Array();
|
||||||
|
|
||||||
|
/** Creates a skeleton loader that loads attachments using an {@link AtlasAttachmentLoader} with the specified atlas. */
|
||||||
|
public SkeletonLoader (TextureAtlas atlas) {
|
||||||
|
attachmentLoader = new AtlasAttachmentLoader(atlas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a skeleton loader that loads attachments using the specified attachment loader.
|
||||||
|
* <p>
|
||||||
|
* See <a href='http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data'>Loading skeleton data</a> in the
|
||||||
|
* Spine Runtimes Guide. */
|
||||||
|
public SkeletonLoader (AttachmentLoader attachmentLoader) {
|
||||||
|
if (attachmentLoader == null) throw new IllegalArgumentException("attachmentLoader cannot be null.");
|
||||||
|
this.attachmentLoader = attachmentLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
||||||
|
* runtime than were used in Spine.
|
||||||
|
* <p>
|
||||||
|
* See <a href="http://esotericsoftware.com/spine-loading-skeleton-data#Scaling">Scaling</a> in the Spine Runtimes Guide. */
|
||||||
|
public float getScale () {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScale (float scale) {
|
||||||
|
if (scale == 0) throw new IllegalArgumentException("scale cannot be 0.");
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public SkeletonData readSkeletonData (FileHandle file);
|
||||||
|
}
|
||||||
@ -94,9 +94,10 @@ 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;
|
||||||
static float uiScale = 1;
|
static float uiScale = 1;
|
||||||
|
static String[] startSuffixes = {"", "-pro", "-ess"};
|
||||||
static String[] dataSuffixes = {".json", ".skel"};
|
static String[] dataSuffixes = {".json", ".skel"};
|
||||||
static String[] atlasSuffixes = {".atlas", "-pro.atlas", "-ess.atlas"};
|
static String[] endSuffixes = {"", ".txt", ".bytes"};
|
||||||
static String[] extraSuffixes = {"", ".txt", ".bytes"};
|
static String[] atlasSuffixes = {".atlas", "-pma.atlas"};
|
||||||
static String[] args;
|
static String[] args;
|
||||||
static final String version = ""; // Replaced by build.
|
static final String version = ""; // Replaced by build.
|
||||||
|
|
||||||
@ -146,12 +147,14 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
|
|
||||||
FileHandle atlasFile (FileHandle skeletonFile) {
|
FileHandle atlasFile (FileHandle skeletonFile) {
|
||||||
String baseName = skeletonFile.name();
|
String baseName = skeletonFile.name();
|
||||||
for (String extraSuffix : extraSuffixes) {
|
for (String startSuffix : startSuffixes) {
|
||||||
for (String dataSuffix : dataSuffixes) {
|
for (String endSuffix : endSuffixes) {
|
||||||
String suffix = dataSuffix + extraSuffix;
|
for (String dataSuffix : dataSuffixes) {
|
||||||
if (baseName.endsWith(suffix)) {
|
String suffix = startSuffix + dataSuffix + endSuffix;
|
||||||
FileHandle file = atlasFile(skeletonFile, baseName.substring(0, baseName.length() - suffix.length()));
|
if (baseName.endsWith(suffix)) {
|
||||||
if (file != null) return file;
|
FileHandle file = atlasFile(skeletonFile, baseName.substring(0, baseName.length() - suffix.length()));
|
||||||
|
if (file != null) return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,10 +162,12 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private FileHandle atlasFile (FileHandle skeletonFile, String baseName) {
|
private FileHandle atlasFile (FileHandle skeletonFile, String baseName) {
|
||||||
for (String extraSuffix : extraSuffixes) {
|
for (String startSuffix : startSuffixes) {
|
||||||
for (String suffix : atlasSuffixes) {
|
for (String endSuffix : endSuffixes) {
|
||||||
FileHandle file = skeletonFile.sibling(baseName + suffix + extraSuffix);
|
for (String suffix : atlasSuffixes) {
|
||||||
if (file.exists()) return file;
|
FileHandle file = skeletonFile.sibling(baseName + startSuffix + suffix + endSuffix);
|
||||||
|
if (file.exists()) return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -238,6 +243,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
|
|
||||||
state = new AnimationState(new AnimationStateData(skeletonData));
|
state = new AnimationState(new AnimationStateData(skeletonData));
|
||||||
state.addListener(new AnimationStateAdapter() {
|
state.addListener(new AnimationStateAdapter() {
|
||||||
|
|
||||||
public void event (TrackEntry entry, Event event) {
|
public void event (TrackEntry entry, Event event) {
|
||||||
ui.toast(event.getData().getName());
|
ui.toast(event.getData().getName());
|
||||||
}
|
}
|
||||||
@ -254,6 +260,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
|
|
||||||
ui.window.getTitleLabel().setText(skeletonFile.name());
|
ui.window.getTitleLabel().setText(skeletonFile.name());
|
||||||
{
|
{
|
||||||
|
|
||||||
Array<String> items = new Array();
|
Array<String> items = new Array();
|
||||||
for (Skin skin : skeletonData.getSkins())
|
for (Skin skin : skeletonData.getSkins())
|
||||||
items.add(skin.getName());
|
items.add(skin.getName());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user