NathanSweet 12 éve
szülő
commit
31b07f8625

+ 22 - 0
spine-cpp/data/spineboy-walk.json

@@ -274,5 +274,27 @@
 			{ "time": 1.0666, "angle": 3.6 }
 			{ "time": 1.0666, "angle": 3.6 }
 		]
 		]
 	}
 	}
+},
+"slots": {
+	"torso": {
+		"attachment": [
+			{ "time": 0.4333, "name": null },
+			{ "time": 0.8, "name": "torso" }
+		]
+	},
+	"head": {
+		"color": [
+			{ "time": 0.1666, "color": "ffffffff" },
+			{ "time": 0.9333, "color": "ff0f00c1" }
+		]
+	},
+	"eyes": {
+		"attachment": [
+			{ "time": 0.2, "name": "eyes-closed" },
+			{ "time": 0.3, "name": "eyes" },
+			{ "time": 0.7, "name": "eyes-closed" },
+			{ "time": 0.8333, "name": "eyes" }
+		]
+	}
 }
 }
 }
 }

+ 2 - 1
spine-cpp/includes/spine/Animation.h

@@ -133,7 +133,8 @@ public:
 	virtual int getKeyframeCount ();
 	virtual int getKeyframeCount ();
 	virtual void apply (BaseSkeleton *skeleton, float time, float alpha);
 	virtual void apply (BaseSkeleton *skeleton, float time, float alpha);
 
 
-	void setKeyframe (int keyframeIndex, float time, std::string *attachmentName);
+	/** @param attachmentName Pass an empty string to clear the image for a slot. */
+	void setKeyframe (int keyframeIndex, float time, const std::string &attachmentName);
 };
 };
 
 
 } /* namespace spine */
 } /* namespace spine */

+ 2 - 0
spine-cpp/includes/spine/BaseRegionAttachment.h

@@ -13,6 +13,8 @@ public:
 	float x, y, scaleX, scaleY, rotation, width, height;
 	float x, y, scaleX, scaleY, rotation, width, height;
 	float offset[8];
 	float offset[8];
 
 
+	BaseRegionAttachment ();
+
 	void updateOffset ();
 	void updateOffset ();
 
 
 	virtual void updateWorldVertices (Bone *bone) = 0;
 	virtual void updateWorldVertices (Bone *bone) = 0;

+ 1 - 0
spine-cpp/includes/spine/BaseSkeletonJson.h

@@ -13,6 +13,7 @@ class BaseSkeletonJson {
 public:
 public:
 	BaseAttachmentLoader *attachmentLoader;
 	BaseAttachmentLoader *attachmentLoader;
 	float scale;
 	float scale;
+	bool flipY;
 
 
 	BaseSkeletonJson (BaseAttachmentLoader *attachmentLoader);
 	BaseSkeletonJson (BaseAttachmentLoader *attachmentLoader);
 	virtual ~BaseSkeletonJson ();
 	virtual ~BaseSkeletonJson ();

+ 7 - 1
spine-cpp/includes/spine/BoneData.h

@@ -13,12 +13,18 @@ public:
 	float x, y;
 	float x, y;
 	float rotation;
 	float rotation;
 	float scaleX, scaleY;
 	float scaleX, scaleY;
+	float flipY;
 
 
 	BoneData (const std::string &name) :
 	BoneData (const std::string &name) :
 					name(name),
 					name(name),
 					parent(0),
 					parent(0),
+					length(0),
+					x(0),
+					y(0),
+					rotation(0),
 					scaleX(1),
 					scaleX(1),
-					scaleY(1) {
+					scaleY(1),
+					flipY(false) {
 	}
 	}
 };
 };
 
 

+ 2 - 3
spine-cpp/src/main.cpp

@@ -21,6 +21,8 @@ int main () {
 		Animation *animation = skeletonJson.readAnimation(animationFile, skeletonData);
 		Animation *animation = skeletonJson.readAnimation(animationFile, skeletonData);
 
 
 		Skeleton *skeleton = new Skeleton(skeletonData);
 		Skeleton *skeleton = new Skeleton(skeletonData);
+		skeleton->flipX = false;
+		skeleton->flipY = false;
 		skeleton->setToBindPose();
 		skeleton->setToBindPose();
 		skeleton->getRootBone()->x = 200;
 		skeleton->getRootBone()->x = 200;
 		skeleton->getRootBone()->y = 420;
 		skeleton->getRootBone()->y = 420;
@@ -42,9 +44,6 @@ int main () {
 			deltaClock.restart();
 			deltaClock.restart();
 			animationTime += delta;
 			animationTime += delta;
 
 
-			skeleton->setToBindPose();
-			skeleton->getRootBone()->x = 200;
-			skeleton->getRootBone()->y = 420;
 			animation->apply(skeleton, animationTime, true);
 			animation->apply(skeleton, animationTime, true);
 			skeleton->updateWorldTransform();
 			skeleton->updateWorldTransform();
 		}
 		}

+ 0 - 1
spine-cpp/src/spine-sfml/Skeleton.cpp

@@ -17,7 +17,6 @@ Skeleton::Skeleton (SkeletonData *skeletonData) :
 				BaseSkeleton(skeletonData),
 				BaseSkeleton(skeletonData),
 				vertexArray(Quads, skeletonData->bones.size() * 4),
 				vertexArray(Quads, skeletonData->bones.size() * 4),
 				texture(0) {
 				texture(0) {
-	flipY = true; // BOZO - Flip in loader for animation?
 }
 }
 
 
 void Skeleton::draw (RenderTarget& target, RenderStates states) const {
 void Skeleton::draw (RenderTarget& target, RenderStates states) const {

+ 2 - 0
spine-cpp/src/spine-sfml/SkeletonJson.cpp

@@ -5,10 +5,12 @@ namespace spine {
 
 
 SkeletonJson::SkeletonJson (BaseAttachmentLoader *attachmentLoader) :
 SkeletonJson::SkeletonJson (BaseAttachmentLoader *attachmentLoader) :
 				BaseSkeletonJson(attachmentLoader) {
 				BaseSkeletonJson(attachmentLoader) {
+	flipY = true;
 }
 }
 
 
 SkeletonJson::SkeletonJson (Atlas *atlas) :
 SkeletonJson::SkeletonJson (Atlas *atlas) :
 				BaseSkeletonJson(new AtlasAttachmentLoader(atlas)) {
 				BaseSkeletonJson(new AtlasAttachmentLoader(atlas)) {
+	flipY = true;
 }
 }
 
 
 } /* namespace spine */
 } /* namespace spine */

+ 18 - 14
spine-cpp/src/spine/Animation.cpp

@@ -104,7 +104,7 @@ float CurveTimeline::getCurvePercent (int keyframeIndex, float percent) {
 //
 //
 
 
 /** @param target After the first and before the last entry. */
 /** @param target After the first and before the last entry. */
-int binarySearch (float *values, int valuesLength, float target, int step) {
+static int binarySearch (float *values, int valuesLength, float target, int step) {
 	int low = 0;
 	int low = 0;
 	int high = valuesLength / step - 2;
 	int high = valuesLength / step - 2;
 	if (high == 0) return step;
 	if (high == 0) return step;
@@ -120,15 +120,15 @@ int binarySearch (float *values, int valuesLength, float target, int step) {
 	return 0;
 	return 0;
 }
 }
 
 
-int linearSearch (float *values, int valuesLength, float target, int step) {
-	for (int i = 0, last = valuesLength - step; i <= last; i += step) {
-		if (values[i] <= target) continue;
-		return i;
-	}
-	return -1;
-}
-
-//
+/*
+ static int linearSearch (float *values, int valuesLength, float target, int step) {
+ for (int i = 0, last = valuesLength - step; i <= last; i += step) {
+ if (values[i] <= target) continue;
+ return i;
+ }
+ return -1;
+ }
+ */
 
 
 static const int ROTATE_LAST_FRAME_TIME = -2;
 static const int ROTATE_LAST_FRAME_TIME = -2;
 static const int ROTATE_FRAME_VALUE = 1;
 static const int ROTATE_FRAME_VALUE = 1;
@@ -138,6 +138,7 @@ RotateTimeline::RotateTimeline (int keyframeCount) :
 				framesLength(keyframeCount * 2),
 				framesLength(keyframeCount * 2),
 				frames(new float[framesLength]),
 				frames(new float[framesLength]),
 				boneIndex(0) {
 				boneIndex(0) {
+	memset(frames, 0, sizeof(float) * framesLength);
 }
 }
 
 
 RotateTimeline::~RotateTimeline () {
 RotateTimeline::~RotateTimeline () {
@@ -174,7 +175,7 @@ void RotateTimeline::apply (BaseSkeleton *skeleton, float time, float alpha) {
 	}
 	}
 
 
 	// Interpolate between the last frame and the current frame.
 	// Interpolate between the last frame and the current frame.
-	int frameIndex = linearSearch(frames, framesLength, time, 2);
+	int frameIndex = binarySearch(frames, framesLength, time, 2);
 	float lastFrameValue = frames[frameIndex - 1];
 	float lastFrameValue = frames[frameIndex - 1];
 	float frameTime = frames[frameIndex];
 	float frameTime = frames[frameIndex];
 	float percent = 1 - (time - frameTime) / (frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime);
 	float percent = 1 - (time - frameTime) / (frames[frameIndex + ROTATE_LAST_FRAME_TIME] - frameTime);
@@ -208,6 +209,7 @@ TranslateTimeline::TranslateTimeline (int keyframeCount) :
 				framesLength(keyframeCount * 3),
 				framesLength(keyframeCount * 3),
 				frames(new float[framesLength]),
 				frames(new float[framesLength]),
 				boneIndex(0) {
 				boneIndex(0) {
+	memset(frames, 0, sizeof(float) * framesLength);
 }
 }
 
 
 TranslateTimeline::~TranslateTimeline () {
 TranslateTimeline::~TranslateTimeline () {
@@ -260,7 +262,6 @@ void TranslateTimeline::apply (BaseSkeleton *skeleton, float time, float alpha)
 
 
 ScaleTimeline::ScaleTimeline (int keyframeCount) :
 ScaleTimeline::ScaleTimeline (int keyframeCount) :
 				TranslateTimeline(keyframeCount) {
 				TranslateTimeline(keyframeCount) {
-	frames = new float[framesLength];
 }
 }
 
 
 void ScaleTimeline::apply (BaseSkeleton *skeleton, float time, float alpha) {
 void ScaleTimeline::apply (BaseSkeleton *skeleton, float time, float alpha) {
@@ -304,6 +305,7 @@ ColorTimeline::ColorTimeline (int keyframeCount) :
 				framesLength(keyframeCount * 5),
 				framesLength(keyframeCount * 5),
 				frames(new float[framesLength]),
 				frames(new float[framesLength]),
 				slotIndex(0) {
 				slotIndex(0) {
+	memset(frames, 0, sizeof(float) * framesLength);
 }
 }
 
 
 ColorTimeline::~ColorTimeline () {
 ColorTimeline::~ColorTimeline () {
@@ -379,6 +381,8 @@ AttachmentTimeline::AttachmentTimeline (int keyframeCount) :
 				frames(new float[keyframeCount]),
 				frames(new float[keyframeCount]),
 				attachmentNames(new string*[keyframeCount]),
 				attachmentNames(new string*[keyframeCount]),
 				slotIndex(0) {
 				slotIndex(0) {
+	memset(frames, 0, sizeof(float) * keyframeCount);
+	memset(attachmentNames, 0, sizeof(string*) * keyframeCount);
 }
 }
 
 
 AttachmentTimeline::~AttachmentTimeline () {
 AttachmentTimeline::~AttachmentTimeline () {
@@ -397,10 +401,10 @@ int AttachmentTimeline::getKeyframeCount () {
 	return framesLength;
 	return framesLength;
 }
 }
 
 
-void AttachmentTimeline::setKeyframe (int keyframeIndex, float time, string *attachmentName) {
+void AttachmentTimeline::setKeyframe (int keyframeIndex, float time, const string &attachmentName) {
 	frames[keyframeIndex] = time;
 	frames[keyframeIndex] = time;
 	if (attachmentNames[keyframeIndex]) delete attachmentNames[keyframeIndex];
 	if (attachmentNames[keyframeIndex]) delete attachmentNames[keyframeIndex];
-	attachmentNames[keyframeIndex] = attachmentName ? new string(*attachmentName) : 0;
+	attachmentNames[keyframeIndex] = attachmentName.length() == 0 ? 0 : new string(attachmentName);
 }
 }
 
 
 void AttachmentTimeline::apply (BaseSkeleton *skeleton, float time, float alpha) {
 void AttachmentTimeline::apply (BaseSkeleton *skeleton, float time, float alpha) {

+ 10 - 0
spine-cpp/src/spine/BaseRegionAttachment.cpp

@@ -3,6 +3,16 @@
 
 
 namespace spine {
 namespace spine {
 
 
+BaseRegionAttachment::BaseRegionAttachment () :
+				x(0),
+				y(0),
+				scaleX(1),
+				scaleY(1),
+				rotation(0),
+				width(0),
+				height(0) {
+}
+
 void BaseRegionAttachment::updateOffset () {
 void BaseRegionAttachment::updateOffset () {
 	float localX2 = width / 2;
 	float localX2 = width / 2;
 	float localY2 = height / 2;
 	float localY2 = height / 2;

+ 68 - 6
spine-cpp/src/spine/BaseSkeletonJson.cpp

@@ -30,7 +30,8 @@ static float toColor (const string &value, int index) {
 
 
 BaseSkeletonJson::BaseSkeletonJson (BaseAttachmentLoader *attachmentLoader) :
 BaseSkeletonJson::BaseSkeletonJson (BaseAttachmentLoader *attachmentLoader) :
 				attachmentLoader(attachmentLoader),
 				attachmentLoader(attachmentLoader),
-				scale(1) {
+				scale(1),
+				flipY(false) {
 }
 }
 
 
 BaseSkeletonJson::~BaseSkeletonJson () {
 BaseSkeletonJson::~BaseSkeletonJson () {
@@ -88,12 +89,13 @@ SkeletonData* BaseSkeletonJson::readSkeletonData (const char *begin, const char
 		boneData->rotation = boneMap.get("rotation", 0).asDouble();
 		boneData->rotation = boneMap.get("rotation", 0).asDouble();
 		boneData->scaleX = boneMap.get("scaleX", 1).asDouble();
 		boneData->scaleX = boneMap.get("scaleX", 1).asDouble();
 		boneData->scaleY = boneMap.get("scaleY", 1).asDouble();
 		boneData->scaleY = boneMap.get("scaleY", 1).asDouble();
+		boneData->flipY = flipY;
 
 
 		skeletonData->bones.push_back(boneData);
 		skeletonData->bones.push_back(boneData);
 	}
 	}
 
 
-	if (root.isMember("slots")) {
-		Json::Value slots = root["slots"];
+	Json::Value slots = root["slots"];
+	if (!slots.isNull()) {
 		skeletonData->slots.reserve(slots.size());
 		skeletonData->slots.reserve(slots.size());
 		for (int i = 0; i < slots.size(); ++i) {
 		for (int i = 0; i < slots.size(); ++i) {
 			Json::Value slotMap = slots[i];
 			Json::Value slotMap = slots[i];
@@ -194,6 +196,15 @@ Animation* BaseSkeletonJson::readAnimation (const string &json, const SkeletonDa
 	return readAnimation(begin, end, skeletonData);
 	return readAnimation(begin, end, skeletonData);
 }
 }
 
 
+static void readCurve (CurveTimeline *timeline, int keyframeIndex, const Json::Value &valueMap) {
+	Json::Value curve = valueMap["curve"];
+	if (curve.isNull()) return;
+	if (curve.isString() && curve.asString() == "stepped")
+		timeline->setStepped(keyframeIndex);
+	else if (curve.isArray())
+		timeline->setCurve(keyframeIndex, curve[0u].asDouble(), curve[1u].asDouble(), curve[2u].asDouble(), curve[3u].asDouble());
+}
+
 Animation* BaseSkeletonJson::readAnimation (const char *begin, const char *end, const SkeletonData *skeletonData) const {
 Animation* BaseSkeletonJson::readAnimation (const char *begin, const char *end, const SkeletonData *skeletonData) const {
 	if (!begin) throw invalid_argument("begin cannot be null.");
 	if (!begin) throw invalid_argument("begin cannot be null.");
 	if (!end) throw invalid_argument("end cannot be null.");
 	if (!end) throw invalid_argument("end cannot be null.");
@@ -236,8 +247,7 @@ Animation* BaseSkeletonJson::readAnimation (const char *begin, const char *end,
 
 
 					float time = valueMap["time"].asDouble();
 					float time = valueMap["time"].asDouble();
 					timeline->setKeyframe(keyframeIndex, time, valueMap["angle"].asDouble());
 					timeline->setKeyframe(keyframeIndex, time, valueMap["angle"].asDouble());
-					// BOZO
-					// readCurve(timeline, keyframeIndex, valueMap);
+					readCurve(timeline, keyframeIndex, valueMap);
 					keyframeIndex++;
 					keyframeIndex++;
 				}
 				}
 				timelines.push_back(timeline);
 				timelines.push_back(timeline);
@@ -263,7 +273,7 @@ Animation* BaseSkeletonJson::readAnimation (const char *begin, const char *end,
 							valueMap["time"].asDouble(), //
 							valueMap["time"].asDouble(), //
 							valueMap.get("x", 0).asDouble() * timelineScale, //
 							valueMap.get("x", 0).asDouble() * timelineScale, //
 							valueMap.get("y", 0).asDouble() * timelineScale);
 							valueMap.get("y", 0).asDouble() * timelineScale);
-					// readCurve(timeline, keyframeIndex, valueMap);
+					readCurve(timeline, keyframeIndex, valueMap);
 					keyframeIndex++;
 					keyframeIndex++;
 				}
 				}
 				timelines.push_back(timeline);
 				timelines.push_back(timeline);
@@ -275,6 +285,58 @@ Animation* BaseSkeletonJson::readAnimation (const char *begin, const char *end,
 		}
 		}
 	}
 	}
 
 
+	Json::Value slots = root["slots"];
+	if (!slots.isNull()) {
+		vector<string> slotNames = slots.getMemberNames();
+		for (int i = 0; i < slotNames.size(); i++) {
+			string slotName = slotNames[i];
+			int slotIndex = skeletonData->findSlotIndex(slotName);
+			if (slotIndex == -1) throw runtime_error("Slot not found: " + slotName);
+
+			Json::Value timelineMap = slots[slotName];
+			vector<string> timelineNames = timelineMap.getMemberNames();
+			for (int i = 0; i < timelineNames.size(); i++) {
+				string timelineName = timelineNames[i];
+				Json::Value values = timelineMap[timelineName];
+
+				if (timelineName == TIMELINE_COLOR) {
+					ColorTimeline *timeline = new ColorTimeline(values.size());
+					timeline->slotIndex = slotIndex;
+
+					int keyframeIndex = 0;
+					for (int i = 0; i < values.size(); i++) {
+						Json::Value valueMap = values[i];
+
+						string s = valueMap["color"].asString();
+						timeline->setKeyframe(keyframeIndex, valueMap["time"].asDouble(), //
+								toColor(s, 0), toColor(s, 1), toColor(s, 2), toColor(s, 3));
+						readCurve(timeline, keyframeIndex, valueMap);
+						keyframeIndex++;
+					}
+					timelines.push_back(timeline);
+					if (timeline->getDuration() > duration) duration = timeline->getDuration();
+
+				} else if (timelineName == TIMELINE_ATTACHMENT) {
+					AttachmentTimeline *timeline = new AttachmentTimeline(values.size());
+					timeline->slotIndex = slotIndex;
+
+					int keyframeIndex = 0;
+					for (int i = 0; i < values.size(); i++) {
+						Json::Value valueMap = values[i];
+
+						Json::Value name = valueMap["name"];
+						timeline->setKeyframe(keyframeIndex++, valueMap["time"].asDouble(), name.isNull() ? "" : name.asString());
+					}
+					timelines.push_back(timeline);
+					if (timeline->getDuration() > duration) duration = timeline->getDuration();
+
+				} else {
+					throw runtime_error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
+				}
+			}
+		}
+	}
+
 	Animation *animation = new Animation(timelines, duration);
 	Animation *animation = new Animation(timelines, duration);
 	return animation;
 	return animation;
 }
 }

+ 9 - 3
spine-cpp/src/spine/Bone.cpp

@@ -8,10 +8,12 @@ namespace spine {
 Bone::Bone (BoneData *data) :
 Bone::Bone (BoneData *data) :
 				data(data),
 				data(data),
 				parent(0),
 				parent(0),
-				scaleX(1),
-				scaleY(1) {
+				x(data->x),
+				y(data->y),
+				rotation(data->rotation),
+				scaleX(data->scaleX),
+				scaleY(data->scaleY) {
 	if (!data) throw std::invalid_argument("data cannot be null.");
 	if (!data) throw std::invalid_argument("data cannot be null.");
-	setToBindPose();
 }
 }
 
 
 void Bone::setToBindPose () {
 void Bone::setToBindPose () {
@@ -51,6 +53,10 @@ void Bone::updateWorldTransform (bool flipX, bool flipY) {
 		m10 = -m10;
 		m10 = -m10;
 		m11 = -m11;
 		m11 = -m11;
 	}
 	}
+	if (data->flipY) {
+		m10 = -m10;
+		m11 = -m11;
+	}
 }
 }
 
 
 } /* namespace spine */
 } /* namespace spine */

+ 4 - 2
spine-cpp/src/spine/Slot.cpp

@@ -1,6 +1,7 @@
 #include <spine/Slot.h>
 #include <spine/Slot.h>
 #include <spine/SlotData.h>
 #include <spine/SlotData.h>
 #include <spine/BaseSkeleton.h>
 #include <spine/BaseSkeleton.h>
+#include <spine/SkeletonData.h>
 
 
 namespace spine {
 namespace spine {
 
 
@@ -17,6 +18,7 @@ Slot::Slot (SlotData *data, BaseSkeleton *skeleton, Bone *bone) :
 	if (!data) throw std::invalid_argument("data cannot be null.");
 	if (!data) throw std::invalid_argument("data cannot be null.");
 	if (!skeleton) throw std::invalid_argument("skeleton cannot be null.");
 	if (!skeleton) throw std::invalid_argument("skeleton cannot be null.");
 	if (!bone) throw std::invalid_argument("bone cannot be null.");
 	if (!bone) throw std::invalid_argument("bone cannot be null.");
+	setToBindPose();
 }
 }
 
 
 void Slot::setAttachment (Attachment *attachment) {
 void Slot::setAttachment (Attachment *attachment) {
@@ -33,8 +35,8 @@ float Slot::getAttachmentTime () const {
 }
 }
 
 
 void Slot::setToBindPose () {
 void Slot::setToBindPose () {
-	for (int i = 0, n = skeleton->slots.size(); i < n; i++) {
-		if (this == skeleton->slots[i]) {
+	for (int i = 0, n = skeleton->data->slots.size(); i < n; i++) {
+		if (data == skeleton->data->slots[i]) {
 			setToBindPose(i);
 			setToBindPose(i);
 			return;
 			return;
 		}
 		}

+ 7 - 7
spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java

@@ -226,12 +226,12 @@ public class SkeletonJson {
 			for (Entry<String, ?> entry : slotsMap.entries()) {
 			for (Entry<String, ?> entry : slotsMap.entries()) {
 				String slotName = entry.key;
 				String slotName = entry.key;
 				int slotIndex = skeletonData.findSlotIndex(slotName);
 				int slotIndex = skeletonData.findSlotIndex(slotName);
-				OrderedMap<?, ?> propertyMap = (OrderedMap)entry.value;
+				OrderedMap<?, ?> timelineMap = (OrderedMap)entry.value;
 
 
-				for (Entry propertyEntry : propertyMap.entries()) {
-					Array<OrderedMap> values = (Array)propertyEntry.value;
-					String timelineType = (String)propertyEntry.key;
-					if (timelineType.equals(TIMELINE_COLOR)) {
+				for (Entry timelineEntry : timelineMap.entries()) {
+					Array<OrderedMap> values = (Array)timelineEntry.value;
+					String timelineName = (String)timelineEntry.key;
+					if (timelineName.equals(TIMELINE_COLOR)) {
 						ColorTimeline timeline = new ColorTimeline(values.size);
 						ColorTimeline timeline = new ColorTimeline(values.size);
 						timeline.setSlotIndex(slotIndex);
 						timeline.setSlotIndex(slotIndex);
 
 
@@ -246,7 +246,7 @@ public class SkeletonJson {
 						timelines.add(timeline);
 						timelines.add(timeline);
 						duration = Math.max(duration, timeline.getDuration());
 						duration = Math.max(duration, timeline.getDuration());
 
 
-					} else if (timelineType.equals(TIMELINE_ATTACHMENT)) {
+					} else if (timelineName.equals(TIMELINE_ATTACHMENT)) {
 						AttachmentTimeline timeline = new AttachmentTimeline(values.size);
 						AttachmentTimeline timeline = new AttachmentTimeline(values.size);
 						timeline.setSlotIndex(slotIndex);
 						timeline.setSlotIndex(slotIndex);
 
 
@@ -259,7 +259,7 @@ public class SkeletonJson {
 						duration = Math.max(duration, timeline.getDuration());
 						duration = Math.max(duration, timeline.getDuration());
 
 
 					} else
 					} else
-						throw new RuntimeException("Invalid timeline type for a slot: " + timelineType + " (" + slotName + ")");
+						throw new RuntimeException("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
 				}
 				}
 			}
 			}
 		}
 		}

+ 2 - 1
spine-libgdx/src/com/esotericsoftware/spine/Slot.java

@@ -26,6 +26,7 @@ public class Slot {
 		this.skeleton = skeleton;
 		this.skeleton = skeleton;
 		this.bone = bone;
 		this.bone = bone;
 		color = new Color(1, 1, 1, 1);
 		color = new Color(1, 1, 1, 1);
+		setToBindPose();
 	}
 	}
 
 
 	/** Copy constructor. */
 	/** Copy constructor. */
@@ -84,7 +85,7 @@ public class Slot {
 	}
 	}
 
 
 	public void setToBindPose () {
 	public void setToBindPose () {
-		setToBindPose(skeleton.slots.indexOf(this, true));
+		setToBindPose(skeleton.data.slots.indexOf(data, true));
 	}
 	}
 
 
 	public String toString () {
 	public String toString () {