فهرست منبع

[as3] Added SkeletonBinary to load binary .skel files. See #1095.

badlogic 6 سال پیش
والد
کامیت
e8866cc730

+ 1 - 0
examples/export/runtimes.sh

@@ -313,6 +313,7 @@ cp -f ../owl/export/owl.atlas "$ROOT/spine-starling/spine-starling-example/src/"
 cp -f ../owl/export/owl.png "$ROOT/spine-starling/spine-starling-example/src/"
 
 cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-starling/spine-starling-example/src/"
+cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-starling/spine-starling-example/src/"
 cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-starling/spine-starling-example/src/"
 cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-starling/spine-starling-example/src/"
 

BIN
spine-as3/spine-as3-example/lib/spine-as3.swc


+ 0 - 4
spine-as3/spine-as3/.settings/org.eclipse.core.resources.prefs

@@ -45,10 +45,6 @@ encoding//src/spine/animation/TrackEntry.as=UTF-8
 encoding//src/spine/animation/TransformConstraintTimeline.as=UTF-8
 encoding//src/spine/animation/TranslateTimeline.as=UTF-8
 encoding//src/spine/animation/TwoColorTimeline.as=UTF-8
-encoding//src/spine/attachments/AtlasAttachmentLoader.as=UTF-8
-encoding//src/spine/attachments/ClippingAttachment.as=UTF-8
-encoding//src/spine/attachments/MeshAttachment.as=UTF-8
-encoding//src/spine/attachments/PointAttachment.as=UTF-8
 encoding//src/spine/interpolation/Pow.as=UTF-8
 encoding//src/spine/interpolation/PowOut.as=UTF-8
 encoding//src/spine/vertexeffects/JitterEffect.as=UTF-8

+ 117 - 0
spine-as3/spine-as3/src/spine/BinaryInput.as

@@ -0,0 +1,117 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated May 1, 2019. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2019, 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.
+ *
+ * THIS SOFTWARE IS 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 THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package spine {
+	import flash.utils.ByteArray;
+	
+	class BinaryInput {
+		private var bytes : ByteArray;	
+		public var strings : Vector.<String> = new Vector.<String>();
+		
+		public function BinaryInput(bytes: ByteArray) {
+			this.bytes = bytes;		
+		}
+		public function readByte() : int {
+			return bytes.readByte();		
+		}
+	
+		public function readShort() : int {
+			return bytes.readShort();
+		}
+	
+		public function readInt32(): int {
+			 return bytes.readInt();
+		}
+	
+		public function readInt(optimizePositive: Boolean) : int {
+			var b : int = readByte();
+			var result : int = b & 0x7F;
+			if ((b & 0x80) != 0) {
+				b = readByte();
+				result |= (b & 0x7F) << 7;
+				if ((b & 0x80) != 0) {
+					b = readByte();
+					result |= (b & 0x7F) << 14;
+					if ((b & 0x80) != 0) {
+						b = readByte();
+						result |= (b & 0x7F) << 21;
+						if ((b & 0x80) != 0) {
+							b = readByte();
+							result |= (b & 0x7F) << 28;
+						}
+					}
+				}
+			}
+			return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
+		}
+	
+		public function readStringRef (): String {
+			var index : int = readInt(true);
+			return index == 0 ? null : strings[index - 1];
+		}
+	
+		public function readString () : String {
+			var byteCount : int = readInt(true);
+			switch (byteCount) {
+			case 0:
+				return null;
+			case 1:
+				return "";
+			}
+			byteCount--;
+			var chars : String = "";		
+			for (var i : int = 0; i < byteCount;) {
+				var b : int = readByte();
+				switch (b >> 4) {
+				case 12:
+				case 13:
+					chars += String.fromCharCode(((b & 0x1F) << 6 | readByte() & 0x3F));
+					i += 2;
+					break;
+				case 14:
+					chars += String.fromCharCode(((b & 0x0F) << 12 | (readByte() & 0x3F) << 6 | readByte() & 0x3F));
+					i += 3;
+					break;
+				default:
+					chars += String.fromCharCode(b);
+					i++;
+				}
+			}
+			return chars;
+		}
+	
+		public function readFloat (): Number {
+			return bytes.readFloat();		
+		}
+	
+		public function readBoolean (): Boolean {
+			return this.readByte() != 0;
+		}
+	}
+}

+ 2 - 0
spine-as3/spine-as3/src/spine/BlendMode.as

@@ -38,5 +38,7 @@ package spine {
 		public function BlendMode(ordinal : int) {
 			this.ordinal = ordinal;
 		}
+		
+		public static const values : Array = [ normal, additive, multiply, screen ];
 	}
 }

+ 1 - 0
spine-as3/spine-as3/src/spine/BoneData.as

@@ -42,6 +42,7 @@ package spine {
 		public var shearY : Number;
 		public var transformMode : TransformMode = TransformMode.normal;
 		public var skinRequired : Boolean;
+		public var color : Color = new Color(0, 0, 0, 0);
 
 		/** @param parent May be null. */
 		public function BoneData(index : int, name : String, parent : BoneData) {

+ 13 - 0
spine-as3/spine-as3/src/spine/Color.as

@@ -95,5 +95,18 @@ package spine {
 			else if (this.a > 1) this.a = 1;
 			return this;
 		}
+		
+		public function setFromRgba8888(value: int) : void {
+			r = ((value & 0xff000000) >>> 24) / 255;
+			g = ((value & 0x00ff0000) >>> 16) / 255;
+			b = ((value & 0x0000ff00) >>> 8) / 255;
+			a = ((value & 0x000000ff)) / 255;
+		}
+
+		public function setFromRgb888(value: int) : void {
+			r = ((value & 0x00ff0000) >>> 16) / 255;
+			g = ((value & 0x0000ff00) >>> 8) / 255;
+			b = ((value & 0x000000ff)) / 255;
+		}
 	}
 }

+ 2 - 0
spine-as3/spine-as3/src/spine/PositionMode.as

@@ -31,5 +31,7 @@ package spine {
 	public class PositionMode {
 		public static const fixed : PositionMode = new PositionMode();
 		public static const percent : PositionMode = new PositionMode();
+		
+		public static const values : Array = [ fixed, percent ];
 	}
 }

+ 2 - 0
spine-as3/spine-as3/src/spine/RotateMode.as

@@ -32,5 +32,7 @@ package spine {
 		public static const tangent : RotateMode = new RotateMode();
 		public static const chain : RotateMode = new RotateMode();
 		public static const chainScale : RotateMode = new RotateMode();
+		
+		public static const values : Array = [ tangent, chain, chainScale ];
 	}
 }

+ 876 - 0
spine-as3/spine-as3/src/spine/SkeletonBinary.as

@@ -0,0 +1,876 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated May 1, 2019. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2019, 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.
+ *
+ * THIS SOFTWARE IS 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 THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package spine {
+	import spine.attachments.ClippingAttachment;
+	import spine.animation.TwoColorTimeline;
+	import spine.attachments.PointAttachment;
+	import spine.animation.PathConstraintMixTimeline;
+	import spine.animation.PathConstraintSpacingTimeline;
+	import spine.animation.PathConstraintPositionTimeline;
+	import spine.animation.TransformConstraintTimeline;
+	import spine.animation.ShearTimeline;
+	import spine.attachments.PathAttachment;
+	import spine.attachments.VertexAttachment;
+
+	import flash.utils.ByteArray;
+
+	import spine.animation.Animation;
+	import spine.animation.AttachmentTimeline;
+	import spine.animation.ColorTimeline;
+	import spine.animation.CurveTimeline;
+	import spine.animation.DrawOrderTimeline;
+	import spine.animation.EventTimeline;
+	import spine.animation.DeformTimeline;
+	import spine.animation.IkConstraintTimeline;
+	import spine.animation.RotateTimeline;
+	import spine.animation.ScaleTimeline;
+	import spine.animation.Timeline;
+	import spine.animation.TranslateTimeline;
+	import spine.attachments.Attachment;
+	import spine.attachments.AttachmentLoader;
+	import spine.attachments.AttachmentType;
+	import spine.attachments.BoundingBoxAttachment;
+	import spine.attachments.MeshAttachment;
+	import spine.attachments.RegionAttachment;
+
+	public class SkeletonBinary {
+		public var attachmentLoader : AttachmentLoader;
+		public var scale : Number = 1;
+		private var linkedMeshes : Vector.<LinkedMesh> = new Vector.<LinkedMesh>();
+		
+		private static const BONE_ROTATE : int = 0;
+		private static const BONE_TRANSLATE : int = 1;
+		private static const BONE_SCALE : int = 2;
+		private static const BONE_SHEAR : int = 3;
+
+		private static const SLOT_ATTACHMENT : int = 0;
+		private static const SLOT_COLOR : int = 1;
+		private static const SLOT_TWO_COLOR : int = 2;
+
+		private static const PATH_POSITION : int = 0;
+		private static const PATH_SPACING : int = 1;
+		private static const PATH_MIX : int = 2;
+
+		private static const CURVE_LINEAR : int = 0;
+		private static const CURVE_STEPPED : int = 1;
+		private static const CURVE_BEZIER : int = 2;
+
+		public function SkeletonBinary(attachmentLoader : AttachmentLoader = null) {
+			this.attachmentLoader = attachmentLoader;
+		}		
+
+		/** @param object A String or ByteArray. */
+		public function readSkeletonData(object : *) : SkeletonData {
+			if (object == null) throw new ArgumentError("object cannot be null.");
+			if (!(object is ByteArray)) throw new ArgumentError("Object must be a ByteArray");
+			
+			var scale : Number = this.scale;
+
+			var skeletonData : SkeletonData = new SkeletonData();
+			skeletonData.name = ""; // BOZO
+
+			var input : BinaryInput = new BinaryInput(object);
+
+			skeletonData.hash = input.readString();
+			skeletonData.version = input.readString();
+			skeletonData.x = input.readFloat();
+			skeletonData.y = input.readFloat();
+			skeletonData.width = input.readFloat();
+			skeletonData.height = input.readFloat();
+
+			var nonessential : Boolean = input.readBoolean();
+			if (nonessential) {
+				skeletonData.fps = input.readFloat();
+
+				skeletonData.imagesPath = input.readString();
+				skeletonData.audioPath = input.readString();
+			}
+
+			var n : int = 0;
+			var i : int = 0;
+			// Strings.
+			n = input.readInt(true);
+			for (i = 0; i < n; i++)
+				input.strings.push(input.readString());
+
+			// Bones.
+			n = input.readInt(true);
+			for (i = 0; i < n; i++) {
+				var boneName : String = input.readString();
+				var boneParent : BoneData = i == 0 ? null : skeletonData.bones[input.readInt(true)];
+				var boneData : BoneData = new BoneData(i, boneName, boneParent);
+				boneData.rotation = input.readFloat();
+				boneData.x = input.readFloat() * scale;
+				boneData.y = input.readFloat() * scale;
+				boneData.scaleX = input.readFloat();
+				boneData.scaleY = input.readFloat();
+				boneData.shearX = input.readFloat();
+				boneData.shearY = input.readFloat();
+				boneData.length = input.readFloat() * scale;				
+				boneData.transformMode = TransformMode.values[input.readInt(true)];
+				boneData.skinRequired = input.readBoolean();
+				if (nonessential) boneData.color.setFromRgba8888(input.readInt32());
+				skeletonData.bones.push(boneData);
+			}
+
+			// Slots.
+			n = input.readInt(true);
+			for (i = 0; i < n; i++) {
+				var slotName : String = input.readString();
+				var slotBoneData : BoneData = skeletonData.bones[input.readInt(true)];
+				var slotData : SlotData = new SlotData(i, slotName, slotBoneData);
+				slotData.color.setFromRgba8888(input.readInt32());
+
+				var darkColor : int = input.readInt32();
+				if (darkColor != -1) slotData.darkColor.setFromRgb888(darkColor);
+
+				slotData.attachmentName = input.readStringRef();
+				slotData.blendMode = BlendMode.values[input.readInt(true)];
+				skeletonData.slots.push(slotData);
+			}
+
+			// IK constraints.
+			n = input.readInt(true);
+			var nn : int = 0;
+			var ii : int = 0;
+			for (i = 0; i < n; i++) {
+				var ikData : IkConstraintData = new IkConstraintData(input.readString());
+				ikData.order = input.readInt(true);
+				ikData.skinRequired = input.readBoolean();
+				nn = input.readInt(true);
+				for (ii = 0; ii < nn; ii++)
+					ikData.bones.push(skeletonData.bones[input.readInt(true)]);
+				ikData.target = skeletonData.bones[input.readInt(true)];
+				ikData.mix = input.readFloat();
+				ikData.bendDirection = input.readByte();
+				ikData.compress = input.readBoolean();
+				ikData.stretch = input.readBoolean();
+				ikData.uniform = input.readBoolean();
+				skeletonData.ikConstraints.push(ikData);
+			}
+
+			// Transform constraints.
+			n = input.readInt(true);
+			for (i = 0, nn; i < n; i++) {
+				var transData : TransformConstraintData = new TransformConstraintData(input.readString());
+				transData.order = input.readInt(true);
+				transData.skinRequired = input.readBoolean();
+				nn = input.readInt(true);
+				for (ii = 0; ii < nn; ii++)
+					transData.bones.push(skeletonData.bones[input.readInt(true)]);
+				transData.target = skeletonData.bones[input.readInt(true)];
+				transData.local = input.readBoolean();
+				transData.relative = input.readBoolean();
+				transData.offsetRotation = input.readFloat();
+				transData.offsetX = input.readFloat() * scale;
+				transData.offsetY = input.readFloat() * scale;
+				transData.offsetScaleX = input.readFloat();
+				transData.offsetScaleY = input.readFloat();
+				transData.offsetShearY = input.readFloat();
+				transData.rotateMix = input.readFloat();
+				transData.translateMix = input.readFloat();
+				transData.scaleMix = input.readFloat();
+				transData.shearMix = input.readFloat();
+				skeletonData.transformConstraints.push(transData);
+			}
+
+			// Path constraints.
+			n = input.readInt(true);
+			for (i = 0, nn; i < n; i++) {
+				var pathData : PathConstraintData = new PathConstraintData(input.readString());
+				pathData.order = input.readInt(true);
+				pathData.skinRequired = input.readBoolean();
+				nn = input.readInt(true);
+				for (ii = 0; ii < nn; ii++)
+					pathData.bones.push(skeletonData.bones[input.readInt(true)]);
+				pathData.target = skeletonData.slots[input.readInt(true)];
+				pathData.positionMode = PositionMode.values[input.readInt(true)];
+				pathData.spacingMode = SpacingMode.values[input.readInt(true)];
+				pathData.rotateMode = RotateMode.values[input.readInt(true)];
+				pathData.offsetRotation = input.readFloat();
+				pathData.position = input.readFloat();
+				if (pathData.positionMode == PositionMode.fixed) pathData.position *= scale;
+				pathData.spacing = input.readFloat();
+				if (pathData.spacingMode == SpacingMode.length || pathData.spacingMode == SpacingMode.fixed) pathData.spacing *= scale;
+				pathData.rotateMix = input.readFloat();
+				pathData.translateMix = input.readFloat();
+				skeletonData.pathConstraints.push(pathData);
+			}
+
+			// Default skin.
+			var defaultSkin : Skin = readSkin(input, skeletonData, true, nonessential);
+			if (defaultSkin != null) {
+				skeletonData.defaultSkin = defaultSkin;
+				skeletonData.skins.push(defaultSkin);
+			}
+
+			// Skins.
+			{
+				i = skeletonData.skins.length;
+				skeletonData.skins.length = n = i + input.readInt(true);
+				for (; i < n; i++)
+					skeletonData.skins[i] = readSkin(input, skeletonData, false, nonessential);
+			}
+
+			// Linked meshes.
+			n = this.linkedMeshes.length;
+			for (i = 0; i < n; i++) {
+				var linkedMesh : LinkedMesh = this.linkedMeshes[i];
+				var skin : Skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
+				if (skin == null) throw new Error("Skin not found: " + linkedMesh.skin);
+				var parent : Attachment = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
+				if (parent == null) throw new Error("Parent mesh not found: " + linkedMesh.parent);
+				linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent as VertexAttachment : linkedMesh.mesh;
+				linkedMesh.mesh.parentMesh = parent as MeshAttachment;
+				linkedMesh.mesh.updateUVs();
+			}
+			this.linkedMeshes.length = 0;
+
+			// Events.
+			n = input.readInt(true);
+			for (i = 0; i < n; i++) {
+				var data : EventData = new EventData(input.readStringRef());
+				data.intValue = input.readInt(false);
+				data.floatValue = input.readFloat();
+				data.stringValue = input.readString();
+				data.audioPath = input.readString();
+				if (data.audioPath != null) {
+					data.volume = input.readFloat();
+					data.balance = input.readFloat();
+				}
+				skeletonData.events.push(data);
+			}
+
+			// Animations.
+			n = input.readInt(true);
+			for (i = 0; i < n; i++)
+				skeletonData.animations.push(readAnimation(input, input.readString(), skeletonData));
+			return skeletonData;
+		}
+		
+		private function readSkin (input: BinaryInput, skeletonData: SkeletonData, defaultSkin: Boolean, nonessential: Boolean): Skin {
+			var skin : Skin = new Skin(defaultSkin ? "default" : input.readStringRef());
+			var i : int = 0;
+			var n : int = 0;
+			var ii : int;
+			var nn: int;
+
+			if (!defaultSkin) {
+				skin.bones.length = input.readInt(true);
+				for (i = 0, n = skin.bones.length; i < n; i++)
+					skin.bones[i] = skeletonData.bones[input.readInt(true)];
+
+				for (i = 0, n = input.readInt(true); i < n; i++)
+					skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]);
+				for (i = 0, n = input.readInt(true); i < n; i++)
+					skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]);
+				for (i = 0, n = input.readInt(true); i < n; i++)
+					skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]);
+			}
+
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				var slotIndex : int = input.readInt(true);
+				for (ii = 0, nn = input.readInt(true); ii < nn; ii++) {
+					var name : String = input.readStringRef();
+					var attachment : Attachment = readAttachment(input, skeletonData, skin, slotIndex, name, nonessential);
+					if (attachment != null) skin.setAttachment(slotIndex, name, attachment);
+				}
+			}
+			return skin;
+		}
+		
+		private function readAttachment(input: BinaryInput, skeletonData: SkeletonData, skin: Skin, slotIndex: Number, attachmentName: String, nonessential: Boolean): Attachment {
+			var scale : Number = this.scale;
+			var i : int = 0;
+			var n : int = 0;
+			
+			var vertexCount : int;
+			var vertices : Vertices;
+			var path: String;
+			var rotation : Number;
+			var x : Number;
+			var y: Number;
+			var scaleX : Number;
+			var scaleY : Number;
+			var width : Number;
+			var height : Number;
+			var color : int;
+			var mesh : MeshAttachment;
+
+			var name : String = input.readStringRef();
+			if (name == null) name = attachmentName;
+
+			var typeIndex : int = input.readByte();
+			var type : AttachmentType = AttachmentType.values[typeIndex];
+			switch (type) {
+			case AttachmentType.region: {
+				path = input.readStringRef();
+				rotation = input.readFloat();
+				x = input.readFloat();
+				y = input.readFloat();
+				scaleX = input.readFloat();
+				scaleY = input.readFloat();
+				width = input.readFloat();
+				height = input.readFloat();
+				color = input.readInt32();
+
+				if (path == null) path = name;
+				var region : RegionAttachment = this.attachmentLoader.newRegionAttachment(skin, name, path);
+				if (region == null) return null;
+				region.path = path;
+				region.x = x * scale;
+				region.y = y * scale;
+				region.scaleX = scaleX;
+				region.scaleY = scaleY;
+				region.rotation = rotation;
+				region.width = width * scale;
+				region.height = height * scale;
+				region.color.setFromRgba8888(color);
+				region.updateOffset();
+				return region;
+			}
+			case AttachmentType.boundingbox: {
+				vertexCount = input.readInt(true);
+				vertices = readVertices(input, vertexCount);
+				color = nonessential ? input.readInt32() : 0;
+
+				var box : BoundingBoxAttachment = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
+				if (box == null) return null;
+				box.worldVerticesLength = vertexCount << 1;
+				box.vertices = vertices.vertices;
+				box.bones = vertices.bones;
+				if (nonessential) box.color.setFromRgba8888(color);
+				return box;
+			}
+			case AttachmentType.mesh: {
+				path = input.readStringRef();
+				color = input.readInt32();
+				vertexCount = input.readInt(true);
+				var uvs : Vector.<Number> = readFloatArray(input, vertexCount << 1, 1);
+				var triangles : Vector.<uint> = readUnsignedShortArray(input);
+				vertices = readVertices(input, vertexCount);
+				var hullLength : int = input.readInt(true);
+				var edges : Vector.<int> = null;				
+				if (nonessential) {
+					edges = readShortArray(input);
+					width = input.readFloat();
+					height = input.readFloat();
+				}
+
+				if (path == null) path = name;
+				mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
+				if (mesh == null) return null;
+				mesh.path = path;
+				mesh.color.setFromRgba8888(color);
+				mesh.bones = vertices.bones;
+				mesh.vertices = vertices.vertices;
+				mesh.worldVerticesLength = vertexCount << 1;
+				mesh.triangles = triangles;
+				mesh.regionUVs = uvs;
+				mesh.updateUVs();
+				mesh.hullLength = hullLength << 1;
+				if (nonessential) {
+					mesh.edges = edges;
+					mesh.width = width * scale;
+					mesh.height = height * scale;
+				}
+				return mesh;
+			}
+			case AttachmentType.linkedmesh: {
+				path = input.readStringRef();
+				color = input.readInt32();
+				var skinName : String = input.readStringRef();
+				var parent : String = input.readStringRef();
+				var inheritDeform : Boolean = input.readBoolean();				
+				if (nonessential) {
+					width = input.readFloat();
+					height = input.readFloat();
+				}
+
+				if (path == null) path = name;
+				mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
+				if (mesh == null) return null;
+				mesh.path = path;
+				mesh.color.setFromRgba8888(color);
+				if (nonessential) {
+					mesh.width = width * scale;
+					mesh.height = height * scale;
+				}
+				this.linkedMeshes.push(new LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform));
+				return mesh;
+			}
+			case AttachmentType.path: {
+				var closed : Boolean = input.readBoolean();
+				var constantSpeed : Boolean = input.readBoolean();
+				vertexCount = input.readInt(true);
+				vertices = this.readVertices(input, vertexCount);
+				var lengths : Vector.<Number> = new Vector.<Number>();
+				lengths.length = vertexCount / 3;
+				for (i = 0, n = lengths.length; i < n; i++)
+					lengths[i] = input.readFloat() * scale;
+				color = nonessential ? input.readInt32() : 0;
+
+				var pathAttachment : PathAttachment = this.attachmentLoader.newPathAttachment(skin, name);
+				if (pathAttachment == null) return null;
+				pathAttachment.closed = closed;
+				pathAttachment.constantSpeed = constantSpeed;
+				pathAttachment.worldVerticesLength = vertexCount << 1;
+				pathAttachment.vertices = vertices.vertices;
+				pathAttachment.bones = vertices.bones;
+				pathAttachment.lengths = lengths;
+				if (nonessential) pathAttachment.color.setFromRgba8888(color);
+				return pathAttachment;
+			}
+			case AttachmentType.point: {
+				rotation = input.readFloat();
+				x = input.readFloat();
+				y = input.readFloat();
+				color = nonessential ? input.readInt32() : 0;
+
+				var point : PointAttachment = this.attachmentLoader.newPointAttachment(skin, name);
+				if (point == null) return null;
+				point.x = x * scale;
+				point.y = y * scale;
+				point.rotation = rotation;
+				if (nonessential) point.color.setFromRgba8888(color);
+				return point;
+			}
+			case AttachmentType.clipping: {
+				var endSlotIndex : int = input.readInt(true);
+				vertexCount = input.readInt(true);
+				vertices = this.readVertices(input, vertexCount);
+				color = nonessential ? input.readInt32() : 0;
+
+				var clip : ClippingAttachment = this.attachmentLoader.newClippingAttachment(skin, name);
+				if (clip == null) return null;
+				clip.endSlot = skeletonData.slots[endSlotIndex];
+				clip.worldVerticesLength = vertexCount << 1;
+				clip.vertices = vertices.vertices;
+				clip.bones = vertices.bones;
+				if (nonessential) clip.color.setFromRgba8888(color);
+				return clip;
+			}
+			}
+			return null;
+		}
+		
+		private function readVertices (input: BinaryInput, vertexCount: int): Vertices {
+			var verticesLength : int = vertexCount << 1;
+			var vertices : Vertices = new Vertices();
+			var scale : Number = this.scale;
+			if (!input.readBoolean()) {
+				vertices.vertices = readFloatArray(input, verticesLength, scale);
+				return vertices;
+			}
+			var weights : Vector.<Number> = new Vector.<Number>();
+			var bonesArray : Vector.<int> = new Vector.<int>();
+			for (var i : int = 0; i < vertexCount; i++) {
+				var boneCount : int = input.readInt(true);
+				bonesArray.push(boneCount);
+				for (var ii : int = 0; ii < boneCount; ii++) {
+					bonesArray.push(input.readInt(true));
+					weights.push(input.readFloat() * scale);
+					weights.push(input.readFloat() * scale);
+					weights.push(input.readFloat());
+				}
+			}
+			vertices.vertices = weights;
+			vertices.bones = bonesArray;
+			return vertices;
+		}
+
+		private function readFloatArray (input: BinaryInput, n: Number, scale: Number): Vector.<Number> {
+			var i : int = 0;
+			var array : Vector.<Number> = new Vector.<Number>();			
+			array.length = n;
+			if (scale == 1) {
+				for (i = 0; i < n; i++)
+					array[i] = input.readFloat();
+			} else {
+				for (i = 0; i < n; i++)
+					array[i] = input.readFloat() * scale;
+			}
+			return array;
+		}
+
+		private function readShortArray (input: BinaryInput): Vector.<int> {
+			var n : int = input.readInt(true);
+			var array : Vector.<int> = new Vector.<int>();
+			array.length = n;
+			for (var i : int = 0; i < n; i++)
+				array[i] = input.readShort();
+			return array;
+		}
+		
+		private function readUnsignedShortArray (input: BinaryInput): Vector.<uint> {
+			var n : int = input.readInt(true);
+			var array : Vector.<uint> = new Vector.<uint>();
+			array.length = n;
+			for (var i : int = 0; i < n; i++)
+				array[i] = input.readShort();
+			return array;
+		}
+		
+		private function readAnimation (input: BinaryInput, name: String, skeletonData: SkeletonData): Animation {
+			var timelines : Vector.<Timeline> = new Vector.<Timeline>();
+			var scale : Number = this.scale;
+			var duration : Number = 0;
+			var tempColor1 : Color = new Color(0, 0, 0, 0);
+			var tempColor2 : Color = new Color(0, 0, 0, 0);
+			var i : int = 0, n : int = 0, ii : int = 0, nn : int = 0;
+			var slotIndex : int;
+			var timelineType : int;
+			var frameCount : int;
+			var frameIndex : int;
+			var timelineScale : Number;
+			var index : int;
+			var time : Number;
+
+			// Slot timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				slotIndex = input.readInt(true);
+				for (ii = 0, nn = input.readInt(true); ii < nn; ii++) {
+					timelineType = input.readByte();
+					frameCount = input.readInt(true);
+					frameIndex = 0;
+					switch (timelineType) {
+					case SkeletonBinary.SLOT_ATTACHMENT: {
+						var attachmentTimeline : AttachmentTimeline = new AttachmentTimeline(frameCount);
+						attachmentTimeline.slotIndex = slotIndex;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++)
+							attachmentTimeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
+						timelines.push(attachmentTimeline);
+						duration = Math.max(duration, attachmentTimeline.frames[frameCount - 1]);
+						break;
+					}
+					case SkeletonBinary.SLOT_COLOR: {
+						var colorTimeline : ColorTimeline = new ColorTimeline(frameCount);
+						colorTimeline.slotIndex = slotIndex;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							time = input.readFloat();
+							tempColor1.setFromRgba8888(input.readInt32());
+							colorTimeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);
+							if (frameIndex < frameCount - 1) readCurve(input, frameIndex, colorTimeline);
+						}
+						timelines.push(colorTimeline);
+						duration = Math.max(duration, colorTimeline.frames[(frameCount - 1) * ColorTimeline.ENTRIES]);
+						break;
+					}
+					case SkeletonBinary.SLOT_TWO_COLOR: {
+						var twoColorTimeline : TwoColorTimeline = new TwoColorTimeline(frameCount);
+						twoColorTimeline.slotIndex = slotIndex;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							time = input.readFloat();
+							tempColor1.setFromRgba8888(input.readInt32());
+							tempColor2.setFromRgb888(input.readInt32());
+							twoColorTimeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r,
+								tempColor2.g, tempColor2.b);
+							if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, twoColorTimeline);
+						}
+						timelines.push(twoColorTimeline);
+						duration = Math.max(duration, twoColorTimeline.frames[(frameCount - 1) * TwoColorTimeline.ENTRIES]);
+						break;
+					}
+					}
+				}
+			}
+
+			// Bone timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				var boneIndex : int = input.readInt(true);
+				for (ii = 0, nn = input.readInt(true); ii < nn; ii++) {
+					timelineType = input.readByte();
+					frameCount = input.readInt(true);
+					frameIndex = 0;
+					switch (timelineType) {
+					case SkeletonBinary.BONE_ROTATE: {
+						var rotateTimeline : RotateTimeline = new RotateTimeline(frameCount);
+						rotateTimeline.boneIndex = boneIndex;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							rotateTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat());
+							if (frameIndex < frameCount - 1) readCurve(input, frameIndex, rotateTimeline);
+						}
+						timelines.push(rotateTimeline);
+						duration = Math.max(duration, rotateTimeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]);
+						break;
+					}
+					case SkeletonBinary.BONE_TRANSLATE:
+					case SkeletonBinary.BONE_SCALE:
+					case SkeletonBinary.BONE_SHEAR: {
+						var translateTimeline : TranslateTimeline;
+						timelineScale = 1;
+						if (timelineType == SkeletonBinary.BONE_SCALE)
+							translateTimeline = new ScaleTimeline(frameCount);
+						else if (timelineType == SkeletonBinary.BONE_SHEAR)
+							translateTimeline = new ShearTimeline(frameCount);
+						else {
+							translateTimeline = new TranslateTimeline(frameCount);
+							timelineScale = scale;
+						}
+						translateTimeline.boneIndex = boneIndex;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							translateTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale,
+								input.readFloat() * timelineScale);
+							if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, translateTimeline);
+						}
+						timelines.push(translateTimeline);
+						duration = Math.max(duration, translateTimeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]);
+						break;
+					}
+					}
+				}
+			}
+
+			// IK constraint timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				index = input.readInt(true);
+				frameCount = input.readInt(true);
+				var ikConstraintTimeline : IkConstraintTimeline = new IkConstraintTimeline(frameCount);
+				frameIndex = 0;
+				ikConstraintTimeline.ikConstraintIndex = index;
+				for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+					ikConstraintTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readByte(), input.readBoolean(),
+						input.readBoolean());
+					if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, ikConstraintTimeline);
+				}
+				timelines.push(ikConstraintTimeline);
+				duration = Math.max(duration, ikConstraintTimeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]);
+			}
+
+			// Transform constraint timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				index = input.readInt(true);
+				frameCount = input.readInt(true);
+				var transformConstraintTimeline : TransformConstraintTimeline = new TransformConstraintTimeline(frameCount);
+				transformConstraintTimeline.transformConstraintIndex = index;
+				for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+					transformConstraintTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(),
+						input.readFloat());
+					if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, transformConstraintTimeline);
+				}
+				timelines.push(transformConstraintTimeline);
+				duration = Math.max(duration, transformConstraintTimeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]);
+			}
+
+			// Path constraint timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				index = input.readInt(true);
+				var data : PathConstraintData = skeletonData.pathConstraints[index];
+				for (ii = 0, nn = input.readInt(true); ii < nn; ii++) {
+					timelineType = input.readByte();
+					frameCount = input.readInt(true);
+					switch (timelineType) {
+					case SkeletonBinary.PATH_POSITION:
+					case SkeletonBinary.PATH_SPACING: {
+						var pathConstraintPositionTimeline : PathConstraintPositionTimeline;
+						timelineScale = 1;
+						if (timelineType == SkeletonBinary.PATH_SPACING) {
+							pathConstraintPositionTimeline = new PathConstraintSpacingTimeline(frameCount);
+							if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) timelineScale = scale;
+						} else {
+							pathConstraintPositionTimeline = new PathConstraintPositionTimeline(frameCount);
+							if (data.positionMode == PositionMode.fixed) timelineScale = scale;
+						}
+						pathConstraintPositionTimeline.pathConstraintIndex = index;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							pathConstraintPositionTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);
+							if (frameIndex < frameCount - 1) readCurve(input, frameIndex, pathConstraintPositionTimeline);
+						}
+						timelines.push(pathConstraintPositionTimeline);
+						duration = Math.max(duration, pathConstraintPositionTimeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
+						break;
+					}
+					case SkeletonBinary.PATH_MIX: {
+						var pathConstraintMixTimeline : PathConstraintMixTimeline = new PathConstraintMixTimeline(frameCount);
+						pathConstraintMixTimeline.pathConstraintIndex = index;
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							pathConstraintMixTimeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
+							if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, pathConstraintMixTimeline);
+						}
+						timelines.push(pathConstraintMixTimeline);
+						duration = Math.max(duration, pathConstraintMixTimeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
+						break;
+					}
+					}
+				}
+			}
+
+			// Deform timelines.
+			for (i = 0, n = input.readInt(true); i < n; i++) {
+				var skin : Skin = skeletonData.skins[input.readInt(true)];
+				for (ii = 0, nn = input.readInt(true); ii < nn; ii++) {
+					slotIndex = input.readInt(true);
+					for (var iii : int = 0, nnn : int = input.readInt(true); iii < nnn; iii++) {
+						var attachment : VertexAttachment = skin.getAttachment(slotIndex, input.readStringRef()) as VertexAttachment;
+						var weighted : Boolean = attachment.bones != null;
+						var vertices : Vector.<Number> = attachment.vertices;
+						var deformLength : int = weighted ? vertices.length / 3 * 2 : vertices.length;
+
+						frameCount = input.readInt(true);
+						var deformTimeline : DeformTimeline= new DeformTimeline(frameCount);
+						deformTimeline.slotIndex = slotIndex;
+						deformTimeline.attachment = attachment;
+
+						for (frameIndex = 0; frameIndex < frameCount; frameIndex++) {
+							time = input.readFloat();
+							var deform : Vector.<Number>;
+							var end : int = input.readInt(true);
+							if (end == 0) {
+								if (weighted) {
+									deform = new Vector.<Number>();
+									deform.length = deformLength;
+								} else
+									deform = vertices;								
+							} else {
+								var v : int, vn: int;
+								deform = new Vector.<Number>();
+								deform.length = deformLength;
+								var start : int = input.readInt(true);
+								end += start;
+								if (scale == 1) {
+									for (v = start; v < end; v++)
+										deform[v] = input.readFloat();
+								} else {
+									for (v = start; v < end; v++)
+										deform[v] = input.readFloat() * scale;
+								}
+								if (!weighted) {
+									for (v = 0, vn = deform.length; v < vn; v++)
+										deform[v] += vertices[v];
+								}
+							}
+
+							deformTimeline.setFrame(frameIndex, time, deform);
+							if (frameIndex < frameCount - 1) readCurve(input, frameIndex, deformTimeline);
+						}
+						timelines.push(deformTimeline);
+						duration = Math.max(duration, deformTimeline.frames[frameCount - 1]);
+					}
+				}
+			}
+
+			// Draw order timeline.
+			var drawOrderCount : int = input.readInt(true);
+			if (drawOrderCount > 0) {
+				var drawOrderTimeline : DrawOrderTimeline = new DrawOrderTimeline(drawOrderCount);
+				var slotCount : int = skeletonData.slots.length;
+				for (i = 0; i < drawOrderCount; i++) {
+					time = input.readFloat();
+					var offsetCount : int = input.readInt(true);
+					var drawOrder : Vector.<int> = new Vector.<int>();
+					drawOrder.length = slotCount;
+					for (ii = slotCount - 1; ii >= 0; ii--)
+						drawOrder[ii] = -1;
+					var unchanged : Vector.<int> = new Vector.<int>();
+					unchanged.length = slotCount - offsetCount;
+					var originalIndex : int = 0, unchangedIndex : int = 0;
+					for (ii = 0; ii < offsetCount; ii++) {
+						slotIndex = input.readInt(true);
+						// Collect unchanged items.
+						while (originalIndex != slotIndex)
+							unchanged[unchangedIndex++] = originalIndex++;
+						// Set changed items.
+						drawOrder[originalIndex + input.readInt(true)] = originalIndex++;
+					}
+					// Collect remaining unchanged items.
+					while (originalIndex < slotCount)
+						unchanged[unchangedIndex++] = originalIndex++;
+					// Fill in unchanged items.
+					for (ii = slotCount - 1; ii >= 0; ii--)
+						if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
+					drawOrderTimeline.setFrame(i, time, drawOrder);
+				}
+				timelines.push(drawOrderTimeline);
+				duration = Math.max(duration, drawOrderTimeline.frames[drawOrderCount - 1]);
+			}
+
+			// Event timeline.
+			var eventCount : int = input.readInt(true);
+			if (eventCount > 0) {
+				var eventTimeline : EventTimeline = new EventTimeline(eventCount);
+				for (i = 0; i < eventCount; i++) {
+					time = input.readFloat();
+					var eventData : EventData = skeletonData.events[input.readInt(true)];
+					var event : Event = new Event(time, eventData);
+					event.intValue = input.readInt(false);
+					event.floatValue = input.readFloat();
+					event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;
+					if (event.data.audioPath != null) {
+						event.volume = input.readFloat();
+						event.balance = input.readFloat();
+					}
+					eventTimeline.setFrame(i, event);
+				}
+				timelines.push(eventTimeline);
+				duration = Math.max(duration, eventTimeline.frames[eventCount - 1]);
+			}
+
+			return new Animation(name, timelines, duration);
+		}
+
+		private function readCurve (input: BinaryInput, frameIndex: Number, timeline: CurveTimeline) : void {
+			switch (input.readByte()) {
+			case SkeletonBinary.CURVE_STEPPED:
+				timeline.setStepped(frameIndex);
+				break;
+			case SkeletonBinary.CURVE_BEZIER:
+				setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());
+				break;
+			}
+		}
+
+		public function setCurve (timeline: CurveTimeline, frameIndex: Number, cx1: Number, cy1: Number, cx2: Number, cy2: Number) : void {
+			timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2);
+		}
+		
+	}
+}
+
+import spine.attachments.MeshAttachment;
+
+class Vertices {
+	public var vertices : Vector.<Number> = new Vector.<Number>();
+	public var bones : Vector.<int> = new Vector.<int>();
+}
+
+class LinkedMesh {
+	internal var parent : String, skin : String;
+	internal var slotIndex : int;
+	internal var mesh : MeshAttachment;
+	internal var inheritDeform : Boolean;
+
+	public function LinkedMesh(mesh : MeshAttachment, skin : String, slotIndex : int, parent : String, inheritDeform : Boolean) {
+		this.mesh = mesh;
+		this.skin = skin;
+		this.slotIndex = slotIndex;
+		this.parent = parent;
+		this.inheritDeform = inheritDeform;
+	}
+}

+ 1 - 0
spine-as3/spine-as3/src/spine/SkeletonData.as

@@ -46,6 +46,7 @@ package spine {
 		public var version : String, hash : String;
 		public var fps : Number;
 		public var imagesPath : String;
+		public var audioPath : String;
 
 		public function SkeletonData() {
 		}

+ 2 - 0
spine-as3/spine-as3/src/spine/SpacingMode.as

@@ -32,5 +32,7 @@ package spine {
 		public static const length : SpacingMode = new SpacingMode();
 		public static const fixed : SpacingMode = new SpacingMode();
 		public static const percent : SpacingMode = new SpacingMode();
+		
+		public static const values : Array = [ length, fixed, percent ];
 	}
 }

+ 2 - 0
spine-as3/spine-as3/src/spine/TransformMode.as

@@ -34,5 +34,7 @@ package spine {
 		public static const noRotationOrReflection : TransformMode = new TransformMode();
 		public static const noScale : TransformMode = new TransformMode();
 		public static const noScaleOrReflection : TransformMode = new TransformMode();
+		
+		public static const values : Array = [ normal, onlyTranslation, noRotationOrReflection, noScale, noScaleOrReflection ];
 	}
 }

+ 2 - 0
spine-as3/spine-as3/src/spine/attachments/AttachmentType.as

@@ -39,6 +39,8 @@ package spine.attachments {
 		public static const clipping : AttachmentType = new AttachmentType(6, "clipping");
 		public var ordinal : int;
 		public var name : String;
+		
+		public static const values : Array = [ region, boundingbox, mesh, linkedmesh, path, point, clipping ];
 
 		public function AttachmentType(ordinal : int, name : String) {
 			this.ordinal = ordinal;

+ 4 - 0
spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as

@@ -28,7 +28,11 @@
  *****************************************************************************/
 
 package spine.attachments {
+	import spine.Color;
+	
 	public dynamic class BoundingBoxAttachment extends VertexAttachment {
+		public var color : Color = new Color(0, 0, 0, 0);
+		
 		public function BoundingBoxAttachment(name : String) {
 			super(name);
 		}

+ 2 - 0
spine-as3/spine-as3/src/spine/attachments/PathAttachment.as

@@ -28,9 +28,11 @@
  *****************************************************************************/
 
 package spine.attachments {
+	import spine.Color;
 	public dynamic class PathAttachment extends VertexAttachment {
 		public var lengths : Vector.<Number>;
 		public var closed : Boolean, constantSpeed : Boolean;
+		public var color : Color = new Color(0, 0, 0, 0);
 
 		public function PathAttachment(name : String) {
 			super(name);

BIN
spine-starling/spine-starling-example/lib/spine-as3.swc


BIN
spine-starling/spine-starling-example/src/mix-and-match-pro.skel


+ 5 - 4
spine-starling/spine-starling-example/src/spine/examples/MixAndMatchExample.as

@@ -28,6 +28,7 @@
  *****************************************************************************/
 
 package spine.examples {
+	import spine.SkeletonBinary;
 	import spine.Skin;	
 	import starling.display.DisplayObjectContainer;
 	import starling.events.Touch;
@@ -45,7 +46,7 @@ package spine.examples {
 	import spine.starling.SkeletonAnimation;
 
 	public class MixAndMatchExample extends Sprite {
-		[Embed(source = "/mix-and-match-pro.json", mimeType = "application/octet-stream")]
+		[Embed(source = "/mix-and-match-pro.skel", mimeType = "application/octet-stream")]
 		static public const MixAndMatchJson : Class;
 
 		[Embed(source = "/mix-and-match.atlas", mimeType = "application/octet-stream")]
@@ -60,9 +61,9 @@ package spine.examples {
 			var spineAtlas : Atlas = new Atlas(new MixAndMatchAtlas(), new StarlingTextureLoader(new MixAndMatchAtlasTexture()));
 			attachmentLoader = new AtlasAttachmentLoader(spineAtlas);
 
-			var json : SkeletonJson = new SkeletonJson(attachmentLoader);
-			json.scale = 0.5;
-			var skeletonData : SkeletonData = json.readSkeletonData(new MixAndMatchJson());
+			var binary : SkeletonBinary = new SkeletonBinary(attachmentLoader);
+			binary.scale = 0.5;
+			var skeletonData : SkeletonData = binary.readSkeletonData(new MixAndMatchJson());
 
 			this.x = 400;
 			this.y = 500;

BIN
spine-starling/spine-starling/lib/spine-as3.swc