diff --git a/spine-as3/spine-as3/src/spine/Skeleton.as b/spine-as3/spine-as3/src/spine/Skeleton.as index 83770ac7c..04ff6b8f2 100644 --- a/spine-as3/spine-as3/src/spine/Skeleton.as +++ b/spine-as3/spine-as3/src/spine/Skeleton.as @@ -41,7 +41,7 @@ public class Skeleton { public var g:Number = 1; public var b:Number = 1; public var a:Number = 1; - public var time:Number; + public var time:Number = 0; public var flipX:Boolean; public var flipY:Boolean; public var x:Number = 0; diff --git a/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as b/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as index b22e9daf2..cd42a0c3b 100644 --- a/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as @@ -96,9 +96,9 @@ public dynamic class MeshAttachment extends Attachment { if (slot.attachmentVertices.length == verticesCount) vertices = slot.attachmentVertices; for (var i:int = 0, ii:int = 0; i < verticesCount; i += 2, ii += 2) { var vx:Number = vertices[i]; - var vy:Number = vertices[ii]; - worldVertices[i] = vx * m00 + vy * m01 + x; - worldVertices[ii] = vx * m10 + vy * m11 + y; + var vy:Number = vertices[int(i + 1)]; + worldVertices[ii] = vx * m00 + vy * m01 + x; + worldVertices[int(ii + 1)] = vx * m10 + vy * m11 + y; } } } diff --git a/spine-starling/spine-starling-example/html-template/index.template.html b/spine-starling/spine-starling-example/html-template/index.template.html index 3b89e4ee5..b6e57525e 100644 --- a/spine-starling/spine-starling-example/html-template/index.template.html +++ b/spine-starling/spine-starling-example/html-template/index.template.html @@ -1,109 +1,109 @@ - - - ${title} - - - - - - - - - - + - - - -
-

- To view this page ensure that Adobe Flash Player version - ${version_major}.${version_minor}.${version_revision} or greater is installed. -

- -
- - + var attributes = {}; + attributes.id = "${application}"; + attributes.name = "${application}"; + attributes.align = "middle"; + swfobject.embedSWF( + "${swf}.swf", "flashContent", + "${width}", "${height}", + swfVersionStr, xiSwfUrlStr, + flashvars, params, attributes); + // JavaScript enabled so display the flashContent div in case it is not replaced with a swf object. + swfobject.createCSS("#flashContent", "display:block;text-align:left;"); + + + + +
+

+ To view this page ensure that Adobe Flash Player version + ${version_major}.${version_minor}.${version_revision} or greater is installed. +

+ +
+ + diff --git a/spine-starling/spine-starling-example/src/AtlasExample.as b/spine-starling/spine-starling-example/src/AtlasExample.as index 3322926d7..af0aaa342 100644 --- a/spine-starling/spine-starling-example/src/AtlasExample.as +++ b/spine-starling/spine-starling-example/src/AtlasExample.as @@ -1,14 +1,15 @@ package { +import flash.display.Bitmap; + import spine.Event; import spine.SkeletonData; import spine.SkeletonJson; import spine.animation.AnimationStateData; import spine.atlas.Atlas; import spine.attachments.AtlasAttachmentLoader; -import spine.starling.StarlingTextureLoader; import spine.starling.SkeletonAnimation; -import spine.starling.StarlingAtlasAttachmentLoader; +import spine.starling.StarlingTextureLoader; import starling.core.Starling; import starling.display.Sprite; @@ -16,7 +17,6 @@ import starling.events.Touch; import starling.events.TouchEvent; import starling.events.TouchPhase; import starling.textures.Texture; -import starling.textures.TextureAtlas; public class AtlasExample extends Sprite { [Embed(source = "spineboy.atlas", mimeType = "application/octet-stream")] @@ -33,14 +33,14 @@ public class AtlasExample extends Sprite { public function AtlasExample () { var atlas:Atlas = new Atlas(new SpineboyAtlasFile(), new StarlingTextureLoader(new SpineboyAtlasTexture())); var json:SkeletonJson = new SkeletonJson(new AtlasAttachmentLoader(atlas)); + json.scale = 0.6; var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson()); var stateData:AnimationStateData = new AnimationStateData(skeletonData); - stateData.setMixByName("walk", "jump", 0.2); - stateData.setMixByName("jump", "walk", 0.4); - stateData.setMixByName("jump", "jump", 0.2); + stateData.defaultMix = 0.2; + stateData.setMixByName("jump", "run", 0.3); - skeleton = new SkeletonAnimation(skeletonData, stateData); + skeleton = new SkeletonAnimation(skeletonData, false, stateData); skeleton.x = 320; skeleton.y = 420; @@ -60,7 +60,7 @@ public class AtlasExample extends Sprite { skeleton.state.setAnimationByName(0, "walk", true); skeleton.state.addAnimationByName(0, "jump", false, 3); - skeleton.state.addAnimationByName(0, "walk", true, 0); + skeleton.state.addAnimationByName(0, "run", true, 0); addChild(skeleton); Starling.juggler.add(skeleton); @@ -72,7 +72,7 @@ public class AtlasExample extends Sprite { var touch:Touch = event.getTouch(this); if (touch && touch.phase == TouchPhase.BEGAN) { skeleton.state.setAnimationByName(0, "jump", false); - skeleton.state.addAnimationByName(0, "walk", true, 0); + skeleton.state.addAnimationByName(0, "run", true, 0); } } } diff --git a/spine-starling/spine-starling-example/src/GoblinsExample.as b/spine-starling/spine-starling-example/src/GoblinsExample.as index 742109b83..52762ca7d 100644 --- a/spine-starling/spine-starling-example/src/GoblinsExample.as +++ b/spine-starling/spine-starling-example/src/GoblinsExample.as @@ -19,13 +19,13 @@ import starling.textures.Texture; import starling.textures.TextureAtlas; public class GoblinsExample extends Sprite { - [Embed(source = "goblins.atlas", mimeType = "application/octet-stream")] + [Embed(source = "goblins-ffd.atlas", mimeType = "application/octet-stream")] static public const SpineboyAtlasFile:Class; - [Embed(source = "goblins.png")] + [Embed(source = "goblins-ffd.png")] static public const SpineboyAtlasTexture:Class; - [Embed(source = "goblins.json", mimeType = "application/octet-stream")] + [Embed(source = "goblins-ffd.json", mimeType = "application/octet-stream")] static public const SpineboyJson:Class; private var skeleton:SkeletonAnimation; @@ -35,7 +35,7 @@ public class GoblinsExample extends Sprite { var json:SkeletonJson = new SkeletonJson(new AtlasAttachmentLoader(atlas)); var skeletonData:SkeletonData = json.readSkeletonData(new SpineboyJson()); - skeleton = new SkeletonAnimation(skeletonData); + skeleton = new SkeletonAnimation(skeletonData, true); skeleton.x = 320; skeleton.y = 420; skeleton.skeleton.skinName = "goblin"; diff --git a/spine-starling/spine-starling-example/src/Main.as b/spine-starling/spine-starling-example/src/Main.as index 08e618af1..ce79f44a3 100644 --- a/spine-starling/spine-starling-example/src/Main.as +++ b/spine-starling/spine-starling-example/src/Main.as @@ -2,6 +2,7 @@ package { import flash.display.Sprite; + import starling.core.Starling; [SWF(width = "640", height = "480", frameRate = "60", backgroundColor = "#dddddd")] @@ -9,7 +10,13 @@ public class Main extends Sprite { private var _starling:Starling; public function Main () { - _starling = new Starling(AtlasExample, stage); + var example:Class; + //example = AtlasExample; + //example = StarlingAtlasExample; + example = GoblinsExample; + + _starling = new Starling(example, stage); + _starling.showStats = true; _starling.start(); } } diff --git a/spine-starling/spine-starling-example/src/StarlingAtlasExample.as b/spine-starling/spine-starling-example/src/StarlingAtlasExample.as index 7efc309fc..41d7a4505 100644 --- a/spine-starling/spine-starling-example/src/StarlingAtlasExample.as +++ b/spine-starling/spine-starling-example/src/StarlingAtlasExample.as @@ -22,7 +22,7 @@ public class StarlingAtlasExample extends Sprite { [Embed(source = "spineboy-starling.png")] static public const SpineboyAtlasTexture:Class; - [Embed(source = "spineboy.json", mimeType = "application/octet-stream")] + [Embed(source = "spineboy-starling.json", mimeType = "application/octet-stream")] static public const SpineboyJson:Class; private var skeleton:SkeletonAnimation; @@ -40,24 +40,24 @@ public class StarlingAtlasExample extends Sprite { stateData.setMixByName("jump", "walk", 0.4); stateData.setMixByName("jump", "jump", 0.2); - skeleton = new SkeletonAnimation(skeletonData, stateData); + skeleton = new SkeletonAnimation(skeletonData, false, stateData); skeleton.x = 320; skeleton.y = 420; - skeleton.state.onStart = function (trackIndex:int) : void { + skeleton.state.onStart.add(function (trackIndex:int) : void { trace(trackIndex + " start: " + skeleton.state.getCurrent(trackIndex)); - }; - skeleton.state.onEnd = function (trackIndex:int) : void { + }); + skeleton.state.onEnd.add(function (trackIndex:int) : void { trace(trackIndex + " end: " + skeleton.state.getCurrent(trackIndex)); - }; - skeleton.state.onComplete = function (trackIndex:int, count:int) : void { + }); + skeleton.state.onComplete.add(function (trackIndex:int, count:int) : void { trace(trackIndex + " complete: " + skeleton.state.getCurrent(trackIndex) + ", " + count); - }; - skeleton.state.onEvent = function (trackIndex:int, event:Event) : void { + }); + skeleton.state.onEvent.add(function (trackIndex:int, event:Event) : void { trace(trackIndex + " event: " + skeleton.state.getCurrent(trackIndex) + ", " + event.data.name + ": " + event.intValue + ", " + event.floatValue + ", " + event.stringValue); - }; - + }); + skeleton.state.setAnimationByName(0, "walk", true); skeleton.state.addAnimationByName(0, "jump", false, 3); skeleton.state.addAnimationByName(0, "walk", true, 0); diff --git a/spine-starling/spine-starling-example/src/goblins-ffd.atlas b/spine-starling/spine-starling-example/src/goblins-ffd.atlas index b977b07f6..5fefae2bb 100644 --- a/spine-starling/spine-starling-example/src/goblins-ffd.atlas +++ b/spine-starling/spine-starling-example/src/goblins-ffd.atlas @@ -4,288 +4,288 @@ format: RGBA8888 filter: Linear,Linear repeat: none dagger - rotate: false - xy: 2, 28 + rotate: true + xy: 372, 100 size: 26, 108 orig: 26, 108 offset: 0, 0 index: -1 goblin/eyes-closed rotate: false - xy: 137, 29 + xy: 2, 7 size: 34, 12 orig: 34, 12 offset: 0, 0 index: -1 goblin/head rotate: false - xy: 26, 357 + xy: 107, 36 size: 103, 66 orig: 103, 66 offset: 0, 0 index: -1 goblin/left-arm rotate: false - xy: 30, 28 + xy: 901, 56 size: 37, 35 orig: 37, 35 offset: 0, 0 index: -1 goblin/left-foot rotate: false - xy: 134, 260 + xy: 929, 95 size: 65, 31 orig: 65, 31 offset: 0, 0 index: -1 goblin/left-hand rotate: false - xy: 69, 25 + xy: 452, 2 size: 36, 41 orig: 36, 41 offset: 0, 0 index: -1 goblin/left-lower-leg - rotate: false - xy: 134, 293 + rotate: true + xy: 713, 93 size: 33, 70 orig: 33, 70 offset: 0, 0 index: -1 goblin/left-shoulder rotate: false - xy: 137, 43 + xy: 610, 44 size: 29, 44 orig: 29, 44 offset: 0, 0 index: -1 goblin/left-upper-leg - rotate: false - xy: 30, 65 + rotate: true + xy: 638, 93 size: 33, 73 orig: 33, 73 offset: 0, 0 index: -1 goblin/neck rotate: false - xy: 201, 387 + xy: 490, 2 size: 36, 41 orig: 36, 41 offset: 0, 0 index: -1 goblin/pelvis rotate: false - xy: 26, 140 + xy: 482, 45 size: 62, 43 orig: 62, 43 offset: 0, 0 index: -1 goblin/right-arm - rotate: false - xy: 171, 84 + rotate: true + xy: 690, 2 size: 23, 50 orig: 23, 50 offset: 0, 0 index: -1 goblin/right-foot rotate: false - xy: 134, 225 + xy: 771, 58 size: 63, 33 orig: 63, 33 offset: 0, 0 index: -1 goblin/right-hand rotate: false - xy: 204, 258 + xy: 940, 56 size: 36, 37 orig: 36, 37 offset: 0, 0 index: -1 goblin/right-lower-leg - rotate: false - xy: 201, 430 + rotate: true + xy: 482, 90 size: 36, 76 orig: 36, 76 offset: 0, 0 index: -1 goblin/right-shoulder - rotate: false - xy: 130, 89 + rotate: true + xy: 602, 3 size: 39, 45 orig: 39, 45 offset: 0, 0 index: -1 goblin/right-upper-leg - rotate: false - xy: 98, 214 + rotate: true + xy: 641, 57 size: 34, 63 orig: 34, 63 offset: 0, 0 index: -1 goblin/torso - rotate: false - xy: 131, 410 + rotate: true + xy: 212, 34 size: 68, 96 orig: 68, 96 offset: 0, 0 index: -1 goblin/undie-straps rotate: false - xy: 2, 7 + xy: 380, 5 size: 55, 19 orig: 55, 19 offset: 0, 0 index: -1 goblin/undies rotate: false - xy: 199, 227 + xy: 174, 5 size: 36, 29 orig: 36, 29 offset: 0, 0 index: -1 goblingirl/eyes-closed rotate: false - xy: 59, 2 + xy: 269, 11 size: 37, 21 orig: 37, 21 offset: 0, 0 index: -1 goblingirl/head rotate: false - xy: 26, 425 + xy: 2, 21 size: 103, 81 orig: 103, 81 offset: 0, 0 index: -1 goblingirl/left-arm - rotate: false - xy: 201, 190 + rotate: true + xy: 978, 56 size: 37, 35 orig: 37, 35 offset: 0, 0 index: -1 goblingirl/left-foot rotate: false - xy: 134, 192 + xy: 107, 3 size: 65, 31 orig: 65, 31 offset: 0, 0 index: -1 goblingirl/left-hand rotate: false - xy: 196, 109 + xy: 565, 2 size: 35, 40 orig: 35, 40 offset: 0, 0 index: -1 goblingirl/left-lower-leg - rotate: false - xy: 169, 293 + rotate: true + xy: 785, 93 size: 33, 70 orig: 33, 70 offset: 0, 0 index: -1 goblingirl/left-shoulder - rotate: false - xy: 107, 30 + rotate: true + xy: 690, 27 size: 28, 46 orig: 28, 46 offset: 0, 0 index: -1 goblingirl/left-upper-leg - rotate: false - xy: 65, 68 + rotate: true + xy: 857, 93 size: 33, 70 orig: 33, 70 offset: 0, 0 index: -1 goblingirl/neck rotate: false - xy: 204, 297 + xy: 528, 2 size: 35, 41 orig: 35, 41 offset: 0, 0 index: -1 goblingirl/pelvis rotate: false - xy: 131, 365 + xy: 546, 45 size: 62, 43 orig: 62, 43 offset: 0, 0 index: -1 goblingirl/right-arm rotate: false - xy: 100, 97 + xy: 452, 48 size: 28, 50 orig: 28, 50 offset: 0, 0 index: -1 goblingirl/right-foot rotate: false - xy: 134, 157 + xy: 836, 58 size: 63, 33 orig: 63, 33 offset: 0, 0 index: -1 goblingirl/right-hand - rotate: false - xy: 199, 151 + rotate: true + xy: 771, 20 size: 36, 37 orig: 36, 37 offset: 0, 0 index: -1 goblingirl/right-lower-leg - rotate: false - xy: 96, 279 + rotate: true + xy: 560, 90 size: 36, 76 orig: 36, 76 offset: 0, 0 index: -1 goblingirl/right-shoulder rotate: false - xy: 204, 340 + xy: 649, 10 size: 39, 45 orig: 39, 45 offset: 0, 0 index: -1 goblingirl/right-upper-leg - rotate: false - xy: 98, 149 + rotate: true + xy: 706, 57 size: 34, 63 orig: 34, 63 offset: 0, 0 index: -1 goblingirl/torso rotate: false - xy: 26, 259 + xy: 310, 2 size: 68, 96 orig: 68, 96 offset: 0, 0 index: -1 goblingirl/undie-straps rotate: false - xy: 134, 136 + xy: 212, 13 size: 55, 19 orig: 55, 19 offset: 0, 0 index: -1 goblingirl/undies rotate: false - xy: 196, 78 + xy: 810, 27 size: 36, 29 orig: 36, 29 offset: 0, 0 index: -1 shield rotate: false - xy: 26, 185 + xy: 380, 26 size: 70, 72 orig: 70, 72 offset: 0, 0 index: -1 spear - rotate: false - xy: 2, 138 + rotate: true + xy: 2, 104 size: 22, 368 orig: 22, 368 offset: 0, 0 diff --git a/spine-starling/spine-starling-example/src/goblins-ffd.json b/spine-starling/spine-starling-example/src/goblins-ffd.json index 163060444..67a624a36 100644 --- a/spine-starling/spine-starling-example/src/goblins-ffd.json +++ b/spine-starling/spine-starling-example/src/goblins-ffd.json @@ -759,6 +759,11 @@ }, "ffd": { "default": { + "left hand item": { + "spear": [ + { "time": 0 } + ] + }, "right hand item": { "dagger": [ { diff --git a/spine-starling/spine-starling-example/src/goblins-ffd.png b/spine-starling/spine-starling-example/src/goblins-ffd.png index f172361f2..a3daf0010 100644 Binary files a/spine-starling/spine-starling-example/src/goblins-ffd.png and b/spine-starling/spine-starling-example/src/goblins-ffd.png differ diff --git a/spine-starling/spine-starling-example/src/spineboy-starling.json b/spine-starling/spine-starling-example/src/spineboy-starling.json new file mode 100644 index 000000000..113e72c33 --- /dev/null +++ b/spine-starling/spine-starling-example/src/spineboy-starling.json @@ -0,0 +1,1002 @@ +{ +"bones": [ + { "name": "root" }, + { "name": "hip", "parent": "root", "x": 0.64, "y": 114.41 }, + { "name": "left upper leg", "parent": "hip", "length": 50.39, "x": 14.45, "y": 2.81, "rotation": -89.09 }, + { "name": "pelvis", "parent": "hip", "x": 1.41, "y": -6.57 }, + { "name": "right upper leg", "parent": "hip", "length": 45.76, "x": -18.27, "rotation": -101.13 }, + { "name": "torso", "parent": "hip", "length": 85.82, "x": -6.42, "y": 1.97, "rotation": 94.95 }, + { "name": "left lower leg", "parent": "left upper leg", "length": 56.45, "x": 51.78, "y": 3.46, "rotation": -16.65 }, + { "name": "left shoulder", "parent": "torso", "length": 44.19, "x": 78.96, "y": -15.75, "rotation": -156.96 }, + { "name": "neck", "parent": "torso", "length": 18.38, "x": 83.64, "y": -1.78, "rotation": 0.9 }, + { "name": "right lower leg", "parent": "right upper leg", "length": 58.52, "x": 50.21, "y": 0.6, "rotation": -10.7 }, + { "name": "right shoulder", "parent": "torso", "length": 49.95, "x": 81.9, "y": 6.79, "rotation": 130.6 }, + { "name": "head", "parent": "neck", "length": 68.28, "x": 19.09, "y": 6.97, "rotation": -8.94 }, + { "name": "left arm", "parent": "left shoulder", "length": 35.62, "x": 44.19, "y": -0.01, "rotation": 28.16 }, + { "name": "left foot", "parent": "left lower leg", "length": 46.5, "x": 64.02, "y": -8.67, "rotation": 102.43 }, + { "name": "right arm", "parent": "right shoulder", "length": 36.74, "x": 49.95, "y": -0.12, "rotation": 40.12 }, + { "name": "right foot", "parent": "right lower leg", "length": 45.45, "x": 64.88, "y": 0.04, "rotation": 110.3 }, + { "name": "left hand", "parent": "left arm", "length": 11.52, "x": 35.62, "y": 0.07, "rotation": 2.7 }, + { "name": "right hand", "parent": "right arm", "length": 15.32, "x": 36.9, "y": 0.34, "rotation": 2.35 } +], +"slots": [ + { "name": "left shoulder", "bone": "left shoulder", "attachment": "left-shoulder" }, + { "name": "left arm", "bone": "left arm", "attachment": "left-arm" }, + { "name": "left hand", "bone": "left hand", "attachment": "left-hand" }, + { "name": "left foot", "bone": "left foot", "attachment": "left-foot" }, + { "name": "left lower leg", "bone": "left lower leg", "attachment": "left-lower-leg" }, + { "name": "left upper leg", "bone": "left upper leg", "attachment": "left-upper-leg" }, + { "name": "pelvis", "bone": "pelvis", "attachment": "pelvis" }, + { "name": "right foot", "bone": "right foot", "attachment": "right-foot" }, + { "name": "right lower leg", "bone": "right lower leg", "attachment": "right-lower-leg" }, + { "name": "right upper leg", "bone": "right upper leg", "attachment": "right-upper-leg" }, + { "name": "torso", "bone": "torso", "attachment": "torso" }, + { "name": "neck", "bone": "neck", "attachment": "neck" }, + { "name": "head", "bone": "head", "attachment": "head" }, + { "name": "eyes", "bone": "head", "attachment": "eyes" }, + { "name": "right shoulder", "bone": "right shoulder", "attachment": "right-shoulder", "additive": true }, + { "name": "right arm", "bone": "right arm", "attachment": "right-arm" }, + { "name": "right hand", "bone": "right hand", "attachment": "right-hand" }, + { "name": "bb-head", "bone": "head", "attachment": "bb-head" } +], +"skins": { + "default": { + "bb-head": { + "bb-head": { + "type": "boundingbox", + "vertices": [ + 55.69696, + -44.60648, + 8.2226715, + -47.609646, + -11.244263, + -32.942703, + -0.05206299, + 35.835804, + 61.018433, + 43.227512, + 90.35846, + -16.054127, + 115.41275, + -32.817406, + 78.29431, + -56.05409 + ] + } + }, + "eyes": { + "eyes": { "x": 28.94, "y": -32.92, "rotation": -86.9, "width": 34, "height": 27 }, + "eyes-closed": { "x": 28.77, "y": -32.86, "rotation": -86.9, "width": 34, "height": 27 } + }, + "head": { + "head": { "x": 53.94, "y": -5.75, "rotation": -86.9, "width": 121, "height": 132 } + }, + "left arm": { + "left-arm": { "x": 15.11, "y": -0.44, "rotation": 33.84, "width": 35, "height": 29 } + }, + "left foot": { + "left-foot": { "x": 24.35, "y": 8.88, "rotation": 3.32, "width": 65, "height": 30 } + }, + "left hand": { + "left-hand": { "x": 0.75, "y": 1.86, "rotation": 31.14, "width": 35, "height": 38 } + }, + "left lower leg": { + "left-lower-leg": { "x": 24.55, "y": -1.92, "rotation": 105.75, "width": 49, "height": 64 } + }, + "left shoulder": { + "left-shoulder": { "x": 23.74, "y": 0.11, "rotation": 62.01, "width": 34, "height": 53 } + }, + "left upper leg": { + "left-upper-leg": { "x": 26.12, "y": -1.85, "rotation": 89.09, "width": 33, "height": 67 } + }, + "neck": { + "neck": { "x": 9.42, "y": -3.66, "rotation": -100.15, "width": 34, "height": 28 } + }, + "pelvis": { + "pelvis": { "x": -4.83, "y": 10.62, "width": 63, "height": 47 } + }, + "right arm": { + "right-arm": { "x": 18.34, "y": -2.64, "rotation": 94.32, "width": 21, "height": 45 } + }, + "right foot": { + "right-foot": { "x": 19.02, "y": 8.47, "rotation": 1.52, "width": 67, "height": 30 } + }, + "right hand": { + "right-hand": { "x": 6.82, "y": 1.25, "rotation": 91.96, "width": 32, "height": 32 } + }, + "right lower leg": { + "right-lower-leg": { "x": 23.28, "y": -2.59, "rotation": 111.83, "width": 51, "height": 64 } + }, + "right shoulder": { + "right-shoulder": { "x": 25.86, "y": 0.03, "rotation": 134.44, "width": 52, "height": 51 } + }, + "right upper leg": { + "right-upper-leg": { "x": 23.03, "y": 0.25, "rotation": 101.13, "width": 44, "height": 70 } + }, + "torso": { + "torso": { "x": 44.57, "y": -7.08, "rotation": -94.95, "width": 68, "height": 92 } + } + } +}, +"events": { + "behind": {}, + "headAttach": {}, + "headPop": {} +}, +"animations": { + "drawOrder": { + "bones": { + "head": { + "rotate": [ + { "time": 0, "angle": 0 }, + { "time": 0.4827, "angle": -23.11 }, + { "time": 0.8965, "angle": -56.45 }, + { "time": 1.3103, "angle": 1.38 }, + { "time": 1.7931, "angle": 36.12 }, + { "time": 2.1379, "angle": 1.24 }, + { "time": 2.6206, "angle": -37.12 }, + { "time": 2.9666, "angle": 2.07 }, + { "time": 3.4666, "angle": 34.72 }, + { "time": 3.9, "angle": 359.99 } + ], + "translate": [ + { + "time": 0, + "x": 0, + "y": 0, + "curve": [ 0.19, 0.4, 0.586, 0.75 ] + }, + { + "time": 0.2758, + "x": 57.88, + "y": -35.72, + "curve": [ 0.39, 0.54, 0.632, 0.72 ] + }, + { + "time": 0.4827, + "x": 87.26, + "y": -87.89, + "curve": [ 0.325, 0.23, 0.587, 0.36 ] + }, + { + "time": 0.6896, + "x": 28.89, + "y": -114.62, + "curve": [ 0.383, 0.23, 0.736, 0.55 ] + }, + { + "time": 0.8965, + "x": -76.58, + "y": -124.98, + "curve": [ 0.129, 0.21, 0.547, 0.64 ] + }, + { + "time": 1.1034, + "x": -154.37, + "y": -77.13, + "curve": [ 0.354, 0.48, 0.729, 0.9 ] + }, + { + "time": 1.3103, + "x": -181.02, + "y": 18.56, + "curve": [ 0.063, 0.15, 0.52, 0.62 ] + }, + { + "time": 1.5862, + "x": -150.38, + "y": 128.67, + "curve": [ 0.381, 0.54, 0.778, 1 ] + }, + { + "time": 1.7931, + "x": -112.08, + "y": 146.28, + "curve": [ 0.242, 0, 0.626, 0.45 ] + }, + { + "time": 1.931, + "x": -63.7, + "y": 111.22, + "curve": [ 0.398, 0.35, 0.786, 0.76 ] + }, + { + "time": 2.1379, + "x": -48.94, + "y": -1.55, + "curve": [ 0.188, 0.21, 0.575, 0.61 ] + }, + { + "time": 2.3448, + "x": -91.69, + "y": -91.93, + "curve": [ 0.362, 0.51, 0.766, 1 ] + }, + { + "time": 2.6206, + "x": -142.79, + "y": -126.83, + "curve": [ 0.227, 0.34, 0.593, 0.75 ] + }, + { + "time": 2.7586, + "x": -176.7, + "y": -98.32, + "curve": [ 0.26, 0.4, 0.612, 0.71 ] + }, + { + "time": 2.8965, + "x": -163.95, + "y": -24.04, + "curve": [ 0.338, 0.37, 0.676, 0.71 ] + }, + { + "time": 2.9655, + "x": -150.17, + "y": 10.71, + "curve": [ 0.387, 0.61, 0.741, 1 ] + }, + { + "time": 3.1034, + "x": -102.44, + "y": 45.92, + "curve": [ 0.31, 0.24, 0.648, 0.58 ] + }, + { + "time": 3.2413, + "x": -53.99, + "y": 70.39, + "curve": [ 0.325, 0.29, 0.663, 0.63 ] + }, + { + "time": 3.3793, + "x": 1.88, + "y": 55.54, + "curve": [ 0.387, 0.33, 0.769, 0.73 ] + }, + { + "time": 3.5862, + "x": 34.26, + "y": 36.13, + "curve": [ 0.206, 0.28, 0.596, 0.67 ] + }, + { + "time": 3.7931, + "x": 23.94, + "y": 1.01, + "curve": [ 0.373, 0.56, 0.759, 1 ] + }, + { "time": 4, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0.8275, "x": 1, "y": 1 }, + { "time": 1.3103, "x": 0.742, "y": 0.742 }, + { "time": 1.7931, "x": 1, "y": 1 }, + { "time": 2.1379, "x": 1.502, "y": 1.502 }, + { "time": 2.6206, "x": 1, "y": 1 }, + { "time": 2.9655, "x": 0.707, "y": 0.707 }, + { "time": 3.3793, "x": 1, "y": 1 } + ] + } + }, + "events": [ + { "time": 0, "name": "headPop", "string": "pop.wav" }, + { "time": 1.3103, "name": "behind" }, + { "time": 2.9655, "name": "behind" }, + { "time": 4, "name": "headAttach", "string": "attach.wav" } + ], + "draworder": [ + { + "time": 0.6206, + "offsets": [ + { "slot": "head", "offset": -12 }, + { "slot": "eyes", "offset": -12 } + ] + }, + { + "time": 1.7931, + "offsets": [ + { "slot": "head", "offset": 3 }, + { "slot": "eyes", "offset": 3 } + ] + }, + { + "time": 2.6206, + "offsets": [ + { "slot": "head", "offset": -12 }, + { "slot": "eyes", "offset": -12 } + ] + }, + { "time": 3.5862 } + ] + }, + "jump": { + "bones": { + "hip": { + "rotate": [ + { "time": 0, "angle": 0, "curve": "stepped" }, + { "time": 0.9333, "angle": 0, "curve": "stepped" }, + { "time": 1.3666, "angle": 0 } + ], + "translate": [ + { "time": 0, "x": -11.57, "y": -3 }, + { "time": 0.2333, "x": -16.2, "y": -19.43 }, + { + "time": 0.3333, + "x": 7.66, + "y": -8.48, + "curve": [ 0.057, 0.06, 0.712, 1 ] + }, + { "time": 0.3666, "x": 15.38, "y": 5.01 }, + { "time": 0.4666, "x": -7.84, "y": 57.22 }, + { + "time": 0.6, + "x": -10.81, + "y": 96.34, + "curve": [ 0.241, 0, 1, 1 ] + }, + { "time": 0.7333, "x": -7.01, "y": 54.7 }, + { "time": 0.8, "x": -10.58, "y": 32.2 }, + { "time": 0.9333, "x": -31.99, "y": 0.45 }, + { "time": 1.0666, "x": -12.48, "y": -29.47 }, + { "time": 1.3666, "x": -11.57, "y": -3 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left upper leg": { + "rotate": [ + { "time": 0, "angle": 17.13 }, + { "time": 0.2333, "angle": 44.35 }, + { "time": 0.3333, "angle": 16.46 }, + { "time": 0.4, "angle": -9.88 }, + { "time": 0.4666, "angle": -11.42 }, + { "time": 0.5666, "angle": 23.46 }, + { "time": 0.7666, "angle": 71.82 }, + { "time": 0.9333, "angle": 65.53 }, + { "time": 1.0666, "angle": 51.01 }, + { "time": 1.3666, "angle": 17.13 } + ], + "translate": [ + { "time": 0, "x": -3, "y": -2.25, "curve": "stepped" }, + { "time": 0.9333, "x": -3, "y": -2.25, "curve": "stepped" }, + { "time": 1.3666, "x": -3, "y": -2.25 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left lower leg": { + "rotate": [ + { "time": 0, "angle": -16.25 }, + { "time": 0.2333, "angle": -52.21 }, + { "time": 0.4, "angle": 15.04 }, + { "time": 0.4666, "angle": -8.95 }, + { "time": 0.5666, "angle": -39.53 }, + { "time": 0.7666, "angle": -27.27 }, + { "time": 0.9333, "angle": -3.52 }, + { "time": 1.0666, "angle": -61.92 }, + { "time": 1.3666, "angle": -16.25 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left foot": { + "rotate": [ + { "time": 0, "angle": 0.33 }, + { "time": 0.2333, "angle": 6.2 }, + { "time": 0.3333, "angle": 14.73 }, + { "time": 0.4, "angle": -15.54 }, + { "time": 0.4333, "angle": -21.2 }, + { "time": 0.5666, "angle": -7.55 }, + { "time": 0.7666, "angle": -0.67 }, + { "time": 0.9333, "angle": -0.58 }, + { "time": 1.0666, "angle": 14.64 }, + { "time": 1.3666, "angle": 0.33 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right upper leg": { + "rotate": [ + { "time": 0, "angle": 25.97 }, + { "time": 0.2333, "angle": 46.43 }, + { "time": 0.3333, "angle": 22.61 }, + { "time": 0.4, "angle": 2.13 }, + { + "time": 0.4666, + "angle": 0.04, + "curve": [ 0, 0, 0.637, 0.98 ] + }, + { "time": 0.6, "angle": 65.55 }, + { "time": 0.7666, "angle": 64.93 }, + { "time": 0.9333, "angle": 41.08 }, + { "time": 1.0666, "angle": 66.25 }, + { "time": 1.3666, "angle": 25.97 } + ], + "translate": [ + { "time": 0, "x": 5.74, "y": 0.61 }, + { "time": 0.2333, "x": 4.79, "y": 1.79 }, + { "time": 0.3333, "x": 6.05, "y": -4.55 }, + { "time": 0.9333, "x": 4.79, "y": 1.79, "curve": "stepped" }, + { "time": 1.0666, "x": 4.79, "y": 1.79 }, + { "time": 1.3666, "x": 5.74, "y": 0.61 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right lower leg": { + "rotate": [ + { "time": 0, "angle": -27.46 }, + { "time": 0.2333, "angle": -64.03 }, + { "time": 0.4, "angle": -48.36 }, + { "time": 0.5666, "angle": -76.86 }, + { "time": 0.7666, "angle": -26.89 }, + { "time": 0.9, "angle": -18.97 }, + { "time": 0.9333, "angle": -14.18 }, + { "time": 1.0666, "angle": -80.45 }, + { "time": 1.3666, "angle": -27.46 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right foot": { + "rotate": [ + { "time": 0, "angle": 1.08 }, + { "time": 0.2333, "angle": 16.02 }, + { "time": 0.3, "angle": 12.94 }, + { "time": 0.3333, "angle": 15.16 }, + { "time": 0.4, "angle": -14.7 }, + { "time": 0.4333, "angle": -12.85 }, + { "time": 0.4666, "angle": -19.18 }, + { "time": 0.5666, "angle": -15.82 }, + { "time": 0.6, "angle": -3.59 }, + { "time": 0.7666, "angle": -3.56 }, + { "time": 0.9333, "angle": 1.86 }, + { "time": 1.0666, "angle": 16.02 }, + { "time": 1.3666, "angle": 1.08 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "torso": { + "rotate": [ + { "time": 0, "angle": -13.35 }, + { "time": 0.2333, "angle": -48.95 }, + { "time": 0.4333, "angle": -35.77 }, + { "time": 0.6, "angle": -4.59 }, + { "time": 0.7666, "angle": 14.61 }, + { "time": 0.9333, "angle": 15.74 }, + { "time": 1.0666, "angle": -32.44 }, + { "time": 1.3666, "angle": -13.35 } + ], + "translate": [ + { "time": 0, "x": -3.67, "y": 1.68, "curve": "stepped" }, + { "time": 0.9333, "x": -3.67, "y": 1.68, "curve": "stepped" }, + { "time": 1.3666, "x": -3.67, "y": 1.68 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "neck": { + "rotate": [ + { "time": 0, "angle": 12.78 }, + { "time": 0.2333, "angle": 16.46 }, + { "time": 0.4, "angle": 26.49 }, + { "time": 0.6, "angle": 15.51 }, + { "time": 0.7666, "angle": 1.34 }, + { "time": 0.9333, "angle": 2.35 }, + { "time": 1.0666, "angle": 6.08 }, + { "time": 1.3, "angle": 21.23 }, + { "time": 1.3666, "angle": 12.78 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "head": { + "rotate": [ + { "time": 0, "angle": 5.19 }, + { "time": 0.2333, "angle": 20.27 }, + { "time": 0.4, "angle": 15.27 }, + { "time": 0.6, "angle": -24.69 }, + { "time": 0.7666, "angle": -11.02 }, + { "time": 0.9333, "angle": -24.38 }, + { "time": 1.0666, "angle": 11.99 }, + { "time": 1.3, "angle": 4.86 }, + { "time": 1.3666, "angle": 5.19 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left shoulder": { + "rotate": [ + { + "time": 0, + "angle": 0.05, + "curve": [ 0, 0, 0.62, 1 ] + }, + { + "time": 0.2333, + "angle": 279.66, + "curve": [ 0.218, 0.67, 0.66, 0.99 ] + }, + { + "time": 0.5, + "angle": 62.27, + "curve": [ 0.462, 0, 0.764, 0.58 ] + }, + { "time": 0.9333, "angle": 28.91 }, + { "time": 1.0666, "angle": -8.62 }, + { "time": 1.1666, "angle": -18.43 }, + { "time": 1.3666, "angle": 0.05 } + ], + "translate": [ + { "time": 0, "x": -1.76, "y": 0.56, "curve": "stepped" }, + { "time": 0.9333, "x": -1.76, "y": 0.56, "curve": "stepped" }, + { "time": 1.3666, "x": -1.76, "y": 0.56 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left hand": { + "rotate": [ + { "time": 0, "angle": 11.58, "curve": "stepped" }, + { "time": 0.9333, "angle": 11.58, "curve": "stepped" }, + { "time": 1.3666, "angle": 11.58 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "left arm": { + "rotate": [ + { "time": 0, "angle": 0.51 }, + { "time": 0.4333, "angle": 12.82 }, + { "time": 0.6, "angle": 47.55 }, + { "time": 0.9333, "angle": 12.82 }, + { "time": 1.1666, "angle": -6.5 }, + { "time": 1.3666, "angle": 0.51 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right shoulder": { + "rotate": [ + { + "time": 0, + "angle": 43.82, + "curve": [ 0, 0, 0.62, 1 ] + }, + { + "time": 0.2333, + "angle": -8.74, + "curve": [ 0.304, 0.58, 0.709, 0.97 ] + }, + { + "time": 0.5333, + "angle": -208.02, + "curve": [ 0.462, 0, 0.764, 0.58 ] + }, + { "time": 0.9333, "angle": -246.72 }, + { "time": 1.0666, "angle": -307.13 }, + { "time": 1.1666, "angle": 37.15 }, + { "time": 1.3666, "angle": 43.82 } + ], + "translate": [ + { "time": 0, "x": -7.84, "y": 7.19, "curve": "stepped" }, + { "time": 0.9333, "x": -7.84, "y": 7.19, "curve": "stepped" }, + { "time": 1.3666, "x": -7.84, "y": 7.19 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right arm": { + "rotate": [ + { "time": 0, "angle": -4.02 }, + { "time": 0.6, "angle": 17.5 }, + { "time": 0.9333, "angle": -4.02 }, + { "time": 1.1666, "angle": -16.72 }, + { "time": 1.3666, "angle": -4.02 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "right hand": { + "rotate": [ + { "time": 0, "angle": 22.92, "curve": "stepped" }, + { "time": 0.9333, "angle": 22.92, "curve": "stepped" }, + { "time": 1.3666, "angle": 22.92 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" }, + { "time": 1.3666, "x": 0, "y": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 0.9333, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + }, + "root": { + "rotate": [ + { "time": 0, "angle": 0 }, + { "time": 0.4333, "angle": -14.52 }, + { "time": 0.8, "angle": 9.86 }, + { "time": 1.3666, "angle": 0 } + ], + "scale": [ + { "time": 0, "x": 1, "y": 1, "curve": "stepped" }, + { "time": 1.3666, "x": 1, "y": 1 } + ] + } + } + }, + "walk": { + "bones": { + "left upper leg": { + "rotate": [ + { "time": 0, "angle": -26.55 }, + { "time": 0.1333, "angle": -8.78 }, + { "time": 0.2666, "angle": 9.51 }, + { "time": 0.4, "angle": 30.74 }, + { "time": 0.5333, "angle": 25.33 }, + { "time": 0.6666, "angle": 26.11 }, + { "time": 0.8, "angle": -7.7 }, + { "time": 0.9333, "angle": -21.19 }, + { "time": 1.0666, "angle": -26.55 } + ], + "translate": [ + { "time": 0, "x": -3, "y": -2.25 }, + { "time": 0.4, "x": -2.18, "y": -2.25 }, + { "time": 1.0666, "x": -3, "y": -2.25 } + ] + }, + "right upper leg": { + "rotate": [ + { "time": 0, "angle": 42.45 }, + { "time": 0.1333, "angle": 52.1 }, + { "time": 0.2666, "angle": 5.96 }, + { "time": 0.5333, "angle": -16.93 }, + { "time": 0.6666, "angle": 1.89 }, + { + "time": 0.8, + "angle": 28.06, + "curve": [ 0.462, 0.11, 1, 1 ] + }, + { + "time": 0.9333, + "angle": 58.68, + "curve": [ 0.5, 0.02, 1, 1 ] + }, + { "time": 1.0666, "angle": 42.45 } + ], + "translate": [ + { "time": 0, "x": 8.11, "y": -2.36 }, + { "time": 0.1333, "x": 10.03, "y": -2.56 }, + { "time": 0.4, "x": 2.76, "y": -2.97 }, + { "time": 0.5333, "x": 2.76, "y": -2.81 }, + { "time": 0.9333, "x": 8.67, "y": -2.54 }, + { "time": 1.0666, "x": 8.11, "y": -2.36 } + ] + }, + "left lower leg": { + "rotate": [ + { "time": 0, "angle": -10.21 }, + { "time": 0.1333, "angle": -55.64 }, + { "time": 0.2666, "angle": -68.12 }, + { "time": 0.5333, "angle": 5.11 }, + { "time": 0.6666, "angle": -28.29 }, + { "time": 0.8, "angle": 4.08 }, + { "time": 0.9333, "angle": 3.53 }, + { "time": 1.0666, "angle": -10.21 } + ] + }, + "left foot": { + "rotate": [ + { "time": 0, "angle": -3.69 }, + { "time": 0.1333, "angle": -10.42 }, + { "time": 0.2666, "angle": -17.14 }, + { "time": 0.4, "angle": -2.83 }, + { "time": 0.5333, "angle": -3.87 }, + { "time": 0.6666, "angle": 2.78 }, + { "time": 0.8, "angle": 1.68 }, + { "time": 0.9333, "angle": -8.54 }, + { "time": 1.0666, "angle": -3.69 } + ] + }, + "right shoulder": { + "rotate": [ + { + "time": 0, + "angle": 20.89, + "curve": [ 0.264, 0, 0.75, 1 ] + }, + { + "time": 0.1333, + "angle": 3.72, + "curve": [ 0.272, 0, 0.841, 1 ] + }, + { "time": 0.6666, "angle": -278.28 }, + { "time": 1.0666, "angle": 20.89 } + ], + "translate": [ + { "time": 0, "x": -7.84, "y": 7.19 }, + { "time": 0.1333, "x": -6.36, "y": 6.42 }, + { "time": 0.6666, "x": -11.07, "y": 5.25 }, + { "time": 1.0666, "x": -7.84, "y": 7.19 } + ] + }, + "right arm": { + "rotate": [ + { + "time": 0, + "angle": -4.02, + "curve": [ 0.267, 0, 0.804, 0.99 ] + }, + { + "time": 0.1333, + "angle": -13.99, + "curve": [ 0.341, 0, 1, 1 ] + }, + { + "time": 0.6666, + "angle": 36.54, + "curve": [ 0.307, 0, 0.787, 0.99 ] + }, + { "time": 1.0666, "angle": -4.02 } + ] + }, + "right hand": { + "rotate": [ + { "time": 0, "angle": 22.92 }, + { "time": 0.4, "angle": -8.97 }, + { "time": 0.6666, "angle": 0.51 }, + { "time": 1.0666, "angle": 22.92 } + ] + }, + "left shoulder": { + "rotate": [ + { "time": 0, "angle": -1.47 }, + { "time": 0.1333, "angle": 13.6 }, + { "time": 0.6666, "angle": 280.74 }, + { "time": 1.0666, "angle": -1.47 } + ], + "translate": [ + { "time": 0, "x": -1.76, "y": 0.56 }, + { "time": 0.6666, "x": -2.47, "y": 8.14 }, + { "time": 1.0666, "x": -1.76, "y": 0.56 } + ] + }, + "left hand": { + "rotate": [ + { + "time": 0, + "angle": 11.58, + "curve": [ 0.169, 0.37, 0.632, 1.55 ] + }, + { + "time": 0.1333, + "angle": 28.13, + "curve": [ 0.692, 0, 0.692, 0.99 ] + }, + { + "time": 0.6666, + "angle": -27.42, + "curve": [ 0.117, 0.41, 0.738, 1.76 ] + }, + { "time": 0.8, "angle": -36.32 }, + { "time": 1.0666, "angle": 11.58 } + ] + }, + "left arm": { + "rotate": [ + { "time": 0, "angle": -8.27 }, + { "time": 0.1333, "angle": 18.43 }, + { "time": 0.6666, "angle": 0.88 }, + { "time": 1.0666, "angle": -8.27 } + ] + }, + "torso": { + "rotate": [ + { "time": 0, "angle": -10.28 }, + { + "time": 0.1333, + "angle": -15.38, + "curve": [ 0.545, 0, 1, 1 ] + }, + { + "time": 0.4, + "angle": -9.78, + "curve": [ 0.58, 0.17, 1, 1 ] + }, + { "time": 0.6666, "angle": -15.75 }, + { "time": 0.9333, "angle": -7.06 }, + { "time": 1.0666, "angle": -10.28 } + ], + "translate": [ + { "time": 0, "x": -3.67, "y": 1.68 }, + { "time": 0.1333, "x": -3.67, "y": 0.68 }, + { "time": 0.4, "x": -3.67, "y": 1.97 }, + { "time": 0.6666, "x": -3.67, "y": -0.14 }, + { "time": 1.0666, "x": -3.67, "y": 1.68 } + ] + }, + "right foot": { + "rotate": [ + { "time": 0, "angle": -5.25 }, + { "time": 0.2666, "angle": -4.08 }, + { "time": 0.4, "angle": -6.45 }, + { "time": 0.5333, "angle": -5.39 }, + { "time": 0.8, "angle": -11.68 }, + { "time": 0.9333, "angle": 0.46 }, + { "time": 1.0666, "angle": -5.25 } + ] + }, + "right lower leg": { + "rotate": [ + { "time": 0, "angle": -3.39 }, + { "time": 0.1333, "angle": -45.53 }, + { "time": 0.2666, "angle": -2.59 }, + { "time": 0.5333, "angle": -19.53 }, + { "time": 0.6666, "angle": -64.8 }, + { + "time": 0.8, + "angle": -82.56, + "curve": [ 0.557, 0.18, 1, 1 ] + }, + { "time": 1.0666, "angle": -3.39 } + ] + }, + "hip": { + "rotate": [ + { "time": 0, "angle": 0, "curve": "stepped" }, + { "time": 1.0666, "angle": 0 } + ], + "translate": [ + { "time": 0, "x": 0, "y": 0 }, + { + "time": 0.1333, + "x": 0, + "y": -7.61, + "curve": [ 0.272, 0.86, 1, 1 ] + }, + { "time": 0.4, "x": 0, "y": 8.7 }, + { "time": 0.5333, "x": 0, "y": -0.41 }, + { + "time": 0.6666, + "x": 0, + "y": -7.05, + "curve": [ 0.235, 0.89, 1, 1 ] + }, + { "time": 0.8, "x": 0, "y": 2.92 }, + { "time": 0.9333, "x": 0, "y": 6.78 }, + { "time": 1.0666, "x": 0, "y": 0 } + ] + }, + "neck": { + "rotate": [ + { "time": 0, "angle": 3.6 }, + { "time": 0.1333, "angle": 17.49 }, + { "time": 0.2666, "angle": 6.1 }, + { "time": 0.4, "angle": 3.45 }, + { "time": 0.5333, "angle": 5.17 }, + { "time": 0.6666, "angle": 18.36 }, + { "time": 0.8, "angle": 6.09 }, + { "time": 0.9333, "angle": 2.28 }, + { "time": 1.0666, "angle": 3.6 } + ] + }, + "head": { + "rotate": [ + { + "time": 0, + "angle": 3.6, + "curve": [ 0, 0, 0.704, 1.61 ] + }, + { "time": 0.1666, "angle": -0.2 }, + { "time": 0.2666, "angle": 6.1 }, + { "time": 0.4, "angle": 3.45 }, + { + "time": 0.5333, + "angle": 5.17, + "curve": [ 0, 0, 0.704, 1.61 ] + }, + { "time": 0.7, "angle": 1.1 }, + { "time": 0.8, "angle": 6.09 }, + { "time": 0.9333, "angle": 2.28 }, + { "time": 1.0666, "angle": 3.6 } + ] + } + } + } +} +} \ No newline at end of file diff --git a/spine-starling/spine-starling-example/src/spineboy.json b/spine-starling/spine-starling-example/src/spineboy.json index 1ffa7aad5..7b4497712 100644 --- a/spine-starling/spine-starling-example/src/spineboy.json +++ b/spine-starling/spine-starling-example/src/spineboy.json @@ -54,7 +54,8 @@ { "name": "goggles", "bone": "head", "attachment": "goggles" }, { "name": "front_bracer", "bone": "front_bracer", "attachment": "front_bracer" }, { "name": "front_fist", "bone": "front_fist", "attachment": "front_fist_closed" }, - { "name": "muzzle", "bone": "gunTip", "additive": true } + { "name": "muzzle", "bone": "gunTip", "additive": true }, + { "name": "head-bb", "bone": "head" } ], "skins": { "default": { @@ -92,6 +93,12 @@ "head": { "head": { "x": 128.95, "y": 0.29, "rotation": -70.63, "width": 271, "height": 298 } }, + "head-bb": { + "head": { + "type": "boundingbox", + "vertices": [ -19.143097, -70.30209, 40.80313, -118.074234, 257.77155, -115.61827, 285.16193, 57.18005, 120.77191, 164.95125, -5.067627, 76.94907 ] + } + }, "mouth": { "mouth_grind": { "x": 23.68, "y": -32.23, "rotation": -70.63, "width": 93, "height": 59 }, "mouth_oooo": { "x": 23.68, "y": -32.23, "rotation": -70.63, "width": 93, "height": 59 }, diff --git a/spine-starling/spine-starling-example/src/spineboy.png b/spine-starling/spine-starling-example/src/spineboy.png index b43262310..dce2fe3e2 100644 Binary files a/spine-starling/spine-starling-example/src/spineboy.png and b/spine-starling/spine-starling-example/src/spineboy.png differ diff --git a/spine-starling/spine-starling/.actionScriptProperties b/spine-starling/spine-starling/.actionScriptProperties index 4fc55b79c..3989493fb 100644 --- a/spine-starling/spine-starling/.actionScriptProperties +++ b/spine-starling/spine-starling/.actionScriptProperties @@ -10,7 +10,7 @@ - + diff --git a/spine-starling/spine-starling/libs/starling-1.5.1.swc b/spine-starling/spine-starling/libs/starling-1.5.1.swc new file mode 100644 index 000000000..7f019ca67 Binary files /dev/null and b/spine-starling/spine-starling/libs/starling-1.5.1.swc differ diff --git a/spine-starling/spine-starling/libs/starling-1.5rc.swc b/spine-starling/spine-starling/libs/starling-1.5rc.swc deleted file mode 100644 index 5c074acdb..000000000 Binary files a/spine-starling/spine-starling/libs/starling-1.5rc.swc and /dev/null differ diff --git a/spine-starling/spine-starling/src/spine/starling/PolygonBatch.as b/spine-starling/spine-starling/src/spine/starling/PolygonBatch.as new file mode 100644 index 000000000..f0c4b464c --- /dev/null +++ b/spine-starling/spine-starling/src/spine/starling/PolygonBatch.as @@ -0,0 +1,272 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.1 + * + * Copyright (c) 2013, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to install, execute and perform the Spine Runtimes + * Software (the "Software") solely for internal use. Without the written + * permission of Esoteric Software (typically granted by licensing Spine), you + * may not (a) modify, translate, adapt or otherwise create derivative works, + * improvements of the Software or develop new applications using the Software + * or (b) remove, delete, alter or obscure any trademarks or any copyright, + * trademark, patent or other intellectual property or proprietary rights + * notices on or in the Software, including any copy thereof. Redistributions + * in binary or source form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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.starling { +import flash.display3D.Context3D; +import flash.display3D.Context3DProgramType; +import flash.display3D.Context3DTextureFormat; +import flash.display3D.Context3DVertexBufferFormat; +import flash.display3D.IndexBuffer3D; +import flash.display3D.Program3D; +import flash.display3D.VertexBuffer3D; +import flash.events.Event; +import flash.geom.Matrix; +import flash.geom.Point; +import flash.utils.Dictionary; + +import starling.core.RenderSupport; +import starling.core.Starling; +import starling.display.BlendMode; +import starling.textures.Texture; +import starling.textures.TextureSmoothing; +import starling.utils.MatrixUtil; +import starling.utils.VertexData; + +internal class PolygonBatch { + static private var _tempPoint:Point = new Point(); + static private var _renderAlpha:Vector. = new [1.0, 1.0, 1.0, 1.0]; + static private var _programNameCache:Dictionary = new Dictionary(); + + private var _capacity:int; + public var maxCapacity:int = 2000; + public var smoothing:String = "bilinear"; + + private var _texture:Texture; + private var _support:RenderSupport; + private var _programBits:uint; + private var _blendMode:String; + private var _additive:Boolean; + + private var _verticesCount:int; + private var _vertices:Vector. = new []; + private var _verticesBuffer:VertexBuffer3D; + + private var _trianglesCount:int; + private var _triangles:Vector. = new []; + private var _trianglesBuffer:IndexBuffer3D; + + public function PolygonBatch () { + resize(32); + Starling.current.stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContextCreated, false, 0, true); + } + + public function dispose () : void { + Starling.current.stage3D.removeEventListener(Event.CONTEXT3D_CREATE, onContextCreated); + if (_verticesBuffer) _verticesBuffer.dispose(); + if (_trianglesBuffer) _trianglesBuffer.dispose(); + } + + public function begin (support:RenderSupport, alpha:Number, blendMode:String) : void { + _support = support; + _renderAlpha[3] = alpha; + _programBits = 0xffffffff; + + support.finishQuadBatch(); + + support.blendMode = blendMode; + support.applyBlendMode(true); + _blendMode = support.blendMode; + _additive = false; + + var context:Context3D = Starling.context; + context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 0, _renderAlpha, 1); + context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 1, support.mvpMatrix3D, true); + + var verticesBuffer:VertexBuffer3D = _verticesBuffer; + if (verticesBuffer) { + context.setVertexBufferAt(0, verticesBuffer, VertexData.POSITION_OFFSET, Context3DVertexBufferFormat.FLOAT_2); + context.setVertexBufferAt(1, verticesBuffer, VertexData.COLOR_OFFSET, Context3DVertexBufferFormat.FLOAT_4); + context.setVertexBufferAt(2, verticesBuffer, VertexData.TEXCOORD_OFFSET, Context3DVertexBufferFormat.FLOAT_2); + } + } + + public function end () : void { + flush(); + var context:Context3D = Starling.context; + context.setTextureAt(0, null); + context.setVertexBufferAt(2, null); + context.setVertexBufferAt(1, null); + context.setVertexBufferAt(0, null); + } + + public function add (texture:Texture, vertices:Vector., vl:int, uvs:Vector., triangles:Vector., + r:Number, g:Number, b:Number, a:Number, additive:Boolean, matrix:Matrix) : void { + if (additive != _additive) { + _additive = additive; + flush(); + _support.blendMode = additive ? BlendMode.ADD : _blendMode; + _support.applyBlendMode(true); + } + + if (texture != _texture) { + flush(); + _texture = texture; + } + + var tl:int = triangles.length; + var vc:int = _verticesCount, tc:int = _trianglesCount; + var firstVertex:int = vc >> 3; + if (firstVertex + (vl >> 1) > _capacity) resize(vl >> 1); + if (tc + tl > _triangles.length) resize(tl / 3); + + var i:int, t:Vector. = _triangles; + for (i = 0; i < tl; i += 3, tc += 3) { + t[tc] = firstVertex + triangles[i]; + t[int(tc + 1)] = firstVertex + triangles[int(i + 1)]; + t[int(tc + 2)] = firstVertex + triangles[int(i + 2)]; + } + _trianglesCount = tc; + + var v:Vector. = _vertices; + if (matrix) { + var point:Point = _tempPoint; + for (i = 0; i < vl; i += 2, vc += 8) { + MatrixUtil.transformCoords(matrix, vertices[i], vertices[int(i + 1)], point); + v[vc] = point.x; + v[int(vc + 1)] = point.y; + v[int(vc + 2)] = r; + v[int(vc + 3)] = g; + v[int(vc + 4)] = b; + v[int(vc + 5)] = a; + v[int(vc + 6)] = uvs[i]; + v[int(vc + 7)] = uvs[int(i + 1)]; + } + } else { + for (i = 0; i < vl; i += 2, vc += 8) { + v[vc] = vertices[i]; + v[int(vc + 1)] = vertices[int(i + 1)]; + v[int(vc + 2)] = r; + v[int(vc + 3)] = g; + v[int(vc + 4)] = b; + v[int(vc + 5)] = a; + v[int(vc + 6)] = uvs[i]; + v[int(vc + 7)] = uvs[int(i + 1)]; + } + } + _verticesCount = vc; + } + + private function resize (additional:int) : void { + var newCapacity:int = (_verticesCount >> 3) + additional; + if (newCapacity > maxCapacity) { + flush(); + newCapacity = additional; + if (newCapacity < _capacity) return; + if (newCapacity > maxCapacity) throw new ArgumentError("Too many vertices: " + newCapacity + " > " + maxCapacity); + } + _capacity = newCapacity; + _vertices.length = newCapacity << 3; + _triangles.length = newCapacity * 3; + _verticesBuffer = null; + _trianglesBuffer = null; + } + + public function flush () : void { + if (!_verticesCount) return; + + var context:Context3D = Starling.context; + + if (!_verticesBuffer) { + _verticesBuffer = context.createVertexBuffer(_capacity, 8); + var count:int = _verticesCount >> 3; + _verticesBuffer.uploadFromVector(_vertices, 0, count); + var verticesTemp:Vector. = new []; // Buffer must be filled completely once. + verticesTemp.length = (_capacity << 3) - _verticesCount; + _verticesBuffer.uploadFromVector(verticesTemp, count, _capacity - count); + verticesTemp = null; + + _trianglesBuffer = context.createIndexBuffer(_capacity * 3); + _trianglesBuffer.uploadFromVector(_triangles, 0, _trianglesCount); + var trianglesTemp:Vector. = new []; // Buffer must be filled completely once. + trianglesTemp.length = _capacity * 3 - _trianglesCount; + _trianglesBuffer.uploadFromVector(trianglesTemp, _trianglesCount, trianglesTemp.length); + trianglesTemp = null; + + context.setVertexBufferAt(0, _verticesBuffer, VertexData.POSITION_OFFSET, Context3DVertexBufferFormat.FLOAT_2); + context.setVertexBufferAt(1, _verticesBuffer, VertexData.COLOR_OFFSET, Context3DVertexBufferFormat.FLOAT_4); + context.setVertexBufferAt(2, _verticesBuffer, VertexData.TEXCOORD_OFFSET, Context3DVertexBufferFormat.FLOAT_2); + } else { + _verticesBuffer.uploadFromVector(_vertices, 0, _verticesCount >> 3); + _trianglesBuffer.uploadFromVector(_triangles, 0, _trianglesCount); + } + + setProgram(context); + context.setTextureAt(0, _texture.base); + context.drawTriangles(_trianglesBuffer, 0, _trianglesCount / 3); + + _verticesCount = 0; + _trianglesCount = 0; + + _support.raiseDrawCount(); + } + + private function onContextCreated (event:Event) : void { + _verticesBuffer = null; + _trianglesBuffer = null; + } + + private function setProgram (context:Context3D) : void { + var bits:uint = 0; + var texture:Texture = _texture; + if (texture.mipMapping) bits |= 1 << 1; + if (texture.repeat) bits |= 1 << 2; + if (smoothing != TextureSmoothing.BILINEAR) bits |= 1 << (smoothing == TextureSmoothing.TRILINEAR ? 3 : 4); + if (texture.format != Context3DTextureFormat.BGRA) bits |= 1 << (texture.format == "compressedAlpha" ? 5 : 6); + if (bits == _programBits) return; + _programBits = bits; + + var name:String = _programNameCache[bits]; + if (name == null) { + name = "PB_i." + bits.toString(16); + _programNameCache[bits] = name; + } + + var program:Program3D = Starling.current.getProgram(name); + if (!program) { + // va0 -> position + // va1 -> color + // va2 -> texCoords + // vc0 -> alpha + // vc1 -> mvpMatrix + // fs0 -> texture + var vertexShader:String = + "m44 op, va0, vc1 \n" + // 4x4 matrix transform to output clipspace + "mul v0, va1, vc0 \n" + // multiply alpha (vc0) with color (va1) + "mov v1, va2 \n"; // pass texture coordinates to fragment program + var flags:String = RenderSupport.getTextureLookupFlags(texture.format, texture.mipMapping, texture.repeat, smoothing); + var fragmentShader:String = + "tex ft1, v1, fs0 " + flags + " \n" + // sample texture 0 + "mul oc, ft1, v0 \n"; // multiply color with texel color + Starling.current.registerProgramFromSource(name, vertexShader, fragmentShader); + } + context.setProgram(program); + } +} +} diff --git a/spine-starling/spine-starling/src/spine/starling/SkeletonAnimation.as b/spine-starling/spine-starling/src/spine/starling/SkeletonAnimation.as index 8dd38256e..9a801c395 100644 --- a/spine-starling/spine-starling/src/spine/starling/SkeletonAnimation.as +++ b/spine-starling/spine-starling/src/spine/starling/SkeletonAnimation.as @@ -29,23 +29,27 @@ *****************************************************************************/ package spine.starling { +import spine.SkeletonData; import spine.animation.AnimationState; import spine.animation.AnimationStateData; -import spine.SkeletonData; -public class SkeletonAnimation extends SkeletonSprite { +import starling.animation.IAnimatable; + +public class SkeletonAnimation extends SkeletonSprite implements IAnimatable { public var state:AnimationState; - - public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) { - super(skeletonData); + public var timeScale:Number = 1; + + public function SkeletonAnimation (skeletonData:SkeletonData, renderMeshes:Boolean = false, stateData:AnimationStateData = null) { + super(skeletonData, renderMeshes); state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData)); } - - override public function advanceTime (time:Number) : void { + + public function advanceTime (time:Number) : void { + time *= timeScale; + skeleton.update(time); state.update(time); state.apply(skeleton); skeleton.updateWorldTransform(); - super.advanceTime(time); } } diff --git a/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as b/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as index 576ae3528..8e7774bcd 100644 --- a/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as +++ b/spine-starling/spine-starling/src/spine/starling/SkeletonSprite.as @@ -29,6 +29,8 @@ *****************************************************************************/ package spine.starling { +import flash.display3D.Context3D; +import flash.display3D.textures.Texture; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; @@ -37,79 +39,172 @@ import spine.Bone; import spine.Skeleton; import spine.SkeletonData; import spine.Slot; -import spine.atlas.AtlasPage; import spine.atlas.AtlasRegion; +import spine.attachments.Attachment; +import spine.attachments.MeshAttachment; import spine.attachments.RegionAttachment; +import spine.attachments.SkinnedMeshAttachment; -import starling.animation.IAnimatable; import starling.core.RenderSupport; +import starling.core.Starling; import starling.display.BlendMode; import starling.display.DisplayObject; import starling.utils.Color; import starling.utils.MatrixUtil; import starling.utils.VertexData; -public class SkeletonSprite extends DisplayObject implements IAnimatable { - static private var tempPoint:Point = new Point(); - static private var tempMatrix:Matrix = new Matrix(); - static private var tempVertices:Vector. = new Vector.(8); +public class SkeletonSprite extends DisplayObject { + static private var _tempPoint:Point = new Point(); + static private var _tempMatrix:Matrix = new Matrix(); + static private var _tempVertices:Vector. = new Vector.(8); + static private var _quadTriangles:Vector. = new [0, 1, 2, 2, 3, 0]; private var _skeleton:Skeleton; + private var _renderMeshes:Boolean; + private var _polygonBatch:PolygonBatch; + public var batchable:Boolean = true; + private var _batched:Boolean; - public function SkeletonSprite (skeletonData:SkeletonData) { + public function SkeletonSprite (skeletonData:SkeletonData, renderMeshes:Boolean = false) { Bone.yDown = true; + _renderMeshes = renderMeshes; + if (renderMeshes) _polygonBatch = new PolygonBatch(); + _skeleton = new Skeleton(skeletonData); _skeleton.updateWorldTransform(); } - public function advanceTime (delta:Number) : void { - _skeleton.update(delta); - } - override public function render (support:RenderSupport, alpha:Number) : void { alpha *= this.alpha * skeleton.a; + if (_renderMeshes) + renderMeshes(support, alpha); + else + renderRegions(support, alpha); + } + + private function renderMeshes (support:RenderSupport, alpha:Number) : void { + if (!batchable) { + _polygonBatch.begin(support, alpha, blendMode); + addToBatch(_polygonBatch, support, alpha, null); + _polygonBatch.end(); + } else if (!_batched) { + support.popMatrix(); + _polygonBatch.begin(support, alpha, blendMode); + addToBatch(_polygonBatch, support, alpha, transformationMatrix); + for(var i:int = parent.getChildIndex(this) + 1, n:int = parent.numChildren; i < n; ++i) { + var skeletonSprite:SkeletonSprite = parent.getChildAt(i) as SkeletonSprite; + if (!skeletonSprite || !skeletonSprite.batchable || skeletonSprite.blendMode != blendMode) break; + skeletonSprite._batched = true; + skeletonSprite.addToBatch(_polygonBatch, support, alpha, skeletonSprite.transformationMatrix); + } + _polygonBatch.end(); + support.pushMatrix(); + support.transformMatrix(this); + } else + _batched = false; + } + + private function addToBatch (polygonBatch:PolygonBatch, support:RenderSupport, skeletonA:Number, matrix:Matrix) : void { + var skeletonR:Number = skeleton.r; + var skeletonG:Number = skeleton.g; + var skeletonB:Number = skeleton.b; + var x:Number = skeleton.x; + var y:Number = skeleton.y; + var worldVertices:Vector. = _tempVertices; + var drawOrder:Vector. = skeleton.drawOrder; + for (var i:int = 0, n:int = drawOrder.length; i < n; ++i) { + var slot:Slot = drawOrder[i]; + var attachment:Attachment = slot.attachment; + if (!attachment) continue; + var image:SkeletonImage, verticesLength:int, uvs:Vector., triangles:Vector.; + var r:Number, g:Number, b:Number, a:Number; + if (attachment is RegionAttachment) { + var region:RegionAttachment = RegionAttachment(slot.attachment); + verticesLength = 8; + region.computeWorldVertices(x, y, slot.bone, worldVertices); + uvs = region.uvs; + triangles = _quadTriangles; + r = region.r; + g = region.g; + b = region.b; + a = region.a; + image = region.rendererObject as SkeletonImage; + if (image == null) region.rendererObject = image = SkeletonImage(AtlasRegion(region.rendererObject).rendererObject); + } else if (attachment is MeshAttachment) { + var mesh:MeshAttachment = MeshAttachment(attachment); + verticesLength = mesh.vertices.length; + if (worldVertices.length < verticesLength) worldVertices.length = verticesLength; + mesh.computeWorldVertices(x, y, slot, worldVertices); + uvs = mesh.uvs; + triangles = mesh.triangles; + r = mesh.r; + g = mesh.g; + b = mesh.b; + a = mesh.a; + image = mesh.rendererObject as SkeletonImage; + if (image == null) mesh.rendererObject = image = SkeletonImage(AtlasRegion(mesh.rendererObject).rendererObject); + } else if (attachment is SkinnedMeshAttachment) { + var skinnedMesh:SkinnedMeshAttachment = SkinnedMeshAttachment(attachment); + verticesLength = skinnedMesh.uvs.length; + if (worldVertices.length < verticesLength) worldVertices.length = verticesLength; + skinnedMesh.computeWorldVertices(x, y, slot, worldVertices); + uvs = skinnedMesh.uvs; + triangles = skinnedMesh.triangles; + r = skinnedMesh.r; + g = skinnedMesh.g; + b = skinnedMesh.b; + a = skinnedMesh.a; + image = skinnedMesh.rendererObject as SkeletonImage; + if (image == null) skinnedMesh.rendererObject = image = SkeletonImage(AtlasRegion(skinnedMesh.rendererObject).rendererObject); + } + if (image) { + a *= skeletonA * slot.a; + r *= skeletonR * slot.r * a; + g *= skeletonG * slot.g * a; + b *= skeletonB * slot.b * a; + polygonBatch.add(image.texture, worldVertices, verticesLength, uvs, triangles, r, g, b, a, slot.data.additiveBlending, matrix); + } + } + } + + private function renderRegions (support:RenderSupport, alpha:Number) : void { var r:Number = skeleton.r * 255; var g:Number = skeleton.g * 255; var b:Number = skeleton.b * 255; var x:Number = skeleton.x; var y:Number = skeleton.y; var drawOrder:Vector. = skeleton.drawOrder; - for (var i:int = 0, n:int = drawOrder.length; i < n; i++) { + var worldVertices:Vector. = _tempVertices; + for (var i:int = 0, n:int = drawOrder.length; i < n; ++i) { var slot:Slot = drawOrder[i]; - var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment; - if (regionAttachment != null) { - var vertices:Vector. = tempVertices; - regionAttachment.computeWorldVertices(x, y, slot.bone, vertices); - var a:Number = slot.a * regionAttachment.a; + var region:RegionAttachment = slot.attachment as RegionAttachment; + if (region != null) { + region.computeWorldVertices(x, y, slot.bone, worldVertices); + var a:Number = slot.a * region.a; var rgb:uint = Color.rgb( - r * slot.r * regionAttachment.r, - g * slot.g * regionAttachment.g, - b * slot.b * regionAttachment.b); + r * slot.r * region.r, + g * slot.g * region.g, + b * slot.b * region.b); - var image:SkeletonImage; - image = regionAttachment.rendererObject as SkeletonImage; - if (image == null) { - image = SkeletonImage(AtlasRegion(regionAttachment.rendererObject).rendererObject); - regionAttachment.rendererObject = image; - } + var image:SkeletonImage = region.rendererObject as SkeletonImage; + if (image == null) region.rendererObject = image = SkeletonImage(AtlasRegion(region.rendererObject).rendererObject); var vertexData:VertexData = image.vertexData; - - vertexData.setPosition(0, vertices[2], vertices[3]); + vertexData.setPosition(0, worldVertices[2], worldVertices[3]); vertexData.setColorAndAlpha(0, rgb, a); - - vertexData.setPosition(1, vertices[4], vertices[5]); + + vertexData.setPosition(1, worldVertices[4], worldVertices[5]); vertexData.setColorAndAlpha(1, rgb, a); - vertexData.setPosition(2, vertices[0], vertices[1]); + vertexData.setPosition(2, worldVertices[0], worldVertices[1]); vertexData.setColorAndAlpha(2, rgb, a); - - vertexData.setPosition(3, vertices[6], vertices[7]); + + vertexData.setPosition(3, worldVertices[6], worldVertices[7]); vertexData.setColorAndAlpha(3, rgb, a); - + image.updateVertices(); - support.blendMode = slot.data.additiveBlending ? BlendMode.ADD : BlendMode.NORMAL; + support.blendMode = slot.data.additiveBlending ? BlendMode.ADD : blendMode; support.batchQuad(image, alpha, image.texture); } } @@ -122,63 +217,35 @@ public class SkeletonSprite extends DisplayObject implements IAnimatable { var minX:Number = Number.MAX_VALUE, minY:Number = Number.MAX_VALUE; var maxX:Number = Number.MIN_VALUE, maxY:Number = Number.MIN_VALUE; var slots:Vector. = skeleton.slots; - var value:Number; - for (var i:int = 0, n:int = slots.length; i < n; i++) { + var worldVertices:Vector. = _tempVertices; + for (var i:int = 0, n:int = slots.length; i < n; ++i) { var slot:Slot = slots[i]; - var regionAttachment:RegionAttachment = slot.attachment as RegionAttachment; - if (!regionAttachment) + var attachment:Attachment = slot.attachment; + if (!attachment) continue; + var verticesLength:int; + if (attachment is RegionAttachment) { + var region:RegionAttachment = RegionAttachment(slot.attachment); + verticesLength = 8; + region.computeWorldVertices(0, 0, slot.bone, worldVertices); + } else if (attachment is MeshAttachment) { + var mesh:MeshAttachment = MeshAttachment(attachment); + verticesLength = mesh.vertices.length; + if (worldVertices.length < verticesLength) worldVertices.length = verticesLength; + mesh.computeWorldVertices(0, 0, slot, worldVertices); + } else if (attachment is SkinnedMeshAttachment) { + var skinnedMesh:SkinnedMeshAttachment = SkinnedMeshAttachment(attachment); + verticesLength = skinnedMesh.uvs.length; + if (worldVertices.length < verticesLength) worldVertices.length = verticesLength; + skinnedMesh.computeWorldVertices(0, 0, slot, worldVertices); + } else continue; - - var vertices:Vector. = tempVertices; - regionAttachment.computeWorldVertices(skeleton.x, skeleton.y, slot.bone, vertices); - - value = vertices[0]; - if (value < minX) - minX = value; - if (value > maxX) - maxX = value; - - value = vertices[1]; - if (value < minY) - minY = value; - if (value > maxY) - maxY = value; - - value = vertices[2]; - if (value < minX) - minX = value; - if (value > maxX) - maxX = value; - - value = vertices[3]; - if (value < minY) - minY = value; - if (value > maxY) - maxY = value; - - value = vertices[4]; - if (value < minX) - minX = value; - if (value > maxX) - maxX = value; - - value = vertices[5]; - if (value < minY) - minY = value; - if (value > maxY) - maxY = value; - - value = vertices[6]; - if (value < minX) - minX = value; - if (value > maxX) - maxX = value; - - value = vertices[7]; - if (value < minY) - minY = value; - if (value > maxY) - maxY = value; + for (var ii:int = 0; ii < verticesLength; ii += 2) { + var x:Number = worldVertices[ii], y:Number = worldVertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } } minX *= scaleX; @@ -211,9 +278,9 @@ public class SkeletonSprite extends DisplayObject implements IAnimatable { else if (targetSpace == parent) resultRect.setTo(x, y, 0, 0); else { - getTransformationMatrix(targetSpace, tempMatrix); - MatrixUtil.transformCoords(tempMatrix, 0, 0, tempPoint); - resultRect.setTo(tempPoint.x, tempPoint.y, 0, 0); + getTransformationMatrix(targetSpace, _tempMatrix); + MatrixUtil.transformCoords(_tempMatrix, 0, 0, _tempPoint); + resultRect.setTo(_tempPoint.x, _tempPoint.y, 0, 0); } return resultRect; }