diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/AnimationStateTests.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/AnimationStateTests.java index e74745f43..4df486d51 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/AnimationStateTests.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/AnimationStateTests.java @@ -36,6 +36,7 @@ import com.badlogic.gdx.Files.FileType; import com.badlogic.gdx.backends.lwjgl.LwjglFileHandle; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Null; import com.badlogic.gdx.utils.Pool; import com.esotericsoftware.spine.AnimationState.AnimationStateListener; @@ -47,19 +48,15 @@ import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.PathAttachment; import com.esotericsoftware.spine.attachments.PointAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment; -import com.esotericsoftware.spine.attachments.SequenceAttachment; +import com.esotericsoftware.spine.attachments.Sequence; public class AnimationStateTests { final SkeletonJson json = new SkeletonJson(new AttachmentLoader() { - public RegionAttachment newRegionAttachment (Skin skin, String name, String path) { + public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) { return null; } - public MeshAttachment newMeshAttachment (Skin skin, String name, String path) { - return null; - } - - public SequenceAttachment newSequenceAttachment (Skin skin, String name, String path, int frameCount) { + public MeshAttachment newMeshAttachment (Skin skin, String name, String path, @Null Sequence sequence) { return null; } @@ -893,7 +890,6 @@ public class AnimationStateTests { state.apply(skeleton); while (time < endTime) { time += incr; - skeleton.update(incr); state.update(incr); // Reduce float discrepancies for tests. diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java index c5a1e93f7..e492bbf94 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java @@ -30,6 +30,7 @@ package com.esotericsoftware.spine; import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Null; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; @@ -40,21 +41,17 @@ import com.esotericsoftware.spine.attachments.MeshAttachment; import com.esotericsoftware.spine.attachments.PathAttachment; import com.esotericsoftware.spine.attachments.PointAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment; -import com.esotericsoftware.spine.attachments.SequenceAttachment; +import com.esotericsoftware.spine.attachments.Sequence; public class BonePlotting { static public void main (String[] args) throws Exception { // This example shows how to load skeleton data and plot a bone transform for each animation. SkeletonJson json = new SkeletonJson(new AttachmentLoader() { - public RegionAttachment newRegionAttachment (Skin skin, String name, String path) { + public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) { return null; } - public MeshAttachment newMeshAttachment (Skin skin, String name, String path) { - return null; - } - - public SequenceAttachment newSequenceAttachment (Skin skin, String name, String path, int frameCount) { + public MeshAttachment newMeshAttachment (Skin skin, String name, String path, @Null Sequence sequence) { return null; } diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java index a5d81f1dc..a32408a2a 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java @@ -49,12 +49,14 @@ import com.badlogic.gdx.physics.box2d.FixtureDef; import com.badlogic.gdx.physics.box2d.PolygonShape; import com.badlogic.gdx.physics.box2d.World; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Null; import com.badlogic.gdx.utils.ScreenUtils; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader; import com.esotericsoftware.spine.attachments.RegionAttachment; +import com.esotericsoftware.spine.attachments.Sequence; public class Box2DExample extends ApplicationAdapter { SpriteBatch batch; @@ -85,7 +87,7 @@ public class Box2DExample extends ApplicationAdapter { // This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep // track of the Box2D body for each attachment. AtlasAttachmentLoader atlasLoader = new AtlasAttachmentLoader(atlas) { - public RegionAttachment newRegionAttachment (Skin skin, String name, String path) { + public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) { Box2dAttachment attachment = new Box2dAttachment(name); AtlasRegion region = atlas.findRegion(attachment.getName()); if (region == null) throw new RuntimeException("Region not found in atlas: " + attachment); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixTest.java index 6f39a6eae..cee706c5a 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixTest.java @@ -125,7 +125,6 @@ public class MixTest extends ApplicationAdapter { } skeleton.updateWorldTransform(); - skeleton.update(Gdx.graphics.getDeltaTime()); batch.begin(); renderer.draw(batch, skeleton); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java index 999cb130f..900018b67 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java @@ -134,7 +134,6 @@ public class NormalMapTest extends ApplicationAdapter { time += Gdx.graphics.getDeltaTime(); if (animation != null) animation.apply(skeleton, lastTime, time, true, null, 1, MixBlend.first, MixDirection.in); skeleton.updateWorldTransform(); - skeleton.update(Gdx.graphics.getDeltaTime()); lightPosition.x = Gdx.input.getX(); lightPosition.y = (Gdx.graphics.getHeight() - 1 - Gdx.input.getY()); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java index e759a5ae0..4fc136f75 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java @@ -85,7 +85,6 @@ public class VertexEffectTest extends ApplicationAdapter { public void render () { // Update the skeleton and animation time. float delta = Gdx.graphics.getDeltaTime(); - skeleton.update(delta); state.update(delta); swirlTime += delta; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 3ba5122b9..028debe4f 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -40,6 +40,9 @@ import com.badlogic.gdx.utils.Null; import com.badlogic.gdx.utils.ObjectSet; import com.esotericsoftware.spine.attachments.Attachment; +import com.esotericsoftware.spine.attachments.HasTextureRegion; +import com.esotericsoftware.spine.attachments.Sequence; +import com.esotericsoftware.spine.attachments.Sequence.SequenceMode; import com.esotericsoftware.spine.attachments.VertexAttachment; /** Stores a list of timelines to animate a skeleton's pose over time. */ @@ -175,7 +178,8 @@ public class Animation { attachment, deform, // event, drawOrder, // ikConstraint, transformConstraint, // - pathConstraintPosition, pathConstraintSpacing, pathConstraintMix + pathConstraintPosition, pathConstraintSpacing, pathConstraintMix, // + sequence } /** The base class for all timelines. */ @@ -1646,7 +1650,7 @@ public class Animation { /** The attachment that will be deformed. *
- * See {@link VertexAttachment#getDeformAttachment()}. */
+ * See {@link VertexAttachment#getTimelineAttachment()}. */
public VertexAttachment getAttachment () {
return attachment;
}
@@ -1724,9 +1728,9 @@ public class Animation {
if (!slot.bone.active) return;
Attachment slotAttachment = slot.attachment;
if (!(slotAttachment instanceof VertexAttachment)
- || ((VertexAttachment)slotAttachment).getDeformAttachment() != attachment) return;
+ || ((VertexAttachment)slotAttachment).getTimelineAttachment() != attachment) return;
- FloatArray deformArray = slot.getDeform();
+ FloatArray deformArray = slot.deform;
if (deformArray.size == 0) blend = setup;
float[][] vertices = this.vertices;
@@ -1734,7 +1738,6 @@ public class Animation {
float[] frames = this.frames;
if (time < frames[0]) { // Time is before first frame.
- VertexAttachment vertexAttachment = (VertexAttachment)slotAttachment;
switch (blend) {
case setup:
deformArray.clear();
@@ -1745,6 +1748,7 @@ public class Animation {
return;
}
float[] deform = deformArray.setSize(vertexCount);
+ VertexAttachment vertexAttachment = (VertexAttachment)slotAttachment;
if (vertexAttachment.getBones() == null) {
// Unweighted vertex positions.
float[] setupVertices = vertexAttachment.getVertices();
@@ -2419,4 +2423,89 @@ public class Animation {
}
}
}
+
+ /** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. */
+ static public class SequenceTimeline
@@ -60,7 +59,6 @@ public class Skeleton {
final Array
- * See {@link #update(float)}. */
- public float getTime () {
- return time;
- }
-
- public void setTime (float time) {
- this.time = time;
- }
-
- /** Increments the skeleton's {@link #time}. */
- public void update (float delta) {
- time += delta;
- }
-
public String toString () {
return data.name != null ? data.name : super.toString();
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java
index 050805e1f..9d12696e7 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java
@@ -85,9 +85,6 @@ import com.esotericsoftware.spine.attachments.MeshAttachment;
import com.esotericsoftware.spine.attachments.PathAttachment;
import com.esotericsoftware.spine.attachments.PointAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
-import com.esotericsoftware.spine.attachments.SequenceAttachment;
-import com.esotericsoftware.spine.attachments.SequenceAttachment.SequenceMode;
-import com.esotericsoftware.spine.attachments.HasTextureRegion;
import com.esotericsoftware.spine.attachments.VertexAttachment;
/** Loads skeleton data in the Spine binary format.
@@ -303,7 +300,7 @@ public class SkeletonBinary extends SkeletonLoader {
if (skin == null) throw new SerializationException("Skin not found: " + linkedMesh.skin);
Attachment parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
if (parent == null) throw new SerializationException("Parent mesh not found: " + linkedMesh.parent);
- linkedMesh.mesh.setDeformAttachment(linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh);
+ linkedMesh.mesh.setTimelineAttachment(linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh);
linkedMesh.mesh.setParentMesh((MeshAttachment)parent);
linkedMesh.mesh.updateRegion();
}
@@ -399,8 +396,10 @@ public class SkeletonBinary extends SkeletonLoader {
float height = input.readFloat();
int color = input.readInt();
+ // BOZO! - Read sequence.
+
if (path == null) path = name;
- RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path);
+ RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, null);
if (region == null) return null;
region.setPath(path);
region.setX(x * scale);
@@ -443,8 +442,10 @@ public class SkeletonBinary extends SkeletonLoader {
height = input.readFloat();
}
+ // BOZO! - Read sequence.
+
if (path == null) path = name;
- MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path);
+ MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, null);
if (mesh == null) return null;
mesh.setPath(path);
Color.rgba8888ToColor(mesh.getColor(), color);
@@ -467,15 +468,17 @@ public class SkeletonBinary extends SkeletonLoader {
int color = input.readInt();
String skinName = input.readStringRef();
String parent = input.readStringRef();
- boolean inheritDeform = input.readBoolean();
+ boolean inheritTimelines = input.readBoolean();
float width = 0, height = 0;
if (nonessential) {
width = input.readFloat();
height = input.readFloat();
}
+ // BOZO! - Read sequence.
+
if (path == null) path = name;
- MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path);
+ MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, null);
if (mesh == null) return null;
mesh.setPath(path);
Color.rgba8888ToColor(mesh.getColor(), color);
@@ -483,7 +486,7 @@ public class SkeletonBinary extends SkeletonLoader {
mesh.setWidth(width * scale);
mesh.setHeight(height * scale);
}
- linkedMeshes.add(new LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform));
+ linkedMeshes.add(new LinkedMesh(mesh, skinName, slotIndex, parent, inheritTimelines));
return mesh;
}
case path: {
@@ -521,7 +524,7 @@ public class SkeletonBinary extends SkeletonLoader {
if (nonessential) Color.rgba8888ToColor(point.getColor(), color);
return point;
}
- case clipping: {
+ case clipping:
int endSlotIndex = input.readInt(true);
int vertexCount = input.readInt(true);
Vertices vertices = readVertices(input, vertexCount);
@@ -536,25 +539,6 @@ public class SkeletonBinary extends SkeletonLoader {
if (nonessential) Color.rgba8888ToColor(clip.getColor(), color);
return clip;
}
- case sequence:
- Attachment attachment = readAttachment(input, skeletonData, skin, slotIndex, attachmentName, nonessential);
- int frameCount = input.readInt(true);
- float frameTime = input.readFloat();
- SequenceMode mode = SequenceMode.values[input.readInt(true)];
-
- if (attachment == null) return null;
- String path = ((HasTextureRegion)attachment).getPath();
-
- SequenceAttachment sequence = attachmentLoader.newSequenceAttachment(skin, name, path, frameCount);
- if (sequence == null) return null;
-
- sequence.setAttachment(attachment);
- sequence.setPath(path);
- sequence.setFrameCount(frameCount);
- sequence.setFrameTime(frameTime);
- sequence.setMode(mode);
- return sequence;
- }
return null;
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java
index d32534b13..66ce3bbfe 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java
@@ -84,9 +84,6 @@ import com.esotericsoftware.spine.attachments.MeshAttachment;
import com.esotericsoftware.spine.attachments.PathAttachment;
import com.esotericsoftware.spine.attachments.PointAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment;
-import com.esotericsoftware.spine.attachments.SequenceAttachment;
-import com.esotericsoftware.spine.attachments.SequenceAttachment.SequenceMode;
-import com.esotericsoftware.spine.attachments.HasTextureRegion;
import com.esotericsoftware.spine.attachments.VertexAttachment;
/** Loads skeleton data in the Spine JSON format.
@@ -324,7 +321,7 @@ public class SkeletonJson extends SkeletonLoader {
if (skin == null) throw new SerializationException("Skin not found: " + linkedMesh.skin);
Attachment parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
if (parent == null) throw new SerializationException("Parent mesh not found: " + linkedMesh.parent);
- linkedMesh.mesh.setDeformAttachment(linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh);
+ linkedMesh.mesh.setTimelineAttachment(linkedMesh.inheritTimelines ? (VertexAttachment)parent : linkedMesh.mesh);
linkedMesh.mesh.setParentMesh((MeshAttachment)parent);
linkedMesh.mesh.updateRegion();
}
@@ -369,7 +366,8 @@ public class SkeletonJson extends SkeletonLoader {
switch (AttachmentType.valueOf(map.getString("type", AttachmentType.region.name()))) {
case region: {
String path = map.getString("path", name);
- RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path);
+ // BOZO! - Read sequence.
+ RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path, null);
if (region == null) return null;
region.setPath(path);
region.setX(map.getFloat("x", 0) * scale);
@@ -398,7 +396,8 @@ public class SkeletonJson extends SkeletonLoader {
case mesh:
case linkedmesh: {
String path = map.getString("path", name);
- MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path);
+ // BOZO! - Read sequence.
+ MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path, null);
if (mesh == null) return null;
mesh.setPath(path);
@@ -411,7 +410,7 @@ public class SkeletonJson extends SkeletonLoader {
String parent = map.getString("parent", null);
if (parent != null) {
linkedMeshes
- .add(new LinkedMesh(mesh, map.getString("skin", null), slotIndex, parent, map.getBoolean("deform", true)));
+ .add(new LinkedMesh(mesh, map.getString("skin", null), slotIndex, parent, map.getBoolean("timelines", true)));
return mesh;
}
@@ -455,7 +454,7 @@ public class SkeletonJson extends SkeletonLoader {
if (color != null) Color.valueOf(color, point.getColor());
return point;
}
- case clipping: {
+ case clipping:
ClippingAttachment clip = attachmentLoader.newClippingAttachment(skin, name);
if (clip == null) return null;
@@ -472,20 +471,6 @@ public class SkeletonJson extends SkeletonLoader {
if (color != null) Color.valueOf(color, clip.getColor());
return clip;
}
- case sequence:
- Attachment attachment = readAttachment(map.getChild("attachment"), skin, slotIndex, name, skeletonData);
- if (attachment == null) return null;
- String path = ((HasTextureRegion)attachment).getPath();
- int frameCount = map.getInt("count");
- SequenceAttachment sequence = attachmentLoader.newSequenceAttachment(skin, name, path, frameCount);
- if (sequence == null) return null;
- sequence.setAttachment(attachment);
- sequence.setPath(path);
- sequence.setFrameCount(frameCount);
- sequence.setFrameTime(map.getInt("time"));
- sequence.setMode(SequenceMode.valueOf(map.getString("mode", SequenceMode.forward.name())));
- return sequence;
- }
return null;
}
@@ -1068,14 +1053,14 @@ public class SkeletonJson extends SkeletonLoader {
String parent, skin;
int slotIndex;
MeshAttachment mesh;
- boolean inheritDeform;
+ boolean inheritTimelines;
- public LinkedMesh (MeshAttachment mesh, String skin, int slotIndex, String parent, boolean inheritDeform) {
+ public LinkedMesh (MeshAttachment mesh, String skin, int slotIndex, String parent, boolean inheritTimelines) {
this.mesh = mesh;
this.skin = skin;
this.slotIndex = slotIndex;
this.parent = parent;
- this.inheritDeform = inheritDeform;
+ this.inheritTimelines = inheritTimelines;
}
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java
index a93f7e333..4f66bef09 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java
@@ -98,7 +98,7 @@ public class SkeletonRenderer {
Attachment attachment = slot.attachment;
if (attachment instanceof RegionAttachment) {
RegionAttachment region = (RegionAttachment)attachment;
- region.computeWorldVertices(slot.getBone(), vertices, 0, 5);
+ region.computeWorldVertices(slot, vertices, 0, 5);
Color color = region.getColor(), slotColor = slot.getColor();
float alpha = a * slotColor.a * color.a * 255;
float multiplier = pmaColors ? alpha : 255;
@@ -183,7 +183,7 @@ public class SkeletonRenderer {
RegionAttachment region = (RegionAttachment)attachment;
verticesLength = vertexSize << 2;
vertices = this.vertices.items;
- region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize);
+ region.computeWorldVertices(slot, vertices, 0, vertexSize);
triangles = quadTriangles;
texture = region.getRegion().getTexture();
uvs = region.getUVs();
@@ -309,7 +309,7 @@ public class SkeletonRenderer {
RegionAttachment region = (RegionAttachment)attachment;
verticesLength = vertexSize << 2;
vertices = this.vertices.items;
- region.computeWorldVertices(slot.getBone(), vertices, 0, vertexSize);
+ region.computeWorldVertices(slot, vertices, 0, vertexSize);
triangles = quadTriangles;
texture = region.getRegion().getTexture();
uvs = region.getUVs();
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java
index be2a67da5..f50e89c02 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java
@@ -127,7 +127,7 @@ public class SkeletonRendererDebug {
if (attachment instanceof RegionAttachment) {
RegionAttachment region = (RegionAttachment)attachment;
float[] vertices = this.vertices.items;
- region.computeWorldVertices(slot.getBone(), vertices, 0, 2);
+ region.computeWorldVertices(slot, vertices, 0, 2);
shapes.line(vertices[0], vertices[1], vertices[2], vertices[3]);
shapes.line(vertices[2], vertices[3], vertices[4], vertices[5]);
shapes.line(vertices[4], vertices[5], vertices[6], vertices[7]);
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Slot.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Slot.java
index 2dd1fb348..13c75c2fd 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Slot.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Slot.java
@@ -35,6 +35,7 @@ import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.Animation.DeformTimeline;
import com.esotericsoftware.spine.attachments.Attachment;
+import com.esotericsoftware.spine.attachments.Sequence;
import com.esotericsoftware.spine.attachments.VertexAttachment;
/** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store
@@ -46,8 +47,8 @@ public class Slot {
final Color color = new Color();
@Null final Color darkColor;
@Null Attachment attachment;
- private float attachmentTime;
- private FloatArray deform = new FloatArray();
+ int sequenceIndex;
+ FloatArray deform = new FloatArray();
int attachmentState;
@@ -69,7 +70,7 @@ public class Slot {
color.set(slot.color);
darkColor = slot.darkColor == null ? null : new Color(slot.darkColor);
attachment = slot.attachment;
- attachmentTime = slot.attachmentTime;
+ sequenceIndex = slot.sequenceIndex;
deform.addAll(slot.deform);
}
@@ -105,27 +106,28 @@ public class Slot {
return attachment;
}
- /** Sets the slot's attachment and, if the attachment changed, resets {@link #attachmentTime} and clears the {@link #deform}.
- * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getDeformAttachment()} as the specified
- * attachment. */
+ /** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}.
+ * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the
+ * specified attachment. */
public void setAttachment (@Null Attachment attachment) {
if (this.attachment == attachment) return;
if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment)
- || ((VertexAttachment)attachment).getDeformAttachment() != ((VertexAttachment)this.attachment).getDeformAttachment()) {
+ || ((VertexAttachment)attachment).getTimelineAttachment() != ((VertexAttachment)this.attachment)
+ .getTimelineAttachment()) {
deform.clear();
}
this.attachment = attachment;
- attachmentTime = bone.skeleton.time;
+ sequenceIndex = -1;
}
- /** The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton
- * {@link Skeleton#time}. */
- public float getAttachmentTime () {
- return bone.skeleton.time - attachmentTime;
+ /** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the
+ * {@link Sequence#getSetupIndex()}. */
+ public int getSequenceIndex () {
+ return sequenceIndex;
}
- public void setAttachmentTime (float time) {
- attachmentTime = bone.skeleton.time - time;
+ public void setSequenceIndex (int sequenceIndex) {
+ this.sequenceIndex = sequenceIndex;
}
/** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java
index e5ba26041..384baabd4 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java
@@ -31,6 +31,8 @@ package com.esotericsoftware.spine.attachments;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.Skin;
@@ -47,32 +49,39 @@ public class AtlasAttachmentLoader implements AttachmentLoader {
this.atlas = atlas;
}
- public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
- AtlasRegion region = atlas.findRegion(path);
- if (region == null) throw new RuntimeException("Region not found in atlas: " + path + " (region attachment: " + name + ")");
- RegionAttachment attachment = new RegionAttachment(name);
- attachment.setRegion(region);
- return attachment;
- }
-
- public MeshAttachment newMeshAttachment (Skin skin, String name, String path) {
- AtlasRegion region = atlas.findRegion(path);
- if (region == null) throw new RuntimeException("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
- MeshAttachment attachment = new MeshAttachment(name);
- attachment.setRegion(region);
- return attachment;
- }
-
- public SequenceAttachment newSequenceAttachment (Skin skin, String name, String path, int frameCount) {
- AtlasRegion[] regions = new AtlasRegion[frameCount];
- for (int i = 0; i < frameCount; i++) {
- AtlasRegion region = atlas.findRegion(path + frameCount); // BOZO - Zero pad?
- if (region == null)
- throw new RuntimeException("Region not found in atlas: " + path + frameCount + " (sequence: " + name + ")");
+ private void loadSequence (String name, String basePath, Sequence sequence) {
+ TextureRegion[] regions = sequence.getRegions();
+ for (int i = 0, n = regions.length; i < n; i++) {
+ String path = sequence.getPath(basePath, i);
+ regions[i] = atlas.findRegion(path);
+ if (regions[i] == null) throw new RuntimeException("Region not found in atlas: " + path + " (sequence: " + name + ")");
}
- SequenceAttachment sequence = new SequenceAttachment(name);
- sequence.setRegions(regions);
- return sequence;
+ }
+
+ public RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence) {
+ RegionAttachment attachment = new RegionAttachment(name);
+ if (sequence != null)
+ loadSequence(name, path, sequence);
+ else {
+ AtlasRegion region = atlas.findRegion(path);
+ if (region == null)
+ throw new RuntimeException("Region not found in atlas: " + path + " (region attachment: " + name + ")");
+ attachment.setRegion(region);
+ }
+ return attachment;
+ }
+
+ public MeshAttachment newMeshAttachment (Skin skin, String name, String path, @Null Sequence sequence) {
+ MeshAttachment attachment = new MeshAttachment(name);
+ if (sequence != null)
+ loadSequence(name, path, sequence);
+ else {
+ AtlasRegion region = atlas.findRegion(path);
+ if (region == null)
+ throw new RuntimeException("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
+ attachment.setRegion(region);
+ }
+ return attachment;
}
public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name) {
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Attachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Attachment.java
index 0ecc20f47..b76fc6bbc 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Attachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Attachment.java
@@ -31,13 +31,18 @@ package com.esotericsoftware.spine.attachments;
/** The base class for all attachments. */
abstract public class Attachment {
- String name;
+ final String name;
public Attachment (String name) {
if (name == null) throw new IllegalArgumentException("name cannot be null.");
this.name = name;
}
+ /** Copy constructor. */
+ protected Attachment (Attachment other) {
+ name = other.name;
+ }
+
/** The attachment's name. */
public String getName () {
return name;
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java
index 47084c130..cbe0bd55e 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentLoader.java
@@ -39,13 +39,10 @@ import com.esotericsoftware.spine.Skin;
* Runtimes Guide. */
public interface AttachmentLoader {
/** @return May be null to not load the attachment. */
- public @Null RegionAttachment newRegionAttachment (Skin skin, String name, String path);
+ public @Null RegionAttachment newRegionAttachment (Skin skin, String name, String path, @Null Sequence sequence);
/** @return May be null to not load the attachment. In that case null should also be returned for child meshes. */
- public @Null MeshAttachment newMeshAttachment (Skin skin, String name, String path);
-
- /** @return May be null to not load the attachment. */
- public @Null SequenceAttachment newSequenceAttachment (Skin skin, String name, String path, int frameCount);
+ public @Null MeshAttachment newMeshAttachment (Skin skin, String name, String path, @Null Sequence sequence);
/** @return May be null to not load the attachment. */
public @Null BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name);
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java
index 7bb2a1ba8..99346857b 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/BoundingBoxAttachment.java
@@ -46,16 +46,19 @@ public class BoundingBoxAttachment extends VertexAttachment {
super(name);
}
+ /** Copy constructor. */
+ protected BoundingBoxAttachment (BoundingBoxAttachment other) {
+ super(other);
+ color.set(other.color);
+ }
+
/** The color of the bounding box as it was in Spine, or a default color if nonessential data was not exported. Bounding boxes
* are not usually rendered at runtime. */
public Color getColor () {
return color;
}
- public Attachment copy () {
- BoundingBoxAttachment copy = new BoundingBoxAttachment(name);
- copyTo(copy);
- copy.color.set(color);
- return copy;
+ public BoundingBoxAttachment copy () {
+ return new BoundingBoxAttachment(name);
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java
index cd804cfc8..3b2825a80 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/ClippingAttachment.java
@@ -45,6 +45,13 @@ public class ClippingAttachment extends VertexAttachment {
super(name);
}
+ /** Copy constructor. */
+ protected ClippingAttachment (ClippingAttachment other) {
+ super(other);
+ endSlot = other.endSlot;
+ color.set(other.color);
+ }
+
/** Clipping is performed between the clipping attachment's slot and the end slot. If null clipping is done until the end of
* the skeleton's rendering. */
public @Null SlotData getEndSlot () {
@@ -61,11 +68,7 @@ public class ClippingAttachment extends VertexAttachment {
return color;
}
- public Attachment copy () {
- ClippingAttachment copy = new ClippingAttachment(name);
- copyTo(copy);
- copy.endSlot = endSlot;
- copy.color.set(color);
- return copy;
+ public ClippingAttachment copy () {
+ return new ClippingAttachment(name);
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/HasTextureRegion.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/HasTextureRegion.java
index 32247e169..6c37b6f48 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/HasTextureRegion.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/HasTextureRegion.java
@@ -3,6 +3,7 @@ package com.esotericsoftware.spine.attachments;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.utils.Null;
public interface HasTextureRegion {
/** The name used to find the {@link #getRegion()}. */
@@ -10,16 +11,20 @@ public interface HasTextureRegion {
public void setPath (String path);
- /** Sets the region used to draw the attachment. If the region or its properties are changed, {@link #updateRegion()} must be
- * called. */
- public void setRegion (TextureRegion region);
-
public TextureRegion getRegion ();
- /** Updates any values the attachment calculates using the {@link #getRegion()}. Must be called after changing the region or
- * the region's properties. */
+ /** Sets the region used to draw the attachment. After setting the region or if the region's properties are changed,
+ * {@link #updateRegion()} must be called. */
+ public void setRegion (TextureRegion region);
+
+ /** Updates any values the attachment calculates using the {@link #getRegion()}. Must be called after setting the
+ * {@link #getRegion()} or if the region's properties are changed. */
public void updateRegion ();
/** The color to tint the attachment. */
public Color getColor ();
+
+ public @Null Sequence getSequence ();
+
+ public void setSequence (@Null Sequence sequence);
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java
index a82a2a63d..c1eae3fc0 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java
@@ -36,6 +36,8 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Null;
+import com.esotericsoftware.spine.Slot;
+
/** An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not
* supported. Each vertex has UVs (texture coordinates) and triangles are used to map an image on to the mesh.
*
@@ -48,6 +50,7 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
private final Color color = new Color(1, 1, 1, 1);
private int hullLength;
private @Null MeshAttachment parentMesh;
+ private @Null Sequence sequence;
// Nonessential.
private @Null short[] edges;
@@ -57,6 +60,36 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
super(name);
}
+ /** Copy constructor. Use {@link #newLinkedMesh()} if the other mesh is a linked mesh. */
+ protected MeshAttachment (MeshAttachment other) {
+ super(other);
+
+ if (parentMesh != null) throw new IllegalArgumentException("Use newLinkedMesh to copy a linked mesh.");
+
+ region = other.region;
+ path = other.path;
+ color.set(other.color);
+
+ regionUVs = new float[other.regionUVs.length];
+ arraycopy(other.regionUVs, 0, regionUVs, 0, regionUVs.length);
+
+ uvs = new float[other.uvs.length];
+ arraycopy(other.uvs, 0, uvs, 0, uvs.length);
+
+ triangles = new short[other.triangles.length];
+ arraycopy(other.triangles, 0, triangles, 0, triangles.length);
+
+ hullLength = other.hullLength;
+
+ // Nonessential.
+ if (other.edges != null) {
+ edges = new short[other.edges.length];
+ arraycopy(other.edges, 0, edges, 0, edges.length);
+ }
+ width = other.width;
+ height = other.height;
+ }
+
public void setRegion (TextureRegion region) {
if (region == null) throw new IllegalArgumentException("region cannot be null.");
this.region = region;
@@ -67,8 +100,8 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
return region;
}
- /** Calculates {@link #uvs} using {@link #regionUVs} and the {@link #region}. Must be called after changing the region or the
- * region's properties. */
+ /** Calculates {@link #uvs} using the {@link #regionUVs} and {@link #region}. Must be called if the {@link #region},
+ * {@link #regionUVs}, or the region's properties are changed. */
public void updateRegion () {
float[] regionUVs = this.regionUVs;
if (this.uvs == null || this.uvs.length != regionUVs.length) this.uvs = new float[regionUVs.length];
@@ -131,6 +164,12 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
}
}
+ /** If the attachment has a {@link #sequence}, the {@link #region} may be changed. */
+ public void computeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride) {
+ if (sequence != null) sequence.apply(slot, this);
+ super.computeWorldVertices(slot, start, count, worldVertices, offset, stride);
+ }
+
/** Triplets of vertex indices which describe the mesh's triangulation. */
public short[] getTriangles () {
return triangles;
@@ -210,6 +249,14 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
this.height = height;
}
+ public @Null Sequence getSequence () {
+ return sequence;
+ }
+
+ public void setSequence (@Null Sequence sequence) {
+ this.sequence = sequence;
+ }
+
/** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices},
* {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the
* parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */
@@ -232,42 +279,19 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
}
}
- public Attachment copy () {
- if (parentMesh != null) return newLinkedMesh();
-
- MeshAttachment copy = new MeshAttachment(name);
- copy.region = region;
- copy.path = path;
- copy.color.set(color);
-
- copyTo(copy);
- copy.regionUVs = new float[regionUVs.length];
- arraycopy(regionUVs, 0, copy.regionUVs, 0, regionUVs.length);
- copy.uvs = new float[uvs.length];
- arraycopy(uvs, 0, copy.uvs, 0, uvs.length);
- copy.triangles = new short[triangles.length];
- arraycopy(triangles, 0, copy.triangles, 0, triangles.length);
- copy.hullLength = hullLength;
-
- // Nonessential.
- if (edges != null) {
- copy.edges = new short[edges.length];
- arraycopy(edges, 0, copy.edges, 0, edges.length);
- }
- copy.width = width;
- copy.height = height;
- return copy;
- }
-
/** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. */
public MeshAttachment newLinkedMesh () {
MeshAttachment mesh = new MeshAttachment(name);
+ mesh.timelineAttachment = timelineAttachment;
mesh.region = region;
mesh.path = path;
mesh.color.set(color);
- mesh.deformAttachment = deformAttachment;
mesh.setParentMesh(parentMesh != null ? parentMesh : this);
mesh.updateRegion();
return mesh;
}
+
+ public MeshAttachment copy () {
+ return parentMesh != null ? newLinkedMesh() : new MeshAttachment(this);
+ }
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java
index fdd622399..2f75df7ba 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PathAttachment.java
@@ -49,6 +49,18 @@ public class PathAttachment extends VertexAttachment {
super(name);
}
+ /** Copy constructor. */
+ protected PathAttachment (PathAttachment other) {
+ super(other);
+
+ lengths = new float[other.lengths.length];
+ arraycopy(other.lengths, 0, lengths, 0, lengths.length);
+
+ closed = other.closed;
+ constantSpeed = other.constantSpeed;
+ color.set(other.color);
+ }
+
/** If true, the start and end knots are connected. */
public boolean getClosed () {
return closed;
@@ -83,14 +95,7 @@ public class PathAttachment extends VertexAttachment {
return color;
}
- public Attachment copy () {
- PathAttachment copy = new PathAttachment(name);
- copyTo(copy);
- copy.lengths = new float[lengths.length];
- arraycopy(lengths, 0, copy.lengths, 0, lengths.length);
- copy.closed = closed;
- copy.constantSpeed = constantSpeed;
- copy.color.set(color);
- return copy;
+ public PathAttachment copy () {
+ return new PathAttachment(this);
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java
index b9b26a107..4a3e5a14a 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/PointAttachment.java
@@ -51,6 +51,15 @@ public class PointAttachment extends Attachment {
super(name);
}
+ /** Copy constructor. */
+ protected PointAttachment (PointAttachment other) {
+ super(other);
+ x = other.x;
+ y = other.y;
+ rotation = other.rotation;
+ color.set(other.color);
+ }
+
public float getX () {
return x;
}
@@ -94,12 +103,7 @@ public class PointAttachment extends Attachment {
return (float)Math.atan2(y, x) * radDeg;
}
- public Attachment copy () {
- PointAttachment copy = new PointAttachment(name);
- copy.x = x;
- copy.y = y;
- copy.rotation = rotation;
- copy.color.set(color);
- return copy;
+ public PointAttachment copy () {
+ return new PointAttachment(this);
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java
index 0f0a3e138..0301cdc1d 100644
--- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/RegionAttachment.java
@@ -34,21 +34,19 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
+import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.Bone;
+import com.esotericsoftware.spine.Slot;
/** An attachment that displays a textured quadrilateral.
*
* See Region attachments in the Spine User Guide. */
public class RegionAttachment extends Attachment implements HasTextureRegion {
- static public final int BLX = 0;
- static public final int BLY = 1;
- static public final int ULX = 2;
- static public final int ULY = 3;
- static public final int URX = 4;
- static public final int URY = 5;
- static public final int BRX = 6;
- static public final int BRY = 7;
+ static public final int BLX = 0, BLY = 1;
+ static public final int ULX = 2, ULY = 3;
+ static public final int URX = 4, URY = 5;
+ static public final int BRX = 6, BRY = 7;
private TextureRegion region;
private String path;
@@ -56,13 +54,31 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
private final float[] uvs = new float[8];
private final float[] offset = new float[8];
private final Color color = new Color(1, 1, 1, 1);
+ private @Null Sequence sequence;
public RegionAttachment (String name) {
super(name);
}
- /** Calculates the {@link #offset} using the {@link #region}. Must be called after changing the region or the region's
- * properties. */
+ /** Copy constructor. */
+ protected RegionAttachment (RegionAttachment other) {
+ super(other);
+ region = other.region;
+ path = other.path;
+ x = other.x;
+ y = other.y;
+ scaleX = other.scaleX;
+ scaleY = other.scaleY;
+ rotation = other.rotation;
+ width = other.width;
+ height = other.height;
+ arraycopy(other.uvs, 0, uvs, 0, 8);
+ arraycopy(other.offset, 0, offset, 0, 8);
+ color.set(other.color);
+ }
+
+ /** Calculates the {@link #offset} and {@link #uvs} using the {@link #region} and the attachment's transform. Must be called if
+ * the {@link #region}, transform, or the region's properties are changed. */
public void updateRegion () {
float width = getWidth();
float height = getHeight();
@@ -70,11 +86,13 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
float localY2 = height / 2;
float localX = -localX2;
float localY = -localY2;
+ boolean rotated = false;
if (region instanceof AtlasRegion) {
AtlasRegion region = (AtlasRegion)this.region;
localX += region.offsetX / region.originalWidth * width;
localY += region.offsetY / region.originalHeight * height;
if (region.degrees == 90) {
+ rotated = true;
localX2 -= (region.originalWidth - region.offsetX - region.packedHeight) / region.originalWidth * width;
localY2 -= (region.originalHeight - region.offsetY - region.packedWidth) / region.originalHeight * height;
} else {
@@ -110,13 +128,9 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
offset[URY] = localY2Cos + localX2Sin;
offset[BRX] = localX2Cos - localYSin;
offset[BRY] = localYCos + localX2Sin;
- }
- public void setRegion (TextureRegion region) {
- if (region == null) throw new IllegalArgumentException("region cannot be null.");
- this.region = region;
float[] uvs = this.uvs;
- if (region instanceof AtlasRegion && ((AtlasRegion)region).degrees == 90) {
+ if (rotated) {
uvs[URX] = region.getU();
uvs[URY] = region.getV2();
uvs[BRX] = region.getU();
@@ -137,20 +151,29 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
}
}
+ public void setRegion (TextureRegion region) {
+ if (region == null) throw new IllegalArgumentException("region cannot be null.");
+ this.region = region;
+ }
+
public TextureRegion getRegion () {
if (region == null) throw new IllegalStateException("Region has not been set: " + name);
return region;
}
- /** Transforms the attachment's four vertices to world coordinates.
+ /** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the
+ * {@link #region} may be changed.
*
* See World transforms in the Spine
* Runtimes Guide.
* @param worldVertices The output world vertices. Must have a length >=
- * See Sequence attachments in the Spine User Guide. */
-public class SequenceAttachment
@@ -120,17 +140,6 @@ abstract public class VertexAttachment extends Attachment {
}
}
- /** Deform keys for the deform attachment are also applied to this attachment.
- * @return May be null if no deform keys should be applied. */
- public @Null VertexAttachment getDeformAttachment () {
- return deformAttachment;
- }
-
- /** @param deformAttachment May be null if no deform keys should be applied. */
- public void setDeformAttachment (@Null VertexAttachment deformAttachment) {
- this.deformAttachment = deformAttachment;
- }
-
/** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting
* the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#getBones()}. Will be null
* if this attachment has no weights. */
@@ -164,29 +173,22 @@ abstract public class VertexAttachment extends Attachment {
this.worldVerticesLength = worldVerticesLength;
}
+ /** Timelines for the timeline attachment are also applied to this attachment.
+ * @return May be null if no attachment-specific timelines should be applied. */
+ public @Null Attachment getTimelineAttachment () {
+ return timelineAttachment;
+ }
+
+ /** @param timelineAttachment May be null if no attachment-specific timelines should be applied. */
+ public void setTimelineAttachment (Attachment timelineAttachment) {
+ this.timelineAttachment = timelineAttachment;
+ }
+
/** Returns a unique ID for this attachment. */
public int getId () {
return id;
}
- /** Does not copy id (generated) or name (set on construction). */
- void copyTo (VertexAttachment attachment) {
- if (bones != null) {
- attachment.bones = new int[bones.length];
- arraycopy(bones, 0, attachment.bones, 0, bones.length);
- } else
- attachment.bones = null;
-
- if (vertices != null) {
- attachment.vertices = new float[vertices.length];
- arraycopy(vertices, 0, attachment.vertices, 0, vertices.length);
- } else
- attachment.vertices = null;
-
- attachment.worldVerticesLength = worldVerticesLength;
- attachment.deformAttachment = deformAttachment;
- }
-
static private synchronized int nextID () {
return nextID++;
}
diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java
index d8ab6f51d..f72a48852 100644
--- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java
+++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java
@@ -258,7 +258,6 @@ public class SkeletonViewer extends ApplicationAdapter {
skeleton.setSlotsToSetupPose();
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
- skeleton.update(delta);
state.update(delta);
state.apply(skeleton);
skeleton.updateWorldTransform();
frameCount, inclusive.
+ * @param time The frame time in seconds. */
+ public void setFrame (int frame, float time, SequenceMode mode, int index, float frameTime) {
+ frame *= ENTRIES;
+ frames[frame] = time;
+ frames[frame + MODE] = mode.ordinal() | (index << 4);
+ frames[frame + FRAME_TIME] = frameTime;
+ }
+
+ public void apply (Skeleton skeleton, float lastTime, float time, @Null Arrayoffset + 8.
* @param offset The worldVertices index to begin writing values.
* @param stride The number of worldVertices entries between the value pairs written. */
- public void computeWorldVertices (Bone bone, float[] worldVertices, int offset, int stride) {
+ public void computeWorldVertices (Slot slot, float[] worldVertices, int offset, int stride) {
+ if (sequence != null) sequence.apply(slot, this);
+
float[] vertexOffset = this.offset;
+ Bone bone = slot.getBone();
float x = bone.getWorldX(), y = bone.getWorldY();
float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD();
float offsetX, offsetY;
@@ -265,20 +288,15 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
this.path = path;
}
- public Attachment copy () {
- RegionAttachment copy = new RegionAttachment(name);
- copy.region = region;
- copy.path = path;
- copy.x = x;
- copy.y = y;
- copy.scaleX = scaleX;
- copy.scaleY = scaleY;
- copy.rotation = rotation;
- copy.width = width;
- copy.height = height;
- arraycopy(uvs, 0, copy.uvs, 0, 8);
- arraycopy(offset, 0, copy.offset, 0, 8);
- copy.color.set(color);
- return copy;
+ public @Null Sequence getSequence () {
+ return sequence;
+ }
+
+ public void setSequence (@Null Sequence sequence) {
+ this.sequence = sequence;
+ }
+
+ public RegionAttachment copy () {
+ return new RegionAttachment(this);
}
}
diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Sequence.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Sequence.java
new file mode 100644
index 000000000..b7004ac0c
--- /dev/null
+++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/Sequence.java
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated September 24, 2021. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2021, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package com.esotericsoftware.spine.attachments;
+
+import static com.esotericsoftware.spine.utils.SpineUtils.*;
+
+import com.badlogic.gdx.graphics.g2d.TextureRegion;
+
+import com.esotericsoftware.spine.Slot;
+
+public class Sequence {
+ static private int nextID;
+
+ private final int id = nextID();
+ private final TextureRegion[] regions;
+ private int start, digits, setupIndex;
+
+ public Sequence (int count) {
+ regions = new TextureRegion[count];
+ }
+
+ /** Copy constructor. */
+ protected Sequence (Sequence other) {
+ regions = new TextureRegion[other.regions.length];
+ arraycopy(other.regions, 0, regions, 0, regions.length);
+
+ start = other.start;
+ digits = other.digits;
+ setupIndex = other.setupIndex;
+ }
+
+ public