123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862 |
- /******************************************************************************
- * Spine Runtimes Software License
- * Version 2.3
- *
- * Copyright (c) 2013-2015, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to use, install, execute and perform the Spine
- * Runtimes Software (the "Software") and derivative works solely for personal
- * or internal use. Without the written permission of Esoteric Software (see
- * Section 2 of the Spine Software License Agreement), 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 SOFTWARE 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.
- *****************************************************************************/
- var spine = {
- radDeg: 180 / Math.PI,
- degRad: Math.PI / 180,
- Float32Array: typeof(Float32Array) === 'undefined' ? Array : Float32Array,
- Uint32Array: typeof(Uint32Array) === 'undefined' ? Array : Uint32Array,
- Uint16Array: typeof(Uint16Array) === 'undefined' ? Array : Uint16Array
- };
- spine.temp = new spine.Float32Array(2);
- spine.BoneData = function (name, parent) {
- this.name = name;
- this.parent = parent;
- };
- spine.BoneData.prototype = {
- length: 0,
- x: 0, y: 0,
- rotation: 0,
- scaleX: 1, scaleY: 1,
- inheritScale: true,
- inheritRotation: true
- };
- spine.BlendMode = {
- normal: 0,
- additive: 1,
- multiply: 2,
- screen: 3
- };
- spine.SlotData = function (name, boneData) {
- this.name = name;
- this.boneData = boneData;
- };
- spine.SlotData.prototype = {
- r: 1, g: 1, b: 1, a: 1,
- attachmentName: null,
- blendMode: spine.BlendMode.normal
- };
- spine.IkConstraintData = function (name) {
- this.name = name;
- this.bones = [];
- };
- spine.IkConstraintData.prototype = {
- target: null,
- bendDirection: 1,
- mix: 1
- };
- spine.TransformConstraintData = function (name) {
- this.name = name;
- };
- spine.TransformConstraintData.prototype = {
- bone: null,
- target: null,
- translateMix: 1,
- x: 0, y: 0
- };
- spine.Bone = function (boneData, skeleton, parent) {
- this.data = boneData;
- this.skeleton = skeleton;
- this.parent = parent;
- this.setToSetupPose();
- };
- spine.Bone.yDown = false;
- spine.Bone.prototype = {
- x: 0, y: 0, rotation: 0, scaleX: 1, scaleY: 1,
- a: 0, b: 0, worldX: 0,
- c: 0, d: 0, worldY: 0,
- worldSignX: 1, worldSignY: 1,
- update: function () {
- this.updateWorldTransform(this.x, this.y, this.rotation, this.scaleX, this.scaleY);
- },
- updateWorldTransformWith: function () {
- this.updateWorldTransform(this.x, this.y, this.rotation, this.scaleX, this.scaleY);
- },
- updateWorldTransform: function (x, y, rotation, scaleX, scaleY) {
- this.appliedRotation = rotation;
- this.appliedScaleX = scaleX;
- this.appliedScaleY = scaleY;
- rotation *= spine.degRad;
- var cos = Math.cos(rotation), sin = Math.sin(rotation);
- var la = cos * scaleX, lb = -sin * scaleY, lc = sin * scaleX, ld = cos * scaleY;
- var parent = this.parent;
- if (!parent) { // Root bone.
- var skeleton = this.skeleton;
- if (skeleton.flipX) {
- x = -x;
- la = -la;
- lb = -lb;
- }
- if (skeleton.flipY != spine.Bone.yDown) {
- y = -y;
- lc = -lc;
- ld = -ld;
- }
- this.a = la;
- this.b = lb;
- this.c = lc;
- this.d = ld;
- this.worldX = x;
- this.worldY = y;
- this.worldSignX = scaleX < 0 ? -1 : 1;
- this.worldSignY = scaleY < 0 ? -1 : 1;
- return;
- }
- var pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
- this.worldX = pa * x + pb * y + parent.worldX;
- this.worldY = pc * x + pd * y + parent.worldY;
- this.worldSignX = parent.worldSignX * (scaleX < 0 ? -1 : 1);
- this.worldSignY = parent.worldSignY * (scaleY < 0 ? -1 : 1);
- if (this.data.inheritRotation && this.data.inheritScale) {
- this.a = pa * la + pb * lc;
- this.b = pa * lb + pb * ld;
- this.c = pc * la + pd * lc;
- this.d = pc * lb + pd * ld;
- } else {
- if (this.data.inheritRotation) { // No scale inheritance.
- pa = 1;
- pb = 0;
- pc = 0;
- pd = 1;
- do {
- rotation = parent.appliedRotation * spine.degRad;
- cos = Math.cos(rotation);
- sin = Math.sin(rotation);
- var temp = pa * cos + pb * sin;
- pb = pa * -sin + pb * cos;
- pa = temp;
- temp = pc * cos + pd * sin;
- pd = pc * -sin + pd * cos;
- pc = temp;
- if (!parent.data.inheritRotation) break;
- parent = parent.parent;
- } while (parent);
- this.a = pa * la + pb * lc;
- this.b = pa * lb + pb * ld;
- this.c = pc * la + pd * lc;
- this.d = pc * lb + pd * ld;
- } else if (this.data.inheritScale) { // No rotation inheritance.
- pa = 1;
- pb = 0;
- pc = 0;
- pd = 1;
- do {
- rotation = parent.appliedRotation * spine.degRad;
- cos = Math.cos(rotation);
- sin = Math.sin(rotation);
- var psx = parent.appliedScaleX, psy = parent.appliedScaleY;
- var za = cos * psx, zb = -sin * psy, zc = sin * psx, zd = cos * psy;
- var temp = pa * za + pb * zc;
- pb = pa * zb + pb * zd;
- pa = temp;
- temp = pc * za + pd * zc;
- pd = pc * zb + pd * zd;
- pc = temp;
- if (psx < 0) rotation = -rotation;
- cos = Math.cos(-rotation);
- sin = Math.sin(-rotation);
- temp = pa * cos + pb * sin;
- pb = pa * -sin + pb * cos;
- pa = temp;
- temp = pc * cos + pd * sin;
- pd = pc * -sin + pd * cos;
- pc = temp;
- if (!parent.data.inheritScale) break;
- parent = parent.parent;
- } while (parent);
- this.a = pa * la + pb * lc;
- this.b = pa * lb + pb * ld;
- this.c = pc * la + pd * lc;
- this.d = pc * lb + pd * ld;
- } else {
- this.a = la;
- this.b = lb;
- this.c = lc;
- this.d = ld;
- }
- if (this.skeleton.flipX) {
- this.a = -this.a;
- this.b = -this.b;
- }
- if (this.skeleton.flipY != spine.Bone.yDown) {
- this.c = -this.c;
- this.d = -this.d;
- }
- }
- },
- setToSetupPose: function () {
- var data = this.data;
- this.x = data.x;
- this.y = data.y;
- this.rotation = data.rotation;
- this.scaleX = data.scaleX;
- this.scaleY = data.scaleY;
- },
- getWorldRotationX: function () {
- return Math.atan2(this.c, this.a) * spine.radDeg;
- },
- getWorldRotationY: function () {
- return Math.atan2(this.d, this.b) * spine.radDeg;
- },
- getWorldScaleX: function () {
- return Math.sqrt(this.a * this.a + this.b * this.b) * this.worldSignX;
- },
- getWorldScaleY: function () {
- return Math.sqrt(this.c * this.c + this.d * this.d) * this.worldSignY;
- },
- worldToLocal: function (world) {
- var x = world[0] - this.worldX, y = world[1] - this.worldY;
- var a = this.a, b = this.b, c = this.c, d = this.d;
- var invDet = 1 / (a * d - b * c);
- world[0] = (x * d * invDet - y * b * invDet);
- world[1] = (y * a * invDet - x * c * invDet);
- return world;
- },
- localToWorld: function (local) {
- var x = local[0], y = local[1];
- local[0] = x * this.a + y * this.b + this.worldX;
- local[1] = x * this.c + y * this.d + this.worldY;
- return local;
- }
- };
- spine.Slot = function (slotData, bone) {
- this.data = slotData;
- this.bone = bone;
- this.attachmentVertices = new spine.Float32Array();
- this.setToSetupPose();
- };
- spine.Slot.prototype = {
- r: 1, g: 1, b: 1, a: 1,
- _attachmentTime: 0,
- attachment: null,
- setAttachment: function (attachment) {
- if (this.attachment == attachment) return;
- this.attachment = attachment;
- this._attachmentTime = this.bone.skeleton.time;
- this.attachmentVertices.length = 0;
- },
- setAttachmentTime: function (time) {
- this._attachmentTime = this.bone.skeleton.time - time;
- },
- getAttachmentTime: function () {
- return this.bone.skeleton.time - this._attachmentTime;
- },
- setToSetupPose: function () {
- var data = this.data;
- this.r = data.r;
- this.g = data.g;
- this.b = data.b;
- this.a = data.a;
- if (!data.attachmentName)
- this.setAttachment(null);
- else {
- var slotDatas = this.bone.skeleton.data.slots;
- for (var i = 0, n = slotDatas.length; i < n; i++) {
- if (slotDatas[i] == data) {
- this.attachment = null;
- this.setAttachment(this.bone.skeleton.getAttachmentBySlotIndex(i, data.attachmentName));
- break;
- }
- }
- }
- }
- };
- spine.IkConstraint = function (data, skeleton) {
- this.data = data;
- this.mix = data.mix;
- this.bendDirection = data.bendDirection;
- this.bones = [];
- for (var i = 0, n = data.bones.length; i < n; i++)
- this.bones[i] = skeleton.findBone(data.bones[i].name);
- this.target = skeleton.findBone(data.target.name);
- };
- spine.IkConstraint.prototype = {
- apply: function () {
- this.update();
- },
- update: function () {
- var target = this.target;
- var bones = this.bones;
- switch (bones.length) {
- case 1:
- spine.IkConstraint.apply1(bones[0], target.worldX, target.worldY, this.mix);
- break;
- case 2:
- spine.IkConstraint.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix);
- break;
- }
- },
- };
- /** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
- * coordinate system. */
- spine.IkConstraint.apply1 = function (bone, targetX, targetY, alpha) {
- var parentRotation = !bone.parent ? 0 : bone.parent.getWorldRotationX();
- var rotation = bone.rotation;
- var rotationIK = Math.atan2(targetY - bone.worldY, targetX - bone.worldX) * spine.radDeg - parentRotation;
- if ((bone.worldSignX != bone.worldSignY) != (bone.skeleton.flipX != (bone.skeleton.flipY != spine.Bone.yDown)))
- rotationIK = 360 - rotationIK;
- if (rotationIK > 180) rotationIK -= 360;
- else if (rotationIK < -180) rotationIK += 360;
- bone.updateWorldTransform(bone.x, bone.y, rotation + (rotationIK - rotation) * alpha, bone.appliedScaleX, bone.appliedScaleY);
- };
- /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
- * target is specified in the world coordinate system.
- * @param child A direct descendant of the parent bone. */
- spine.IkConstraint.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) {
- if (alpha == 0) return;
- var px = parent.x, py = parent.y, psx = parent.appliedScaleX, psy = parent.appliedScaleY;
- var os1, os2, s2;
- if (psx < 0) {
- psx = -psx;
- os1 = 180;
- s2 = -1;
- } else {
- os1 = 0;
- s2 = 1;
- }
- if (psy < 0) {
- psy = -psy;
- s2 = -s2;
- }
- var cx = child.x, cy = child.y, csx = child.appliedScaleX;
- var u = Math.abs(psx - psy) <= 0.0001;
- if (!u && cy != 0) {
- child.worldX = parent.a * cx + parent.worldX;
- child.worldY = parent.c * cx + parent.worldY;
- cy = 0;
- }
- if (csx < 0) {
- csx = -csx;
- os2 = 180;
- } else
- os2 = 0;
- var pp = parent.parent;
- var tx, ty, dx, dy;
- if (!pp) {
- tx = targetX - px;
- ty = targetY - py;
- dx = child.worldX - px;
- dy = child.worldY - py;
- } else {
- var a = pp.a, b = pp.b, c = pp.c, d = pp.d, invDet = 1 / (a * d - b * c);
- var wx = pp.worldX, wy = pp.worldY, x = targetX - wx, y = targetY - wy;
- tx = (x * d - y * b) * invDet - px;
- ty = (y * a - x * c) * invDet - py;
- x = child.worldX - wx;
- y = child.worldY - wy;
- dx = (x * d - y * b) * invDet - px;
- dy = (y * a - x * c) * invDet - py;
- }
- var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2;
- outer:
- if (u) {
- l2 *= psx;
- var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2);
- if (cos < -1) cos = -1;
- else if (cos > 1) cos = 1;
- a2 = Math.acos(cos) * bendDir;
- var a = l1 + l2 * cos, o = l2 * Math.sin(a2);
- a1 = Math.atan2(ty * a - tx * o, tx * a + ty * o);
- } else {
- var a = psx * l2, b = psy * l2, ta = Math.atan2(ty, tx);
- var aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty;
- var c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
- var d = c1 * c1 - 4 * c2 * c0;
- if (d >= 0) {
- var q = Math.sqrt(d);
- if (c1 < 0) q = -q;
- q = -(c1 + q) / 2;
- var r0 = q / c2, r1 = c0 / q;
- var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
- if (r * r <= dd) {
- var y = Math.sqrt(dd - r * r) * bendDir;
- a1 = ta - Math.atan2(y, r);
- a2 = Math.atan2(y / psy, (r - l1) / psx);
- break outer;
- }
- }
- var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
- var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
- var x = l1 + a, dist = x * x;
- if (dist > maxDist) {
- maxAngle = 0;
- maxDist = dist;
- maxX = x;
- }
- x = l1 - a;
- dist = x * x;
- if (dist < minDist) {
- minAngle = Math.PI;
- minDist = dist;
- minX = x;
- }
- var angle = Math.acos(-a * l1 / (aa - bb));
- x = a * Math.cos(angle) + l1;
- var y = b * Math.sin(angle);
- dist = x * x + y * y;
- if (dist < minDist) {
- minAngle = angle;
- minDist = dist;
- minX = x;
- minY = y;
- }
- if (dist > maxDist) {
- maxAngle = angle;
- maxDist = dist;
- maxX = x;
- maxY = y;
- }
- if (dd <= (minDist + maxDist) / 2) {
- a1 = ta - Math.atan2(minY * bendDir, minX);
- a2 = minAngle * bendDir;
- } else {
- a1 = ta - Math.atan2(maxY * bendDir, maxX);
- a2 = maxAngle * bendDir;
- }
- }
- var os = Math.atan2(cy, cx) * s2;
- a1 = (a1 - os) * spine.radDeg + os1;
- a2 = (a2 + os) * spine.radDeg * s2 + os2;
- if (a1 > 180) a1 -= 360;
- else if (a1 < -180) a1 += 360;
- if (a2 > 180) a2 -= 360;
- else if (a2 < -180) a2 += 360;
- var rotation = parent.rotation;
- parent.updateWorldTransform(px, py, rotation + (a1 - rotation) * alpha, parent.appliedScaleX, parent.appliedScaleY);
- rotation = child.rotation;
- child.updateWorldTransform(cx, cy, rotation + (a2 - rotation) * alpha, child.appliedScaleX, child.appliedScaleY);
- };
- spine.TransformConstraint = function (data, skeleton) {
- this.data = data;
- this.translateMix = data.translateMix;
- this.x = data.x;
- this.y = data.y;
- this.bone = skeleton.findBone(data.bone.name);
- this.target = skeleton.findBone(data.target.name);
- };
- spine.TransformConstraint.prototype = {
- apply: function () {
- this.update();
- },
- update: function () {
- var translateMix = this.translateMix;
- if (translateMix > 0) {
- var temp = spine.temp;
- temp[0] = x;
- temp[1] = y;
- this.target.localToWorld(temp);
- var bone = this.bone;
- bone.worldX += (temp[0] - bone.worldX) * translateMix;
- bone.worldY += (temp[1] - bone.worldY) * translateMix;
- }
- },
- };
- spine.Skin = function (name) {
- this.name = name;
- this.attachments = {};
- };
- spine.Skin.prototype = {
- addAttachment: function (slotIndex, name, attachment) {
- this.attachments[slotIndex + ":" + name] = attachment;
- },
- getAttachment: function (slotIndex, name) {
- return this.attachments[slotIndex + ":" + name];
- },
- _attachAll: function (skeleton, oldSkin) {
- for (var key in oldSkin.attachments) {
- var colon = key.indexOf(":");
- var slotIndex = parseInt(key.substring(0, colon));
- var name = key.substring(colon + 1);
- var slot = skeleton.slots[slotIndex];
- if (slot.attachment && slot.attachment.name == name) {
- var attachment = this.getAttachment(slotIndex, name);
- if (attachment) slot.setAttachment(attachment);
- }
- }
- }
- };
- spine.Animation = function (name, timelines, duration) {
- this.name = name;
- this.timelines = timelines;
- this.duration = duration;
- };
- spine.Animation.prototype = {
- apply: function (skeleton, lastTime, time, loop, events) {
- if (loop && this.duration != 0) {
- time %= this.duration;
- if (lastTime > 0) lastTime %= this.duration;
- }
- var timelines = this.timelines;
- for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, 1);
- },
- mix: function (skeleton, lastTime, time, loop, events, alpha) {
- if (loop && this.duration != 0) {
- time %= this.duration;
- if (lastTime > 0) lastTime %= this.duration;
- }
- var timelines = this.timelines;
- for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, alpha);
- }
- };
- spine.Animation.binarySearch = function (values, target, step) {
- var low = 0;
- var high = Math.floor(values.length / step) - 2;
- if (!high) return step;
- var current = high >>> 1;
- while (true) {
- if (values[(current + 1) * step] <= target)
- low = current + 1;
- else
- high = current;
- if (low == high) return (low + 1) * step;
- current = (low + high) >>> 1;
- }
- };
- spine.Animation.binarySearch1 = function (values, target) {
- var low = 0;
- var high = values.length - 2;
- if (!high) return 1;
- var current = high >>> 1;
- while (true) {
- if (values[current + 1] <= target)
- low = current + 1;
- else
- high = current;
- if (low == high) return low + 1;
- current = (low + high) >>> 1;
- }
- };
- spine.Animation.linearSearch = function (values, target, step) {
- for (var i = 0, last = values.length - step; i <= last; i += step)
- if (values[i] > target) return i;
- return -1;
- };
- spine.Curves = function (frameCount) {
- var count = (frameCount - 1) * 19/*BEZIER_SIZE*/;
- this.curves = new spine.Float32Array(count); // type, x, y, ...
- this.curves.length = count;
- };
- spine.Curves.prototype = {
- setLinear: function (frameIndex) {
- this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 0/*LINEAR*/;
- },
- setStepped: function (frameIndex) {
- this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 1/*STEPPED*/;
- },
- /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
- * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
- * the difference between the keyframe's values. */
- setCurve: function (frameIndex, cx1, cy1, cx2, cy2) {
- var subdiv1 = 1 / 10/*BEZIER_SEGMENTS*/, subdiv2 = subdiv1 * subdiv1, subdiv3 = subdiv2 * subdiv1;
- var pre1 = 3 * subdiv1, pre2 = 3 * subdiv2, pre4 = 6 * subdiv2, pre5 = 6 * subdiv3;
- var tmp1x = -cx1 * 2 + cx2, tmp1y = -cy1 * 2 + cy2, tmp2x = (cx1 - cx2) * 3 + 1, tmp2y = (cy1 - cy2) * 3 + 1;
- var dfx = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv3, dfy = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv3;
- var ddfx = tmp1x * pre4 + tmp2x * pre5, ddfy = tmp1y * pre4 + tmp2y * pre5;
- var dddfx = tmp2x * pre5, dddfy = tmp2y * pre5;
- var i = frameIndex * 19/*BEZIER_SIZE*/;
- var curves = this.curves;
- curves[i++] = 2/*BEZIER*/;
- var x = dfx, y = dfy;
- for (var n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) {
- curves[i] = x;
- curves[i + 1] = y;
- dfx += ddfx;
- dfy += ddfy;
- ddfx += dddfx;
- ddfy += dddfy;
- x += dfx;
- y += dfy;
- }
- },
- getCurvePercent: function (frameIndex, percent) {
- percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent);
- var curves = this.curves;
- var i = frameIndex * 19/*BEZIER_SIZE*/;
- var type = curves[i];
- if (type === 0/*LINEAR*/) return percent;
- if (type == 1/*STEPPED*/) return 0;
- i++;
- var x = 0;
- for (var start = i, n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) {
- x = curves[i];
- if (x >= percent) {
- var prevX, prevY;
- if (i == start) {
- prevX = 0;
- prevY = 0;
- } else {
- prevX = curves[i - 2];
- prevY = curves[i - 1];
- }
- return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
- }
- }
- var y = curves[i - 1];
- return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
- }
- };
- spine.RotateTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount * 2); // time, angle, ...
- this.frames.length = frameCount * 2;
- };
- spine.RotateTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 2;
- },
- setFrame: function (frameIndex, time, angle) {
- frameIndex *= 2;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = angle;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var bone = skeleton.bones[this.boneIndex];
- if (time >= frames[frames.length - 2]) { // Time is after last frame.
- var amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- bone.rotation += amount * alpha;
- return;
- }
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 2);
- var prevFrameValue = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent);
- var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - prevFrameValue;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- amount = bone.data.rotation + (prevFrameValue + amount * percent) - bone.rotation;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- bone.rotation += amount * alpha;
- }
- };
- spine.TranslateTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount * 3); // time, x, y, ...
- this.frames.length = frameCount * 3;
- };
- spine.TranslateTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, x, y) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = x;
- this.frames[frameIndex + 2] = y;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var bone = skeleton.bones[this.boneIndex];
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha;
- bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha;
- return;
- }
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameX = frames[frameIndex - 2];
- var prevFrameY = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
- bone.x += (bone.data.x + prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent - bone.x) * alpha;
- bone.y += (bone.data.y + prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent - bone.y) * alpha;
- }
- };
- spine.ScaleTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount * 3); // time, x, y, ...
- this.frames.length = frameCount * 3;
- };
- spine.ScaleTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, x, y) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = x;
- this.frames[frameIndex + 2] = y;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var bone = skeleton.bones[this.boneIndex];
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- bone.scaleX += (bone.data.scaleX * frames[frames.length - 2] - bone.scaleX) * alpha;
- bone.scaleY += (bone.data.scaleY * frames[frames.length - 1] - bone.scaleY) * alpha;
- return;
- }
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameX = frames[frameIndex - 2];
- var prevFrameY = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
- bone.scaleX += (bone.data.scaleX * (prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent) - bone.scaleX) * alpha;
- bone.scaleY += (bone.data.scaleY * (prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent) - bone.scaleY) * alpha;
- }
- };
- spine.ColorTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount * 5); // time, r, g, b, a, ...
- this.frames.length = frameCount * 5;
- };
- spine.ColorTimeline.prototype = {
- slotIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 5;
- },
- setFrame: function (frameIndex, time, r, g, b, a) {
- frameIndex *= 5;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = r;
- this.frames[frameIndex + 2] = g;
- this.frames[frameIndex + 3] = b;
- this.frames[frameIndex + 4] = a;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var r, g, b, a;
- if (time >= frames[frames.length - 5]) {
- // Time is after last frame.
- var i = frames.length - 1;
- r = frames[i - 3];
- g = frames[i - 2];
- b = frames[i - 1];
- a = frames[i];
- } else {
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 5);
- var prevFrameR = frames[frameIndex - 4];
- var prevFrameG = frames[frameIndex - 3];
- var prevFrameB = frames[frameIndex - 2];
- var prevFrameA = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent);
- r = prevFrameR + (frames[frameIndex + 1/*FRAME_R*/] - prevFrameR) * percent;
- g = prevFrameG + (frames[frameIndex + 2/*FRAME_G*/] - prevFrameG) * percent;
- b = prevFrameB + (frames[frameIndex + 3/*FRAME_B*/] - prevFrameB) * percent;
- a = prevFrameA + (frames[frameIndex + 4/*FRAME_A*/] - prevFrameA) * percent;
- }
- var slot = skeleton.slots[this.slotIndex];
- if (alpha < 1) {
- slot.r += (r - slot.r) * alpha;
- slot.g += (g - slot.g) * alpha;
- slot.b += (b - slot.b) * alpha;
- slot.a += (a - slot.a) * alpha;
- } else {
- slot.r = r;
- slot.g = g;
- slot.b = b;
- slot.a = a;
- }
- }
- };
- spine.AttachmentTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount); // time, ...
- this.frames.length = frameCount;
- this.attachmentNames = [];
- this.attachmentNames.length = frameCount;
- };
- spine.AttachmentTimeline.prototype = {
- slotIndex: 0,
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, attachmentName) {
- this.frames[frameIndex] = time;
- this.attachmentNames[frameIndex] = attachmentName;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) {
- if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0);
- return;
- } else if (lastTime > time) //
- lastTime = -1;
- var frameIndex = time >= frames[frames.length - 1] ? frames.length - 1 : spine.Animation.binarySearch1(frames, time) - 1;
- if (frames[frameIndex] < lastTime) return;
- var attachmentName = this.attachmentNames[frameIndex];
- skeleton.slots[this.slotIndex].setAttachment(
- !attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName));
- }
- };
- spine.EventTimeline = function (frameCount) {
- this.frames = new spine.Float32Array(frameCount); // time, ...
- this.frames.length = frameCount;
- this.events = [];
- this.events.length = frameCount;
- };
- spine.EventTimeline.prototype = {
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, event) {
- this.frames[frameIndex] = event.time;
- this.events[frameIndex] = event;
- },
- /** Fires events for frames > lastTime and <= time. */
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- if (!firedEvents) return;
- var frames = this.frames;
- var frameCount = frames.length;
- if (lastTime > time) { // Fire events after last time for looped animations.
- this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha);
- lastTime = -1;
- } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
- return;
- if (time < frames[0]) return; // Time is before first frame.
- var frameIndex;
- if (lastTime < frames[0])
- frameIndex = 0;
- else {
- frameIndex = spine.Animation.binarySearch1(frames, lastTime);
- var frame = frames[frameIndex];
- while (frameIndex > 0) { // Fire multiple events with the same frame.
- if (frames[frameIndex - 1] != frame) break;
- frameIndex--;
- }
- }
- var events = this.events;
- for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
- firedEvents[firedEvents.length] = events[frameIndex];
- }
- };
- spine.DrawOrderTimeline = function (frameCount) {
- this.frames = new spine.Float32Array(frameCount); // time, ...
- this.frames.length = frameCount;
- this.drawOrders = [];
- this.drawOrders.length = frameCount;
- };
- spine.DrawOrderTimeline.prototype = {
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, drawOrder) {
- this.frames[frameIndex] = time;
- this.drawOrders[frameIndex] = drawOrder;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var frameIndex;
- if (time >= frames[frames.length - 1]) // Time is after last frame.
- frameIndex = frames.length - 1;
- else
- frameIndex = spine.Animation.binarySearch1(frames, time) - 1;
- var drawOrder = skeleton.drawOrder;
- var slots = skeleton.slots;
- var drawOrderToSetupIndex = this.drawOrders[frameIndex];
- if (!drawOrderToSetupIndex) {
- for (var i = 0, n = slots.length; i < n; i++)
- drawOrder[i] = slots[i];
- } else {
- for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
- drawOrder[i] = skeleton.slots[drawOrderToSetupIndex[i]];
- }
- }
- };
- spine.FfdTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount);
- this.frames.length = frameCount;
- this.frameVertices = [];
- this.frameVertices.length = frameCount;
- };
- spine.FfdTimeline.prototype = {
- slotIndex: 0,
- attachment: 0,
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, vertices) {
- this.frames[frameIndex] = time;
- this.frameVertices[frameIndex] = vertices;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var slot = skeleton.slots[this.slotIndex];
- var slotAttachment = slot.attachment;
- if (!slotAttachment) return;
- if (slotAttachment != this.attachment && (!slotAttachment.inheritFFD || slotAttachment.parentMesh != this.attachment)) return;
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var frameVertices = this.frameVertices;
- var vertexCount = frameVertices[0].length;
- var vertices = slot.attachmentVertices;
- if (vertices.length != vertexCount) {
- slot.attachmentVertices = vertices = new spine.Float32Array(vertexCount);
- alpha = 1;
- }
- if (time >= frames[frames.length - 1]) { // Time is after last frame.
- var lastVertices = frameVertices[frames.length - 1];
- if (alpha < 1) {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
- } else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] = lastVertices[i];
- }
- return;
- }
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch1(frames, time);
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
- var prevVertices = frameVertices[frameIndex - 1];
- var nextVertices = frameVertices[frameIndex];
- if (alpha < 1) {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
- }
- } else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = prev + (nextVertices[i] - prev) * percent;
- }
- }
- }
- };
- spine.IkConstraintTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = new spine.Float32Array(frameCount * 3); // time, mix, bendDirection, ...
- this.frames.length = frameCount * 3;
- };
- spine.IkConstraintTimeline.prototype = {
- ikConstraintIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, mix, bendDirection) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = mix;
- this.frames[frameIndex + 2] = bendDirection;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
- var ikConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- ikConstraint.mix += (frames[frames.length - 2] - ikConstraint.mix) * alpha;
- ikConstraint.bendDirection = frames[frames.length - 1];
- return;
- }
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameMix = frames[frameIndex + -2/*PREV_FRAME_MIX*/];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
- var mix = prevFrameMix + (frames[frameIndex + 1/*FRAME_MIX*/] - prevFrameMix) * percent;
- ikConstraint.mix += (mix - ikConstraint.mix) * alpha;
- ikConstraint.bendDirection = frames[frameIndex + -1/*PREV_FRAME_BEND_DIRECTION*/];
- }
- };
- spine.SkeletonData = function () {
- this.bones = [];
- this.slots = [];
- this.skins = [];
- this.events = [];
- this.animations = [];
- this.ikConstraints = [];
- this.transformConstraints = [];
- };
- spine.SkeletonData.prototype = {
- name: null,
- defaultSkin: null,
- width: 0, height: 0,
- version: null, hash: null,
- /** @return May be null. */
- findBone: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].name == boneName) return bones[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findBoneIndex: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].name == boneName) return i;
- return -1;
- },
- /** @return May be null. */
- findSlot: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- if (slots[i].name == slotName) return slot[i];
- }
- return null;
- },
- /** @return -1 if the bone was not found. */
- findSlotIndex: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].name == slotName) return i;
- return -1;
- },
- /** @return May be null. */
- findSkin: function (skinName) {
- var skins = this.skins;
- for (var i = 0, n = skins.length; i < n; i++)
- if (skins[i].name == skinName) return skins[i];
- return null;
- },
- /** @return May be null. */
- findEvent: function (eventName) {
- var events = this.events;
- for (var i = 0, n = events.length; i < n; i++)
- if (events[i].name == eventName) return events[i];
- return null;
- },
- /** @return May be null. */
- findAnimation: function (animationName) {
- var animations = this.animations;
- for (var i = 0, n = animations.length; i < n; i++)
- if (animations[i].name == animationName) return animations[i];
- return null;
- },
- /** @return May be null. */
- findIkConstraint: function (constraintName) {
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++)
- if (ikConstraints[i].name == constraintName) return ikConstraints[i];
- return null;
- },
- /** @return May be null. */
- findTransformConstraints: function (constraintName) {
- var transformConstraints = this.transformConstraints;
- for (var i = 0, n = transformConstraints.length; i < n; i++)
- if (transformConstraints[i].name == constraintName) return transformConstraints[i];
- return null;
- }
- };
- spine.Skeleton = function (skeletonData) {
- this.data = skeletonData;
- this.bones = [];
- for (var i = 0, n = skeletonData.bones.length; i < n; i++) {
- var boneData = skeletonData.bones[i];
- var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)];
- this.bones[i] = new spine.Bone(boneData, this, parent);
- }
- this.slots = [];
- this.drawOrder = [];
- for (var i = 0, n = skeletonData.slots.length; i < n; i++) {
- var slotData = skeletonData.slots[i];
- var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)];
- var slot = new spine.Slot(slotData, bone);
- this.slots[i] = slot;
- this.drawOrder[i] = slot;
- }
- this.ikConstraints = [];
- for (var i = 0, n = skeletonData.ikConstraints.length; i < n; i++)
- this.ikConstraints[i] = new spine.IkConstraint(skeletonData.ikConstraints[i], this);
- this.transformConstraints = [];
- for (var i = 0, n = skeletonData.transformConstraints.length; i < n; i++)
- this.transformConstraints[i] = new spine.TransformConstraint(skeletonData.transformConstraints[i], this);
- this.cache = [];
- this.updateCache();
- };
- spine.Skeleton.prototype = {
- x: 0, y: 0,
- skin: null,
- r: 1, g: 1, b: 1, a: 1,
- time: 0,
- flipX: false, flipY: false,
- /** Caches information about bones and constraints. Must be called if bones or constraints are added or removed. */
- updateCache: function () {
- var bones = this.bones;
- var updateCache = this.cache;
- var ikConstraints = this.ikConstraints;
- var transformConstraints = this.transformConstraints;
- var ikConstraintsCount = ikConstraints.length;
- var transformConstraintsCount = transformConstraints.length;
- updateCache.length = 0;
- for (var i = 0, n = bones.length; i < n; i++) {
- var bone = bones[i];
- updateCache[updateCache.length] = bone;
- for (var ii = 0; ii < ikConstraintsCount; ii++) {
- var ikConstraint = ikConstraints[ii];
- if (bone == ikConstraint.bones[ikConstraint.bones.length - 1]) {
- updateCache[updateCache.length] = ikConstraint;
- break;
- }
- }
- }
- for (var i = 0; i < transformConstraintsCount; i++) {
- var transformConstraint = transformConstraints[i];
- for (var ii = updateCache.length - 1; ii >= 0; ii--) {
- var object = updateCache[ii];
- if (object == transformConstraint.bone || object == transformConstraint.target) {
- updateCache.splice(ii + 1, 0, transformConstraint);
- break;
- }
- }
- }
- },
- /** Updates the world transform for each bone and applies constraints. */
- updateWorldTransform: function () {
- var updateCache = this.cache;
- for (var i = 0, n = updateCache.length; i < n; i++)
- updateCache[i].update();
- },
- /** Sets the bones, constraints, and slots to their setup pose values. */
- setToSetupPose: function () {
- this.setBonesToSetupPose();
- this.setSlotsToSetupPose();
- },
- /** Sets the bones and constraints to their setup pose values. */
- setBonesToSetupPose: function () {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- bones[i].setToSetupPose();
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++) {
- var constraint = ikConstraints[i];
- constraint.bendDirection = constraint.data.bendDirection;
- constraint.mix = constraint.data.mix;
- }
- var transformConstraints = this.transformConstraints;
- for (var i = 0, n = transformConstraints.length; i < n; i++) {
- var constraint = transformConstraints[i];
- constraint.translateMix = constraint.data.translateMix;
- constraint.x = constraint.data.x;
- constraint.y = constraint.data.y;
- }
- },
- setSlotsToSetupPose: function () {
- var slots = this.slots;
- var drawOrder = this.drawOrder;
- for (var i = 0, n = slots.length; i < n; i++) {
- drawOrder[i] = slots[i];
- slots[i].setToSetupPose(i);
- }
- },
- /** @return May return null. */
- getRootBone: function () {
- return this.bones.length ? this.bones[0] : null;
- },
- /** @return May be null. */
- findBone: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].data.name == boneName) return bones[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findBoneIndex: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].data.name == boneName) return i;
- return -1;
- },
- /** @return May be null. */
- findSlot: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].data.name == slotName) return slots[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findSlotIndex: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].data.name == slotName) return i;
- return -1;
- },
- setSkinByName: function (skinName) {
- var skin = this.data.findSkin(skinName);
- if (!skin) throw "Skin not found: " + skinName;
- this.setSkin(skin);
- },
- /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
- * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
- * no old skin, each slot's setup mode attachment is attached from the new skin.
- * @param newSkin May be null. */
- setSkin: function (newSkin) {
- if (newSkin) {
- if (this.skin)
- newSkin._attachAll(this, this.skin);
- else {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- var slot = slots[i];
- var name = slot.data.attachmentName;
- if (name) {
- var attachment = newSkin.getAttachment(i, name);
- if (attachment) slot.setAttachment(attachment);
- }
- }
- }
- }
- this.skin = newSkin;
- },
- /** @return May be null. */
- getAttachmentBySlotName: function (slotName, attachmentName) {
- return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName);
- },
- /** @return May be null. */
- getAttachmentBySlotIndex: function (slotIndex, attachmentName) {
- if (this.skin) {
- var attachment = this.skin.getAttachment(slotIndex, attachmentName);
- if (attachment) return attachment;
- }
- if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
- return null;
- },
- /** @param attachmentName May be null. */
- setAttachment: function (slotName, attachmentName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- var slot = slots[i];
- if (slot.data.name == slotName) {
- var attachment = null;
- if (attachmentName) {
- attachment = this.getAttachmentBySlotIndex(i, attachmentName);
- if (!attachment) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName;
- }
- slot.setAttachment(attachment);
- return;
- }
- }
- throw "Slot not found: " + slotName;
- },
- /** @return May be null. */
- findIkConstraint: function (constraintName) {
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++)
- if (ikConstraints[i].data.name == constraintName) return ikConstraints[i];
- return null;
- },
- /** @return May be null. */
- findTransformConstraint: function (constraintName) {
- var transformConstraints = this.transformConstraints;
- for (var i = 0, n = transformConstraints.length; i < n; i++)
- if (transformConstraints[i].data.name == constraintName) return transformConstraints[i];
- return null;
- },
- update: function (delta) {
- this.time += delta;
- }
- };
- spine.EventData = function (name) {
- this.name = name;
- };
- spine.EventData.prototype = {
- intValue: 0,
- floatValue: 0,
- stringValue: null
- };
- spine.Event = function (time, data) {
- this.time = time;
- this.data = data;
- };
- spine.Event.prototype = {
- intValue: 0,
- floatValue: 0,
- stringValue: null
- };
- spine.AttachmentType = {
- region: 0,
- boundingbox: 1,
- mesh: 2,
- weightedmesh: 3,
- linkedmesh: 4,
- weightedlinkedmesh: 5
- };
- spine.RegionAttachment = function (name) {
- this.name = name;
- this.offset = new spine.Float32Array(8);
- this.offset.length = 8;
- this.uvs = new spine.Float32Array(8);
- this.uvs.length = 8;
- };
- spine.RegionAttachment.prototype = {
- type: spine.AttachmentType.region,
- x: 0, y: 0,
- rotation: 0,
- scaleX: 1, scaleY: 1,
- width: 0, height: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- rendererObject: null,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- setUVs: function (u, v, u2, v2, rotate) {
- var uvs = this.uvs;
- if (rotate) {
- uvs[2/*X2*/] = u;
- uvs[3/*Y2*/] = v2;
- uvs[4/*X3*/] = u;
- uvs[5/*Y3*/] = v;
- uvs[6/*X4*/] = u2;
- uvs[7/*Y4*/] = v;
- uvs[0/*X1*/] = u2;
- uvs[1/*Y1*/] = v2;
- } else {
- uvs[0/*X1*/] = u;
- uvs[1/*Y1*/] = v2;
- uvs[2/*X2*/] = u;
- uvs[3/*Y2*/] = v;
- uvs[4/*X3*/] = u2;
- uvs[5/*Y3*/] = v;
- uvs[6/*X4*/] = u2;
- uvs[7/*Y4*/] = v2;
- }
- },
- updateOffset: function () {
- var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX;
- var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY;
- var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX;
- var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY;
- var localX2 = localX + this.regionWidth * regionScaleX;
- var localY2 = localY + this.regionHeight * regionScaleY;
- var radians = this.rotation * spine.degRad;
- var cos = Math.cos(radians);
- var sin = Math.sin(radians);
- var localXCos = localX * cos + this.x;
- var localXSin = localX * sin;
- var localYCos = localY * cos + this.y;
- var localYSin = localY * sin;
- var localX2Cos = localX2 * cos + this.x;
- var localX2Sin = localX2 * sin;
- var localY2Cos = localY2 * cos + this.y;
- var localY2Sin = localY2 * sin;
- var offset = this.offset;
- offset[0/*X1*/] = localXCos - localYSin;
- offset[1/*Y1*/] = localYCos + localXSin;
- offset[2/*X2*/] = localXCos - localY2Sin;
- offset[3/*Y2*/] = localY2Cos + localXSin;
- offset[4/*X3*/] = localX2Cos - localY2Sin;
- offset[5/*Y3*/] = localY2Cos + localX2Sin;
- offset[6/*X4*/] = localX2Cos - localYSin;
- offset[7/*Y4*/] = localYCos + localX2Sin;
- },
- computeVertices: function (x, y, bone, vertices) {
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.a, m01 = bone.b, m10 = bone.c, m11 = bone.d;
- var offset = this.offset;
- vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x;
- vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y;
- vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x;
- vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y;
- vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x;
- vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y;
- vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x;
- vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y;
- }
- };
- spine.MeshAttachment = function (name) {
- this.name = name;
- };
- spine.MeshAttachment.prototype = {
- type: spine.AttachmentType.mesh,
- vertices: null,
- uvs: null,
- regionUVs: null,
- triangles: null,
- hullLength: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- inheritFFD: true,
- parentMesh: null,
- rendererObject: null,
- regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- edges: null,
- width: 0, height: 0,
- updateUVs: function () {
- var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV;
- var n = this.regionUVs.length;
- if (!this.uvs || this.uvs.length != n) this.uvs = new spine.Float32Array(n);
- if (this.regionRotate) {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width;
- this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height;
- }
- } else {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i] * width;
- this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height;
- }
- }
- },
- computeWorldVertices: function (x, y, slot, worldVertices) {
- var bone = slot.bone;
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.a, m01 = bone.b, m10 = bone.c, m11 = bone.d;
- var vertices = this.vertices;
- var verticesCount = vertices.length;
- if (slot.attachmentVertices.length == verticesCount) vertices = slot.attachmentVertices;
- for (var i = 0; i < verticesCount; i += 2) {
- var vx = vertices[i];
- var vy = vertices[i + 1];
- worldVertices[i] = vx * m00 + vy * m01 + x;
- worldVertices[i + 1] = vx * m10 + vy * m11 + y;
- }
- },
- setParentMesh: function (parentMesh) {
- this.parentMesh = parentMesh;
- if (parentMesh) {
- this.vertices = parentMesh.vertices;
- this.regionUVs = parentMesh.regionUVs;
- this.triangles = parentMesh.triangles;
- this.hullLength = parentMesh.hullLength;
- this.edges = parentMesh.edges;
- this.width = parentMesh.width;
- this.height = parentMesh.height;
- }
- }
- };
- spine.WeightedMeshAttachment = function (name) {
- this.name = name;
- };
- spine.WeightedMeshAttachment.prototype = {
- type: spine.AttachmentType.weightedmesh,
- bones: null,
- weights: null,
- uvs: null,
- regionUVs: null,
- triangles: null,
- hullLength: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- inheritFFD: true,
- parentMesh: null,
- rendererObject: null,
- regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- edges: null,
- width: 0, height: 0,
- updateUVs: function (u, v, u2, v2, rotate) {
- var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV;
- var n = this.regionUVs.length;
- if (!this.uvs || this.uvs.length != n) this.uvs = new spine.Float32Array(n);
- if (this.regionRotate) {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width;
- this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height;
- }
- } else {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i] * width;
- this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height;
- }
- }
- },
- computeWorldVertices: function (x, y, slot, worldVertices) {
- var skeletonBones = slot.bone.skeleton.bones;
- var weights = this.weights;
- var bones = this.bones;
- var w = 0, v = 0, b = 0, f = 0, n = bones.length, nn;
- var wx, wy, bone, vx, vy, weight;
- if (!slot.attachmentVertices.length) {
- for (; v < n; w += 2) {
- wx = 0;
- wy = 0;
- nn = bones[v++] + v;
- for (; v < nn; v++, b += 3) {
- bone = skeletonBones[bones[v]];
- vx = weights[b];
- vy = weights[b + 1];
- weight = weights[b + 2];
- wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
- wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
- }
- worldVertices[w] = wx + x;
- worldVertices[w + 1] = wy + y;
- }
- } else {
- var ffd = slot.attachmentVertices;
- for (; v < n; w += 2) {
- wx = 0;
- wy = 0;
- nn = bones[v++] + v;
- for (; v < nn; v++, b += 3, f += 2) {
- bone = skeletonBones[bones[v]];
- vx = weights[b] + ffd[f];
- vy = weights[b + 1] + ffd[f + 1];
- weight = weights[b + 2];
- wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
- wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
- }
- worldVertices[w] = wx + x;
- worldVertices[w + 1] = wy + y;
- }
- }
- },
- setParentMesh: function (parentMesh) {
- this.parentMesh = parentMesh;
- if (parentMesh) {
- this.bones = parentMesh.bones;
- this.weights = parentMesh.weights;
- this.regionUVs = parentMesh.regionUVs;
- this.triangles = parentMesh.triangles;
- this.hullLength = parentMesh.hullLength;
- this.edges = parentMesh.edges;
- this.width = parentMesh.width;
- this.height = parentMesh.height;
- }
- }
- };
- spine.BoundingBoxAttachment = function (name) {
- this.name = name;
- };
- spine.BoundingBoxAttachment.prototype = {
- type: spine.AttachmentType.boundingbox,
- computeWorldVertices: function (x, y, bone, worldVertices) {
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.a, m01 = bone.b, m10 = bone.c, m11 = bone.d;
- var vertices = this.vertices;
- for (var i = 0, n = vertices.length; i < n; i += 2) {
- var px = vertices[i];
- var py = vertices[i + 1];
- worldVertices[i] = px * m00 + py * m01 + x;
- worldVertices[i + 1] = px * m10 + py * m11 + y;
- }
- }
- };
- spine.AnimationStateData = function (skeletonData) {
- this.skeletonData = skeletonData;
- this.animationToMixTime = {};
- };
- spine.AnimationStateData.prototype = {
- defaultMix: 0,
- setMixByName: function (fromName, toName, duration) {
- var from = this.skeletonData.findAnimation(fromName);
- if (!from) throw "Animation not found: " + fromName;
- var to = this.skeletonData.findAnimation(toName);
- if (!to) throw "Animation not found: " + toName;
- this.setMix(from, to, duration);
- },
- setMix: function (from, to, duration) {
- this.animationToMixTime[from.name + ":" + to.name] = duration;
- },
- getMix: function (from, to) {
- var key = from.name + ":" + to.name;
- return this.animationToMixTime.hasOwnProperty(key) ? this.animationToMixTime[key] : this.defaultMix;
- }
- };
- spine.TrackEntry = function () {};
- spine.TrackEntry.prototype = {
- next: null, previous: null,
- animation: null,
- loop: false,
- delay: 0, time: 0, lastTime: -1, endTime: 0,
- timeScale: 1,
- mixTime: 0, mixDuration: 0, mix: 1,
- onStart: null, onEnd: null, onComplete: null, onEvent: null
- };
- spine.AnimationState = function (stateData) {
- this.data = stateData;
- this.tracks = [];
- this.events = [];
- };
- spine.AnimationState.prototype = {
- onStart: null,
- onEnd: null,
- onComplete: null,
- onEvent: null,
- timeScale: 1,
- update: function (delta) {
- delta *= this.timeScale;
- for (var i = 0; i < this.tracks.length; i++) {
- var current = this.tracks[i];
- if (!current) continue;
- current.time += delta * current.timeScale;
- if (current.previous) {
- var previousDelta = delta * current.previous.timeScale;
- current.previous.time += previousDelta;
- current.mixTime += previousDelta;
- }
- var next = current.next;
- if (next) {
- next.time = current.lastTime - next.delay;
- if (next.time >= 0) this.setCurrent(i, next);
- } else {
- // End non-looping animation when it reaches its end time and there is no next entry.
- if (!current.loop && current.lastTime >= current.endTime) this.clearTrack(i);
- }
- }
- },
- apply: function (skeleton) {
- for (var i = 0; i < this.tracks.length; i++) {
- var current = this.tracks[i];
- if (!current) continue;
- this.events.length = 0;
- var time = current.time;
- var lastTime = current.lastTime;
- var endTime = current.endTime;
- var loop = current.loop;
- if (!loop && time > endTime) time = endTime;
- var previous = current.previous;
- if (!previous) {
- if (current.mix == 1)
- current.animation.apply(skeleton, current.lastTime, time, loop, this.events);
- else
- current.animation.mix(skeleton, current.lastTime, time, loop, this.events, current.mix);
- } else {
- var previousTime = previous.time;
- if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
- previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
- var alpha = current.mixTime / current.mixDuration * current.mix;
- if (alpha >= 1) {
- alpha = 1;
- current.previous = null;
- }
- current.animation.mix(skeleton, current.lastTime, time, loop, this.events, alpha);
- }
- for (var ii = 0, nn = this.events.length; ii < nn; ii++) {
- var event = this.events[ii];
- if (current.onEvent) current.onEvent(i, event);
- if (this.onEvent) this.onEvent(i, event);
- }
- // Check if completed the animation or a loop iteration.
- if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
- var count = Math.floor(time / endTime);
- if (current.onComplete) current.onComplete(i, count);
- if (this.onComplete) this.onComplete(i, count);
- }
- current.lastTime = current.time;
- }
- },
- clearTracks: function () {
- for (var i = 0, n = this.tracks.length; i < n; i++)
- this.clearTrack(i);
- this.tracks.length = 0;
- },
- clearTrack: function (trackIndex) {
- if (trackIndex >= this.tracks.length) return;
- var current = this.tracks[trackIndex];
- if (!current) return;
- if (current.onEnd) current.onEnd(trackIndex);
- if (this.onEnd) this.onEnd(trackIndex);
- this.tracks[trackIndex] = null;
- },
- _expandToIndex: function (index) {
- if (index < this.tracks.length) return this.tracks[index];
- while (index >= this.tracks.length)
- this.tracks[this.tracks.length] = null;
- return null;
- },
- setCurrent: function (index, entry) {
- var current = this._expandToIndex(index);
- if (current) {
- var previous = current.previous;
- current.previous = null;
- if (current.onEnd) current.onEnd(index);
- if (this.onEnd) this.onEnd(index);
- entry.mixDuration = this.data.getMix(current.animation, entry.animation);
- if (entry.mixDuration > 0) {
- entry.mixTime = 0;
- // If a mix is in progress, mix from the closest animation.
- if (previous && current.mixTime / current.mixDuration < 0.5)
- entry.previous = previous;
- else
- entry.previous = current;
- }
- }
- this.tracks[index] = entry;
- if (entry.onStart) entry.onStart(index);
- if (this.onStart) this.onStart(index);
- },
- setAnimationByName: function (trackIndex, animationName, loop) {
- var animation = this.data.skeletonData.findAnimation(animationName);
- if (!animation) throw "Animation not found: " + animationName;
- return this.setAnimation(trackIndex, animation, loop);
- },
- /** Set the current animation. Any queued animations are cleared. */
- setAnimation: function (trackIndex, animation, loop) {
- var entry = new spine.TrackEntry();
- entry.animation = animation;
- entry.loop = loop;
- entry.endTime = animation.duration;
- this.setCurrent(trackIndex, entry);
- return entry;
- },
- addAnimationByName: function (trackIndex, animationName, loop, delay) {
- var animation = this.data.skeletonData.findAnimation(animationName);
- if (!animation) throw "Animation not found: " + animationName;
- return this.addAnimation(trackIndex, animation, loop, delay);
- },
- /** Adds an animation to be played delay seconds after the current or last queued animation.
- * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
- addAnimation: function (trackIndex, animation, loop, delay) {
- var entry = new spine.TrackEntry();
- entry.animation = animation;
- entry.loop = loop;
- entry.endTime = animation.duration;
- var last = this._expandToIndex(trackIndex);
- if (last) {
- while (last.next)
- last = last.next;
- last.next = entry;
- } else
- this.tracks[trackIndex] = entry;
- if (delay <= 0) {
- if (last)
- delay += last.endTime - this.data.getMix(last.animation, animation);
- else
- delay = 0;
- }
- entry.delay = delay;
- return entry;
- },
- /** May be null. */
- getCurrent: function (trackIndex) {
- if (trackIndex >= this.tracks.length) return null;
- return this.tracks[trackIndex];
- }
- };
- spine.SkeletonJson = function (attachmentLoader) {
- this.attachmentLoader = attachmentLoader;
- this.linkedMeshes = [];
- };
- spine.SkeletonJson.prototype = {
- scale: 1,
- readSkeletonData: function (root, name) {
- var skeletonData = new spine.SkeletonData();
- skeletonData.name = name;
- // Skeleton.
- var skeletonMap = root["skeleton"];
- if (skeletonMap) {
- skeletonData.hash = skeletonMap["hash"];
- skeletonData.version = skeletonMap["spine"];
- skeletonData.width = skeletonMap["width"] || 0;
- skeletonData.height = skeletonMap["height"] || 0;
- }
- // Bones.
- var bones = root["bones"];
- for (var i = 0, n = bones.length; i < n; i++) {
- var boneMap = bones[i];
- var parent = null;
- if (boneMap["parent"]) {
- parent = skeletonData.findBone(boneMap["parent"]);
- if (!parent) throw "Parent bone not found: " + boneMap["parent"];
- }
- var boneData = new spine.BoneData(boneMap["name"], parent);
- boneData.length = (boneMap["length"] || 0) * this.scale;
- boneData.x = (boneMap["x"] || 0) * this.scale;
- boneData.y = (boneMap["y"] || 0) * this.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[i] = boneData;
- }
- // IK constraints.
- var ik = root["ik"];
- if (ik) {
- for (var i = 0, n = ik.length; i < n; i++) {
- var ikMap = ik[i];
- var ikConstraintData = new spine.IkConstraintData(ikMap["name"]);
- var bones = ikMap["bones"];
- for (var ii = 0, nn = bones.length; ii < nn; ii++) {
- var bone = skeletonData.findBone(bones[ii]);
- if (!bone) throw "IK bone not found: " + bones[ii];
- ikConstraintData.bones[ii] = bone;
- }
- ikConstraintData.target = skeletonData.findBone(ikMap["target"]);
- if (!ikConstraintData.target) throw "Target bone not found: " + ikMap["target"];
- ikConstraintData.bendDirection = (!ikMap.hasOwnProperty("bendPositive") || ikMap["bendPositive"]) ? 1 : -1;
- ikConstraintData.mix = ikMap.hasOwnProperty("mix") ? ikMap["mix"] : 1;
- skeletonData.ikConstraints[i] = ikConstraintData;
- }
- }
- // Transform constraints.
- var transform = root["transform"];
- if (transform) {
- for (var i = 0, n = transform.length; i < n; i++) {
- var transformMap = transform[i];
- var transformConstraintData = new spine.TransformConstraintData(transformMap["name"]);
- transformConstraintData.bone = skeletonData.findBone(transformMap["bone"]);
- if (!transformConstraintData.bone) throw "Bone not found: " + transformMap["bone"];
- transformConstraintData.target = skeletonData.findBone(transformMap["target"]);
- if (!transformConstraintData.target) throw "Target bone not found: " + transformMap["target"];
- transformConstraintData.mix = transformMap.hasOwnProperty("translateMix") ? ikMap["translateMix"] : 1;
- transformConstraintData.x = (transformMap["x"] || 0) * this.scale;
- transformConstraintData.y = (transformMap["y"] || 0) * this.scale;
- skeletonData.transformConstraints[i] = transformConstraintData;
- }
- }
- // Slots.
- var slots = root["slots"];
- for (var i = 0, n = slots.length; i < n; i++) {
- var slotMap = slots[i];
- var boneData = skeletonData.findBone(slotMap["bone"]);
- if (!boneData) throw "Slot bone not found: " + slotMap["bone"];
- var slotData = new spine.SlotData(slotMap["name"], boneData);
- var color = slotMap["color"];
- if (color) {
- slotData.r = this.toColor(color, 0);
- slotData.g = this.toColor(color, 1);
- slotData.b = this.toColor(color, 2);
- slotData.a = this.toColor(color, 3);
- }
- slotData.attachmentName = slotMap["attachment"];
- slotData.blendMode = spine.BlendMode[slotMap["blend"] || "normal"];
- skeletonData.slots[i] = slotData;
- }
- // Skins.
- var skins = root["skins"];
- for (var skinName in skins) {
- if (!skins.hasOwnProperty(skinName)) continue;
- var skinMap = skins[skinName];
- var skin = new spine.Skin(skinName);
- for (var slotName in skinMap) {
- if (!skinMap.hasOwnProperty(slotName)) continue;
- var slotIndex = skeletonData.findSlotIndex(slotName);
- var slotEntry = skinMap[slotName];
- for (var attachmentName in slotEntry) {
- if (!slotEntry.hasOwnProperty(attachmentName)) continue;
- var attachment = this.readAttachment(skin, slotIndex, attachmentName, slotEntry[attachmentName]);
- if (attachment) skin.addAttachment(slotIndex, attachmentName, attachment);
- }
- }
- skeletonData.skins[skeletonData.skins.length] = skin;
- if (skin.name == "default") skeletonData.defaultSkin = skin;
- }
- // Linked meshes.
- for (var i = 0, n = this.linkedMeshes.length; i < n; i++) {
- var linkedMesh = this.linkedMeshes[i];
- var skin = !linkedMesh.skin ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);
- if (!skin) throw "Skin not found: " + linkedMesh.skin;
- var parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);
- if (!parent) throw "Parent mesh not found: " + linkedMesh.parent;
- linkedMesh.mesh.setParentMesh(parent);
- linkedMesh.mesh.updateUVs();
- }
- this.linkedMeshes.length = 0;
- // Events.
- var events = root["events"];
- for (var eventName in events) {
- if (!events.hasOwnProperty(eventName)) continue;
- var eventMap = events[eventName];
- var eventData = new spine.EventData(eventName);
- eventData.intValue = eventMap["int"] || 0;
- eventData.floatValue = eventMap["float"] || 0;
- eventData.stringValue = eventMap["string"] || null;
- skeletonData.events[skeletonData.events.length] = eventData;
- }
- // Animations.
- var animations = root["animations"];
- for (var animationName in animations) {
- if (!animations.hasOwnProperty(animationName)) continue;
- this.readAnimation(animationName, animations[animationName], skeletonData);
- }
- return skeletonData;
- },
- readAttachment: function (skin, slotIndex, name, map) {
- name = map["name"] || name;
- var type = map["type"] || "region";
- if (type == "skinnedmesh") type = "weightedmesh";
- type = spine.AttachmentType[type];
- var path = map["path"] || name;
- var scale = this.scale;
- switch (type) {
- case spine.AttachmentType.region:
- var region = this.attachmentLoader.newRegionAttachment(skin, name, path);
- if (!region) return null;
- region.path = path;
- region.x = (map["x"] || 0) * scale;
- region.y = (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 = (map["width"] || 0) * scale;
- region.height = (map["height"] || 0) * scale;
- var color = map["color"];
- if (color) {
- region.r = this.toColor(color, 0);
- region.g = this.toColor(color, 1);
- region.b = this.toColor(color, 2);
- region.a = this.toColor(color, 3);
- }
- region.updateOffset();
- return region;
- case spine.AttachmentType.mesh:
- case spine.AttachmentType.linkedmesh:
- var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
- if (!mesh) return null;
- mesh.path = path;
- color = map["color"];
- if (color) {
- mesh.r = this.toColor(color, 0);
- mesh.g = this.toColor(color, 1);
- mesh.b = this.toColor(color, 2);
- mesh.a = this.toColor(color, 3);
- }
- mesh.width = (map["width"] || 0) * scale;
- mesh.height = (map["height"] || 0) * scale;
- if (!map["parent"]) {
- mesh.vertices = this.getFloatArray(map, "vertices", scale);
- mesh.triangles = this.getUint32Array(map, "triangles");
- mesh.regionUVs = this.getFloatArray(map, "uvs", 1);
- mesh.updateUVs();
- mesh.hullLength = (map["hull"] || 0) * 2;
- if (map["edges"]) mesh.edges = this.getUint16Array(map, "edges");
- } else {
- mesh.inheritFFD = map.hasOwnProperty("ffd") ? map["ffd"] : true;
- this.linkedMeshes[this.linkedMeshes.length] = {mesh: mesh, skin: map["skin"], slotIndex: slotIndex, parent: map["parent"]};
- }
- return mesh;
- case spine.AttachmentType.weightedmesh:
- case spine.AttachmentType.weightedlinkedmesh:
- var mesh = this.attachmentLoader.newWeightedMeshAttachment(skin, name, path);
- if (!mesh) return null;
- mesh.path = path;
- color = map["color"];
- if (color) {
- mesh.r = this.toColor(color, 0);
- mesh.g = this.toColor(color, 1);
- mesh.b = this.toColor(color, 2);
- mesh.a = this.toColor(color, 3);
- }
- mesh.width = (map["width"] || 0) * scale;
- mesh.height = (map["height"] || 0) * scale;
- if (!map["parent"]) {
- var uvs = this.getFloatArray(map, "uvs", 1);
- var vertices = this.getFloatArray(map, "vertices", 1);
- var weights = new spine.Float32Array(uvs.length * 3 * 3);
- var bones = new spine.Uint32Array(uvs.length * 3);
- for (var i = 0, b = 0, w = 0, n = vertices.length; i < n; ) {
- var boneCount = vertices[i++] | 0;
- bones[b++] = boneCount;
- for (var nn = i + boneCount * 4; i < nn; ) {
- bones[b++] = vertices[i];
- weights[w++] = vertices[i + 1] * scale;
- weights[w++] = vertices[i + 2] * scale;
- weights[w++] = vertices[i + 3];
- i += 4;
- }
- }
- mesh.bones = bones;
- mesh.weights = weights;
- mesh.triangles = this.getUint32Array(map, "triangles");
- mesh.regionUVs = uvs;
- mesh.updateUVs();
- mesh.hullLength = (map["hull"] || 0) * 2;
- if (map["edges"]) mesh.edges = this.getUint16Array(map, "edges");
- } else {
- mesh.inheritFFD = map.hasOwnProperty("ffd") ? map["ffd"] : true;
- this.linkedMeshes[this.linkedMeshes.length] = {mesh: mesh, skin: map["skin"], slotIndex: slotIndex, parent: map["parent"]};
- }
- return mesh;
- case spine.AttachmentType.boundingbox:
- var attachment = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
- var vertices = map["vertices"];
- attachment.vertices = new spine.Float32Array(vertices.length);
- for (var i = 0, n = vertices.length; i < n; i++)
- attachment.vertices[i] = vertices[i] * scale;
- return attachment;
- }
- throw "Unknown attachment type: " + type;
- },
- readAnimation: function (name, map, skeletonData) {
- var timelines = [];
- var duration = 0;
- var slots = map["slots"];
- for (var slotName in slots) {
- if (!slots.hasOwnProperty(slotName)) continue;
- var slotMap = slots[slotName];
- var slotIndex = skeletonData.findSlotIndex(slotName);
- for (var timelineName in slotMap) {
- if (!slotMap.hasOwnProperty(timelineName)) continue;
- var values = slotMap[timelineName];
- if (timelineName == "color") {
- var timeline = new spine.ColorTimeline(values.length);
- timeline.slotIndex = slotIndex;
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var color = valueMap["color"];
- var r = this.toColor(color, 0);
- var g = this.toColor(color, 1);
- var b = this.toColor(color, 2);
- var a = this.toColor(color, 3);
- timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]);
- } else if (timelineName == "attachment") {
- var timeline = new spine.AttachmentTimeline(values.length);
- timeline.slotIndex = slotIndex;
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
- } else
- throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")";
- }
- }
- var bones = map["bones"];
- for (var boneName in bones) {
- if (!bones.hasOwnProperty(boneName)) continue;
- var boneIndex = skeletonData.findBoneIndex(boneName);
- if (boneIndex == -1) throw "Bone not found: " + boneName;
- var boneMap = bones[boneName];
- for (var timelineName in boneMap) {
- if (!boneMap.hasOwnProperty(timelineName)) continue;
- var values = boneMap[timelineName];
- if (timelineName == "rotate") {
- var timeline = new spine.RotateTimeline(values.length);
- timeline.boneIndex = boneIndex;
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]);
- } else if (timelineName == "translate" || timelineName == "scale") {
- var timeline;
- var timelineScale = 1;
- if (timelineName == "scale")
- timeline = new spine.ScaleTimeline(values.length);
- else {
- timeline = new spine.TranslateTimeline(values.length);
- timelineScale = this.scale;
- }
- timeline.boneIndex = boneIndex;
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var x = (valueMap["x"] || 0) * timelineScale;
- var y = (valueMap["y"] || 0) * timelineScale;
- timeline.setFrame(frameIndex, valueMap["time"], x, y);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]);
- } else
- throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")";
- }
- }
- var ikMap = map["ik"];
- for (var ikConstraintName in ikMap) {
- if (!ikMap.hasOwnProperty(ikConstraintName)) continue;
- var ikConstraint = skeletonData.findIkConstraint(ikConstraintName);
- var values = ikMap[ikConstraintName];
- var timeline = new spine.IkConstraintTimeline(values.length);
- timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var mix = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
- var bendDirection = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
- timeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]);
- }
- var ffd = map["ffd"];
- for (var skinName in ffd) {
- var skin = skeletonData.findSkin(skinName);
- var slotMap = ffd[skinName];
- for (slotName in slotMap) {
- var slotIndex = skeletonData.findSlotIndex(slotName);
- var meshMap = slotMap[slotName];
- for (var meshName in meshMap) {
- var values = meshMap[meshName];
- var timeline = new spine.FfdTimeline(values.length);
- var attachment = skin.getAttachment(slotIndex, meshName);
- if (!attachment) throw "FFD attachment not found: " + meshName;
- timeline.slotIndex = slotIndex;
- timeline.attachment = attachment;
- var isMesh = attachment.type == spine.AttachmentType.mesh;
- var vertexCount;
- if (isMesh)
- vertexCount = attachment.vertices.length;
- else
- vertexCount = attachment.weights.length / 3 * 2;
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var vertices;
- if (!valueMap["vertices"]) {
- if (isMesh)
- vertices = attachment.vertices;
- else {
- vertices = new spine.Float32Array(vertexCount);
- vertices.length = vertexCount;
- }
- } else {
- var verticesValue = valueMap["vertices"];
- var vertices = new spine.Float32Array(vertexCount);
- vertices.length = vertexCount;
- var start = valueMap["offset"] || 0;
- var nn = verticesValue.length;
- if (this.scale == 1) {
- for (var ii = 0; ii < nn; ii++)
- vertices[ii + start] = verticesValue[ii];
- } else {
- for (var ii = 0; ii < nn; ii++)
- vertices[ii + start] = verticesValue[ii] * this.scale;
- }
- if (isMesh) {
- var meshVertices = attachment.vertices;
- for (var ii = 0, nn = vertices.length; ii < nn; ii++)
- vertices[ii] += meshVertices[ii];
- }
- }
- timeline.setFrame(frameIndex, valueMap["time"], vertices);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
- }
- }
- }
- var drawOrderValues = map["drawOrder"];
- if (!drawOrderValues) drawOrderValues = map["draworder"];
- if (drawOrderValues) {
- var timeline = new spine.DrawOrderTimeline(drawOrderValues.length);
- var slotCount = skeletonData.slots.length;
- var frameIndex = 0;
- for (var i = 0, n = drawOrderValues.length; i < n; i++) {
- var drawOrderMap = drawOrderValues[i];
- var drawOrder = null;
- if (drawOrderMap["offsets"]) {
- drawOrder = new spine.Uint32Array(slotCount);
- drawOrder.length = slotCount;
- for (var ii = slotCount - 1; ii >= 0; ii--)
- drawOrder[ii] = 4294967295;
- var offsets = drawOrderMap["offsets"];
- var unchanged = new spine.Uint32Array(slotCount - offsets.length);
- unchanged.length = slotCount - offsets.length;
- var originalIndex = 0, unchangedIndex = 0;
- for (var ii = 0, nn = offsets.length; ii < nn; ii++) {
- var offsetMap = offsets[ii];
- var slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
- if (slotIndex == -1) throw "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++;
- // Fill in unchanged items.
- for (var ii = slotCount - 1; ii >= 0; ii--)
- if (drawOrder[ii] == 4294967295) drawOrder[ii] = unchanged[--unchangedIndex];
- }
- timeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
- }
- var events = map["events"];
- if (events) {
- var timeline = new spine.EventTimeline(events.length);
- var frameIndex = 0;
- for (var i = 0, n = events.length; i < n; i++) {
- var eventMap = events[i];
- var eventData = skeletonData.findEvent(eventMap["name"]);
- if (!eventData) throw "Event not found: " + eventMap["name"];
- var event = new spine.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;
- timeline.setFrame(frameIndex++, event);
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
- }
- skeletonData.animations[skeletonData.animations.length] = new spine.Animation(name, timelines, duration);
- },
- readCurve: function (timeline, frameIndex, valueMap) {
- var curve = valueMap["curve"];
- if (!curve)
- timeline.curves.setLinear(frameIndex);
- else if (curve == "stepped")
- timeline.curves.setStepped(frameIndex);
- else if (curve instanceof Array)
- timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
- },
- toColor: function (hexString, colorIndex) {
- if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString;
- return parseInt(hexString.substring(colorIndex * 2, (colorIndex * 2) + 2), 16) / 255;
- },
- getFloatArray: function (map, name, scale) {
- var list = map[name];
- var values = new spine.Float32Array(list.length);
- var i = 0, n = 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;
- },
- getUint32Array: function (map, name) {
- var list = map[name];
- var values = new spine.Uint32Array(list.length);
- for (var i = 0, n = list.length; i < n; i++)
- values[i] = list[i] | 0;
- return values;
- },
- getUint16Array: function (map, name) {
- var list = map[name];
- var values = new spine.Uint16Array(list.length);
- for (var i = 0, n = list.length; i < n; i++)
- values[i] = list[i] | 0;
- return values;
- }
- };
- spine.Atlas = function (atlasText, textureLoader) {
- this.textureLoader = textureLoader;
- this.pages = [];
- this.regions = [];
- var reader = new spine.AtlasReader(atlasText);
- var tuple = [];
- tuple.length = 4;
- var page = null;
- while (true) {
- var line = reader.readLine();
- if (line === null) break;
- line = reader.trim(line);
- if (!line.length)
- page = null;
- else if (!page) {
- page = new spine.AtlasPage();
- page.name = line;
- if (reader.readTuple(tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
- page.width = parseInt(tuple[0]);
- page.height = parseInt(tuple[1]);
- reader.readTuple(tuple);
- }
- page.format = spine.Atlas.Format[tuple[0]];
- reader.readTuple(tuple);
- page.minFilter = spine.Atlas.TextureFilter[tuple[0]];
- page.magFilter = spine.Atlas.TextureFilter[tuple[1]];
- var direction = reader.readValue();
- page.uWrap = spine.Atlas.TextureWrap.clampToEdge;
- page.vWrap = spine.Atlas.TextureWrap.clampToEdge;
- if (direction == "x")
- page.uWrap = spine.Atlas.TextureWrap.repeat;
- else if (direction == "y")
- page.vWrap = spine.Atlas.TextureWrap.repeat;
- else if (direction == "xy")
- page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat;
- textureLoader.load(page, line, this);
- this.pages[this.pages.length] = page;
- } else {
- var region = new spine.AtlasRegion();
- region.name = line;
- region.page = page;
- region.rotate = reader.readValue() == "true";
- reader.readTuple(tuple);
- var x = parseInt(tuple[0]);
- var y = parseInt(tuple[1]);
- reader.readTuple(tuple);
- var width = parseInt(tuple[0]);
- var height = parseInt(tuple[1]);
- region.u = x / page.width;
- region.v = y / page.height;
- if (region.rotate) {
- region.u2 = (x + height) / page.width;
- region.v2 = (y + width) / page.height;
- } else {
- region.u2 = (x + width) / page.width;
- region.v2 = (y + height) / page.height;
- }
- region.x = x;
- region.y = y;
- region.width = Math.abs(width);
- region.height = Math.abs(height);
- if (reader.readTuple(tuple) == 4) { // split is optional
- region.splits = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
- if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits
- region.pads = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
- reader.readTuple(tuple);
- }
- }
- region.originalWidth = parseInt(tuple[0]);
- region.originalHeight = parseInt(tuple[1]);
- reader.readTuple(tuple);
- region.offsetX = parseInt(tuple[0]);
- region.offsetY = parseInt(tuple[1]);
- region.index = parseInt(reader.readValue());
- this.regions[this.regions.length] = region;
- }
- }
- };
- spine.Atlas.prototype = {
- findRegion: function (name) {
- var regions = this.regions;
- for (var i = 0, n = regions.length; i < n; i++)
- if (regions[i].name == name) return regions[i];
- return null;
- },
- dispose: function () {
- var pages = this.pages;
- for (var i = 0, n = pages.length; i < n; i++)
- this.textureLoader.unload(pages[i].rendererObject);
- },
- updateUVs: function (page) {
- var regions = this.regions;
- for (var i = 0, n = regions.length; i < n; i++) {
- var region = regions[i];
- if (region.page != page) continue;
- region.u = region.x / page.width;
- region.v = region.y / page.height;
- if (region.rotate) {
- region.u2 = (region.x + region.height) / page.width;
- region.v2 = (region.y + region.width) / page.height;
- } else {
- region.u2 = (region.x + region.width) / page.width;
- region.v2 = (region.y + region.height) / page.height;
- }
- }
- }
- };
- spine.Atlas.Format = {
- alpha: 0,
- intensity: 1,
- luminanceAlpha: 2,
- rgb565: 3,
- rgba4444: 4,
- rgb888: 5,
- rgba8888: 6
- };
- spine.Atlas.TextureFilter = {
- nearest: 0,
- linear: 1,
- mipMap: 2,
- mipMapNearestNearest: 3,
- mipMapLinearNearest: 4,
- mipMapNearestLinear: 5,
- mipMapLinearLinear: 6
- };
- spine.Atlas.TextureWrap = {
- mirroredRepeat: 0,
- clampToEdge: 1,
- repeat: 2
- };
- spine.AtlasPage = function () {};
- spine.AtlasPage.prototype = {
- name: null,
- format: null,
- minFilter: null,
- magFilter: null,
- uWrap: null,
- vWrap: null,
- rendererObject: null,
- width: 0,
- height: 0
- };
- spine.AtlasRegion = function () {};
- spine.AtlasRegion.prototype = {
- page: null,
- name: null,
- x: 0, y: 0,
- width: 0, height: 0,
- u: 0, v: 0, u2: 0, v2: 0,
- offsetX: 0, offsetY: 0,
- originalWidth: 0, originalHeight: 0,
- index: 0,
- rotate: false,
- splits: null,
- pads: null
- };
- spine.AtlasReader = function (text) {
- this.lines = text.split(/\r\n|\r|\n/);
- };
- spine.AtlasReader.prototype = {
- index: 0,
- trim: function (value) {
- return value.replace(/^\s+|\s+$/g, "");
- },
- readLine: function () {
- if (this.index >= this.lines.length) return null;
- return this.lines[this.index++];
- },
- readValue: function () {
- var line = this.readLine();
- var colon = line.indexOf(":");
- if (colon == -1) throw "Invalid line: " + line;
- return this.trim(line.substring(colon + 1));
- },
- /** Returns the number of tuple values read (1, 2 or 4). */
- readTuple: function (tuple) {
- var line = this.readLine();
- var colon = line.indexOf(":");
- if (colon == -1) throw "Invalid line: " + line;
- var i = 0, lastMatch = colon + 1;
- for (; i < 3; i++) {
- var comma = line.indexOf(",", lastMatch);
- if (comma == -1) break;
- tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch));
- lastMatch = comma + 1;
- }
- tuple[i] = this.trim(line.substring(lastMatch));
- return i + 1;
- }
- };
- spine.AtlasAttachmentLoader = function (atlas) {
- this.atlas = atlas;
- };
- spine.AtlasAttachmentLoader.prototype = {
- newRegionAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (region attachment: " + name + ")";
- var attachment = new spine.RegionAttachment(name);
- attachment.rendererObject = region;
- attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate);
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newMeshAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (mesh attachment: " + name + ")";
- var attachment = new spine.MeshAttachment(name);
- attachment.rendererObject = region;
- attachment.regionU = region.u;
- attachment.regionV = region.v;
- attachment.regionU2 = region.u2;
- attachment.regionV2 = region.v2;
- attachment.regionRotate = region.rotate;
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newWeightedMeshAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (weighted mesh attachment: " + name + ")";
- var attachment = new spine.WeightedMeshAttachment(name);
- attachment.rendererObject = region;
- attachment.regionU = region.u;
- attachment.regionV = region.v;
- attachment.regionU2 = region.u2;
- attachment.regionV2 = region.v2;
- attachment.regionRotate = region.rotate;
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newBoundingBoxAttachment: function (skin, name) {
- return new spine.BoundingBoxAttachment(name);
- }
- };
- spine.SkeletonBounds = function () {
- this.polygonPool = [];
- this.polygons = [];
- this.boundingBoxes = [];
- };
- spine.SkeletonBounds.prototype = {
- minX: 0, minY: 0, maxX: 0, maxY: 0,
- update: function (skeleton, updateAabb) {
- var slots = skeleton.slots;
- var slotCount = slots.length;
- var x = skeleton.x, y = skeleton.y;
- var boundingBoxes = this.boundingBoxes;
- var polygonPool = this.polygonPool;
- var polygons = this.polygons;
- boundingBoxes.length = 0;
- for (var i = 0, n = polygons.length; i < n; i++)
- polygonPool[polygonPool.length] = polygons[i];
- polygons.length = 0;
- for (var i = 0; i < slotCount; i++) {
- var slot = slots[i];
- var boundingBox = slot.attachment;
- if (boundingBox.type != spine.AttachmentType.boundingbox) continue;
- boundingBoxes[boundingBoxes.length] = boundingBox;
- var poolCount = polygonPool.length, polygon;
- if (poolCount > 0) {
- polygon = polygonPool[poolCount - 1];
- polygonPool.splice(poolCount - 1, 1);
- polygon.length = boundingBox.vertices.length;
- } else
- polygon = new Array(boundingBox.vertices.length);
- polygons[polygons.length] = polygon;
- boundingBox.computeWorldVertices(x, y, slot.bone, polygon);
- }
- if (updateAabb) this.aabbCompute();
- },
- aabbCompute: function () {
- var polygons = this.polygons;
- var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = -Number.MAX_VALUE, maxY = -Number.MAX_VALUE;
- for (var i = 0, n = polygons.length; i < n; i++) {
- var vertices = polygons[i];
- for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) {
- var x = vertices[ii];
- var y = vertices[ii + 1];
- minX = Math.min(minX, x);
- minY = Math.min(minY, y);
- maxX = Math.max(maxX, x);
- maxY = Math.max(maxY, y);
- }
- }
- this.minX = minX;
- this.minY = minY;
- this.maxX = maxX;
- this.maxY = maxY;
- },
- /** Returns true if the axis aligned bounding box contains the point. */
- aabbContainsPoint: function (x, y) {
- return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
- },
- /** Returns true if the axis aligned bounding box intersects the line segment. */
- aabbIntersectsSegment: function (x1, y1, x2, y2) {
- var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
- if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
- return false;
- var m = (y2 - y1) / (x2 - x1);
- var y = m * (minX - x1) + y1;
- if (y > minY && y < maxY) return true;
- y = m * (maxX - x1) + y1;
- if (y > minY && y < maxY) return true;
- var x = (minY - y1) / m + x1;
- if (x > minX && x < maxX) return true;
- x = (maxY - y1) / m + x1;
- if (x > minX && x < maxX) return true;
- return false;
- },
- /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
- aabbIntersectsSkeleton: function (bounds) {
- return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
- },
- /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
- * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */
- containsPoint: function (x, y) {
- var polygons = this.polygons;
- for (var i = 0, n = polygons.length; i < n; i++)
- if (this.polygonContainsPoint(polygons[i], x, y)) return this.boundingBoxes[i];
- return null;
- },
- /** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
- * more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. */
- intersectsSegment: function (x1, y1, x2, y2) {
- var polygons = this.polygons;
- for (var i = 0, n = polygons.length; i < n; i++)
- if (polygons[i].intersectsSegment(x1, y1, x2, y2)) return this.boundingBoxes[i];
- return null;
- },
- /** Returns true if the polygon contains the point. */
- polygonContainsPoint: function (polygon, x, y) {
- var nn = polygon.length;
- var prevIndex = nn - 2;
- var inside = false;
- for (var ii = 0; ii < nn; ii += 2) {
- var vertexY = polygon[ii + 1];
- var prevY = polygon[prevIndex + 1];
- if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
- var vertexX = polygon[ii];
- if (vertexX + (y - vertexY) / (prevY - vertexY) * (polygon[prevIndex] - vertexX) < x) inside = !inside;
- }
- prevIndex = ii;
- }
- return inside;
- },
- /** Returns true if the polygon contains the line segment. */
- polygonIntersectsSegment: function (polygon, x1, y1, x2, y2) {
- var nn = polygon.length;
- var width12 = x1 - x2, height12 = y1 - y2;
- var det1 = x1 * y2 - y1 * x2;
- var x3 = polygon[nn - 2], y3 = polygon[nn - 1];
- for (var ii = 0; ii < nn; ii += 2) {
- var x4 = polygon[ii], y4 = polygon[ii + 1];
- var det2 = x3 * y4 - y3 * x4;
- var width34 = x3 - x4, height34 = y3 - y4;
- var det3 = width12 * height34 - height12 * width34;
- var x = (det1 * width34 - width12 * det2) / det3;
- if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
- var y = (det1 * height34 - height12 * det2) / det3;
- if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true;
- }
- x3 = x4;
- y3 = y4;
- }
- return false;
- },
- getPolygon: function (attachment) {
- var index = this.boundingBoxes.indexOf(attachment);
- return index == -1 ? null : this.polygons[index];
- },
- getWidth: function () {
- return this.maxX - this.minX;
- },
- getHeight: function () {
- return this.maxY - this.minY;
- }
- };
|