|
@@ -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;
|
|
|
|
+ }
|
|
|
|
+}
|