|
@@ -28,560 +28,547 @@
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*****************************************************************************/
|
|
*****************************************************************************/
|
|
-
|
|
|
|
package spine {
|
|
package spine {
|
|
-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.FfdTimeline;
|
|
|
|
-import spine.animation.FlipXTimeline;
|
|
|
|
-import spine.animation.FlipYTimeline;
|
|
|
|
-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;
|
|
|
|
-import spine.attachments.SkinnedMeshAttachment;
|
|
|
|
-
|
|
|
|
-public class SkeletonJson {
|
|
|
|
- public var attachmentLoader:AttachmentLoader;
|
|
|
|
- public var scale:Number = 1;
|
|
|
|
-
|
|
|
|
- public function SkeletonJson (attachmentLoader:AttachmentLoader = null) {
|
|
|
|
- this.attachmentLoader = attachmentLoader;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /** @param object A String or ByteArray. */
|
|
|
|
- public function readSkeletonData (object:*, name:String = null) : SkeletonData {
|
|
|
|
- if (object == null) throw new ArgumentError("object cannot be null.");
|
|
|
|
-
|
|
|
|
- var root:Object;
|
|
|
|
- if (object is String)
|
|
|
|
- root = JSON.parse(String(object));
|
|
|
|
- else if (object is ByteArray)
|
|
|
|
- root = JSON.parse(ByteArray(object).readUTFBytes(ByteArray(object).length));
|
|
|
|
- else if (object is Object)
|
|
|
|
- root = object;
|
|
|
|
- else
|
|
|
|
- throw new ArgumentError("object must be a String, ByteArray or Object.");
|
|
|
|
-
|
|
|
|
- var skeletonData:SkeletonData = new SkeletonData();
|
|
|
|
- skeletonData.name = name;
|
|
|
|
-
|
|
|
|
- // Skeleton.
|
|
|
|
- var skeletonMap:Object = root["skeleton"];
|
|
|
|
- if (skeletonMap) {
|
|
|
|
- skeletonData.hash = skeletonMap["hash"];
|
|
|
|
- skeletonData.version = skeletonMap["spine"];
|
|
|
|
- skeletonData.width = skeletonMap["width"] || 0;
|
|
|
|
- skeletonData.height = skeletonMap["height"] || 0;
|
|
|
|
|
|
+ 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.FfdTimeline;
|
|
|
|
+ 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;
|
|
|
|
+ import spine.attachments.WeightedMeshAttachment;
|
|
|
|
+
|
|
|
|
+ public class SkeletonJson {
|
|
|
|
+ public var attachmentLoader : AttachmentLoader;
|
|
|
|
+ public var scale : Number = 1;
|
|
|
|
+
|
|
|
|
+ public function SkeletonJson(attachmentLoader : AttachmentLoader = null) {
|
|
|
|
+ this.attachmentLoader = attachmentLoader;
|
|
}
|
|
}
|
|
|
|
|
|
- // Bones.
|
|
|
|
- var boneData:BoneData;
|
|
|
|
- for each (var boneMap:Object in root["bones"]) {
|
|
|
|
- var parent:BoneData = null;
|
|
|
|
- var parentName:String = boneMap["parent"];
|
|
|
|
- if (parentName) {
|
|
|
|
- parent = skeletonData.findBone(parentName);
|
|
|
|
- if (!parent) throw new Error("Parent bone not found: " + parentName);
|
|
|
|
|
|
+ /** @param object A String or ByteArray. */
|
|
|
|
+ public function readSkeletonData(object : *, name : String = null) : SkeletonData {
|
|
|
|
+ if (object == null) throw new ArgumentError("object cannot be null.");
|
|
|
|
+
|
|
|
|
+ var root : Object;
|
|
|
|
+ if (object is String)
|
|
|
|
+ root = JSON.parse(String(object));
|
|
|
|
+ else if (object is ByteArray)
|
|
|
|
+ root = JSON.parse(ByteArray(object).readUTFBytes(ByteArray(object).length));
|
|
|
|
+ else if (object is Object)
|
|
|
|
+ root = object;
|
|
|
|
+ else
|
|
|
|
+ throw new ArgumentError("object must be a String, ByteArray or Object.");
|
|
|
|
+
|
|
|
|
+ var skeletonData : SkeletonData = new SkeletonData();
|
|
|
|
+ skeletonData.name = name;
|
|
|
|
+
|
|
|
|
+ // Skeleton.
|
|
|
|
+ var skeletonMap : Object = root["skeleton"];
|
|
|
|
+ if (skeletonMap) {
|
|
|
|
+ skeletonData.hash = skeletonMap["hash"];
|
|
|
|
+ skeletonData.version = skeletonMap["spine"];
|
|
|
|
+ skeletonData.width = skeletonMap["width"] || 0;
|
|
|
|
+ skeletonData.height = skeletonMap["height"] || 0;
|
|
}
|
|
}
|
|
- boneData = new BoneData(boneMap["name"], parent);
|
|
|
|
- boneData.length = Number(boneMap["length"] || 0) * scale;
|
|
|
|
- boneData.x = Number(boneMap["x"] || 0) * scale;
|
|
|
|
- boneData.y = Number(boneMap["y"] || 0) * scale;
|
|
|
|
- boneData.rotation = (boneMap["rotation"] || 0);
|
|
|
|
- boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
|
|
|
|
- boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
|
|
|
|
- boneData.flipX = boneMap["flipX"] || false;
|
|
|
|
- boneData.flipY = boneMap["flipY"] || false;
|
|
|
|
- boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? boneMap["inheritScale"] : true;
|
|
|
|
- boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? boneMap["inheritRotation"] : true;
|
|
|
|
- skeletonData.bones[skeletonData.bones.length] = boneData;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // IK constraints.
|
|
|
|
- for each (var ikMap:Object in root["ik"]) {
|
|
|
|
- var ikConstraintData:IkConstraintData = new IkConstraintData(ikMap["name"]);
|
|
|
|
|
|
|
|
- for each (var boneName:String in ikMap["bones"]) {
|
|
|
|
- var bone:BoneData = skeletonData.findBone(boneName);
|
|
|
|
- if (!bone) throw new Error("IK bone not found: " + boneName);
|
|
|
|
- ikConstraintData.bones[ikConstraintData.bones.length] = bone;
|
|
|
|
|
|
+ // Bones.
|
|
|
|
+ var boneData : BoneData;
|
|
|
|
+ for each (var boneMap : Object in root["bones"]) {
|
|
|
|
+ var parent : BoneData = null;
|
|
|
|
+ var parentName : String = boneMap["parent"];
|
|
|
|
+ if (parentName) {
|
|
|
|
+ parent = skeletonData.findBone(parentName);
|
|
|
|
+ if (!parent) throw new Error("Parent bone not found: " + parentName);
|
|
|
|
+ }
|
|
|
|
+ boneData = new BoneData(boneMap["name"], parent);
|
|
|
|
+ boneData.length = Number(boneMap["length"] || 0) * scale;
|
|
|
|
+ boneData.x = Number(boneMap["x"] || 0) * scale;
|
|
|
|
+ boneData.y = Number(boneMap["y"] || 0) * scale;
|
|
|
|
+ boneData.rotation = (boneMap["rotation"] || 0);
|
|
|
|
+ boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
|
|
|
|
+ boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
|
|
|
|
+ boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? boneMap["inheritScale"] : true;
|
|
|
|
+ boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? boneMap["inheritRotation"] : true;
|
|
|
|
+ skeletonData.bones[skeletonData.bones.length] = boneData;
|
|
}
|
|
}
|
|
|
|
|
|
- ikConstraintData.target = skeletonData.findBone(ikMap["target"]);
|
|
|
|
- if (!ikConstraintData.target) throw new Error("Target bone not found: " + ikMap["target"]);
|
|
|
|
|
|
+ // IK constraints.
|
|
|
|
+ for each (var ikMap : Object in root["ik"]) {
|
|
|
|
+ var ikConstraintData : IkConstraintData = new IkConstraintData(ikMap["name"]);
|
|
|
|
+
|
|
|
|
+ for each (var boneName : String in ikMap["bones"]) {
|
|
|
|
+ var bone : BoneData = skeletonData.findBone(boneName);
|
|
|
|
+ if (!bone) throw new Error("IK bone not found: " + boneName);
|
|
|
|
+ ikConstraintData.bones[ikConstraintData.bones.length] = bone;
|
|
|
|
+ }
|
|
|
|
|
|
- ikConstraintData.bendDirection = (!ikMap.hasOwnProperty("bendPositive") || ikMap["bendPositive"]) ? 1 : -1;
|
|
|
|
- ikConstraintData.mix = ikMap.hasOwnProperty("mix") ? ikMap["mix"] : 1;
|
|
|
|
|
|
+ ikConstraintData.target = skeletonData.findBone(ikMap["target"]);
|
|
|
|
+ if (!ikConstraintData.target) throw new Error("Target bone not found: " + ikMap["target"]);
|
|
|
|
|
|
- skeletonData.ikConstraints[skeletonData.ikConstraints.length] = ikConstraintData;
|
|
|
|
- }
|
|
|
|
|
|
+ ikConstraintData.bendDirection = (!ikMap.hasOwnProperty("bendPositive") || ikMap["bendPositive"]) ? 1 : -1;
|
|
|
|
+ ikConstraintData.mix = ikMap.hasOwnProperty("mix") ? ikMap["mix"] : 1;
|
|
|
|
|
|
- // Slots.
|
|
|
|
- for each (var slotMap:Object in root["slots"]) {
|
|
|
|
- boneName = slotMap["bone"];
|
|
|
|
- boneData = skeletonData.findBone(boneName);
|
|
|
|
- if (!boneData) throw new Error("Slot bone not found: " + boneName);
|
|
|
|
- var slotData:SlotData = new SlotData(slotMap["name"], boneData);
|
|
|
|
-
|
|
|
|
- var color:String = slotMap["color"];
|
|
|
|
- if (color) {
|
|
|
|
- slotData.r = toColor(color, 0);
|
|
|
|
- slotData.g = toColor(color, 1);
|
|
|
|
- slotData.b = toColor(color, 2);
|
|
|
|
- slotData.a = toColor(color, 3);
|
|
|
|
|
|
+ skeletonData.ikConstraints[skeletonData.ikConstraints.length] = ikConstraintData;
|
|
}
|
|
}
|
|
|
|
|
|
- slotData.attachmentName = slotMap["attachment"];
|
|
|
|
- slotData.blendMode = BlendMode[slotMap["blend"] || "normal"];
|
|
|
|
|
|
+ // Transform constraints.
|
|
|
|
+ for each (var transformMap : Object in root["transform"]) {
|
|
|
|
+ var transformConstraintData : TransformConstraintData = new TransformConstraintData(transformMap["name"]);
|
|
|
|
|
|
- skeletonData.slots[skeletonData.slots.length] = slotData;
|
|
|
|
- }
|
|
|
|
|
|
+ transformConstraintData.bone = skeletonData.findBone(transformMap["bone"]);
|
|
|
|
+ if (!transformConstraintData.bone) throw new Error("Bone not found: " + transformMap["bone"]);
|
|
|
|
|
|
- // Skins.
|
|
|
|
- var skins:Object = root["skins"];
|
|
|
|
- for (var skinName:String in skins) {
|
|
|
|
- var skinMap:Object = skins[skinName];
|
|
|
|
- var skin:Skin = new Skin(skinName);
|
|
|
|
- for (var slotName:String in skinMap) {
|
|
|
|
- var slotIndex:int = skeletonData.findSlotIndex(slotName);
|
|
|
|
- var slotEntry:Object = skinMap[slotName];
|
|
|
|
- for (var attachmentName:String in slotEntry) {
|
|
|
|
- var attachment:Attachment = readAttachment(skin, attachmentName, slotEntry[attachmentName]);
|
|
|
|
- if (attachment != null)
|
|
|
|
- skin.addAttachment(slotIndex, attachmentName, attachment);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- skeletonData.skins[skeletonData.skins.length] = skin;
|
|
|
|
- if (skin.name == "default")
|
|
|
|
- skeletonData.defaultSkin = skin;
|
|
|
|
- }
|
|
|
|
|
|
+ transformConstraintData.target = skeletonData.findBone(transformMap["target"]);
|
|
|
|
+ if (!transformConstraintData.target) throw new Error("Target bone not found: " + transformMap["target"]);
|
|
|
|
|
|
- // Events.
|
|
|
|
- var events:Object = root["events"];
|
|
|
|
- if (events) {
|
|
|
|
- for (var eventName:String in events) {
|
|
|
|
- var eventMap:Object = events[eventName];
|
|
|
|
- var eventData:EventData = new EventData(eventName);
|
|
|
|
- eventData.intValue = eventMap["int"] || 0;
|
|
|
|
- eventData.floatValue = eventMap["float"] || 0;
|
|
|
|
- eventData.stringValue = eventMap["string"] || null;
|
|
|
|
- skeletonData.events[skeletonData.events.length] = eventData;
|
|
|
|
|
|
+ transformConstraintData.translateMix = transformMap.hasOwnProperty("translateMix") ? transformMap["translateMix"] : 1;
|
|
|
|
+ transformConstraintData.x = Number(boneMap["x"] || 0) * scale;
|
|
|
|
+ transformConstraintData.y = Number(boneMap["y"] || 0) * scale;
|
|
|
|
+
|
|
|
|
+ skeletonData.transformConstraints[skeletonData.transformConstraints.length] = transformConstraintData;
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- // Animations.
|
|
|
|
- var animations:Object = root["animations"];
|
|
|
|
- for (var animationName:String in animations)
|
|
|
|
- readAnimation(animationName, animations[animationName], skeletonData);
|
|
|
|
|
|
+ // Slots.
|
|
|
|
+ for each (var slotMap : Object in root["slots"]) {
|
|
|
|
+ boneName = slotMap["bone"];
|
|
|
|
+ boneData = skeletonData.findBone(boneName);
|
|
|
|
+ if (!boneData) throw new Error("Slot bone not found: " + boneName);
|
|
|
|
+ var slotData : SlotData = new SlotData(slotMap["name"], boneData);
|
|
|
|
+
|
|
|
|
+ var color : String = slotMap["color"];
|
|
|
|
+ if (color) {
|
|
|
|
+ slotData.r = toColor(color, 0);
|
|
|
|
+ slotData.g = toColor(color, 1);
|
|
|
|
+ slotData.b = toColor(color, 2);
|
|
|
|
+ slotData.a = toColor(color, 3);
|
|
|
|
+ }
|
|
|
|
|
|
- return skeletonData;
|
|
|
|
- }
|
|
|
|
|
|
+ slotData.attachmentName = slotMap["attachment"];
|
|
|
|
+ slotData.blendMode = BlendMode[slotMap["blend"] || "normal"];
|
|
|
|
|
|
- private function readAttachment (skin:Skin, name:String, map:Object) : Attachment {
|
|
|
|
- name = map["name"] || name;
|
|
|
|
-
|
|
|
|
- var type:AttachmentType = AttachmentType[map["type"] || "region"];
|
|
|
|
- var path:String = map["path"] || name;
|
|
|
|
-
|
|
|
|
- var scale:Number = this.scale;
|
|
|
|
- var color:String, vertices:Vector.<Number>;
|
|
|
|
- switch (type) {
|
|
|
|
- case AttachmentType.region:
|
|
|
|
- var region:RegionAttachment = attachmentLoader.newRegionAttachment(skin, name, path);
|
|
|
|
- if (!region) return null;
|
|
|
|
- region.path = path;
|
|
|
|
- region.x = Number(map["x"] || 0) * scale;
|
|
|
|
- region.y = Number(map["y"] || 0) * scale;
|
|
|
|
- region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
|
|
|
|
- region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
|
|
|
|
- region.rotation = map["rotation"] || 0;
|
|
|
|
- region.width = Number(map["width"] || 0) * scale;
|
|
|
|
- region.height = Number(map["height"] || 0) * scale;
|
|
|
|
-
|
|
|
|
- color = map["color"];
|
|
|
|
- if (color) {
|
|
|
|
- region.r = toColor(color, 0);
|
|
|
|
- region.g = toColor(color, 1);
|
|
|
|
- region.b = toColor(color, 2);
|
|
|
|
- region.a = toColor(color, 3);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- region.updateOffset();
|
|
|
|
- return region;
|
|
|
|
-
|
|
|
|
- case AttachmentType.mesh:
|
|
|
|
- var mesh:MeshAttachment = attachmentLoader.newMeshAttachment(skin, name, path);
|
|
|
|
- if (!mesh) return null;
|
|
|
|
- mesh.path = path;
|
|
|
|
- mesh.vertices = getFloatArray(map, "vertices", scale);
|
|
|
|
- mesh.triangles = getUintArray(map, "triangles");
|
|
|
|
- mesh.regionUVs = getFloatArray(map, "uvs", 1);
|
|
|
|
- mesh.updateUVs();
|
|
|
|
-
|
|
|
|
- color = map["color"];
|
|
|
|
- if (color) {
|
|
|
|
- mesh.r = toColor(color, 0);
|
|
|
|
- mesh.g = toColor(color, 1);
|
|
|
|
- mesh.b = toColor(color, 2);
|
|
|
|
- mesh.a = toColor(color, 3);
|
|
|
|
|
|
+ skeletonData.slots[skeletonData.slots.length] = slotData;
|
|
}
|
|
}
|
|
|
|
|
|
- mesh.hullLength = int(map["hull"] || 0) * 2;
|
|
|
|
- if (map["edges"]) mesh.edges = getIntArray(map, "edges");
|
|
|
|
- mesh.width = Number(map["width"] || 0) * scale;
|
|
|
|
- mesh.height = Number(map["height"] || 0) * scale;
|
|
|
|
- return mesh;
|
|
|
|
- case AttachmentType.skinnedmesh:
|
|
|
|
- var weightedMesh:SkinnedMeshAttachment = attachmentLoader.newSkinnedMeshAttachment(skin, name, path);
|
|
|
|
- if (!weightedMesh) return null;
|
|
|
|
- weightedMesh.path = path;
|
|
|
|
-
|
|
|
|
- var uvs:Vector.<Number> = getFloatArray(map, "uvs", 1);
|
|
|
|
- vertices = getFloatArray(map, "vertices", 1);
|
|
|
|
- var weights:Vector.<Number> = new Vector.<Number>();
|
|
|
|
- var bones:Vector.<int> = new Vector.<int>();
|
|
|
|
- for (var i:int = 0, n:int = vertices.length; i < n; ) {
|
|
|
|
- var boneCount:int = int(vertices[i++]);
|
|
|
|
- bones[bones.length] = boneCount;
|
|
|
|
- for (var nn:int = i + boneCount * 4; i < nn; ) {
|
|
|
|
- bones[bones.length] = vertices[i];
|
|
|
|
- weights[weights.length] = vertices[i + 1] * scale;
|
|
|
|
- weights[weights.length] = vertices[i + 2] * scale;
|
|
|
|
- weights[weights.length] = vertices[i + 3];
|
|
|
|
- i += 4;
|
|
|
|
|
|
+ // Skins.
|
|
|
|
+ var skins : Object = root["skins"];
|
|
|
|
+ for (var skinName : String in skins) {
|
|
|
|
+ var skinMap : Object = skins[skinName];
|
|
|
|
+ var skin : Skin = new Skin(skinName);
|
|
|
|
+ for (var slotName : String in skinMap) {
|
|
|
|
+ var slotIndex : int = skeletonData.findSlotIndex(slotName);
|
|
|
|
+ var slotEntry : Object = skinMap[slotName];
|
|
|
|
+ for (var attachmentName : String in slotEntry) {
|
|
|
|
+ var attachment : Attachment = readAttachment(skin, attachmentName, slotEntry[attachmentName]);
|
|
|
|
+ if (attachment != null)
|
|
|
|
+ skin.addAttachment(slotIndex, attachmentName, attachment);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ skeletonData.skins[skeletonData.skins.length] = skin;
|
|
|
|
+ if (skin.name == "default")
|
|
|
|
+ skeletonData.defaultSkin = skin;
|
|
}
|
|
}
|
|
- weightedMesh.bones = bones;
|
|
|
|
- weightedMesh.weights = weights;
|
|
|
|
- weightedMesh.triangles = getUintArray(map, "triangles");
|
|
|
|
- weightedMesh.regionUVs = uvs;
|
|
|
|
- weightedMesh.updateUVs();
|
|
|
|
-
|
|
|
|
- color = map["color"];
|
|
|
|
- if (color) {
|
|
|
|
- weightedMesh.r = toColor(color, 0);
|
|
|
|
- weightedMesh.g = toColor(color, 1);
|
|
|
|
- weightedMesh.b = toColor(color, 2);
|
|
|
|
- weightedMesh.a = toColor(color, 3);
|
|
|
|
|
|
+
|
|
|
|
+ // Events.
|
|
|
|
+ var events : Object = root["events"];
|
|
|
|
+ if (events) {
|
|
|
|
+ for (var eventName : String in events) {
|
|
|
|
+ var eventMap : Object = events[eventName];
|
|
|
|
+ var eventData : EventData = new EventData(eventName);
|
|
|
|
+ eventData.intValue = eventMap["int"] || 0;
|
|
|
|
+ eventData.floatValue = eventMap["float"] || 0;
|
|
|
|
+ eventData.stringValue = eventMap["string"] || null;
|
|
|
|
+ skeletonData.events[skeletonData.events.length] = eventData;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
- weightedMesh.hullLength = int(map["hull"] || 0) * 2;
|
|
|
|
- if (map["edges"]) weightedMesh.edges = getIntArray(map, "edges");
|
|
|
|
- weightedMesh.width = Number(map["width"] || 0) * scale;
|
|
|
|
- weightedMesh.height = Number(map["height"] || 0) * scale;
|
|
|
|
- return weightedMesh;
|
|
|
|
- case AttachmentType.boundingbox:
|
|
|
|
- var box:BoundingBoxAttachment = attachmentLoader.newBoundingBoxAttachment(skin, name);
|
|
|
|
- vertices = box.vertices;
|
|
|
|
- for each (var point:Number in map["vertices"])
|
|
|
|
- vertices[vertices.length] = point * scale;
|
|
|
|
- return box;
|
|
|
|
- }
|
|
|
|
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
|
|
+ // Animations.
|
|
|
|
+ var animations : Object = root["animations"];
|
|
|
|
+ for (var animationName : String in animations)
|
|
|
|
+ readAnimation(animationName, animations[animationName], skeletonData);
|
|
|
|
|
|
- private function readAnimation (name:String, map:Object, skeletonData:SkeletonData) : void {
|
|
|
|
- var timelines:Vector.<Timeline> = new Vector.<Timeline>();
|
|
|
|
- var duration:Number = 0;
|
|
|
|
-
|
|
|
|
- var slotMap:Object, slotIndex:int, slotName:String;
|
|
|
|
- var values:Array, valueMap:Object, frameIndex:int;
|
|
|
|
- var i:int;
|
|
|
|
- var timelineName:String;
|
|
|
|
-
|
|
|
|
- var slots:Object = map["slots"];
|
|
|
|
- for (slotName in slots) {
|
|
|
|
- slotMap = slots[slotName];
|
|
|
|
- slotIndex = skeletonData.findSlotIndex(slotName);
|
|
|
|
-
|
|
|
|
- for (timelineName in slotMap) {
|
|
|
|
- values = slotMap[timelineName];
|
|
|
|
- if (timelineName == "color") {
|
|
|
|
- var colorTimeline:ColorTimeline = new ColorTimeline(values.length);
|
|
|
|
- colorTimeline.slotIndex = slotIndex;
|
|
|
|
-
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- var color:String = valueMap["color"];
|
|
|
|
- var r:Number = toColor(color, 0);
|
|
|
|
- var g:Number = toColor(color, 1);
|
|
|
|
- var b:Number = toColor(color, 2);
|
|
|
|
- var a:Number = toColor(color, 3);
|
|
|
|
- colorTimeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
|
|
|
|
- readCurve(colorTimeline, frameIndex, valueMap);
|
|
|
|
- frameIndex++;
|
|
|
|
- }
|
|
|
|
- timelines[timelines.length] = colorTimeline;
|
|
|
|
- duration = Math.max(duration, colorTimeline.frames[colorTimeline.frameCount * 5 - 5]);
|
|
|
|
-
|
|
|
|
- } else if (timelineName == "attachment") {
|
|
|
|
- var attachmentTimeline:AttachmentTimeline = new AttachmentTimeline(values.length);
|
|
|
|
- attachmentTimeline.slotIndex = slotIndex;
|
|
|
|
-
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values)
|
|
|
|
- attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
|
|
|
|
- timelines[timelines.length] = attachmentTimeline;
|
|
|
|
- duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
|
|
|
|
-
|
|
|
|
- } else
|
|
|
|
- throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
|
|
|
|
- }
|
|
|
|
|
|
+ return skeletonData;
|
|
}
|
|
}
|
|
|
|
|
|
- var bones:Object = map["bones"];
|
|
|
|
- for (var boneName:String in bones) {
|
|
|
|
- var boneIndex:int = skeletonData.findBoneIndex(boneName);
|
|
|
|
- if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
|
|
|
|
- var boneMap:Object = bones[boneName];
|
|
|
|
-
|
|
|
|
- for (timelineName in boneMap) {
|
|
|
|
- values = boneMap[timelineName];
|
|
|
|
- if (timelineName == "rotate") {
|
|
|
|
- var rotateTimeline:RotateTimeline = new RotateTimeline(values.length);
|
|
|
|
- rotateTimeline.boneIndex = boneIndex;
|
|
|
|
-
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- rotateTimeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
|
|
|
|
- readCurve(rotateTimeline, frameIndex, valueMap);
|
|
|
|
- frameIndex++;
|
|
|
|
|
|
+ private function readAttachment(skin : Skin, name : String, map : Object) : Attachment {
|
|
|
|
+ name = map["name"] || name;
|
|
|
|
+
|
|
|
|
+ var typeName : String = map["type"] || "region";
|
|
|
|
+ if (typeName == "skinnedmesh") typeName = "weightedmesh";
|
|
|
|
+ var type : AttachmentType = AttachmentType[typeName];
|
|
|
|
+ var path : String = map["path"] || name;
|
|
|
|
+
|
|
|
|
+ var scale : Number = this.scale;
|
|
|
|
+ var color : String, vertices : Vector.<Number>;
|
|
|
|
+ switch (type) {
|
|
|
|
+ case AttachmentType.region:
|
|
|
|
+ var region : RegionAttachment = attachmentLoader.newRegionAttachment(skin, name, path);
|
|
|
|
+ if (!region) return null;
|
|
|
|
+ region.path = path;
|
|
|
|
+ region.x = Number(map["x"] || 0) * scale;
|
|
|
|
+ region.y = Number(map["y"] || 0) * scale;
|
|
|
|
+ region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
|
|
|
|
+ region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
|
|
|
|
+ region.rotation = map["rotation"] || 0;
|
|
|
|
+ region.width = Number(map["width"] || 0) * scale;
|
|
|
|
+ region.height = Number(map["height"] || 0) * scale;
|
|
|
|
+ color = map["color"];
|
|
|
|
+ if (color) {
|
|
|
|
+ region.r = toColor(color, 0);
|
|
|
|
+ region.g = toColor(color, 1);
|
|
|
|
+ region.b = toColor(color, 2);
|
|
|
|
+ region.a = toColor(color, 3);
|
|
}
|
|
}
|
|
- timelines[timelines.length] = rotateTimeline;
|
|
|
|
- duration = Math.max(duration, rotateTimeline.frames[rotateTimeline.frameCount * 2 - 2]);
|
|
|
|
-
|
|
|
|
- } else if (timelineName == "translate" || timelineName == "scale") {
|
|
|
|
- var timeline:TranslateTimeline;
|
|
|
|
- var timelineScale:Number = 1;
|
|
|
|
- if (timelineName == "scale")
|
|
|
|
- timeline = new ScaleTimeline(values.length);
|
|
|
|
- else {
|
|
|
|
- timeline = new TranslateTimeline(values.length);
|
|
|
|
- timelineScale = scale;
|
|
|
|
|
|
+ region.updateOffset();
|
|
|
|
+ return region;
|
|
|
|
+ case AttachmentType.mesh:
|
|
|
|
+ var mesh : MeshAttachment = attachmentLoader.newMeshAttachment(skin, name, path);
|
|
|
|
+ if (!mesh) return null;
|
|
|
|
+ mesh.path = path;
|
|
|
|
+ mesh.vertices = getFloatArray(map, "vertices", scale);
|
|
|
|
+ mesh.triangles = getUintArray(map, "triangles");
|
|
|
|
+ mesh.regionUVs = getFloatArray(map, "uvs", 1);
|
|
|
|
+ mesh.updateUVs();
|
|
|
|
+ color = map["color"];
|
|
|
|
+ if (color) {
|
|
|
|
+ mesh.r = toColor(color, 0);
|
|
|
|
+ mesh.g = toColor(color, 1);
|
|
|
|
+ mesh.b = toColor(color, 2);
|
|
|
|
+ mesh.a = toColor(color, 3);
|
|
}
|
|
}
|
|
- timeline.boneIndex = boneIndex;
|
|
|
|
-
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- var x:Number = Number(valueMap["x"] || 0) * timelineScale;
|
|
|
|
- var y:Number = Number(valueMap["y"] || 0) * timelineScale;
|
|
|
|
- timeline.setFrame(frameIndex, valueMap["time"], x, y);
|
|
|
|
- readCurve(timeline, frameIndex, valueMap);
|
|
|
|
- frameIndex++;
|
|
|
|
|
|
+ mesh.hullLength = int(map["hull"] || 0) * 2;
|
|
|
|
+ if (map["edges"]) mesh.edges = getIntArray(map, "edges");
|
|
|
|
+ mesh.width = Number(map["width"] || 0) * scale;
|
|
|
|
+ mesh.height = Number(map["height"] || 0) * scale;
|
|
|
|
+ return mesh;
|
|
|
|
+ case AttachmentType.weightedmesh:
|
|
|
|
+ var weightedMesh : WeightedMeshAttachment = attachmentLoader.newWeightedMeshAttachment(skin, name, path);
|
|
|
|
+ if (!weightedMesh) return null;
|
|
|
|
+ weightedMesh.path = path;
|
|
|
|
+ var uvs : Vector.<Number> = getFloatArray(map, "uvs", 1);
|
|
|
|
+ vertices = getFloatArray(map, "vertices", 1);
|
|
|
|
+ var weights : Vector.<Number> = new Vector.<Number>();
|
|
|
|
+ var bones : Vector.<int> = new Vector.<int>();
|
|
|
|
+ for (var i : int = 0, n : int = vertices.length; i < n;) {
|
|
|
|
+ var boneCount : int = int(vertices[i++]);
|
|
|
|
+ bones[bones.length] = boneCount;
|
|
|
|
+ for (var nn : int = i + boneCount * 4; i < nn;) {
|
|
|
|
+ bones[bones.length] = vertices[i];
|
|
|
|
+ weights[weights.length] = vertices[i + 1] * scale;
|
|
|
|
+ weights[weights.length] = vertices[i + 2] * scale;
|
|
|
|
+ weights[weights.length] = vertices[i + 3];
|
|
|
|
+ i += 4;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- timelines[timelines.length] = timeline;
|
|
|
|
- duration = Math.max(duration, timeline.frames[timeline.frameCount * 3 - 3]);
|
|
|
|
-
|
|
|
|
- } else if (timelineName == "flipX" || timelineName == "flipY") {
|
|
|
|
- var flipX:Boolean = timelineName == "flipX";
|
|
|
|
- var flipTimeline:FlipXTimeline = flipX ? new FlipXTimeline(values.length) : new FlipYTimeline(values.length);
|
|
|
|
- flipTimeline.boneIndex = boneIndex;
|
|
|
|
-
|
|
|
|
- var field:String = flipX ? "x" : "y";
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- flipTimeline.setFrame(frameIndex, valueMap["time"], valueMap[field] || false);
|
|
|
|
- frameIndex++;
|
|
|
|
|
|
+ weightedMesh.bones = bones;
|
|
|
|
+ weightedMesh.weights = weights;
|
|
|
|
+ weightedMesh.triangles = getUintArray(map, "triangles");
|
|
|
|
+ weightedMesh.regionUVs = uvs;
|
|
|
|
+ weightedMesh.updateUVs();
|
|
|
|
+ color = map["color"];
|
|
|
|
+ if (color) {
|
|
|
|
+ weightedMesh.r = toColor(color, 0);
|
|
|
|
+ weightedMesh.g = toColor(color, 1);
|
|
|
|
+ weightedMesh.b = toColor(color, 2);
|
|
|
|
+ weightedMesh.a = toColor(color, 3);
|
|
}
|
|
}
|
|
- timelines[timelines.length] = flipTimeline;
|
|
|
|
- duration = Math.max(duration, flipTimeline.frames[flipTimeline.frameCount * 3 - 3]);
|
|
|
|
-
|
|
|
|
- } else
|
|
|
|
- throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
|
|
|
|
|
|
+ weightedMesh.hullLength = int(map["hull"] || 0) * 2;
|
|
|
|
+ if (map["edges"]) weightedMesh.edges = getIntArray(map, "edges");
|
|
|
|
+ weightedMesh.width = Number(map["width"] || 0) * scale;
|
|
|
|
+ weightedMesh.height = Number(map["height"] || 0) * scale;
|
|
|
|
+ return weightedMesh;
|
|
|
|
+ case AttachmentType.boundingbox:
|
|
|
|
+ var box : BoundingBoxAttachment = attachmentLoader.newBoundingBoxAttachment(skin, name);
|
|
|
|
+ vertices = box.vertices;
|
|
|
|
+ for each (var point : Number in map["vertices"])
|
|
|
|
+ vertices[vertices.length] = point * scale;
|
|
|
|
+ return box;
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- var ikMap:Object = map["ik"];
|
|
|
|
- for (var ikConstraintName:String in ikMap) {
|
|
|
|
- var ikConstraint:IkConstraintData = skeletonData.findIkConstraint(ikConstraintName);
|
|
|
|
- values = ikMap[ikConstraintName];
|
|
|
|
- var ikTimeline:IkConstraintTimeline = new IkConstraintTimeline(values.length);
|
|
|
|
- ikTimeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- var mix:Number = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
|
|
|
|
- var bendDirection:int = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
|
|
|
|
- ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
|
|
|
|
- readCurve(ikTimeline, frameIndex, valueMap);
|
|
|
|
- frameIndex++;
|
|
|
|
- }
|
|
|
|
- timelines[timelines.length] = ikTimeline;
|
|
|
|
- duration = Math.max(duration, ikTimeline.frames[ikTimeline.frameCount * 3 - 3]);
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
- var ffd:Object = map["ffd"];
|
|
|
|
- for (var skinName:String in ffd) {
|
|
|
|
- var skin:Skin = skeletonData.findSkin(skinName);
|
|
|
|
- slotMap = ffd[skinName];
|
|
|
|
- for (slotName in slotMap) {
|
|
|
|
|
|
+ private function readAnimation(name : String, map : Object, skeletonData : SkeletonData) : void {
|
|
|
|
+ var timelines : Vector.<Timeline> = new Vector.<Timeline>();
|
|
|
|
+ var duration : Number = 0;
|
|
|
|
+
|
|
|
|
+ var slotMap : Object, slotIndex : int, slotName : String;
|
|
|
|
+ var values : Array, valueMap : Object, frameIndex : int;
|
|
|
|
+ var i : int;
|
|
|
|
+ var timelineName : String;
|
|
|
|
+
|
|
|
|
+ var slots : Object = map["slots"];
|
|
|
|
+ for (slotName in slots) {
|
|
|
|
+ slotMap = slots[slotName];
|
|
slotIndex = skeletonData.findSlotIndex(slotName);
|
|
slotIndex = skeletonData.findSlotIndex(slotName);
|
|
- var meshMap:Object = slotMap[slotName];
|
|
|
|
- for (var meshName:String in meshMap) {
|
|
|
|
- values = meshMap[meshName];
|
|
|
|
- var ffdTimeline:FfdTimeline = new FfdTimeline(values.length);
|
|
|
|
- var attachment:Attachment = skin.getAttachment(slotIndex, meshName);
|
|
|
|
- if (!attachment) throw new Error("FFD attachment not found: " + meshName);
|
|
|
|
- ffdTimeline.slotIndex = slotIndex;
|
|
|
|
- ffdTimeline.attachment = attachment;
|
|
|
|
-
|
|
|
|
- var vertexCount:int;
|
|
|
|
- if (attachment is MeshAttachment)
|
|
|
|
- vertexCount = (attachment as MeshAttachment).vertices.length;
|
|
|
|
- else
|
|
|
|
- vertexCount = (attachment as SkinnedMeshAttachment).weights.length / 3 * 2;
|
|
|
|
-
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (valueMap in values) {
|
|
|
|
- var vertices:Vector.<Number>;
|
|
|
|
- if (!valueMap["vertices"]) {
|
|
|
|
- if (attachment is MeshAttachment)
|
|
|
|
- vertices = (attachment as MeshAttachment).vertices;
|
|
|
|
- else
|
|
|
|
- vertices = new Vector.<Number>(vertexCount, true);
|
|
|
|
- } else {
|
|
|
|
- var verticesValue:Array = valueMap["vertices"];
|
|
|
|
- vertices = new Vector.<Number>(vertexCount, true);
|
|
|
|
- var start:int = valueMap["offset"] || 0;
|
|
|
|
- var n:int = verticesValue.length;
|
|
|
|
- if (scale == 1) {
|
|
|
|
- for (i = 0; i < n; i++)
|
|
|
|
- vertices[i + start] = verticesValue[i];
|
|
|
|
|
|
+
|
|
|
|
+ for (timelineName in slotMap) {
|
|
|
|
+ values = slotMap[timelineName];
|
|
|
|
+ if (timelineName == "color") {
|
|
|
|
+ var colorTimeline : ColorTimeline = new ColorTimeline(values.length);
|
|
|
|
+ colorTimeline.slotIndex = slotIndex;
|
|
|
|
+
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values) {
|
|
|
|
+ var color : String = valueMap["color"];
|
|
|
|
+ var r : Number = toColor(color, 0);
|
|
|
|
+ var g : Number = toColor(color, 1);
|
|
|
|
+ var b : Number = toColor(color, 2);
|
|
|
|
+ var a : Number = toColor(color, 3);
|
|
|
|
+ colorTimeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
|
|
|
|
+ readCurve(colorTimeline, frameIndex, valueMap);
|
|
|
|
+ frameIndex++;
|
|
|
|
+ }
|
|
|
|
+ timelines[timelines.length] = colorTimeline;
|
|
|
|
+ duration = Math.max(duration, colorTimeline.frames[colorTimeline.frameCount * 5 - 5]);
|
|
|
|
+ } else if (timelineName == "attachment") {
|
|
|
|
+ var attachmentTimeline : AttachmentTimeline = new AttachmentTimeline(values.length);
|
|
|
|
+ attachmentTimeline.slotIndex = slotIndex;
|
|
|
|
+
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values)
|
|
|
|
+ attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
|
|
|
|
+ timelines[timelines.length] = attachmentTimeline;
|
|
|
|
+ duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
|
|
|
|
+ } else
|
|
|
|
+ throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var bones : Object = map["bones"];
|
|
|
|
+ for (var boneName : String in bones) {
|
|
|
|
+ var boneIndex : int = skeletonData.findBoneIndex(boneName);
|
|
|
|
+ if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
|
|
|
|
+ var boneMap : Object = bones[boneName];
|
|
|
|
+
|
|
|
|
+ for (timelineName in boneMap) {
|
|
|
|
+ values = boneMap[timelineName];
|
|
|
|
+ if (timelineName == "rotate") {
|
|
|
|
+ var rotateTimeline : RotateTimeline = new RotateTimeline(values.length);
|
|
|
|
+ rotateTimeline.boneIndex = boneIndex;
|
|
|
|
+
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values) {
|
|
|
|
+ rotateTimeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
|
|
|
|
+ readCurve(rotateTimeline, frameIndex, valueMap);
|
|
|
|
+ frameIndex++;
|
|
|
|
+ }
|
|
|
|
+ timelines[timelines.length] = rotateTimeline;
|
|
|
|
+ duration = Math.max(duration, rotateTimeline.frames[rotateTimeline.frameCount * 2 - 2]);
|
|
|
|
+ } else if (timelineName == "translate" || timelineName == "scale") {
|
|
|
|
+ var timeline : TranslateTimeline;
|
|
|
|
+ var timelineScale : Number = 1;
|
|
|
|
+ if (timelineName == "scale")
|
|
|
|
+ timeline = new ScaleTimeline(values.length);
|
|
|
|
+ else {
|
|
|
|
+ timeline = new TranslateTimeline(values.length);
|
|
|
|
+ timelineScale = scale;
|
|
|
|
+ }
|
|
|
|
+ timeline.boneIndex = boneIndex;
|
|
|
|
+
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values) {
|
|
|
|
+ var x : Number = Number(valueMap["x"] || 0) * timelineScale;
|
|
|
|
+ var y : Number = Number(valueMap["y"] || 0) * timelineScale;
|
|
|
|
+ timeline.setFrame(frameIndex, valueMap["time"], x, y);
|
|
|
|
+ readCurve(timeline, frameIndex, valueMap);
|
|
|
|
+ frameIndex++;
|
|
|
|
+ }
|
|
|
|
+ timelines[timelines.length] = timeline;
|
|
|
|
+ duration = Math.max(duration, timeline.frames[timeline.frameCount * 3 - 3]);
|
|
|
|
+ } else
|
|
|
|
+ throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var ikMap : Object = map["ik"];
|
|
|
|
+ for (var ikConstraintName : String in ikMap) {
|
|
|
|
+ var ikConstraint : IkConstraintData = skeletonData.findIkConstraint(ikConstraintName);
|
|
|
|
+ values = ikMap[ikConstraintName];
|
|
|
|
+ var ikTimeline : IkConstraintTimeline = new IkConstraintTimeline(values.length);
|
|
|
|
+ ikTimeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values) {
|
|
|
|
+ var mix : Number = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
|
|
|
|
+ var bendDirection : int = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
|
|
|
|
+ ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
|
|
|
|
+ readCurve(ikTimeline, frameIndex, valueMap);
|
|
|
|
+ frameIndex++;
|
|
|
|
+ }
|
|
|
|
+ timelines[timelines.length] = ikTimeline;
|
|
|
|
+ duration = Math.max(duration, ikTimeline.frames[ikTimeline.frameCount * 3 - 3]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var ffd : Object = map["ffd"];
|
|
|
|
+ for (var skinName : String in ffd) {
|
|
|
|
+ var skin : Skin = skeletonData.findSkin(skinName);
|
|
|
|
+ slotMap = ffd[skinName];
|
|
|
|
+ for (slotName in slotMap) {
|
|
|
|
+ slotIndex = skeletonData.findSlotIndex(slotName);
|
|
|
|
+ var meshMap : Object = slotMap[slotName];
|
|
|
|
+ for (var meshName : String in meshMap) {
|
|
|
|
+ values = meshMap[meshName];
|
|
|
|
+ var ffdTimeline : FfdTimeline = new FfdTimeline(values.length);
|
|
|
|
+ var attachment : Attachment = skin.getAttachment(slotIndex, meshName);
|
|
|
|
+ if (!attachment) throw new Error("FFD attachment not found: " + meshName);
|
|
|
|
+ ffdTimeline.slotIndex = slotIndex;
|
|
|
|
+ ffdTimeline.attachment = attachment;
|
|
|
|
+
|
|
|
|
+ var vertexCount : int;
|
|
|
|
+ if (attachment is MeshAttachment)
|
|
|
|
+ vertexCount = (attachment as MeshAttachment).vertices.length;
|
|
|
|
+ else
|
|
|
|
+ vertexCount = (attachment as WeightedMeshAttachment).weights.length / 3 * 2;
|
|
|
|
+
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (valueMap in values) {
|
|
|
|
+ var vertices : Vector.<Number>;
|
|
|
|
+ if (!valueMap["vertices"]) {
|
|
|
|
+ if (attachment is MeshAttachment)
|
|
|
|
+ vertices = (attachment as MeshAttachment).vertices;
|
|
|
|
+ else
|
|
|
|
+ vertices = new Vector.<Number>(vertexCount, true);
|
|
} else {
|
|
} else {
|
|
- for (i = 0; i < n; i++)
|
|
|
|
- vertices[i + start] = verticesValue[i] * scale;
|
|
|
|
- }
|
|
|
|
- if (attachment is MeshAttachment) {
|
|
|
|
- var meshVertices:Vector.<Number> = (attachment as MeshAttachment).vertices;
|
|
|
|
- for (i = 0; i < vertexCount; i++)
|
|
|
|
- vertices[i] += meshVertices[i];
|
|
|
|
|
|
+ var verticesValue : Array = valueMap["vertices"];
|
|
|
|
+ vertices = new Vector.<Number>(vertexCount, true);
|
|
|
|
+ var start : int = valueMap["offset"] || 0;
|
|
|
|
+ var n : int = verticesValue.length;
|
|
|
|
+ if (scale == 1) {
|
|
|
|
+ for (i = 0; i < n; i++)
|
|
|
|
+ vertices[i + start] = verticesValue[i];
|
|
|
|
+ } else {
|
|
|
|
+ for (i = 0; i < n; i++)
|
|
|
|
+ vertices[i + start] = verticesValue[i] * scale;
|
|
|
|
+ }
|
|
|
|
+ if (attachment is MeshAttachment) {
|
|
|
|
+ var meshVertices : Vector.<Number> = (attachment as MeshAttachment).vertices;
|
|
|
|
+ for (i = 0; i < vertexCount; i++)
|
|
|
|
+ vertices[i] += meshVertices[i];
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ ffdTimeline.setFrame(frameIndex, valueMap["time"], vertices);
|
|
|
|
+ readCurve(ffdTimeline, frameIndex, valueMap);
|
|
|
|
+ frameIndex++;
|
|
}
|
|
}
|
|
-
|
|
|
|
- ffdTimeline.setFrame(frameIndex, valueMap["time"], vertices);
|
|
|
|
- readCurve(ffdTimeline, frameIndex, valueMap);
|
|
|
|
- frameIndex++;
|
|
|
|
|
|
+ timelines[timelines.length] = ffdTimeline;
|
|
|
|
+ duration = Math.max(duration, ffdTimeline.frames[ffdTimeline.frameCount - 1]);
|
|
}
|
|
}
|
|
- timelines[timelines.length] = ffdTimeline;
|
|
|
|
- duration = Math.max(duration, ffdTimeline.frames[ffdTimeline.frameCount - 1]);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- var drawOrderValues:Array = map["drawOrder"];
|
|
|
|
- if (!drawOrderValues) drawOrderValues = map["draworder"];
|
|
|
|
- if (drawOrderValues) {
|
|
|
|
- var drawOrderTimeline:DrawOrderTimeline = new DrawOrderTimeline(drawOrderValues.length);
|
|
|
|
- var slotCount:int = skeletonData.slots.length;
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (var drawOrderMap:Object in drawOrderValues) {
|
|
|
|
- var drawOrder:Vector.<int> = null;
|
|
|
|
- if (drawOrderMap["offsets"]) {
|
|
|
|
- drawOrder = new Vector.<int>(slotCount);
|
|
|
|
- for (i = slotCount - 1; i >= 0; i--)
|
|
|
|
- drawOrder[i] = -1;
|
|
|
|
- var offsets:Array = drawOrderMap["offsets"];
|
|
|
|
- var unchanged:Vector.<int> = new Vector.<int>(slotCount - offsets.length);
|
|
|
|
- var originalIndex:int = 0, unchangedIndex:int = 0;
|
|
|
|
- for each (var offsetMap:Object in offsets) {
|
|
|
|
- slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
|
|
|
|
- if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]);
|
|
|
|
- // Collect unchanged items.
|
|
|
|
- while (originalIndex != slotIndex)
|
|
|
|
|
|
+ var drawOrderValues : Array = map["drawOrder"];
|
|
|
|
+ if (!drawOrderValues) drawOrderValues = map["draworder"];
|
|
|
|
+ if (drawOrderValues) {
|
|
|
|
+ var drawOrderTimeline : DrawOrderTimeline = new DrawOrderTimeline(drawOrderValues.length);
|
|
|
|
+ var slotCount : int = skeletonData.slots.length;
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (var drawOrderMap : Object in drawOrderValues) {
|
|
|
|
+ var drawOrder : Vector.<int> = null;
|
|
|
|
+ if (drawOrderMap["offsets"]) {
|
|
|
|
+ drawOrder = new Vector.<int>(slotCount);
|
|
|
|
+ for (i = slotCount - 1; i >= 0; i--)
|
|
|
|
+ drawOrder[i] = -1;
|
|
|
|
+ var offsets : Array = drawOrderMap["offsets"];
|
|
|
|
+ var unchanged : Vector.<int> = new Vector.<int>(slotCount - offsets.length);
|
|
|
|
+ var originalIndex : int = 0, unchangedIndex : int = 0;
|
|
|
|
+ for each (var offsetMap : Object in offsets) {
|
|
|
|
+ slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
|
|
|
|
+ if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]);
|
|
|
|
+ // Collect unchanged items.
|
|
|
|
+ while (originalIndex != slotIndex)
|
|
|
|
+ unchanged[unchangedIndex++] = originalIndex++;
|
|
|
|
+ // Set changed items.
|
|
|
|
+ drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++;
|
|
|
|
+ }
|
|
|
|
+ // Collect remaining unchanged items.
|
|
|
|
+ while (originalIndex < slotCount)
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
unchanged[unchangedIndex++] = originalIndex++;
|
|
- // Set changed items.
|
|
|
|
- drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++;
|
|
|
|
|
|
+ // Fill in unchanged items.
|
|
|
|
+ for (i = slotCount - 1; i >= 0; i--)
|
|
|
|
+ if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
|
|
}
|
|
}
|
|
- // Collect remaining unchanged items.
|
|
|
|
- while (originalIndex < slotCount)
|
|
|
|
- unchanged[unchangedIndex++] = originalIndex++;
|
|
|
|
- // Fill in unchanged items.
|
|
|
|
- for (i = slotCount - 1; i >= 0; i--)
|
|
|
|
- if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
|
|
|
|
|
|
+ drawOrderTimeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
|
|
}
|
|
}
|
|
- drawOrderTimeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
|
|
|
|
|
|
+ timelines[timelines.length] = drawOrderTimeline;
|
|
|
|
+ duration = Math.max(duration, drawOrderTimeline.frames[drawOrderTimeline.frameCount - 1]);
|
|
}
|
|
}
|
|
- timelines[timelines.length] = drawOrderTimeline;
|
|
|
|
- duration = Math.max(duration, drawOrderTimeline.frames[drawOrderTimeline.frameCount - 1]);
|
|
|
|
- }
|
|
|
|
|
|
|
|
- var eventsMap:Array = map["events"];
|
|
|
|
- if (eventsMap) {
|
|
|
|
- var eventTimeline:EventTimeline = new EventTimeline(eventsMap.length);
|
|
|
|
- frameIndex = 0;
|
|
|
|
- for each (var eventMap:Object in eventsMap) {
|
|
|
|
- var eventData:EventData = skeletonData.findEvent(eventMap["name"]);
|
|
|
|
- if (!eventData) throw new Error("Event not found: " + eventMap["name"]);
|
|
|
|
- var event:Event = new Event(eventData);
|
|
|
|
- event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
|
|
|
|
- event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
|
|
|
|
- event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
|
|
|
|
- eventTimeline.setFrame(frameIndex++, eventMap["time"], event);
|
|
|
|
|
|
+ var eventsMap : Array = map["events"];
|
|
|
|
+ if (eventsMap) {
|
|
|
|
+ var eventTimeline : EventTimeline = new EventTimeline(eventsMap.length);
|
|
|
|
+ frameIndex = 0;
|
|
|
|
+ for each (var eventMap : Object in eventsMap) {
|
|
|
|
+ var eventData : EventData = skeletonData.findEvent(eventMap["name"]);
|
|
|
|
+ if (!eventData) throw new Error("Event not found: " + eventMap["name"]);
|
|
|
|
+ var event : Event = new Event(eventMap["time"], eventData);
|
|
|
|
+ event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
|
|
|
|
+ event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
|
|
|
|
+ event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
|
|
|
|
+ eventTimeline.setFrame(frameIndex++, event);
|
|
|
|
+ }
|
|
|
|
+ timelines[timelines.length] = eventTimeline;
|
|
|
|
+ duration = Math.max(duration, eventTimeline.frames[eventTimeline.frameCount - 1]);
|
|
}
|
|
}
|
|
- timelines[timelines.length] = eventTimeline;
|
|
|
|
- duration = Math.max(duration, eventTimeline.frames[eventTimeline.frameCount - 1]);
|
|
|
|
|
|
+
|
|
|
|
+ skeletonData.animations[skeletonData.animations.length] = new Animation(name, timelines, duration);
|
|
}
|
|
}
|
|
|
|
|
|
- skeletonData.animations[skeletonData.animations.length] = new Animation(name, timelines, duration);
|
|
|
|
- }
|
|
|
|
|
|
+ static private function readCurve(timeline : CurveTimeline, frameIndex : int, valueMap : Object) : void {
|
|
|
|
+ var curve : Object = valueMap["curve"];
|
|
|
|
+ if (!curve) return;
|
|
|
|
+ if (curve == "stepped")
|
|
|
|
+ timeline.setStepped(frameIndex);
|
|
|
|
+ else if (curve is Array)
|
|
|
|
+ timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
|
|
|
|
+ }
|
|
|
|
|
|
- static private function readCurve (timeline:CurveTimeline, frameIndex:int, valueMap:Object) : void {
|
|
|
|
- var curve:Object = valueMap["curve"];
|
|
|
|
- if (!curve) return;
|
|
|
|
- if (curve == "stepped")
|
|
|
|
- timeline.setStepped(frameIndex);
|
|
|
|
- else if (curve is Array)
|
|
|
|
- timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
|
|
|
|
- }
|
|
|
|
|
|
+ static private function toColor(hexString : String, colorIndex : int) : Number {
|
|
|
|
+ if (hexString.length != 8) throw new ArgumentError("Color hexidecimal length must be 8, recieved: " + hexString);
|
|
|
|
+ return parseInt(hexString.substring(colorIndex * 2, colorIndex * 2 + 2), 16) / 255;
|
|
|
|
+ }
|
|
|
|
|
|
- static private function toColor (hexString:String, colorIndex:int) : Number {
|
|
|
|
- if (hexString.length != 8) throw new ArgumentError("Color hexidecimal length must be 8, recieved: " + hexString);
|
|
|
|
- return parseInt(hexString.substring(colorIndex * 2, colorIndex * 2 + 2), 16) / 255;
|
|
|
|
- }
|
|
|
|
|
|
+ static private function getFloatArray(map : Object, name : String, scale : Number) : Vector.<Number> {
|
|
|
|
+ var list : Array = map[name];
|
|
|
|
+ var values : Vector.<Number> = new Vector.<Number>(list.length, true);
|
|
|
|
+ var i : int = 0, n : int = list.length;
|
|
|
|
+ if (scale == 1) {
|
|
|
|
+ for (; i < n; i++)
|
|
|
|
+ values[i] = list[i];
|
|
|
|
+ } else {
|
|
|
|
+ for (; i < n; i++)
|
|
|
|
+ values[i] = list[i] * scale;
|
|
|
|
+ }
|
|
|
|
+ return values;
|
|
|
|
+ }
|
|
|
|
|
|
- static private function getFloatArray (map:Object, name:String, scale:Number) : Vector.<Number> {
|
|
|
|
- var list:Array = map[name];
|
|
|
|
- var values:Vector.<Number> = new Vector.<Number>(list.length, true);
|
|
|
|
- var i:int = 0, n:int = list.length;
|
|
|
|
- if (scale == 1) {
|
|
|
|
- for (; i < n; i++)
|
|
|
|
- values[i] = list[i];
|
|
|
|
- } else {
|
|
|
|
- for (; i < n; i++)
|
|
|
|
- values[i] = list[i] * scale;
|
|
|
|
|
|
+ static private function getIntArray(map : Object, name : String) : Vector.<int> {
|
|
|
|
+ var list : Array = map[name];
|
|
|
|
+ var values : Vector.<int> = new Vector.<int>(list.length, true);
|
|
|
|
+ for (var i : int = 0, n : int = list.length; i < n; i++)
|
|
|
|
+ values[i] = int(list[i]);
|
|
|
|
+ return values;
|
|
}
|
|
}
|
|
- return values;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- static private function getIntArray (map:Object, name:String) : Vector.<int> {
|
|
|
|
- var list:Array = map[name];
|
|
|
|
- var values:Vector.<int> = new Vector.<int>(list.length, true);
|
|
|
|
- for (var i:int = 0, n:int = list.length; i < n; i++)
|
|
|
|
- values[i] = int(list[i]);
|
|
|
|
- return values;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- static private function getUintArray (map:Object, name:String) : Vector.<uint> {
|
|
|
|
- var list:Array = map[name];
|
|
|
|
- var values:Vector.<uint> = new Vector.<uint>(list.length, true);
|
|
|
|
- for (var i:int = 0, n:int = list.length; i < n; i++)
|
|
|
|
- values[i] = int(list[i]);
|
|
|
|
- return values;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
+ static private function getUintArray(map : Object, name : String) : Vector.<uint> {
|
|
|
|
+ var list : Array = map[name];
|
|
|
|
+ var values : Vector.<uint> = new Vector.<uint>(list.length, true);
|
|
|
|
+ for (var i : int = 0, n : int = list.length; i < n; i++)
|
|
|
|
+ values[i] = int(list[i]);
|
|
|
|
+ return values;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|