Refactored AttachmentLoader, allowing parameters per attachment type. Added attachment path. Added per attachment color.

This commit is contained in:
NathanSweet 2013-11-07 21:48:06 +01:00
parent e5aca584a2
commit d8a3f2231c
7 changed files with 84 additions and 89 deletions

View File

@ -48,8 +48,6 @@ import com.esotericsoftware.spine.attachments.AttachmentLoader;
import com.esotericsoftware.spine.attachments.AttachmentType; import com.esotericsoftware.spine.attachments.AttachmentType;
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.esotericsoftware.spine.attachments.RegionSequenceAttachment;
import com.esotericsoftware.spine.attachments.RegionSequenceAttachment.Mode;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
@ -189,35 +187,33 @@ public class SkeletonBinary {
String name = input.readString(); String name = input.readString();
if (name == null) name = attachmentName; if (name == null) name = attachmentName;
AttachmentType type = AttachmentType.values()[input.readByte()]; switch (AttachmentType.values()[input.readByte()]) {
Attachment attachment = attachmentLoader.newAttachment(skin, type, name); case region:
String path = input.readString();
if (attachment instanceof RegionSequenceAttachment) { if (path.length() == 0) path = name;
RegionSequenceAttachment regionSequenceAttachment = (RegionSequenceAttachment)attachment; RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path);
regionSequenceAttachment.setFrameTime(1 / input.readFloat()); if (region == null) return null;
regionSequenceAttachment.setMode(Mode.values()[input.readInt(true)]); region.setX(input.readFloat() * scale);
region.setY(input.readFloat() * scale);
} else if (attachment instanceof RegionAttachment) { region.setScaleX(input.readFloat());
RegionAttachment regionAttachment = (RegionAttachment)attachment; region.setScaleY(input.readFloat());
regionAttachment.setX(input.readFloat() * scale); region.setRotation(input.readFloat());
regionAttachment.setY(input.readFloat() * scale); region.setWidth(input.readFloat() * scale);
regionAttachment.setScaleX(input.readFloat()); region.setHeight(input.readFloat() * scale);
regionAttachment.setScaleY(input.readFloat()); Color.rgba8888ToColor(region.getColor(), input.readInt());
regionAttachment.setRotation(input.readFloat()); region.updateOffset();
regionAttachment.setWidth(input.readFloat() * scale); return region;
regionAttachment.setHeight(input.readFloat() * scale); case boundingbox:
regionAttachment.updateOffset(); BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name);
if (box == null) return null;
} else if (attachment instanceof BoundingBoxAttachment) {
BoundingBoxAttachment box = (BoundingBoxAttachment)attachment;
int n = input.readInt(true); int n = input.readInt(true);
float[] points = new float[n]; float[] points = new float[n];
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
points[i] = input.readFloat(); points[i] = input.readFloat();
box.setVertices(points); box.setVertices(points);
return box;
} }
return null;
return attachment;
} }
private void readAnimation (String name, DataInput input, SkeletonData skeletonData) { private void readAnimation (String name, DataInput input, SkeletonData skeletonData) {

View File

@ -48,8 +48,6 @@ import com.esotericsoftware.spine.attachments.AttachmentLoader;
import com.esotericsoftware.spine.attachments.AttachmentType; import com.esotericsoftware.spine.attachments.AttachmentType;
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.esotericsoftware.spine.attachments.RegionSequenceAttachment;
import com.esotericsoftware.spine.attachments.RegionSequenceAttachment.Mode;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
@ -170,40 +168,42 @@ public class SkeletonJson {
private Attachment readAttachment (Skin skin, String name, JsonValue map) { private Attachment readAttachment (Skin skin, String name, JsonValue map) {
name = map.getString("name", name); name = map.getString("name", name);
AttachmentType type = AttachmentType.valueOf(map.getString("type", AttachmentType.region.name())); switch (AttachmentType.valueOf(map.getString("type", AttachmentType.region.name()))) {
Attachment attachment = attachmentLoader.newAttachment(skin, type, name); case region:
RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, map.getString("path", name));
region.setX(map.getFloat("x", 0) * scale);
region.setY(map.getFloat("y", 0) * scale);
region.setScaleX(map.getFloat("scaleX", 1));
region.setScaleY(map.getFloat("scaleY", 1));
region.setRotation(map.getFloat("rotation", 0));
region.setWidth(map.getFloat("width") * scale);
region.setHeight(map.getFloat("height") * scale);
if (attachment instanceof RegionSequenceAttachment) { String color = map.getString("color", null);
RegionSequenceAttachment regionSequenceAttachment = (RegionSequenceAttachment)attachment; if (color != null) region.getColor().set(Color.valueOf(color));
float fps = map.getFloat("fps"); region.updateOffset();
regionSequenceAttachment.setFrameTime(fps); return region;
case boundingbox:
String modeString = map.getString("mode"); BoundingBoxAttachment box = attachmentLoader.newBoundingBoxAttachment(skin, name);
regionSequenceAttachment.setMode(modeString == null ? Mode.forward : Mode.valueOf(modeString));
} else if (attachment instanceof RegionAttachment) {
RegionAttachment regionAttachment = (RegionAttachment)attachment;
regionAttachment.setX(map.getFloat("x", 0) * scale);
regionAttachment.setY(map.getFloat("y", 0) * scale);
regionAttachment.setScaleX(map.getFloat("scaleX", 1));
regionAttachment.setScaleY(map.getFloat("scaleY", 1));
regionAttachment.setRotation(map.getFloat("rotation", 0));
regionAttachment.setWidth(map.getFloat("width", 32) * scale);
regionAttachment.setHeight(map.getFloat("height", 32) * scale);
regionAttachment.updateOffset();
} else if (attachment instanceof BoundingBoxAttachment) {
BoundingBoxAttachment box = (BoundingBoxAttachment)attachment;
JsonValue verticesArray = map.require("vertices"); JsonValue verticesArray = map.require("vertices");
float[] vertices = new float[verticesArray.size]; float[] vertices = new float[verticesArray.size];
int i = 0; int i = 0;
for (JsonValue point = verticesArray.child; point != null; point = point.next()) for (JsonValue point = verticesArray.child; point != null; point = point.next())
vertices[i++] = point.asFloat() * scale; vertices[i++] = point.asFloat() * scale;
box.setVertices(vertices); box.setVertices(vertices);
return box;
} }
return attachment; // RegionSequenceAttachment regionSequenceAttachment = (RegionSequenceAttachment)attachment;
//
// float fps = map.getFloat("fps");
// regionSequenceAttachment.setFrameTime(fps);
//
// String modeString = map.getString("mode");
// regionSequenceAttachment.setMode(modeString == null ? Mode.forward : Mode.valueOf(modeString));
return null;
} }
private void readAnimation (String name, JsonValue map, SkeletonData skeletonData) { private void readAnimation (String name, JsonValue map, SkeletonData skeletonData) {

View File

@ -46,28 +46,16 @@ public class AtlasAttachmentLoader implements AttachmentLoader {
this.atlas = atlas; this.atlas = atlas;
} }
public Attachment newAttachment (Skin skin, AttachmentType type, String name) { public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
Attachment attachment = null; RegionAttachment attachment = new RegionAttachment(name);
switch (type) { AtlasRegion region = atlas.findRegion(path);
case region: if (region == null)
attachment = new RegionAttachment(name); throw new RuntimeException("Region not found in atlas: " + attachment + " (region attachment: " + name + ")");
break; attachment.setRegion(region);
case regionsequence:
attachment = new RegionSequenceAttachment(name);
break;
case boundingbox:
return new BoundingBoxAttachment(name);
default:
throw new IllegalArgumentException("Unknown attachment type: " + type);
}
if (attachment instanceof RegionAttachment) {
AtlasRegion region = atlas.findRegion(attachment.getName());
if (region == null)
throw new RuntimeException("Region not found in atlas: " + attachment + " (" + type + " attachment: " + name + ")");
((RegionAttachment)attachment).setRegion(region);
}
return attachment; return attachment;
} }
public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name) {
return new BoundingBoxAttachment(name);
}
} }

View File

@ -37,5 +37,8 @@ import com.esotericsoftware.spine.Skin;
public interface AttachmentLoader { public interface AttachmentLoader {
/** @return May be null to not load any attachment. */ /** @return May be null to not load any attachment. */
public Attachment newAttachment (Skin skin, AttachmentType type, String name); public RegionAttachment newRegionAttachment (Skin skin, String name, String path);
/** @return May be null to not load any attachment. */
public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name);
} }

View File

@ -34,5 +34,5 @@
package com.esotericsoftware.spine.attachments; package com.esotericsoftware.spine.attachments;
public enum AttachmentType { public enum AttachmentType {
region, regionsequence, boundingbox region, boundingbox
} }

View File

@ -60,6 +60,7 @@ public class RegionAttachment extends Attachment {
private float x, y, scaleX = 1, scaleY = 1, rotation, width, height; private float x, y, scaleX = 1, scaleY = 1, rotation, width, height;
private final float[] vertices = new float[20]; private final float[] vertices = new float[20];
private final float[] offset = new float[8]; private final float[] offset = new float[8];
private final Color color = new Color(1, 1, 1, 1);
public RegionAttachment (String name) { public RegionAttachment (String name) {
super(name); super(name);
@ -151,21 +152,26 @@ public class RegionAttachment extends Attachment {
Skeleton skeleton = slot.getSkeleton(); Skeleton skeleton = slot.getSkeleton();
Color skeletonColor = skeleton.getColor(); Color skeletonColor = skeleton.getColor();
Color slotColor = slot.getColor(); Color slotColor = slot.getColor();
Color regionColor = color;
float r = skeletonColor.r * slotColor.r * regionColor.r;
float g = skeletonColor.g * slotColor.g * regionColor.g;
float b = skeletonColor.b * slotColor.b * regionColor.b;
float a = skeletonColor.a * slotColor.a * regionColor.a * 255;
float color; float color;
if (premultipliedAlpha) { if (premultipliedAlpha) {
float a = 255 * skeletonColor.a * slotColor.a; r *= a;
color = NumberUtils.intToFloatColor( // g *= a;
((int)a << 24) // b *= a;
| ((int)(a * skeletonColor.b * slotColor.b) << 16) //
| ((int)(a * skeletonColor.g * slotColor.g) << 8) //
| ((int)(a * skeletonColor.r * slotColor.r)));
} else { } else {
color = NumberUtils.intToFloatColor( // r *= 255;
((int)(255 * skeletonColor.a * slotColor.a) << 24) // g *= 255;
| ((int)(255 * skeletonColor.b * slotColor.b) << 16) // b *= 255;
| ((int)(255 * skeletonColor.g * slotColor.g) << 8) //
| ((int)(255 * skeletonColor.r * slotColor.r)));
} }
color = NumberUtils.intToFloatColor( //
((int)(a) << 24) //
| ((int)(b) << 16) //
| ((int)(g) << 8) //
| ((int)(r)));
float[] vertices = this.vertices; float[] vertices = this.vertices;
float[] offset = this.offset; float[] offset = this.offset;
@ -265,4 +271,8 @@ public class RegionAttachment extends Attachment {
public void setHeight (float height) { public void setHeight (float height) {
this.height = height; this.height = height;
} }
public Color getColor () {
return color;
}
} }

View File

@ -34,8 +34,6 @@
package com.esotericsoftware.spine; package com.esotericsoftware.spine;
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader; import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.AttachmentType;
import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.RegionAttachment;
import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.ApplicationAdapter;
@ -87,7 +85,7 @@ public class Box2DExample extends ApplicationAdapter {
// This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep // This loader creates Box2dAttachments instead of RegionAttachments for an easy way to keep
// track of the Box2D body for each attachment. // track of the Box2D body for each attachment.
AtlasAttachmentLoader atlasLoader = new AtlasAttachmentLoader(atlas) { AtlasAttachmentLoader atlasLoader = new AtlasAttachmentLoader(atlas) {
public Attachment newAttachment (Skin skin, AttachmentType type, String name) { public RegionAttachment newRegionAttachment (Skin skin, String name, String path) {
Box2dAttachment attachment = new Box2dAttachment(name); Box2dAttachment attachment = new Box2dAttachment(name);
AtlasRegion region = atlas.findRegion(attachment.getName()); AtlasRegion region = atlas.findRegion(attachment.getName());
if (region == null) throw new RuntimeException("Region not found in atlas: " + attachment); if (region == null) throw new RuntimeException("Region not found in atlas: " + attachment);