支持spine4.3
This commit is contained in:
1 parent
63e4f61631
commit
0656684a92
206 files changed
+100597
-1320
No files matched your search
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
var ft=Object.defineProperty;var gt=(W,t,e)=>t in W?ft(W,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):W[t]=e;var T=(W,t,e)=>gt(W,typeof t!="symbol"?t+"":t,e);import{f as ht,R as pt,N as dt,ac as ut,Z as mt,b4 as yt,O as rt,b5 as at,U as D,B as Tt}from"./index-Bx8XTHrS.js";import{$ as Rt,a0 as Yt,a1 as Ft,a2 as Et,y as _t,a3 as Ot,a4 as kt,a5 as Xt,a6 as Bt,a7 as Nt,a8 as Dt,a9 as $t,aa as zt,ab as Wt,ad as qt,H as Gt,ae as Jt,af as Ht,ag as Zt,ah as Kt,ai as Qt,aj as jt,ak as te,al as ee,am as se,an as ne,ao as ie,ap as oe,aq as re,ar as ae,as as le,at as ce,au as he,av as pe,aw as de,ax as ue,ay as fe,az as ge,aA as me,aB as ye,aC as Te,aD as be,aE as we,aF as xe,aG as Ae,aH as Pe,aI as Ie,aJ as Ce,aK as Ve,aL as Le,aM as Se,aN as Me,aO as ve,aP as Ue,aQ as Re,aR as Ye,aS as Fe,aT as Ee,x as _e,aU as Oe,aV as ke,aW as Xe,aX as Be,aY as Ne,aZ as De,a_ as $e,a$ as ze,b0 as We,b1 as qe,b2 as Ge,b3 as Je,b6 as He,b7 as Ze,b8 as Ke,b9 as Qe,ba as je,bb as ts,bc as es,bd as ss,be as ns,bf as is,bg as os,bh as rs,bi as as,bj as ls,bk as cs,bl as hs,bm as ps,bn as ds,bo as us,bp as fs,bq as gs,br as ms,bs as ys,bt as Ts,bu as bs,w as ws,X as xs,J as As,Y as Ps,z as Is,bv as Cs,bw as Vs,bx as Ls,by as Ss,bz as Ms,bA as vs,bB as Us,bC as Rs,bD as Ys,bE as Fs,bF as Es,bG as _s,T as Os,bH as ks,bI as Xs,b as Bs,bJ as Ns,c as Ds,bK as $s,bL as zs,bM as Ws,bN as qs,bO as Gs,bP as Js,bQ as Hs,bR as Zs,bS as Ks,bT as Qs,bU as js,bV as tn,bW as en,bX as sn,bY as nn,bZ as on,b_ as rn,V as an,b$ as ln,c0 as cn,c1 as hn,c2 as pn,c3 as dn}from"./index-Bx8XTHrS.js";class It{constructor(t){T(this,"skeletonData");T(this,"animationToMixTime",{});T(this,"defaultMix",0);if(!t)throw new Error("skeletonData cannot be null.");this.skeletonData=t}setMix(t,e,n){return typeof t=="string"?this.setMix1(t,e,n):this.setMix2(t,e,n)}setMix1(t,e,n){const s=this.skeletonData.findAnimation(t);if(!s)throw new Error(`Animation not found: ${t}`);const i=this.skeletonData.findAnimation(e);if(!i)throw new Error(`Animation not found: ${e}`);this.setMix2(s,i,n)}setMix2(t,e,n){if(!t)throw new Error("from cannot be null.");if(!e)throw new Error("to cannot be null.");const s=`${t.name}.${e.name}`;this.animationToMixTime[s]=n}getMix(t,e){const n=`${t.name}.${e.name}`,s=this.animationToMixTime[n];return s===void 0?this.defaultMix:s}}class Ct{constructor(t,e="",n=new bt,s=new lt){T(this,"textureLoader");T(this,"pathPrefix");T(this,"downloader");T(this,"cache");T(this,"errors",{});T(this,"toLoad",0);T(this,"loaded",0);T(this,"texturePmaInfo",{});this.textureLoader=t,this.pathPrefix=e,this.downloader=n,this.cache=s}start(t){return this.toLoad++,this.pathPrefix+t}success(t,e,n){this.toLoad--,this.loaded++,this.cache.assets[e]=n,this.cache.assetsRefCount[e]=(this.cache.assetsRefCount[e]||0)+1,t&&t(e,n)}error(t,e,n){this.toLoad--,this.loaded++,this.errors[e]=n,t&&t(e,n)}loadAll(){return new Promise((e,n)=>{const s=()=>{if(this.isLoadingComplete()){this.hasErrors()?n(this.errors):e(this);return}requestAnimationFrame(s)};requestAnimationFrame(s)})}setRawDataURI(t,e){this.downloader.rawDataUris[this.pathPrefix+t]=e}loadBinary(t,e=()=>{},n=()=>{}){t=this.start(t),!this.reuseAssets(t,e,n)&&(this.cache.assetsLoaded[t]=new Promise((s,i)=>{this.downloader.downloadBinary(t,o=>{this.success(e,t,o),s(o)},(o,r)=>{const l=`Couldn't load binary ${t}: status ${o}, ${r}`;this.error(n,t,l),i(l)})}))}loadText(t,e=()=>{},n=()=>{}){t=this.start(t),this.downloader.downloadText(t,s=>{this.success(e,t,s)},(s,i)=>{this.error(n,t,`Couldn't load text ${t}: status ${s}, ${i}`)})}loadJson(t,e=()=>{},n=()=>{}){t=this.start(t),!this.reuseAssets(t,e,n)&&(this.cache.assetsLoaded[t]=new Promise((s,i)=>{this.downloader.downloadJson(t,o=>{this.success(e,t,o),s(o)},(o,r)=>{const l=`Couldn't load JSON ${t}: status ${o}, ${r}`;this.error(n,t,l),i(l)})}))}reuseAssets(t,e=()=>{},n=()=>{}){const s=this.cache.getAsset(t),i=s!==void 0;return i&&(this.cache.assetsLoaded[t]=s.then(o=>(o=o instanceof Image||o instanceof ImageBitmap?this.textureLoader(o):o,this.success(e,t,o),o)).catch(o=>{this.error(n,t,o)})),i}loadTexture(t,e=()=>{},n=()=>{}){if(t=this.start(t),this.reuseAssets(t,e,n))return;const s=this.texturePmaInfo[t];this.cache.assetsLoaded[t]=new Promise((i,o)=>{if(!!!(typeof window<"u"&&typeof navigator<"u"&&window.document))fetch(t,{mode:"cors"}).then(c=>{if(c.ok)return c.blob();const a=`Couldn't load image: ${t}`;this.error(n,t,`Couldn't load image: ${t}`),o(a)}).then(c=>c?createImageBitmap(c,{premultiplyAlpha:"none",colorSpaceConversion:"none"}):null).then(c=>{if(c){const a=this.createTexture(t,s,c);this.success(e,t,a),i(a)}});else{const c=new Image;c.crossOrigin="anonymous",c.onload=()=>{const a=this.createTexture(t,s,c);this.success(e,t,a),i(a)},c.onerror=()=>{const a=`Couldn't load image: ${t}`;this.error(n,t,a),o(a)},this.downloader.rawDataUris[t]&&(t=this.downloader.rawDataUris[t]),c.src=t}})}loadTextureAtlas(t,e=()=>{},n=()=>{},s){const i=t.lastIndexOf("/"),o=i>=0?t.substring(0,i+1)Line truncated
|
||||
${n}`:""}`)}remove(t){t=this.pathPrefix+t;const e=this.cache.assets[t];return e.dispose&&e.dispose(),delete this.cache.assets[t],delete this.cache.assetsRefCount[t],delete this.cache.assetsLoaded[t],e}removeAll(){for(const t in this.cache.assets){const e=this.cache.assets[t];e.dispose&&e.dispose()}this.cache.assets={},this.cache.assetsLoaded={},this.cache.assetsRefCount={}}isLoadingComplete(){return this.toLoad===0}getToLoad(){return this.toLoad}getLoaded(){return this.loaded}dispose(){this.removeAll()}disposeAsset(t){const e=this.cache.assets[t];if(e instanceof ht){e.dispose();return}this.disposeAssetInternal(t)}hasErrors(){return Object.keys(this.errors).length>0}getErrors(){return this.errors}disposeAssetInternal(t){if(this.cache.assetsRefCount[t]>0&&--this.cache.assetsRefCount[t]===0)return this.remove(t)}createTextureAtlas(t,e,n,s){const i=new ht(t);i.dispose=()=>{var o;if(!(this.cache.assetsRefCount[n]<=0)){this.disposeAssetInternal(n);for(const r of i.pages)(o=r.texture)==null||o.dispose()}};for(const o of i.pages){const r=this.texturePath(e,o.name,s);this.texturePmaInfo[this.pathPrefix+r]=o.pma}return i}createTexture(t,e,n){const s=this.textureLoader(n,e),i=s.dispose.bind(s);return s.dispose=()=>{this.disposeAssetInternal(t)&&i()},s}texturePath(t,e,n){return n?n[e]:t+e}}const nt=class nt{constructor(){T(this,"assets",{});T(this,"assetsRefCount",{});T(this,"assetsLoaded",{})}static getCache(t){const e=nt.AVAILABLE_CACHES.get(t);if(e)return e;const n=new nt;return nt.AVAILABLE_CACHES.set(t,n),n}async addAsset(t,e){return this.assetsLoaded[t]=Promise.resolve(e),this.assets[t]=e,e}getAsset(t){return this.assetsLoaded[t]}};T(nt,"AVAILABLE_CACHES",new Map);let lt=nt;class bt{constructor(){T(this,"callbacks",{});T(this,"rawDataUris",{})}dataUriToString(t){if(!t.startsWith("data:"))throw new Error("Not a data URI.");let e=t.indexOf("base64,");return e!==-1?(e+=7,atob(t.substr(e))):t.substr(t.indexOf(",")+1)}base64ToUint8Array(t){var e=window.atob(t),n=e.length,s=new Uint8Array(n);for(let i=0;i<n;i++)s[i]=e.charCodeAt(i);return s}dataUriToUint8Array(t){if(!t.startsWith("data:"))throw new Error("Not a data URI.");let e=t.indexOf("base64,");if(e===-1)throw new Error("Not a binary data URI.");return e+=7,this.base64ToUint8Array(t.substr(e))}downloadText(t,e,n){if(this.start(t,e,n))return;const s=this.rawDataUris[t];if(s&&!s.includes(".")){try{this.finish(t,200,this.dataUriToString(s))}catch(r){this.finish(t,400,JSON.stringify(r))}return}const i=new XMLHttpRequest;i.overrideMimeType("text/html"),i.open("GET",s||t,!0);const o=()=>{this.finish(t,i.status,i.responseText)};i.onload=o,i.onerror=o,i.send()}downloadJson(t,e,n){this.downloadText(t,s=>{e(JSON.parse(s))},n)}downloadBinary(t,e,n){if(this.start(t,e,n))return;const s=this.rawDataUris[t];if(s&&!s.includes(".")){try{this.finish(t,200,this.dataUriToUint8Array(s))}catch(r){this.finish(t,400,JSON.stringify(r))}return}const i=new XMLHttpRequest;i.open("GET",s||t,!0),i.responseType="arraybuffer";const o=()=>{this.finish(t,i.status,i.response)};i.onload=()=>{i.status===200||i.status===0?this.finish(t,200,new Uint8Array(i.response)):o()},i.onerror=o,i.send()}start(t,e,n){let s=this.callbacks[t];try{if(s)return!0;this.callbacks[t]=s=[]}finally{s.push(e,n)}}finish(t,e,n){const s=this.callbacks[t];if(delete this.callbacks[t],e===200||e===0)for(let i=0,o=s.length;i<o;i+=2)s[i](n);else for(let i=1,o=s.length;i<o;i+=2)s[i](e,n)}}class Vt{constructor(t,e=!1){T(this,"atlas");T(this,"allowMissingRegions");this.atlas=t,this.allowMissingRegions=e}findRegions(t,e,n){const s=n.regions;for(let i=0,o=s.length;i<o;i++)s[i]=this.findRegion(t,n.getPath(e,i))}findRegion(t,e){const n=this.atlas.findRegion(e);if(!n&&!this.allowMissingRegions)throw new Error(`Region not found in atlas: ${e} (attachment: ${t})`);return n}newRegionAttachment(t,e,n,s,i){return this.findRegions(n,s,i),new pt(n,i)}newMeshAttachment(t,e,n,s,i){return this.findRegions(n,s,i),new dt(n,i)}newBoundingBoxAttachment(t,e,n){return new ut(n)}newPathAttachment(t,e,n){return new mt(n)}newPointAttachment(t,e,n){return new yt(n)}newClippingAttachment(t,e,n){return new rt(n)}}class Lt{constructor(){T(this,"minX",0);T(this,"minY",0);T(this,"maxX",0);T(this,"maxY",0);T(this,"boundingBoxes",[]);T(this,"polygons",[]);T(this,"polygonPool",new at(()=>D.newFloatArray(16)))}update(t,e){if(!t)throw new Error("skeleton cannot be null.");const n=this.boundingBoxes,s=this.polygons,i=this.polygonPool,o=t.slots,r=o.length;n.length=0,i.freeAll(s),s.length=0;for(let l=0;l<r;l++){const c=o[l];if(!c.bone.active)continue;const a=c.appliedPose.attachment;if(a instanceof ut){n.push(a);let h=i.obtain();h.length!==a.worldVerticesLength&&(h=D.newFloatArray(a.worldVerticesLength)),s.push(h),a.computeWorldVertices(t,c,0,a.worldVerticesLength,h,0,2)}}e?this.aabbCompute():(this.minX=Number.POSITIVE_INFINITY,this.minY=Number.POSITIVE_INFINITY,this.maxX=Number.NEGATIVE_INFINITY,this.maxY=Number.NEGATIVE_INFINITY)}aabbCompute(){let t=Number.POSITIVE_INFLine truncated
|
||||
Vendored
+1239
File diff suppressed because it is too large.
Load diff
Vendored
-1238
File diff suppressed because it is too large.
Load diff
@@ -1 +1 @@
|
||||
.stage-wrap[data-v-1b609e97]{position:relative;width:100%;height:100%;overflow:hidden}.stage-holder[data-v-1b609e97]{width:100%;height:100%;cursor:grab;touch-action:none;background-color:#0e1219;outline:none}.stage-holder.grid[data-v-1b609e97]{background:conic-gradient(#141a26 90deg,transparent 90deg 180deg,#141a26 180deg 270deg,transparent 270deg);background-size:28px 28px}.stage-holder[data-v-1b609e97]:active{cursor:grabbing}.topbar[data-v-1b609e97]{position:absolute;top:10px;left:10px;right:10px;display:flex;align-items:center;gap:10px;padding:8px 12px;background:#141420d9;border-radius:10px;border:1px solid rgba(255,255,255,.08);font-size:12px;color:#aab;z-index:5;flex-wrap:wrap}.topbar input[type=range][data-v-1b609e97]{background:#1a1a28;border:1px solid #2e2e44;color:#dde;border-radius:5px}.tool-group[data-v-1b609e97]{display:flex;gap:6px;margin-left:6px;padding-left:12px;border-left:1px solid #2a2a3c}.tool-btn[data-v-1b609e97]{width:30px;height:26px;background:#1e1e2e;border:1px solid #2e2e44;border-radius:6px;color:#aab;font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center}.tool-btn[data-v-1b609e97]:hover{background:#2b3a5c;color:#fff}.tool-btn.on[data-v-1b609e97]{background:#3a5a8c;color:#fff;border-color:#5a7ab8}.background-menu[data-v-1b609e97]{position:relative;flex:0 0 auto}.background-btn[data-v-1b609e97]{height:28px;padding:0 11px;border:1px solid #3a4963;border-radius:6px;background:#202a3b;color:#cbd7ed;font-size:12px;cursor:pointer}.background-btn[data-v-1b609e97]:hover,.background-btn.on[data-v-1b609e97]{border-color:#7774ff;background:#343b63;color:#fff}.background-panel[data-v-1b609e97]{position:absolute;top:calc(100% + 9px);right:0;width:248px;box-sizing:border-box;padding:10px;border:1px solid #343b50;border-radius:9px;background:#141420fa;color:#aeb8cc;box-shadow:0 8px 24px #0000007a;z-index:12}.background-upload[data-v-1b609e97]{width:100%;height:30px;border:1px solid #5652b5;border-radius:6px;background:#4540a0;color:#fff;cursor:pointer}.background-upload[data-v-1b609e97]:hover{border-color:#8982ff;background:#554dc2}.background-clear[data-v-1b609e97]{width:100%;height:28px;margin-top:6px;border:1px solid #70404a;border-radius:6px;background:#512a33;color:#efb5bd;cursor:pointer}.background-clear[data-v-1b609e97]:hover:not(:disabled){border-color:#b65b6a;background:#6a303b;color:#fff}.background-clear[data-v-1b609e97]:disabled{opacity:.42;cursor:not-allowed}.background-file-input[data-v-1b609e97]{display:none}.background-file-name[data-v-1b609e97]{margin:7px 2px 9px;overflow:hidden;color:#737f98;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.background-position-row[data-v-1b609e97]{display:grid;grid-template-columns:1fr 1fr;gap:8px}.background-position-row label[data-v-1b609e97]{display:flex;align-items:center;gap:5px;color:#8995ad;font-size:11px}.background-position-row input[data-v-1b609e97]{width:0;min-width:0;flex:1;box-sizing:border-box;height:28px;padding:0 6px;border:1px solid #343e55;border-radius:5px;background:#101522;color:#e1e6f2}.background-opacity-row[data-v-1b609e97]{display:grid;grid-template-columns:46px 1fr 34px;align-items:center;gap:7px;margin-top:10px;font-size:11px}.background-opacity-row input[data-v-1b609e97]{min-width:0;accent-color:#675de0}.background-opacity-row b[data-v-1b609e97]{color:#aeb8cc;font-size:10px;text-align:right;font-variant-numeric:tabular-nums}.help-btn[data-v-1b609e97]{height:28px;margin-left:auto;padding:0 11px;flex:0 0 auto;border:1px solid #3a4963;border-radius:6px;background:#202a3b;color:#cbd7ed;font-size:12px;font-weight:700;cursor:pointer}.help-btn[data-v-1b609e97]:hover,.help-btn.on[data-v-1b609e97]{border-color:#7774ff;background:#343b63;color:#fff}.zoom-pct[data-v-1b609e97]{margin-left:0;font-variant-numeric:tabular-nums;color:#9aa;min-width:44px;text-align:center}.help-overlay[data-v-1b609e97]{position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:72px 24px 28px;box-sizing:border-box;background:#05080fb8;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.help-dialog[data-v-1b609e97]{width:min(820px,100%);max-height:100%;display:flex;flex-direction:column;overflow:hidden;border:1px solid #3a4864;border-radius:14px;background:#141a27;color:#b8c3d8;box-shadow:0 22px 70px #0000009e}.help-head[data-v-1b609e97]{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;padding:18px 20px 15px;border-bottom:1px solid #2b354a;background:linear-gradient(135deg,#202942,#181e2d)}.help-head h2[data-v-1b609e97]{margin:0;color:#eef2ff;font-size:19px}.help-head p[data-v-1b609e97]{margin:5px 0 0;color:#7786a3;font-size:11px}.help-close[data-v-1b609e97]{width:28px;height:28px;flex:0 0 28px;border:1px solid #43516b;border-radius:6px;background:#273249;color:#ccd7ed;cursor:pointer}.help-close[data-v-1b609e97]:hover{border-color:#7774ff;background:#3b4670;color:#fff}.help-body[data-v-1b609e97]{min-height:0;overflowLine truncated
|
||||
.stage-wrap[data-v-9c23fe47]{position:relative;width:100%;height:100%;overflow:hidden}.stage-holder[data-v-9c23fe47]{width:100%;height:100%;cursor:grab;touch-action:none;background-color:#0e1219;outline:none}.stage-holder.grid[data-v-9c23fe47]{background:conic-gradient(#141a26 90deg,transparent 90deg 180deg,#141a26 180deg 270deg,transparent 270deg);background-size:28px 28px}.stage-holder[data-v-9c23fe47]:active{cursor:grabbing}.topbar[data-v-9c23fe47]{position:absolute;top:10px;left:10px;right:10px;display:flex;align-items:center;gap:10px;padding:8px 12px;background:#141420d9;border-radius:10px;border:1px solid rgba(255,255,255,.08);font-size:12px;color:#aab;z-index:5;flex-wrap:wrap}.topbar input[type=range][data-v-9c23fe47]{background:#1a1a28;border:1px solid #2e2e44;color:#dde;border-radius:5px}.tool-group[data-v-9c23fe47]{display:flex;gap:6px;margin-left:6px;padding-left:12px;border-left:1px solid #2a2a3c}.tool-btn[data-v-9c23fe47]{width:30px;height:26px;background:#1e1e2e;border:1px solid #2e2e44;border-radius:6px;color:#aab;font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center}.tool-btn[data-v-9c23fe47]:hover{background:#2b3a5c;color:#fff}.tool-btn.on[data-v-9c23fe47]{background:#3a5a8c;color:#fff;border-color:#5a7ab8}.background-menu[data-v-9c23fe47]{position:relative;flex:0 0 auto}.background-btn[data-v-9c23fe47]{height:28px;padding:0 11px;border:1px solid #3a4963;border-radius:6px;background:#202a3b;color:#cbd7ed;font-size:12px;cursor:pointer}.background-btn[data-v-9c23fe47]:hover,.background-btn.on[data-v-9c23fe47]{border-color:#7774ff;background:#343b63;color:#fff}.background-panel[data-v-9c23fe47]{position:absolute;top:calc(100% + 9px);right:0;width:248px;box-sizing:border-box;padding:10px;border:1px solid #343b50;border-radius:9px;background:#141420fa;color:#aeb8cc;box-shadow:0 8px 24px #0000007a;z-index:12}.background-upload[data-v-9c23fe47]{width:100%;height:30px;border:1px solid #5652b5;border-radius:6px;background:#4540a0;color:#fff;cursor:pointer}.background-upload[data-v-9c23fe47]:hover{border-color:#8982ff;background:#554dc2}.background-clear[data-v-9c23fe47]{width:100%;height:28px;margin-top:6px;border:1px solid #70404a;border-radius:6px;background:#512a33;color:#efb5bd;cursor:pointer}.background-clear[data-v-9c23fe47]:hover:not(:disabled){border-color:#b65b6a;background:#6a303b;color:#fff}.background-clear[data-v-9c23fe47]:disabled{opacity:.42;cursor:not-allowed}.background-file-input[data-v-9c23fe47]{display:none}.background-file-name[data-v-9c23fe47]{margin:7px 2px 9px;overflow:hidden;color:#737f98;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.background-position-row[data-v-9c23fe47]{display:grid;grid-template-columns:1fr 1fr;gap:8px}.background-position-row label[data-v-9c23fe47]{display:flex;align-items:center;gap:5px;color:#8995ad;font-size:11px}.background-position-row input[data-v-9c23fe47]{width:0;min-width:0;flex:1;box-sizing:border-box;height:28px;padding:0 6px;border:1px solid #343e55;border-radius:5px;background:#101522;color:#e1e6f2}.background-opacity-row[data-v-9c23fe47]{display:grid;grid-template-columns:46px 1fr 34px;align-items:center;gap:7px;margin-top:10px;font-size:11px}.background-opacity-row input[data-v-9c23fe47]{min-width:0;accent-color:#675de0}.background-opacity-row b[data-v-9c23fe47]{color:#aeb8cc;font-size:10px;text-align:right;font-variant-numeric:tabular-nums}.help-btn[data-v-9c23fe47]{height:28px;margin-left:auto;padding:0 11px;flex:0 0 auto;border:1px solid #3a4963;border-radius:6px;background:#202a3b;color:#cbd7ed;font-size:12px;font-weight:700;cursor:pointer}.help-btn[data-v-9c23fe47]:hover,.help-btn.on[data-v-9c23fe47]{border-color:#7774ff;background:#343b63;color:#fff}.zoom-pct[data-v-9c23fe47]{margin-left:0;font-variant-numeric:tabular-nums;color:#9aa;min-width:44px;text-align:center}.help-overlay[data-v-9c23fe47]{position:absolute;top:0;right:0;bottom:0;left:0;z-index:40;display:flex;align-items:center;justify-content:center;padding:72px 24px 28px;box-sizing:border-box;background:#05080fb8;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.help-dialog[data-v-9c23fe47]{width:min(820px,100%);max-height:100%;display:flex;flex-direction:column;overflow:hidden;border:1px solid #3a4864;border-radius:14px;background:#141a27;color:#b8c3d8;box-shadow:0 22px 70px #0000009e}.help-head[data-v-9c23fe47]{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;padding:18px 20px 15px;border-bottom:1px solid #2b354a;background:linear-gradient(135deg,#202942,#181e2d)}.help-head h2[data-v-9c23fe47]{margin:0;color:#eef2ff;font-size:19px}.help-head p[data-v-9c23fe47]{margin:5px 0 0;color:#7786a3;font-size:11px}.help-close[data-v-9c23fe47]{width:28px;height:28px;flex:0 0 28px;border:1px solid #43516b;border-radius:6px;background:#273249;color:#ccd7ed;cursor:pointer}.help-close[data-v-9c23fe47]:hover{border-color:#7774ff;background:#3b4670;color:#fff}.help-body[data-v-9c23fe47]{min-height:0;overflowLine truncated
|
||||
Vendored
+71
@@ -0,0 +1,71 @@
|
||||
var Ae=Object.defineProperty;var Be=(m,o,e)=>o in m?Ae(m,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):m[o]=e;var a=(m,o,e)=>Be(m,typeof o!="symbol"?o+"":o,e);import{T as Fe,a as he,b as F,S as ue,M as pe,c as oe,W as ne,B as H,d as z,L as Te,E as O,e as ce,p as q,f as Ee,g as fe,A as Q,h as me,i as De,j as V,s as re,G as we,k as $,l as Y,m as Le,P as Ie,n as Re,o as Ne,C as X,q as be,r as _e,t as Ue,u as Ye,v as Xe,w as ee,x as j,y as ke,z as Ve,D as J,F as ge,V as Ge,H as ae,I as We,J as $e,U as xe,K as E,R as ve,N as ye,O as Pe,Q as Oe,X as He,Y as ze,Z as qe,_ as Ke}from"./index-Bx8XTHrS.js";import{$ as bt,a0 as kt,a1 as vt,a2 as yt,a3 as Pt,a4 as St,a5 as Mt,a6 as At,a7 as Bt,a8 as Ft,a9 as Et,aa as Dt,ab as Lt,ac as It,ad as Rt,ae as Nt,af as _t,ag as Ut,ah as Yt,ai as Xt,aj as Vt,ak as Gt,al as Wt,am as $t,an as Ot,ao as Ht,ap as zt,aq as qt,ar as Kt,as as Zt,at as Jt,au as Qt,av as jt,aw as es,ax as ts,ay as ss,az as os,aA as ns,aB as as,aC as rs,aD as is,aE as ls,aF as hs,aG as cs,aH as ds,aI as us,aJ as ps,aK as fs,aL as ms,aM as gs,aN as xs,aO as Cs,aP as Ts,aQ as ws,aR as bs,aS as ks,aT as vs,aU as ys,aV as Ps,aW as Ss,aX as Ms,aY as As,aZ as Bs,a_ as Fs,a$ as Es,b0 as Ds,b1 as Ls,b2 as Is,b3 as Rs,b4 as Ns,b5 as _s,b6 as Us,b7 as Ys,b8 as Xs,b9 as Vs,ba as Gs,bb as Ws,bc as $s,bd as Os,be as Hs,bf as zs,bg as qs,bh as Ks,bi as Zs,bj as Js,bk as Qs,bl as js,bm as eo,bn as to,bo as so,bp as oo,bq as no,br as ao,bs as ro,bt as io,bu as lo,bv as ho,bw as co,bx as uo,by as po,bz as fo,bA as mo,bB as go,bC as xo,bD as Co,bE as To,bF as wo,bG as bo,bH as ko,bI as vo,bJ as yo,bK as Po,bL as So,bM as Mo,bN as Ao,bO as Bo,bP as Fo,bQ as Eo,bR as Do,bS as Lo,bT as Io,bU as Ro,bV as No,bW as _o,bX as Uo,bY as Yo,bZ as Xo,b_ as Vo,b$ as Go,c0 as Wo,c1 as $o,c2 as Oo,c3 as Ho}from"./index-Bx8XTHrS.js";import{SkeletonClipping as de,SkeletonPhysicsMovement as Ze,AnimationStateData as Je,AtlasAttachmentLoader as Qe,SkeletonBounds as je}from"./index-BOcdShQh.js";import{AssetCache as qo,AssetManagerBase as Ko,Downloader as Zo,SkeletonRendererCore as Jo,Triangulator as Qo}from"./index-BOcdShQh.js";if(typeof window<"u"&&window.PIXI){const m=window.require;window.require=o=>{if(m)return m(o);if(o.startsWith("@pixi/"))return window.PIXI}}const _=class _ extends Fe{constructor(e){super(e.resource.source);a(this,"texture");this.texture=he.from(e)}static from(e){return _.textureMap.has(e)?_.textureMap.get(e):new _(e)}setFilters(e,t){this.texture.baseTexture.scaleMode=_.toPixiTextureFilter(e),this.texture.baseTexture.mipmap=_.toPixiMipMap(e)}setWraps(e,t){this.texture.baseTexture.wrapMode=_.toPixiTextureWrap(e)}dispose(){this.texture.destroy()}static toPixiTextureFilter(e){switch(e){case F.Nearest:case F.MipMapNearestLinear:case F.MipMapNearestNearest:return ue.NEAREST;case F.Linear:case F.MipMapLinearLinear:case F.MipMapLinearNearest:return ue.LINEAR;default:throw new Error(`Unknown texture filter: ${String(e)}`)}}static toPixiMipMap(e){switch(e){case F.Nearest:case F.Linear:return pe.OFF;case F.MipMapNearestLinear:case F.MipMapNearestNearest:case F.MipMapLinearLinear:case F.MipMapLinearNearest:return pe.ON;default:throw new Error(`Unknown texture filter: ${String(e)}`)}}static toPixiTextureWrap(e){switch(e){case oe.ClampToEdge:return ne.CLAMP;case oe.MirroredRepeat:return ne.MIRRORED_REPEAT;case oe.Repeat:return ne.REPEAT;default:throw new Error(`Unknown texture wrap: ${String(e)}`)}}static toPixiBlending(e){switch(e){case H.Normal:return z.NORMAL;case H.Additive:return z.ADD;case H.Multiply:return z.MULTIPLY;case H.Screen:return z.SCREEN;default:throw new Error(`Unknown blendMode: ${String(e)}`)}}};a(_,"textureMap",new Map);let G=_;const K="spineTextureAtlasLoader",et={extension:O.Asset,resolver:{test:m=>V(m,".atlas"),parse:m=>{var e,t;const o=m.split(".");return{resolution:parseFloat(((t=(e=re.RETINA_PREFIX)==null?void 0:e.exec(m))==null?void 0:t[1])??"1"),format:o[o.length-2],src:m}}},loader:{name:K,extension:{type:O.LoadParser,priority:Te.Normal,name:K},test(m){return V(m,".atlas")},async load(m){const o=await re.ADAPTER.fetch(m);if(!o.ok)throw new Error(`[${K}] Failed to fetch ${m}: ${o.status} ${o.statusText}`);return await o.text()},testParse(m,o){const e=V(o.src,".atlas"),t=typeof m=="string",s=o.loadParser===K;return Promise.resolve((e||s)&&t)},unload(m){m.dispose()},async parse(m,o,e){var p;const t=o.data||{};let s=q.dirname(o.src);s&&s.lastIndexOf("/")!==s.length-1&&(s+="/");const n=new Ee(m);if(t.images instanceof fe||typeof t.images=="string"){const h=t.images;t.images={},t.images[n.pages[0].name]=h}const r=[];let l=!0;for(const h of e.parsers)if(h.name==="loadTextures"){l=(p=h.config)==null?void 0:p.preferCreateImageBitmap;break}Q.setPreferences({preferCreateImageBitmap:!1});for(const h of n.pages){const u=h.name,c=t!=null&&t.images?t.images[u]:void 0;if(c instanceof fe)h.setTexture(G.from(c));else{const i=c??q.normalize([...s.split(q.sep),u].join(q.sep)),g={src:De(i,o.src),data:{...t.imageMetadLine truncated
|
||||
attribute vec2 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
|
||||
uniform mat3 projectionMatrix;
|
||||
uniform mat3 translationMatrix;
|
||||
uniform mat3 uTextureMatrix;
|
||||
|
||||
varying vec2 vTextureCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
|
||||
|
||||
vTextureCoord = (uTextureMatrix * vec3(aTextureCoord, 1.0)).xy;
|
||||
}
|
||||
`,rt=`
|
||||
varying vec2 vTextureCoord;
|
||||
uniform vec4 uColor;
|
||||
uniform vec4 uDarkColor;
|
||||
|
||||
uniform sampler2D uSampler;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 texColor = texture2D(uSampler, vTextureCoord);
|
||||
gl_FragColor.a = texColor.a * uColor.a;
|
||||
gl_FragColor.rgb = ((texColor.a - 1.0) * uDarkColor.a + 1.0 - texColor.rgb) * uDarkColor.rgb + texColor.rgb * uColor.rgb;
|
||||
}
|
||||
`;class it extends Le{constructor(e){const t={uSampler:e??he.EMPTY,alpha:1,uTextureMatrix:Re.IDENTITY,uColor:new Float32Array([1,1,1,1]),uDarkColor:new Float32Array([0,0,0,0])},s={tint:16777215,darkTint:0,alpha:1,pluginName:"darkTintBatch"};super(Ie.from(at,rt),t);a(this,"uvMatrix");a(this,"batchable");a(this,"pluginName");a(this,"_tintRGB");a(this,"_darkTintRGB");a(this,"_colorDirty");a(this,"_alpha");a(this,"_tintColor");a(this,"_darkTintColor");this._colorDirty=!1,this.uvMatrix=new Ne(t.uSampler),this.batchable=!0,this.pluginName=s.pluginName,this._tintColor=new X(s.tint),this._darkTintColor=new X(s.darkTint),this._tintRGB=this._tintColor.toLittleEndianNumber(),this._darkTintRGB=this._darkTintColor.toLittleEndianNumber(),this._alpha=s.alpha,this._colorDirty=!0}get texture(){return this.uniforms.uSampler}set texture(e){this.uniforms.uSampler!==e&&(!this.uniforms.uSampler.baseTexture.alphaMode!=!e.baseTexture.alphaMode&&(this._colorDirty=!0),this.uniforms.uSampler=e,this.uvMatrix.texture=e)}set alpha(e){e!==this._alpha&&(this._alpha=e,this._colorDirty=!0)}get alpha(){return this._alpha}set tint(e){e!==this.tint&&(this._tintColor.setValue(e),this._tintRGB=this._tintColor.toLittleEndianNumber(),this._colorDirty=!0)}get tint(){return this._tintColor.value}set darkTint(e){e!==this.darkTint&&(this._darkTintColor.setValue(e),this._darkTintRGB=this._darkTintColor.toLittleEndianNumber(),this._colorDirty=!0)}get darkTint(){return this._darkTintColor.value}get tintValue(){return this._tintColor.toNumber()}get darkTintValue(){return this._darkTintColor.toNumber()}update(){this._colorDirty&&(this._colorDirty=!1,X.shared.setValue(this._tintColor).premultiply(this._alpha,!0).toArray(this.uniforms.uColor),X.shared.setValue(this._darkTintColor).premultiply(this._alpha,!0).premultiply(1,!1).toArray(this.uniforms.uDarkColor)),this.uvMatrix.update()&&(this.uniforms.uTextureMatrix=this.uvMatrix.mapCoord)}}class lt extends be{constructor(e){super(new nt,new it(e),void 0,void 0);a(this,"_darkTintRGB",0)}get darkTint(){return"darkTint"in this.shader?this.shader.darkTint:null}set darkTint(e){this.shader.darkTint=e}get darkTintValue(){return this.shader.darkTintValue}_renderToBatch(e){const t=this.geometry,s=this.shader;s.uvMatrix&&(s.uvMatrix.update(),this.calculateUvs()),this.calculateVertices(),this.indices=t.indexBuffer.data,this._tintRGB=s._tintRGB,this._darkTintRGB=s._darkTintRGB,this._texture=s.texture;const n=this.material.pluginName;e.batch.setObjectRenderer(e.plugins[n]),e.plugins[n].render(this)}}const y=class y extends lt{constructor(){super();a(this,"name","")}updateFromSpineData(e,t,s,n,r,l,p,h){var C,T;this.texture=e.texture;const u=r/(h?12:8)*2,c=this.geometry.getBuffer("aTextureCoord");((C=c.data)==null?void 0:C.length)!==u&&(c.data=new Float32Array(u));const i=this.geometry.getBuffer("aVertexPosition");((T=i.data)==null?void 0:T.length)!==u&&(i.data=new Float32Array(u));let g=0;const x=c.data,d=i.data;for(let k=0;k<r;k+=h?12:8){let b=k;d[g]=n[b++],d[g+1]=n[b++],b+=4,x[g]=n[b++],x[g+1]=n[b++],g+=2}h?(y.auxColor[0]=n[8],y.auxColor[1]=n[9],y.auxColor[2]=n[10],y.auxColor[3]=n[11],this.darkTint=y.auxColor,y.auxColor[0]=n[2],y.auxColor[1]=n[3],y.auxColor[2]=n[4],y.auxColor[3]=n[5],this.tint=y.auxColor):(y.auxColor[0]=n[2],y.auxColor[1]=n[3],y.auxColor[2]=n[4],y.auxColor[3]=n[5],this.tint=y.auxColor),this.blendMode=G.toPixiBlending(t),this.alpha=y.auxColor[3];const f=this.geometry.indexBuffer;if(f.data.length!==l.length)f.data=new Uint32Array(l);else{const k=f.data;for(let b=0;b<p;b++)k[b]=l[b]}this.name=s,c.update(),i.update(),f.update()}};a(y,"auxColor",[0,0,0,0]);let ie=y;class ht extends we{constructor(e=!1){super();a(this,"_buffer");a(this,"_indexBuffer");this._buffer=new $(void 0,e,!1),this._indexBuffer=new $(void 0,e,!0),this.addAttribute("aVertexPosition",this._buffer,2,!1,Y.FLOAT).addAttribute("aTextureCoord",this._buffer,2,!1,Y.FLOAT).addAttribute("aColor",this._buffer,4,!0,Y.UNSIGNED_BYTE).addAttribute("aDarkColor",this._buffer,4,!0,Y.UNSIGNED_BYTE).addAttribute("aTextureId",this._buffer,1,!0,Y.FLOAT).addIndex(this._indexBuffer)}}const ct=`
|
||||
precision highp float;
|
||||
attribute vec2 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
attribute vec4 aColor;
|
||||
attribute vec4 aDarkColor;
|
||||
attribute float aTextureId;
|
||||
|
||||
uniform mat3 projectionMatrix;
|
||||
uniform mat3 translationMatrix;
|
||||
uniform vec4 tint;
|
||||
|
||||
varying vec2 vTextureCoord;
|
||||
varying vec4 vColor;
|
||||
varying vec4 vDarkColor;
|
||||
varying float vTextureId;
|
||||
|
||||
void main(void){
|
||||
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
|
||||
|
||||
vTextureCoord = aTextureCoord;
|
||||
vTextureId = aTextureId;
|
||||
vColor = aColor * tint;
|
||||
vDarkColor = aDarkColor * tint;
|
||||
|
||||
}
|
||||
`,dt=`
|
||||
varying vec2 vTextureCoord;
|
||||
varying vec4 vColor;
|
||||
varying vec4 vDarkColor;
|
||||
varying float vTextureId;
|
||||
uniform sampler2D uSamplers[%count%];
|
||||
|
||||
void main(void){
|
||||
vec4 color;
|
||||
%forloop%
|
||||
|
||||
|
||||
gl_FragColor.a = color.a * vColor.a;
|
||||
gl_FragColor.rgb = ((color.a - 1.0) * vDarkColor.a + 1.0 - color.rgb) * vDarkColor.rgb + color.rgb * vColor.rgb;
|
||||
}
|
||||
`;class Se extends _e{constructor(o){super(o),this.shaderGenerator=new Ue(ct,dt),this.geometryClass=ht,this.vertexSize=7}packInterleavedGeometry(o,e,t,s,n){const{uint32View:r,float32View:l}=e,p=s/this.vertexSize,h=o.uvs,u=o.indices,c=o.vertexData,i=o._texture.baseTexture._batchLocation,g=Math.min(o.worldAlpha,1),x=X.shared.setValue(o._tintRGB).toPremultiplied(g,!0),d=X.shared.setValue(o._darkTintRGB).premultiply(g,!0).toPremultiplied(1,!1);for(let f=0;f<c.length;f+=2)l[s++]=c[f],l[s++]=c[f+1],l[s++]=h[f],l[s++]=h[f+1],r[s++]=x,r[s++]=d,l[s++]=i;for(let f=0;f<u.length;f++)t[n++]=p+u[f]}}a(Se,"extension",{name:"darkTintBatch",type:O.RendererPlugin});ce.add(Se);const U=class U extends be{constructor(){const e=new Ye;e.getBuffer("aVertexPosition").static=!1,e.getBuffer("aTextureCoord").static=!1;const t=new Xe(he.EMPTY);super(e,t);a(this,"name","");a(this,"warnedTwoTint",!1)}updateFromSpineData(e,t,s,n,r,l,p,h){var C,T;this.texture=e.texture;const u=r/(h?12:8)*2,c=this.geometry.getBuffer("aTextureCoord");((C=c.data)==null?void 0:C.length)!==u&&(c.data=new Float32Array(u));const i=this.geometry.getBuffer("aVertexPosition");((T=i.data)==null?void 0:T.length)!==u&&(i.data=new Float32Array(u));let g=0;const x=c.data,d=i.data;for(let k=0;k<r;k+=h?12:8){let b=k;d[g]=n[b++],d[g+1]=n[b++],b+=4,x[g]=n[b++],x[g+1]=n[b++],g+=2}h&&!this.warnedTwoTint&&(console.warn("DarkTint is not enabled by default. To enable use a DarkSlotMesh factory while creating the Spine object."),this.warnedTwoTint=!0),U.auxColor[0]=n[2],U.auxColor[1]=n[3],U.auxColor[2]=n[4],U.auxColor[3]=n[5],this.tint=U.auxColor,this.alpha=U.auxColor[3],this.blendMode=G.toPixiBlending(t);const f=this.geometry.indexBuffer;if(f.data.length!==l.length)f.data=new Uint32Array(l);else{const k=f.data;for(let b=0;b<p;b++)k[b]=l[b]}this.name=s,c.update(),i.update(),f.update()}};a(U,"auxColor",[0,0,0,0]);let le=U;class mt{constructor(o,e,t,s){a(this,"x");a(this,"y");a(this,"width");a(this,"height");this.x=o,this.y=e,this.width=t,this.height=s}calculateBounds(){return{x:this.x,y:this.y,width:this.width,height:this.height}}}class gt{constructor(o=!1){a(this,"clipping");this.clipping=o}calculateBounds(o){if(!o.skeleton)return{x:0,y:0,width:0,height:0};const e=new ee(o.skeleton.data);e.setupPose(),e.updateWorldTransform(j.update);const t=e.getBoundsRect(this.clipping?new de:void 0);return t.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:t}}class xt{constructor(o,e=[],t=.05,s=!1){a(this,"animation");a(this,"skins");a(this,"timeStep");a(this,"clipping");this.animation=o,this.skins=e,this.timeStep=t,this.clipping=s}calculateBounds(o){if(!o.skeleton||!o.state)return{x:0,y:0,width:0,height:0};const e=new ke(o.state.data),t=new ee(o.skeleton.data),s=this.clipping?new de:void 0,n=t.data;if(this.skins.length>0){const l=new Ve("custom-skin");for(const p of this.skins){const h=n.findSkin(p);h!=null&&l.addSkin(h)}t.setSkin(l)}t.setupPose();const r=this.animation!=null?n.findAnimation(this.animation):null;if(r==null){t.updateWorldTransform(j.update);const l=t.getBoundsRect(s);return l.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:l}else{let l=Number.POSITIVE_INFINITY,p=Number.POSITIVE_INFINITY,h=Number.NEGATIVE_INFINITY,u=Number.NEGATIVE_INFINITY;e.clearTracks(),e.setAnimation(0,r,!1);const c=Math.max(r.duration/this.timeStep,1);for(let g=0;g<c;g++){const x=g>0?this.timeStep:0;e.update(x),e.apply(t),t.update(x),t.updateWorldTransform(j.update);const d=t.getBoundsRect(s);l=Math.min(l,d.x),p=Math.min(p,d.y),h=Math.max(h,d.x+d.width),u=Math.max(u,d.y+d.height)}const i={x:l,y:p,width:h-l,height:u-p};return i.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:i}}}const w=class w extends J{constructor(e){super();a(this,"skeleton");a(this,"state");a(this,"skeletonPhysics");a(this,"darkTint",!1);a(this,"hasNeverUpdated",!0);a(this,"_debug");a(this,"slotMeshFactory",()=>new le);a(this,"beforeUpdateWorldTransforms",()=>{});a(this,"afterUpdateWorldTransforms",()=>{});a(this,"_autoUpdate",!1);a(this,"_ticker",ge.shared);a(this,"meshesCache",new Map);a(this,"lightColor",new ae);a(this,"darkColor",new ae);a(this,"clippingVertAux",new Float32Array(6));a(this,"_boundsProvider");a(this,"_boundsPoint",new We);a(this,"_boundsSpineID",-1);a(this,"_boundsSpineDirty",!0);a(this,"slotsObject",new Map);a(this,"verticesCache",xe.newFloatArray(1024));a(this,"clippingSlotToPixiMasks",{});e instanceof $e?e={skeletonData:e}:"skeleton"in e&&(e=new.target.createOptions(e));const{autoUpdate:t=!0,boundsProvider:s,darkTint:n,skeletonData:r,ticker:l}=e;this.skeleton=new ee(r),this.skeletonPhysics=new Ze(this.skeleton,{readTransform:(p,h)=>this.readPhysicsTransform(p,h),worldToSkeleton:p=>this.pixiWorldCoordinatesToSkeleton(p)}),this.state=new ke(new Je(r)),l&&(this._ticker=l),this.autoUpdate=t,this.boundsProvider=s,this.darkTint=n===void 0?this.skeleton.slots.some(p=>!!p.data.setupPose.darkColor):n,this.darkTint&&(this.slotMeshFactory=()=>new ie)}get debug(){return this._debug}set debu
Line truncated
|
||||
Vendored
+2
-2
@@ -8,8 +8,8 @@
|
||||
html, body { margin: 0; padding: 0; background: #111; color: #eee; font-family: system-ui, -apple-system, sans-serif; }
|
||||
#app { display: flex; flex-direction: column; height: 100vh; }
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/index-CnGkEkb-.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CSwdbBmn.css">
|
||||
<script type="module" crossorigin src="/assets/index-Bx8XTHrS.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Dg-D8CvM.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
+8798
File diff suppressed because it is too large.
Load diff
BIN
Binary file not shown.
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
spineboy.png
|
||||
size: 1024, 256
|
||||
filter: Linear, Linear
|
||||
scale: 0.5
|
||||
crosshair
|
||||
bounds: 186, 17, 45, 45
|
||||
eye-indifferent
|
||||
bounds: 137, 17, 47, 45
|
||||
eye-surprised
|
||||
bounds: 623, 45, 47, 45
|
||||
front-bracer
|
||||
bounds: 613, 3, 29, 40
|
||||
front-fist-closed
|
||||
bounds: 278, 2, 38, 41
|
||||
front-fist-open
|
||||
bounds: 233, 18, 43, 44
|
||||
front-foot
|
||||
bounds: 72, 39, 63, 35
|
||||
front-shin
|
||||
bounds: 952, 41, 41, 92
|
||||
front-thigh
|
||||
bounds: 995, 120, 23, 56
|
||||
front-upper-arm
|
||||
bounds: 995, 69, 23, 49
|
||||
goggles
|
||||
bounds: 167, 64, 131, 83
|
||||
gun
|
||||
bounds: 300, 45, 105, 102
|
||||
head
|
||||
bounds: 29, 76, 136, 149
|
||||
hoverboard-board
|
||||
bounds: 167, 149, 246, 76
|
||||
hoverboard-thruster
|
||||
bounds: 674, 8, 30, 32
|
||||
hoverglow-small
|
||||
bounds: 813, 60, 137, 38
|
||||
mouth-grind
|
||||
bounds: 416, 13, 47, 30
|
||||
mouth-oooo
|
||||
bounds: 367, 13, 47, 30
|
||||
mouth-smile
|
||||
bounds: 318, 13, 47, 30
|
||||
muzzle-glow
|
||||
bounds: 706, 15, 25, 25
|
||||
muzzle-ring
|
||||
bounds: 2, 120, 25, 105
|
||||
muzzle01
|
||||
bounds: 554, 50, 67, 40
|
||||
muzzle02
|
||||
bounds: 484, 48, 68, 42
|
||||
muzzle03
|
||||
bounds: 685, 42, 83, 53
|
||||
muzzle04
|
||||
bounds: 407, 45, 75, 45
|
||||
muzzle05
|
||||
bounds: 2, 36, 68, 38
|
||||
neck
|
||||
bounds: 2, 97, 18, 21
|
||||
portal-bg
|
||||
bounds: 550, 92, 133, 133
|
||||
portal-flare1
|
||||
bounds: 484, 16, 56, 30
|
||||
portal-flare2
|
||||
bounds: 810, 27, 57, 31
|
||||
portal-flare3
|
||||
bounds: 869, 28, 58, 30
|
||||
portal-shade
|
||||
bounds: 415, 92, 133, 133
|
||||
portal-streaks1
|
||||
bounds: 685, 97, 126, 128
|
||||
portal-streaks2
|
||||
bounds: 813, 100, 125, 125
|
||||
rear-bracer
|
||||
bounds: 644, 7, 28, 36
|
||||
rear-foot
|
||||
bounds: 554, 18, 57, 30
|
||||
rear-shin
|
||||
bounds: 770, 6, 38, 89
|
||||
rear-thigh
|
||||
bounds: 991, 178, 28, 47
|
||||
rear-upper-arm
|
||||
bounds: 995, 23, 20, 44
|
||||
torso
|
||||
bounds: 940, 135, 49, 90
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 237 KiB |
Vendored
+5
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
这些资源来自 Esoteric Software 官方的
|
||||
[`spine-runtimes`](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
仓库,用于测试本项目对 Spine 3.8、4.0、4.1、4.2 JSON 数据的加载、预览与动画联动。
|
||||
仓库,用于测试本项目对 Spine 3.8、4.0、4.1、4.2、4.3 JSON 数据的加载、预览与动画联动。
|
||||
|
||||
## 目录结构
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
- `spineboy.atlas`:纹理图集
|
||||
- `spineboy.png`:图集贴图
|
||||
|
||||
`4.3/` 还包含官方 `spineboy-pro.skel`,用于验证 4.3 二进制加载和版本识别。
|
||||
|
||||
| 目录 | JSON 中的实际 Spine 版本 | 浏览器访问路径 |
|
||||
| --- | --- | --- |
|
||||
| `3.8/` | `3.8.55` | `/spine-test/3.8/` |
|
||||
| `4.0/` | `4.0.31` | `/spine-test/4.0/` |
|
||||
| `4.1/` | `4.1.17` | `/spine-test/4.1/` |
|
||||
| `4.2/` | `4.2.22` | `/spine-test/4.2/` |
|
||||
| `4.3/` | `4.3.75-beta` | `/spine-test/4.3/` |
|
||||
|
||||
## 手动测试
|
||||
|
||||
@@ -27,4 +30,4 @@
|
||||
4. 检查资源版本、骨骼层级、动画列表、时间轴与粒子挂载联动。
|
||||
|
||||
测试时不要混用不同版本目录中的文件。资源版权和使用条件遵循
|
||||
[`spine-runtimes` License](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/LICENSE)。
|
||||
[`spine-runtimes` License](https://github.com/EsotericSoftware/spine-runtimes/blob/4.3/LICENSE)。
|
||||
Generated
+32
@@ -10,6 +10,8 @@
|
||||
"dependencies": {
|
||||
"@esotericsoftware/spine-core": "file:vendor/spine/spine-core",
|
||||
"@esotericsoftware/spine-pixi-v7": "file:vendor/spine/spine-pixi-v7",
|
||||
"@spine-particle/spine-core-4.3": "file:vendor/spine/spine-core-4.3",
|
||||
"@spine-particle/spine-pixi-v7-4.3": "file:vendor/spine/spine-pixi-v7-4.3",
|
||||
"pinia": "^4.0.3",
|
||||
"pixi.js": "^7.4.3",
|
||||
"vue": "^3.5.13"
|
||||
@@ -1314,6 +1316,14 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@spine-particle/spine-core-4.3": {
|
||||
"resolved": "vendor/spine/spine-core-4.3",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@spine-particle/spine-pixi-v7-4.3": {
|
||||
"resolved": "vendor/spine/spine-pixi-v7-4.3",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/css-font-loading-module": {
|
||||
"version": "0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz",
|
||||
@@ -2410,6 +2420,11 @@
|
||||
"version": "4.2.119",
|
||||
"license": "LicenseRef-LICENSE"
|
||||
},
|
||||
"vendor/spine/spine-core-4.3": {
|
||||
"name": "@spine-particle/spine-core-4.3",
|
||||
"version": "4.3.13",
|
||||
"license": "LicenseRef-LICENSE"
|
||||
},
|
||||
"vendor/spine/spine-pixi-v7": {
|
||||
"name": "@esotericsoftware/spine-pixi-v7",
|
||||
"version": "4.2.119",
|
||||
@@ -2426,6 +2441,23 @@
|
||||
"@pixi/mesh": "^7.2.4",
|
||||
"@pixi/text": "^7.2.4"
|
||||
}
|
||||
},
|
||||
"vendor/spine/spine-pixi-v7-4.3": {
|
||||
"name": "@spine-particle/spine-pixi-v7-4.3",
|
||||
"version": "4.3.13",
|
||||
"license": "LicenseRef-LICENSE",
|
||||
"dependencies": {
|
||||
"@spine-particle/spine-core-4.3": "4.3.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@pixi/assets": "^7.2.4",
|
||||
"@pixi/core": "^7.2.4",
|
||||
"@pixi/display": "^7.2.4",
|
||||
"@pixi/events": "^7.2.4",
|
||||
"@pixi/graphics": "^7.2.4",
|
||||
"@pixi/mesh": "^7.2.4",
|
||||
"@pixi/text": "^7.2.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,14 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"test:spine-json": "node scripts/verify-spine-json.mjs",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@esotericsoftware/spine-core": "file:vendor/spine/spine-core",
|
||||
"@esotericsoftware/spine-pixi-v7": "file:vendor/spine/spine-pixi-v7",
|
||||
"@spine-particle/spine-core-4.3": "file:vendor/spine/spine-core-4.3",
|
||||
"@spine-particle/spine-pixi-v7-4.3": "file:vendor/spine/spine-pixi-v7-4.3",
|
||||
"pinia": "^4.0.3",
|
||||
"pixi.js": "^7.4.3",
|
||||
"vue": "^3.5.13"
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
spineboy.png
|
||||
size: 1024, 256
|
||||
filter: Linear, Linear
|
||||
scale: 0.5
|
||||
crosshair
|
||||
bounds: 186, 17, 45, 45
|
||||
eye-indifferent
|
||||
bounds: 137, 17, 47, 45
|
||||
eye-surprised
|
||||
bounds: 623, 45, 47, 45
|
||||
front-bracer
|
||||
bounds: 613, 3, 29, 40
|
||||
front-fist-closed
|
||||
bounds: 278, 2, 38, 41
|
||||
front-fist-open
|
||||
bounds: 233, 18, 43, 44
|
||||
front-foot
|
||||
bounds: 72, 39, 63, 35
|
||||
front-shin
|
||||
bounds: 952, 41, 41, 92
|
||||
front-thigh
|
||||
bounds: 995, 120, 23, 56
|
||||
front-upper-arm
|
||||
bounds: 995, 69, 23, 49
|
||||
goggles
|
||||
bounds: 167, 64, 131, 83
|
||||
gun
|
||||
bounds: 300, 45, 105, 102
|
||||
head
|
||||
bounds: 29, 76, 136, 149
|
||||
hoverboard-board
|
||||
bounds: 167, 149, 246, 76
|
||||
hoverboard-thruster
|
||||
bounds: 674, 8, 30, 32
|
||||
hoverglow-small
|
||||
bounds: 813, 60, 137, 38
|
||||
mouth-grind
|
||||
bounds: 416, 13, 47, 30
|
||||
mouth-oooo
|
||||
bounds: 367, 13, 47, 30
|
||||
mouth-smile
|
||||
bounds: 318, 13, 47, 30
|
||||
muzzle-glow
|
||||
bounds: 706, 15, 25, 25
|
||||
muzzle-ring
|
||||
bounds: 2, 120, 25, 105
|
||||
muzzle01
|
||||
bounds: 554, 50, 67, 40
|
||||
muzzle02
|
||||
bounds: 484, 48, 68, 42
|
||||
muzzle03
|
||||
bounds: 685, 42, 83, 53
|
||||
muzzle04
|
||||
bounds: 407, 45, 75, 45
|
||||
muzzle05
|
||||
bounds: 2, 36, 68, 38
|
||||
neck
|
||||
bounds: 2, 97, 18, 21
|
||||
portal-bg
|
||||
bounds: 550, 92, 133, 133
|
||||
portal-flare1
|
||||
bounds: 484, 16, 56, 30
|
||||
portal-flare2
|
||||
bounds: 810, 27, 57, 31
|
||||
portal-flare3
|
||||
bounds: 869, 28, 58, 30
|
||||
portal-shade
|
||||
bounds: 415, 92, 133, 133
|
||||
portal-streaks1
|
||||
bounds: 685, 97, 126, 128
|
||||
portal-streaks2
|
||||
bounds: 813, 100, 125, 125
|
||||
rear-bracer
|
||||
bounds: 644, 7, 28, 36
|
||||
rear-foot
|
||||
bounds: 554, 18, 57, 30
|
||||
rear-shin
|
||||
bounds: 770, 6, 38, 89
|
||||
rear-thigh
|
||||
bounds: 991, 178, 28, 47
|
||||
rear-upper-arm
|
||||
bounds: 995, 23, 20, 44
|
||||
torso
|
||||
bounds: 940, 135, 49, 90
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 237 KiB |
@@ -2,7 +2,7 @@
|
||||
|
||||
这些资源来自 Esoteric Software 官方的
|
||||
[`spine-runtimes`](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
仓库,用于测试本项目对 Spine 3.8、4.0、4.1、4.2 JSON 数据的加载、预览与动画联动。
|
||||
仓库,用于测试本项目对 Spine 3.8、4.0、4.1、4.2、4.3 JSON 数据的加载、预览与动画联动。
|
||||
|
||||
## 目录结构
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
- `spineboy.atlas`:纹理图集
|
||||
- `spineboy.png`:图集贴图
|
||||
|
||||
`4.3/` 还包含官方 `spineboy-pro.skel`,用于验证 4.3 二进制加载和版本识别。
|
||||
|
||||
| 目录 | JSON 中的实际 Spine 版本 | 浏览器访问路径 |
|
||||
| --- | --- | --- |
|
||||
| `3.8/` | `3.8.55` | `/spine-test/3.8/` |
|
||||
| `4.0/` | `4.0.31` | `/spine-test/4.0/` |
|
||||
| `4.1/` | `4.1.17` | `/spine-test/4.1/` |
|
||||
| `4.2/` | `4.2.22` | `/spine-test/4.2/` |
|
||||
| `4.3/` | `4.3.75-beta` | `/spine-test/4.3/` |
|
||||
|
||||
## 手动测试
|
||||
|
||||
@@ -27,4 +30,4 @@
|
||||
4. 检查资源版本、骨骼层级、动画列表、时间轴与粒子挂载联动。
|
||||
|
||||
测试时不要混用不同版本目录中的文件。资源版权和使用条件遵循
|
||||
[`spine-runtimes` License](https://github.com/EsotericSoftware/spine-runtimes/blob/4.2/LICENSE)。
|
||||
[`spine-runtimes` License](https://github.com/EsotericSoftware/spine-runtimes/blob/4.3/LICENSE)。
|
||||
@@ -1,25 +1,58 @@
|
||||
import {
|
||||
BoundingBoxAttachment,
|
||||
ClippingAttachment,
|
||||
MeshAttachment,
|
||||
PathAttachment,
|
||||
PointAttachment,
|
||||
RegionAttachment,
|
||||
SkeletonJson,
|
||||
type AttachmentLoader,
|
||||
type Skin,
|
||||
BoundingBoxAttachment as BoundingBoxAttachment43,
|
||||
ClippingAttachment as ClippingAttachment43,
|
||||
MeshAttachment as MeshAttachment43,
|
||||
PathAttachment as PathAttachment43,
|
||||
PointAttachment as PointAttachment43,
|
||||
RegionAttachment as RegionAttachment43,
|
||||
SkeletonJson as SkeletonJson43,
|
||||
TextureRegion as TextureRegion43,
|
||||
type AttachmentLoader as AttachmentLoader43,
|
||||
type Sequence as Sequence43,
|
||||
type Skin as Skin43,
|
||||
} from '@spine-particle/spine-core-4.3'
|
||||
import {
|
||||
BoundingBoxAttachment as BoundingBoxAttachment42,
|
||||
ClippingAttachment as ClippingAttachment42,
|
||||
MeshAttachment as MeshAttachment42,
|
||||
PathAttachment as PathAttachment42,
|
||||
PointAttachment as PointAttachment42,
|
||||
RegionAttachment as RegionAttachment42,
|
||||
SkeletonJson as SkeletonJson42,
|
||||
type AttachmentLoader as AttachmentLoader42,
|
||||
type Skin as Skin42,
|
||||
} from '@esotericsoftware/spine-core'
|
||||
import { normalizeSpine38JsonFor42 } from '../spine/spine38Compatibility'
|
||||
import { normalizeSpineVersion, supportedSpineVersionsText, type SupportedSpineVersion } from '../spine/spineVersion'
|
||||
import type { SpineJsonMap } from './spineJsonTypes'
|
||||
|
||||
class ExportValidationAttachmentLoader implements AttachmentLoader {
|
||||
newRegionAttachment(_skin: Skin, name: string, path: string, _sequence: any) { return new RegionAttachment(name, path) }
|
||||
newMeshAttachment(_skin: Skin, name: string, path: string, _sequence: any) { return new MeshAttachment(name, path) }
|
||||
newBoundingBoxAttachment(_skin: Skin, name: string) { return new BoundingBoxAttachment(name) }
|
||||
newPathAttachment(_skin: Skin, name: string) { return new PathAttachment(name) }
|
||||
newPointAttachment(_skin: Skin, name: string) { return new PointAttachment(name) }
|
||||
newClippingAttachment(_skin: Skin, name: string) { return new ClippingAttachment(name) }
|
||||
class ExportValidationAttachmentLoader42 implements AttachmentLoader42 {
|
||||
newRegionAttachment(_skin: Skin42, name: string, path: string, _sequence: any) { return new RegionAttachment42(name, path) }
|
||||
newMeshAttachment(_skin: Skin42, name: string, path: string, _sequence: any) { return new MeshAttachment42(name, path) }
|
||||
newBoundingBoxAttachment(_skin: Skin42, name: string) { return new BoundingBoxAttachment42(name) }
|
||||
newPathAttachment(_skin: Skin42, name: string) { return new PathAttachment42(name) }
|
||||
newPointAttachment(_skin: Skin42, name: string) { return new PointAttachment42(name) }
|
||||
newClippingAttachment(_skin: Skin42, name: string) { return new ClippingAttachment42(name) }
|
||||
}
|
||||
|
||||
class ExportValidationAttachmentLoader43 implements AttachmentLoader43 {
|
||||
private sequence(sequence: Sequence43) {
|
||||
for (let index = 0; index < sequence.regions.length; index++) {
|
||||
if (sequence.regions[index]) continue
|
||||
const region = new TextureRegion43()
|
||||
region.u = 0; region.v = 0; region.u2 = 1; region.v2 = 1
|
||||
region.width = 1; region.height = 1; region.originalWidth = 1; region.originalHeight = 1
|
||||
region.offsetX = 0; region.offsetY = 0; region.degrees = 0
|
||||
sequence.regions[index] = region
|
||||
}
|
||||
return sequence
|
||||
}
|
||||
newRegionAttachment(_skin: Skin43, _placeholder: string, name: string, _path: string, sequence: Sequence43) { return new RegionAttachment43(name, this.sequence(sequence)) }
|
||||
newMeshAttachment(_skin: Skin43, _placeholder: string, name: string, _path: string, sequence: Sequence43) { return new MeshAttachment43(name, this.sequence(sequence)) }
|
||||
newBoundingBoxAttachment(_skin: Skin43, _placeholder: string, name: string) { return new BoundingBoxAttachment43(name) }
|
||||
newPathAttachment(_skin: Skin43, _placeholder: string, name: string) { return new PathAttachment43(name) }
|
||||
newPointAttachment(_skin: Skin43, _placeholder: string, name: string) { return new PointAttachment43(name) }
|
||||
newClippingAttachment(_skin: Skin43, _placeholder: string, name: string) { return new ClippingAttachment43(name) }
|
||||
}
|
||||
|
||||
const VALID_INHERIT = new Set(['normal', 'onlyTranslation', 'noRotationOrReflection', 'noScale', 'noScaleOrReflection'])
|
||||
@@ -136,8 +169,9 @@ export function validateSpineJson(text: string, expectedVersion?: SupportedSpine
|
||||
validateEditorImportStructure(root, version)
|
||||
if (version === '3.8') validateSpine38Structure(root)
|
||||
const runtimeRoot = version === '3.8' ? normalizeSpine38JsonFor42(JSON.parse(JSON.stringify(root))) : root
|
||||
const reader = new SkeletonJson(new ExportValidationAttachmentLoader())
|
||||
const data = reader.readSkeletonData(runtimeRoot)
|
||||
const data = version === '4.3'
|
||||
? new SkeletonJson43(new ExportValidationAttachmentLoader43()).readSkeletonData(runtimeRoot)
|
||||
: new SkeletonJson42(new ExportValidationAttachmentLoader42()).readSkeletonData(runtimeRoot)
|
||||
if (!data.bones.length) throw new Error('导出结果缺少骨骼')
|
||||
return { version, bones: data.bones.length, slots: data.slots.length, animations: data.animations.length }
|
||||
}
|
||||
@@ -39,7 +39,7 @@
|
||||
<button class="clear" @click="clearBundle">清除</button>
|
||||
</div>
|
||||
<div class="runtime-note">
|
||||
支持 Spine 3.8 / 4.0 / 4.1 / 4.2 JSON · 4.2.119 预览运行时 · 本地离线
|
||||
支持 Spine 3.8 / 4.0 / 4.1 / 4.2 / 4.3 JSON · 对应版本运行时按需加载 · 本地离线
|
||||
<span v-if="spineObject.dataVersion"> · 当前资源 {{ spineObject.dataVersion }}</span>
|
||||
</div>
|
||||
<div v-if="spineObject.error" class="error">{{ spineObject.error }}</div>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Container } from 'pixi.js'
|
||||
import { Spine } from '@esotericsoftware/spine-pixi-v7'
|
||||
import { getSpineAsset } from './spineAssetRegistry'
|
||||
import type { SpineSceneObject } from './spineTypes'
|
||||
|
||||
interface RuntimeEntry {
|
||||
root: Container
|
||||
spine: Spine
|
||||
spine: any
|
||||
runtimeVersion: '4.2' | '4.3'
|
||||
assetVersion: number
|
||||
animation: string
|
||||
}
|
||||
@@ -45,12 +45,13 @@ export class SpineRuntimeLayer {
|
||||
entry.root.destroy({ children: true })
|
||||
}
|
||||
const root = new Container()
|
||||
const spine = new Spine({ skeletonData: asset.skeletonData, autoUpdate: false, darkTint: false })
|
||||
const spine = new asset.SpineClass({ skeletonData: asset.skeletonData, autoUpdate: false, darkTint: false })
|
||||
if (asset.skeletonData.defaultSkin) spine.skeleton.setSkin(asset.skeletonData.defaultSkin)
|
||||
spine.skeleton.setSlotsToSetupPose()
|
||||
if (asset.runtimeVersion === '4.3') spine.skeleton.setupPoseSlots()
|
||||
else spine.skeleton.setSlotsToSetupPose()
|
||||
root.addChild(spine)
|
||||
this.container.addChild(root)
|
||||
entry = { root, spine, assetVersion: object.assetVersion, animation: '' }
|
||||
entry = { root, spine, runtimeVersion: asset.runtimeVersion, assetVersion: object.assetVersion, animation: '' }
|
||||
this.entries.set(object.id, entry)
|
||||
}
|
||||
if (!entry) continue
|
||||
@@ -66,12 +67,13 @@ export class SpineRuntimeLayer {
|
||||
|
||||
if (entry.animation !== object.selectedAnimation) {
|
||||
entry.animation = object.selectedAnimation
|
||||
spine.skeleton.setToSetupPose()
|
||||
if (entry.runtimeVersion === '4.3') spine.skeleton.setupPose()
|
||||
else spine.skeleton.setToSetupPose()
|
||||
spine.state.clearTracks()
|
||||
// 编辑器时间轴负责整体循环;单个 Spine 动画自身只播放一次并停在末帧。
|
||||
if (entry.animation) spine.state.setAnimation(0, entry.animation, false)
|
||||
}
|
||||
const track = spine.state.getCurrent(0)
|
||||
const track = entry.runtimeVersion === '4.3' ? spine.state.getTrack(0) : spine.state.getCurrent(0)
|
||||
if (track) {
|
||||
const duration = object.animations.find((animation) => animation.name === object.selectedAnimation)?.duration || 0
|
||||
const localTime = Math.max(0, frame / Math.max(1, fps) - object.timeOffset)
|
||||
@@ -85,6 +87,7 @@ export class SpineRuntimeLayer {
|
||||
const entry = this.entries.get(objectId)
|
||||
const bone = entry?.spine.skeleton.findBone(boneName)
|
||||
if (!entry || !bone || !bone.active) return null
|
||||
const pose = entry.runtimeVersion === '4.3' ? bone.appliedPose : bone
|
||||
|
||||
// Spine 骨骼矩阵位于 Spine 对象局部空间;与外层 Pixi 容器矩阵组合后,
|
||||
// 再把屏幕 Y 向下坐标转换为编辑器使用的数学坐标(Y 向上)。
|
||||
@@ -95,12 +98,12 @@ export class SpineRuntimeLayer {
|
||||
const rb = -sin * root.scale.y
|
||||
const rc = sin * root.scale.x
|
||||
const rd = cos * root.scale.y
|
||||
const a = ra * bone.a + rb * bone.c
|
||||
const b = ra * bone.b + rb * bone.d
|
||||
const c = rc * bone.a + rd * bone.c
|
||||
const d = rc * bone.b + rd * bone.d
|
||||
const screenX = root.position.x + ra * bone.worldX + rb * bone.worldY
|
||||
const screenY = root.position.y + rc * bone.worldX + rd * bone.worldY
|
||||
const a = ra * pose.a + rb * pose.c
|
||||
const b = ra * pose.b + rb * pose.d
|
||||
const c = rc * pose.a + rd * pose.c
|
||||
const d = rc * pose.b + rd * pose.d
|
||||
const screenX = root.position.x + ra * pose.worldX + rb * pose.worldY
|
||||
const screenY = root.position.y + rc * pose.worldX + rd * pose.worldY
|
||||
return {
|
||||
x: screenX,
|
||||
y: -screenY,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
AtlasAttachmentLoader,
|
||||
SkeletonBinary,
|
||||
SkeletonJson,
|
||||
TextureAtlas,
|
||||
} from '@esotericsoftware/spine-core'
|
||||
import { Spine, SpineTexture } from '@esotericsoftware/spine-pixi-v7'
|
||||
import { bindAtlasTextures } from './spineRuntimeTextures'
|
||||
import type { RuntimeParseResult, SpineTextureMap } from './spineRuntimeTypes'
|
||||
|
||||
function atlasLoader(atlasText: string, textures: SpineTextureMap) {
|
||||
const atlas = new TextureAtlas(atlasText)
|
||||
bindAtlasTextures(atlas, textures, SpineTexture)
|
||||
return new AtlasAttachmentLoader(atlas)
|
||||
}
|
||||
|
||||
export function parseJson42(source: any, atlasText: string, textures: SpineTextureMap): RuntimeParseResult {
|
||||
return {
|
||||
skeletonData: new SkeletonJson(atlasLoader(atlasText, textures)).readSkeletonData(source),
|
||||
SpineClass: Spine,
|
||||
}
|
||||
}
|
||||
|
||||
export function parseBinary42(source: ArrayBuffer, atlasText: string, textures: SpineTextureMap): RuntimeParseResult {
|
||||
return {
|
||||
skeletonData: new SkeletonBinary(atlasLoader(atlasText, textures)).readSkeletonData(source),
|
||||
SpineClass: Spine,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { bindAtlasTextures } from './spineRuntimeTextures'
|
||||
import type { RuntimeParseResult, SpineTextureMap } from './spineRuntimeTypes'
|
||||
|
||||
async function modules() {
|
||||
const [core, pixi] = await Promise.all([
|
||||
import('@spine-particle/spine-core-4.3'),
|
||||
import('@spine-particle/spine-pixi-v7-4.3'),
|
||||
])
|
||||
return { core, pixi }
|
||||
}
|
||||
|
||||
export async function parseJson43(source: any, atlasText: string, textures: SpineTextureMap): Promise<RuntimeParseResult> {
|
||||
const { core, pixi } = await modules()
|
||||
const atlas = new core.TextureAtlas(atlasText)
|
||||
bindAtlasTextures(atlas, textures, pixi.SpineTexture)
|
||||
return {
|
||||
skeletonData: new core.SkeletonJson(new core.AtlasAttachmentLoader(atlas)).readSkeletonData(source),
|
||||
SpineClass: pixi.Spine,
|
||||
}
|
||||
}
|
||||
|
||||
export async function parseBinary43(source: ArrayBuffer, atlasText: string, textures: SpineTextureMap): Promise<RuntimeParseResult> {
|
||||
const { core, pixi } = await modules()
|
||||
const atlas = new core.TextureAtlas(atlasText)
|
||||
bindAtlasTextures(atlas, textures, pixi.SpineTexture)
|
||||
return {
|
||||
skeletonData: new core.SkeletonBinary(new core.AtlasAttachmentLoader(atlas)).readSkeletonData(source),
|
||||
SpineClass: pixi.Spine,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ALPHA_MODES } from 'pixi.js'
|
||||
import type { SpineTextureMap } from './spineRuntimeTypes'
|
||||
|
||||
function basename(path: string) {
|
||||
return path.replace(/\\/g, '/').split('/').pop() || path
|
||||
}
|
||||
|
||||
export function bindAtlasTextures(atlas: any, textures: SpineTextureMap, SpineTexture: { from(baseTexture: any): any }) {
|
||||
for (const page of atlas.pages) {
|
||||
const texture = textures.get(basename(page.name).toLowerCase())
|
||||
if (!texture) throw new Error(`Atlas 引用的纹理未选择:${page.name}`)
|
||||
texture.baseTexture.alphaMode = page.pma ? ALPHA_MODES.PMA : ALPHA_MODES.UNPACK
|
||||
page.setTexture(SpineTexture.from(texture.baseTexture))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Texture } from 'pixi.js'
|
||||
|
||||
export type SpineRuntimeVersion = '4.2' | '4.3'
|
||||
export type SpineClass = new (options: any) => any
|
||||
export type SpineTextureMap = Map<string, Texture>
|
||||
|
||||
export interface RuntimeParseResult {
|
||||
skeletonData: any
|
||||
SpineClass: SpineClass
|
||||
}
|
||||
@@ -1,16 +1,12 @@
|
||||
import {
|
||||
AtlasAttachmentLoader,
|
||||
SkeletonBinary,
|
||||
SkeletonJson,
|
||||
TextureAtlas,
|
||||
type SkeletonData,
|
||||
} from '@esotericsoftware/spine-core'
|
||||
import { SpineTexture } from '@esotericsoftware/spine-pixi-v7'
|
||||
import { ALPHA_MODES, Texture } from 'pixi.js'
|
||||
import { Texture } from 'pixi.js'
|
||||
import type { LoadedSpineAsset } from './spineAssetRegistry'
|
||||
import { parseBinary42, parseJson42 } from './runtime/spineRuntime42'
|
||||
import { parseBinary43, parseJson43 } from './runtime/spineRuntime43'
|
||||
import type { SpineAnimationInfo, SpineBoneInfo } from './spineTypes'
|
||||
import { normalizeSpine38JsonFor42 } from './spine38Compatibility'
|
||||
import { normalizeSpineVersion, supportedSpineVersionsText, type SupportedSpineVersion } from './spineVersion'
|
||||
import { normalizeSpineVersion, spineRuntimeVersion, supportedSpineVersionsText, type SupportedSpineVersion } from './spineVersion'
|
||||
|
||||
type CompatibleSkeletonData = LoadedSpineAsset['skeletonData']
|
||||
|
||||
export interface ParsedSpineBundle extends LoadedSpineAsset {
|
||||
animations: SpineAnimationInfo[]
|
||||
@@ -22,12 +18,19 @@ function basename(path: string) {
|
||||
return path.replace(/\\/g, '/').split('/').pop() || path
|
||||
}
|
||||
|
||||
async function readTexture(file: File) {
|
||||
const url = URL.createObjectURL(file)
|
||||
return await Texture.fromURL(url)
|
||||
async function readTextures(files: File[]) {
|
||||
const entries = await Promise.all(files.map(async (file) => {
|
||||
const url = URL.createObjectURL(file)
|
||||
try {
|
||||
return [basename(file.name).toLowerCase(), await Texture.fromURL(url)] as const
|
||||
} finally {
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
}))
|
||||
return new Map(entries)
|
||||
}
|
||||
|
||||
function boneMetadata(skeletonData: SkeletonData): SpineBoneInfo[] {
|
||||
function boneMetadata(skeletonData: CompatibleSkeletonData): SpineBoneInfo[] {
|
||||
const depths = new Map<string, number>()
|
||||
return skeletonData.bones.map((bone) => {
|
||||
const parent = bone.parent?.name || null
|
||||
@@ -42,27 +45,31 @@ export async function parseSpineBundle(skeletonFile: File, atlasFile: File, text
|
||||
if (!/\.atlas$/i.test(atlasFile.name)) throw new Error('图集文件仅支持 .atlas')
|
||||
if (!textureFiles.length) throw new Error('请至少选择一张纹理图片')
|
||||
|
||||
const atlas = new TextureAtlas(await atlasFile.text())
|
||||
const fileMap = new Map(textureFiles.map((file) => [basename(file.name).toLowerCase(), file]))
|
||||
const textures: Texture[] = []
|
||||
const atlasText = await atlasFile.text()
|
||||
const texturesByName = await readTextures(textureFiles)
|
||||
const textures = [...texturesByName.values()]
|
||||
try {
|
||||
for (const page of atlas.pages) {
|
||||
const file = fileMap.get(basename(page.name).toLowerCase())
|
||||
if (!file) throw new Error(`Atlas 引用的纹理未选择:${page.name}`)
|
||||
const texture = await readTexture(file)
|
||||
// 与 Spine 官方 PixiJS Atlas 加载器保持一致。Spine 导出的 Atlas
|
||||
// 常使用 pma:true;忽略该标记会让骨架数据正常但附件纹理无法正确合成。
|
||||
texture.baseTexture.alphaMode = page.pma ? ALPHA_MODES.PMA : ALPHA_MODES.UNPACK
|
||||
textures.push(texture)
|
||||
page.setTexture(SpineTexture.from(texture.baseTexture))
|
||||
}
|
||||
|
||||
const attachmentLoader = new AtlasAttachmentLoader(atlas)
|
||||
let skeletonData: SkeletonData
|
||||
let skeletonData: CompatibleSkeletonData
|
||||
let SpineClass: new (options: any) => any
|
||||
let dataVersion: SupportedSpineVersion | null = null
|
||||
let runtimeVersion: '4.2' | '4.3'
|
||||
|
||||
if (/\.skel$/i.test(skeletonFile.name)) {
|
||||
const reader = new SkeletonBinary(attachmentLoader)
|
||||
skeletonData = reader.readSkeletonData(await skeletonFile.arrayBuffer())
|
||||
const source = await skeletonFile.arrayBuffer()
|
||||
// 二进制版本只能从数据内部读取:先按 4.3 尝试,再回退到完全保留的旧版链路。
|
||||
try {
|
||||
;({ skeletonData, SpineClass } = await parseBinary43(source, atlasText, texturesByName))
|
||||
runtimeVersion = '4.3'
|
||||
} catch (error43) {
|
||||
try {
|
||||
;({ skeletonData, SpineClass } = parseBinary42(source, atlasText, texturesByName))
|
||||
runtimeVersion = '4.2'
|
||||
} catch (error42) {
|
||||
const message43 = error43 instanceof Error ? error43.message : String(error43)
|
||||
const message42 = error42 instanceof Error ? error42.message : String(error42)
|
||||
throw new Error(`Spine 二进制解析失败(4.3:${message43};旧版:${message42})`)
|
||||
}
|
||||
}
|
||||
dataVersion = normalizeSpineVersion(skeletonData.version)
|
||||
} else {
|
||||
let source: any
|
||||
@@ -73,15 +80,21 @@ export async function parseSpineBundle(skeletonFile: File, atlasFile: File, text
|
||||
}
|
||||
dataVersion = normalizeSpineVersion(source?.skeleton?.spine)
|
||||
if (!dataVersion) throw new Error(`Spine JSON 版本不受支持,仅支持 ${supportedSpineVersionsText()}`)
|
||||
runtimeVersion = spineRuntimeVersion(dataVersion)
|
||||
if (dataVersion === '3.8') normalizeSpine38JsonFor42(source)
|
||||
const reader = new SkeletonJson(attachmentLoader)
|
||||
skeletonData = reader.readSkeletonData(source)
|
||||
const parsed = runtimeVersion === '4.3'
|
||||
? await parseJson43(source, atlasText, texturesByName)
|
||||
: parseJson42(source, atlasText, texturesByName)
|
||||
skeletonData = parsed.skeletonData
|
||||
SpineClass = parsed.SpineClass
|
||||
}
|
||||
if (!dataVersion) throw new Error(`Spine 数据版本不受支持,仅支持 ${supportedSpineVersionsText()}`)
|
||||
|
||||
return {
|
||||
skeletonData,
|
||||
textures,
|
||||
runtimeVersion,
|
||||
SpineClass,
|
||||
dataVersion,
|
||||
animations: skeletonData.animations.map((animation) => ({ name: animation.name, duration: animation.duration })),
|
||||
bones: boneMetadata(skeletonData),
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import type { SkeletonData } from '@esotericsoftware/spine-core'
|
||||
import type { SkeletonData as SkeletonData42 } from '@esotericsoftware/spine-core'
|
||||
import type { SkeletonData as SkeletonData43 } from '@spine-particle/spine-core-4.3'
|
||||
import type { Texture } from 'pixi.js'
|
||||
|
||||
export interface LoadedSpineAsset {
|
||||
skeletonData: SkeletonData
|
||||
skeletonData: SkeletonData42 | SkeletonData43
|
||||
runtimeVersion: '4.2' | '4.3'
|
||||
SpineClass: new (options: any) => any
|
||||
textures: Texture[]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const SUPPORTED_SPINE_VERSIONS = ['3.8', '4.0', '4.1', '4.2'] as const
|
||||
export const SUPPORTED_SPINE_VERSIONS = ['3.8', '4.0', '4.1', '4.2', '4.3'] as const
|
||||
|
||||
export type SupportedSpineVersion = typeof SUPPORTED_SPINE_VERSIONS[number]
|
||||
|
||||
@@ -14,3 +14,8 @@ export function isSupportedSpineVersion(value: unknown): value is SupportedSpine
|
||||
export function supportedSpineVersionsText() {
|
||||
return SUPPORTED_SPINE_VERSIONS.join(' / ')
|
||||
}
|
||||
|
||||
/** 4.3 的约束和姿势模型与旧版不兼容,预览时必须分流到对应的官方运行时。 */
|
||||
export function spineRuntimeVersion(version: SupportedSpineVersion) {
|
||||
return version === '4.3' ? '4.3' as const : '4.2' as const
|
||||
}
|
||||
@@ -832,6 +832,7 @@
|
||||
<option value="4.0">Spine 4.0</option>
|
||||
<option value="4.1">Spine 4.1</option>
|
||||
<option value="4.2">Spine 4.2</option>
|
||||
<option value="4.3">Spine 4.3</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
|
||||
+1
-1
@@ -136,7 +136,7 @@
|
||||
<li><b>创建对象:</b>在左侧“场景对象”中添加粒子、碰撞、路径或 Spine。</li>
|
||||
<li><b>编辑粒子:</b>选中粒子系统,依次调整发射、形状、属性、外观资源和修改器。</li>
|
||||
<li><b>查看效果:</b>使用底部时间轴播放、暂停或拖动到指定帧;修改参数后会自动重新计算。</li>
|
||||
<li><b>保存成果:</b>配置文件用于继续编辑;“导出 Spine Json”支持 Spine 3.8、4.0、4.1 和 4.2。</li>
|
||||
<li><b>保存成果:</b>配置文件用于继续编辑;“导出 Spine Json”支持 Spine 3.8、4.0、4.1、4.2 和 4.3。</li>
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
|
||||
Vendored
+4
-4
@@ -1,10 +1,10 @@
|
||||
# Spine 运行时来源
|
||||
|
||||
- 官方仓库:`https://github.com/EsotericSoftware/spine-runtimes`
|
||||
- 兼容分支:`4.2`
|
||||
- 仓库提交:`b81e5a58ed38704aee4f866f0e0ac672623ce914`
|
||||
- 本地包版本:`@esotericsoftware/spine-core@4.2.119`
|
||||
- 本地包版本:`@esotericsoftware/spine-pixi-v7@4.2.119`
|
||||
- 兼容分支:`4.2`、`4.3`
|
||||
- 旧版兼容运行时:`@esotericsoftware/spine-core@4.2.119`、`@esotericsoftware/spine-pixi-v7@4.2.119`
|
||||
- Spine 4.3 独立运行时:`@spine-particle/spine-core-4.3@4.3.13`、`@spine-particle/spine-pixi-v7-4.3@4.3.13`
|
||||
- 加载策略:Spine 3.8–4.2 固定使用 4.2.119;仅检测到 Spine 4.3 时按需加载 4.3.13
|
||||
- 接入目标:PixiJS 7
|
||||
|
||||
两个包已完整放入当前目录并通过 `file:` 依赖引用,项目安装和构建不需要从 npm 下载运行时代码。
|
||||
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
Spine Runtimes License Agreement
|
||||
Last updated April 5, 2025. Replaces all prior versions.
|
||||
|
||||
Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
|
||||
Integration of the Spine Runtimes into software or otherwise creating
|
||||
derivative works of the Spine Runtimes is permitted under the terms and
|
||||
conditions of Section 2 of the Spine Editor License Agreement:
|
||||
http://esotericsoftware.com/spine-editor-license
|
||||
|
||||
Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
"Products"), provided that each user of the Products must obtain their own
|
||||
Spine Editor license and redistribution of the Products in any form must
|
||||
include this license and copyright notice.
|
||||
|
||||
THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# spine-ts core
|
||||
|
||||
Please see the top-level [README.md](../README.md) for more information.
|
||||
+650
@@ -0,0 +1,650 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Attachment, VertexAttachment } from "./attachments/Attachment.js";
|
||||
import { SequenceMode } from "./attachments/Sequence.js";
|
||||
import type { Inherit } from "./BoneData.js";
|
||||
import type { BonePose } from "./BonePose.js";
|
||||
import type { Event } from "./Event.js";
|
||||
import type { PhysicsConstraintData } from "./PhysicsConstraintData.js";
|
||||
import type { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { Slot } from "./Slot.js";
|
||||
import type { SlotPose } from "./SlotPose.js";
|
||||
import { Color, type NumberArrayLike, StringSet } from "./Utils.js";
|
||||
/** Stores a list of timelines to animate a skeleton's pose over time.
|
||||
*
|
||||
* See <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine Runtimes
|
||||
* Guide. */
|
||||
export declare class Animation {
|
||||
/** The animation's name, unique across all animations in the skeleton.
|
||||
*
|
||||
* See {@link SkeletonData.findAnimation}. */
|
||||
readonly name: string;
|
||||
/** The duration of the animation in seconds, which is usually the highest time of all frames in the timelines. The duration is
|
||||
* used to know when the animation has completed and, for animations that repeat, when it should loop back to the start. */
|
||||
timelines: Array<Timeline>;
|
||||
readonly timelineIds: StringSet;
|
||||
/** {@link Skeleton.getBones} indices that this animation's timelines modify.
|
||||
*
|
||||
* See {@link BoneTimeline.bones}. */
|
||||
readonly bones: Array<number>;
|
||||
/** The color of the animation as it was in Spine, or a default color if nonessential data was not exported. */
|
||||
readonly color: Color;
|
||||
/** The duration of the animation in seconds, which is usually the highest time of all frames in the timeline. The duration is
|
||||
* used to know when it has completed and when it should loop back to the start. */
|
||||
duration: number;
|
||||
constructor(name: string, timelines: Array<Timeline>, duration: number);
|
||||
setTimelines(timelines: Array<Timeline>): void;
|
||||
/** Returns true if this animation contains a timeline with any of the specified property IDs.
|
||||
*
|
||||
* See {@link Timeline.propertyIds}. */
|
||||
hasTimeline(ids: string[]): boolean;
|
||||
/** Applies the animation's timelines to the specified skeleton.
|
||||
*
|
||||
* See {@link Timeline.apply} and
|
||||
* <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine Runtimes
|
||||
* Guide.
|
||||
* @param skeleton The skeleton the animation is applied to. This provides access to the bones, slots, and other skeleton
|
||||
* components the timelines may change.
|
||||
* @param lastTime The last time in seconds this animation was applied. Some timelines trigger only at discrete times, in which
|
||||
* case all keys are triggered between `lastTime` (exclusive) and `time` (inclusive). Pass -1
|
||||
* the first time an animation is applied to ensure frame 0 is triggered.
|
||||
* @param time The time in seconds the skeleton is being posed for. Timelines find the frame before and after this time and
|
||||
* interpolate between the frame values.
|
||||
* @param loop True if `time` beyond the {@link duration} repeats the animation, else the last frame is used.
|
||||
* @param events If any events are fired, they are added to this list. Pass null to ignore fired events or if no timelines fire
|
||||
* events.
|
||||
* @param alpha 0 applies setup or current values (depending on `from`), 1 uses timeline values, and intermediate
|
||||
* values interpolate between them. Adjusting `alpha` over time can mix an animation in or out.
|
||||
* @param from Controls how `alpha` and `add` mix from current or setup pose values to timeline values.
|
||||
* @param add If true, for timelines that support it, their values are added to the setup or current values (depending on
|
||||
* `from`).
|
||||
* @param out True when the animation is mixing out, else it is mixing in. Used by timelines that perform instant transitions.
|
||||
* @param appliedPose True to modify {@link Posed.appliedPose}, else {@link Posed.pose} is modified. */
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event> | null, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Controls whether `alpha` and `add` mix from current or setup pose values and what happens before the
|
||||
* first key.
|
||||
*
|
||||
* See {@link Timeline.apply}. */
|
||||
export declare enum MixFrom {
|
||||
/** Alpha mixes from the current pose. Before the first key, no change is made. */
|
||||
current = 0,
|
||||
/** Alpha mixes from the setup pose. Before the first key, the setup pose is used. */
|
||||
setup = 1,
|
||||
/** Alpha mixes from the current pose. Before the first key, alpha mixes from the current pose to the setup pose. */
|
||||
first = 2
|
||||
}
|
||||
export declare enum Property {
|
||||
rotate = 0,
|
||||
x = 1,
|
||||
y = 2,
|
||||
scaleX = 3,
|
||||
scaleY = 4,
|
||||
shearX = 5,
|
||||
shearY = 6,
|
||||
inherit = 7,
|
||||
rgb = 8,
|
||||
alpha = 9,
|
||||
rgb2 = 10,
|
||||
attachment = 11,
|
||||
deform = 12,
|
||||
event = 13,
|
||||
drawOrder = 14,
|
||||
drawOrderFolder = 15,
|
||||
ikConstraint = 16,
|
||||
transformConstraint = 17,
|
||||
pathConstraintPosition = 18,
|
||||
pathConstraintSpacing = 19,
|
||||
pathConstraintMix = 20,
|
||||
physicsConstraintInertia = 21,
|
||||
physicsConstraintStrength = 22,
|
||||
physicsConstraintDamping = 23,
|
||||
physicsConstraintMass = 24,
|
||||
physicsConstraintWind = 25,
|
||||
physicsConstraintGravity = 26,
|
||||
physicsConstraintMix = 27,
|
||||
physicsConstraintReset = 28,
|
||||
sequence = 29,
|
||||
sliderTime = 30,
|
||||
sliderMix = 31
|
||||
}
|
||||
/** The base class for all timelines.
|
||||
*
|
||||
* See <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
export declare abstract class Timeline {
|
||||
readonly propertyIds: string[];
|
||||
readonly frames: NumberArrayLike;
|
||||
/** True if this timeline supports being applied additively.
|
||||
*
|
||||
* See the `add` parameter in {@link Timeline.apply}. */
|
||||
additive: boolean;
|
||||
/** True if this timeline sets values instantaneously and does not support interpolation between frames. */
|
||||
instant: boolean;
|
||||
constructor(frameCount: number, ...propertyIds: string[]);
|
||||
getPropertyIds(): string[];
|
||||
/** The number of values stored per frame. */
|
||||
getFrameEntries(): number;
|
||||
/** The number of frames in this timeline. */
|
||||
getFrameCount(): number;
|
||||
/** The duration of the timeline in seconds, which is usually the highest time of all frames in the timeline. */
|
||||
getDuration(): number;
|
||||
/** Applies this timeline to the skeleton.
|
||||
*
|
||||
* See <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine
|
||||
* Runtimes Guide.
|
||||
* @param skeleton The skeleton the timeline is applied to. This provides access to the bones, slots, and other skeleton
|
||||
* components the timelines may change.
|
||||
* @param lastTime The last time in seconds this timeline was applied. Some timelines trigger only at discrete times, in
|
||||
* which case all keys are triggered between `lastTime` (exclusive) and `time` (inclusive).
|
||||
* Pass -1 the first time a timeline is applied to ensure frame 0 is triggered.
|
||||
* @param time The time in seconds the skeleton is being posed for. Timelines find the frame before and after this time and
|
||||
* interpolate between the frame values.
|
||||
* @param events If any events are fired, they are added to this list. Pass null to ignore fired events or if no timelines
|
||||
* fire events.
|
||||
* @param alpha 0 applies setup or current values (depending on `from`), 1 uses timeline values, and intermediate
|
||||
* values interpolate between them. Adjusting `alpha` over time can mix a timeline in or out.
|
||||
* @param from Controls how `alpha` and `add` mix from current or setup pose values to timeline
|
||||
* values.
|
||||
* @param add If true, for timelines that support it, their values are added to the setup or current values (depending on
|
||||
* `from`).
|
||||
* @param out True when the animation is mixing out, else it is mixing in. Used by timelines that perform instant
|
||||
* transitions.
|
||||
* @param appliedPose True to modify {@link Posed.appliedPose}, else {@link Posed.pose} is modified. */
|
||||
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event> | null, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
/** Linear search using the specified stride (default 1).
|
||||
* @param time Must be >= the first value in `frames`.
|
||||
* @return The index of the first value <= `time`. */
|
||||
static search(frames: NumberArrayLike, time: number, step?: number): number;
|
||||
}
|
||||
/** An interface for timelines that change a slot's properties. */
|
||||
export interface SlotTimeline {
|
||||
/** The index of the slot in {@link Skeleton.slots} that will be changed when this timeline is applied. */
|
||||
slotIndex: number;
|
||||
}
|
||||
export declare function isSlotTimeline(obj: Timeline & Partial<SlotTimeline>): obj is Timeline & SlotTimeline;
|
||||
/** The base class for timelines that interpolate between frame values using stepped, linear, or a Bezier curve. */
|
||||
export declare abstract class CurveTimeline extends Timeline {
|
||||
protected curves: NumberArrayLike;
|
||||
constructor(frameCount: number, bezierCount: number, ...propertyIds: string[]);
|
||||
/** Sets the specified key frame to linear interpolation. */
|
||||
setLinear(frame: number): void;
|
||||
/** Sets the specified key frame to stepped interpolation. */
|
||||
setStepped(frame: number): void;
|
||||
/** Shrinks the storage for Bezier curves, for use when `bezierCount` (specified in the constructor) was larger
|
||||
* than the actual number of Bezier curves. */
|
||||
shrink(bezierCount: number): void;
|
||||
/** Stores the segments for the specified Bezier curve. For timelines that modify multiple values, there may be more than
|
||||
* one curve per frame.
|
||||
* @param bezier The ordinal of this Bezier curve for this timeline, between 0 and `bezierCount - 1` (specified
|
||||
* in the constructor), inclusive.
|
||||
* @param frame Between 0 and `frameCount - 1`, inclusive.
|
||||
* @param value The index of the value for this frame that this curve is used for.
|
||||
* @param time1 The time for the first key.
|
||||
* @param value1 The value for the first key.
|
||||
* @param cx1 The time for the first Bezier handle.
|
||||
* @param cy1 The value for the first Bezier handle.
|
||||
* @param cx2 The time of the second Bezier handle.
|
||||
* @param cy2 The value for the second Bezier handle.
|
||||
* @param time2 The time for the second key.
|
||||
* @param value2 The value for the second key. */
|
||||
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
|
||||
/** Returns the Bezier interpolated value for the specified time.
|
||||
* @param frameIndex The index into {@link frames} for the values of the frame before `time`.
|
||||
* @param valueOffset The offset from `frameIndex` to the value this curve is used for.
|
||||
* @param i The index of the Bezier segments. See {@link getCurveType}. */
|
||||
getBezierValue(time: number, frameIndex: number, valueOffset: number, i: number): number;
|
||||
}
|
||||
/** The base class for a {@link CurveTimeline} that sets one property with a curve. */
|
||||
export declare abstract class CurveTimeline1 extends CurveTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, propertyId: string);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time and value for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
setFrame(frame: number, time: number, value: number): void;
|
||||
/** Returns the interpolated value for the specified time. */
|
||||
getCurveValue(time: number): number;
|
||||
/** Returns the interpolated value for properties relative to the setup value. The timeline value is added to the setup
|
||||
* value, rather than replacing it.
|
||||
*
|
||||
* See {@link Timeline.apply}.
|
||||
* @param current The current value for the property.
|
||||
* @param setup The setup value for the property. */
|
||||
getRelativeValue(time: number, alpha: number, from: MixFrom, add: boolean, current: number, setup: number): number;
|
||||
/** Returns the interpolated value for properties set as absolute values. The timeline value replaces the setup value,
|
||||
* rather than being relative to it.
|
||||
*
|
||||
* See {@link Timeline.apply}.
|
||||
* @param current The current value for the property.
|
||||
* @param setup The setup value for the property. */
|
||||
getAbsoluteValue(time: number, alpha: number, from: MixFrom, add: boolean, current: number, setup: number): number;
|
||||
/** Returns the interpolated value for properties set as absolute values, using the specified timeline value rather than
|
||||
* calling {@link getCurveValue}.
|
||||
*
|
||||
* See {@link Timeline.apply}.
|
||||
* @param current The current value for the property.
|
||||
* @param setup The setup value for the property.
|
||||
* @param value The timeline value to apply. */
|
||||
getAbsoluteValue(time: number, alpha: number, from: MixFrom, add: boolean, current: number, setup: number, value: number): number;
|
||||
private getAbsoluteValue1;
|
||||
private getAbsoluteValue2;
|
||||
/** Returns the interpolated value for scale properties. The timeline and setup values are multiplied and sign adjusted.
|
||||
*
|
||||
* See {@link Timeline.apply}.
|
||||
* @param current The current value for the property.
|
||||
* @param setup The setup value for the property. */
|
||||
getScaleValue(time: number, alpha: number, from: MixFrom, add: boolean, out: boolean, current: number, setup: number): number;
|
||||
private static beforeFirstKey;
|
||||
}
|
||||
/** An interface for timelines that change a bone's properties. */
|
||||
export interface BoneTimeline {
|
||||
/** The index of the bone in {@link Skeleton.bones} that is changed by this timeline. */
|
||||
boneIndex: number;
|
||||
}
|
||||
export declare function isBoneTimeline(obj: Timeline & Partial<BoneTimeline>): obj is Timeline & BoneTimeline;
|
||||
/** The base class for timelines that change 1 bone property with a curve. */
|
||||
export declare abstract class BoneTimeline1 extends CurveTimeline1 implements BoneTimeline {
|
||||
readonly boneIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number, property: Property);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event> | null, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
protected abstract apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** The base class for timelines that change two bone properties with a curve. */
|
||||
export declare abstract class BoneTimeline2 extends CurveTimeline implements BoneTimeline {
|
||||
readonly boneIndex: number;
|
||||
/** @param bezierCount The maximum number of Bezier curves. See {@link shrink}.
|
||||
* @param propertyIds Unique identifiers for the properties the timeline modifies. */
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number, property1: Property, property2: Property);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time and values for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
setFrame(frame: number, time: number, value1: number, value2: number): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event> | null, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
protected abstract apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.rotation}. */
|
||||
export declare class RotateTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.x} and {@link BonePose.y}. */
|
||||
export declare class TranslateTimeline extends BoneTimeline2 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.x}. */
|
||||
export declare class TranslateXTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.y}. */
|
||||
export declare class TranslateYTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.scaleX} and {@link BonePose.scaleY}. */
|
||||
export declare class ScaleTimeline extends BoneTimeline2 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes a {@link BonePose.scaleX}. */
|
||||
export declare class ScaleXTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes a {@link BonePose.scaleY}. */
|
||||
export declare class ScaleYTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link Bone.shearX} and {@link Bone.shearY}. */
|
||||
export declare class ShearTimeline extends BoneTimeline2 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link Bone.shearX} and {@link Bone.shearY}. */
|
||||
export declare class ShearXTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link Bone.shearX} and {@link Bone.shearY}. */
|
||||
export declare class ShearYTimeline extends BoneTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, boneIndex: number);
|
||||
protected apply1(pose: BonePose, setup: BonePose, time: number, alpha: number, from: MixFrom, add: boolean, out: boolean): void;
|
||||
}
|
||||
/** Changes {@link BonePose.inherit}. */
|
||||
export declare class InheritTimeline extends Timeline implements BoneTimeline {
|
||||
readonly boneIndex: number;
|
||||
constructor(frameCount: number, boneIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the inherit transform mode for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
setFrame(frame: number, time: number, inherit: Inherit): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** The base class for timelines that change any number of slot properties with a curve. */
|
||||
export declare abstract class SlotCurveTimeline extends CurveTimeline implements SlotTimeline {
|
||||
readonly slotIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number, ...propertyIds: string[]);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
protected abstract apply1(slot: Slot, pose: SlotPose, time: number, alpha: number, from: MixFrom, add: boolean): void;
|
||||
}
|
||||
/** Changes {@link SlotPose.color}. */
|
||||
export declare class RGBATimeline extends SlotCurveTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
|
||||
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number): void;
|
||||
protected apply1(slot: Slot, pose: SlotPose, time: number, alpha: number, from: MixFrom, add: boolean): void;
|
||||
}
|
||||
/** Changes RGB for a slot's {@link SlotPose.color}. */
|
||||
export declare class RGBTimeline extends SlotCurveTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
|
||||
setFrame(frame: number, time: number, r: number, g: number, b: number): void;
|
||||
protected apply1(slot: Slot, pose: SlotPose, time: number, alpha: number, from: MixFrom, add: boolean): void;
|
||||
}
|
||||
/** Changes alpha for a slot's {@link SlotPose.color}. */
|
||||
export declare class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
|
||||
slotIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link SlotPose.color} and {@link SlotPose.darkColor} for two color tinting. */
|
||||
export declare class RGBA2Timeline extends SlotCurveTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
|
||||
protected apply1(slot: Slot, pose: SlotPose, time: number, alpha: number, from: MixFrom, add: boolean): void;
|
||||
}
|
||||
/** Changes {@link SlotPose.color} and {@link SlotPose.darkColor} for two color tinting. */
|
||||
export declare class RGB2Timeline extends SlotCurveTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
setFrame(frame: number, time: number, r: number, g: number, b: number, r2: number, g2: number, b2: number): void;
|
||||
protected apply1(slot: Slot, pose: SlotPose, time: number, alpha: number, from: MixFrom, add: boolean): void;
|
||||
}
|
||||
/** Changes {@link SlotPose.ttachment}. */
|
||||
export declare class AttachmentTimeline extends Timeline implements SlotTimeline {
|
||||
slotIndex: number;
|
||||
/** The attachment name for each key frame. May contain null values to clear the attachment. */
|
||||
attachmentNames: Array<string | null>;
|
||||
constructor(frameCount: number, slotIndex: number);
|
||||
getFrameCount(): number;
|
||||
/** Sets the time in seconds and the attachment name for the specified key frame. */
|
||||
setFrame(frame: number, time: number, attachmentName: string | null): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
setAttachment(skeleton: Skeleton, pose: SlotPose, attachmentName: string | null): void;
|
||||
}
|
||||
/** Changes {@link SlotPose.deform} to deform a {@link VertexAttachment}. */
|
||||
export declare class DeformTimeline extends CurveTimeline implements SlotTimeline {
|
||||
readonly slotIndex: number;
|
||||
/** The attachment that will be deformed.
|
||||
*
|
||||
* See {@link VertexAttachment.getTimelineAttachment}. */
|
||||
readonly attachment: VertexAttachment;
|
||||
/** The vertices for each key frame. */
|
||||
vertices: Array<NumberArrayLike>;
|
||||
constructor(frameCount: number, bezierCount: number, slotIndex: number, attachment: VertexAttachment);
|
||||
getFrameCount(): number;
|
||||
/** Sets the time and vertices for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */
|
||||
setFrame(frame: number, time: number, vertices: NumberArrayLike): void;
|
||||
/** @param value1 Ignored (0 is used for a deform timeline).
|
||||
* @param value2 Ignored (1 is used for a deform timeline). */
|
||||
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
|
||||
getCurvePercent(time: number, frame: number): number;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Event[] | null, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
private applyBeforeFirst;
|
||||
private applyToSlot;
|
||||
}
|
||||
/** Changes {@link Slot.getSequenceIndex} for an attachment's {@link Sequence}. */
|
||||
export declare class SequenceTimeline extends Timeline implements SlotTimeline {
|
||||
static ENTRIES: number;
|
||||
static MODE: number;
|
||||
static DELAY: number;
|
||||
readonly slotIndex: number;
|
||||
readonly attachment: Attachment;
|
||||
constructor(frameCount: number, slotIndex: number, attachment: Attachment);
|
||||
getFrameEntries(): number;
|
||||
getSlotIndex(): number;
|
||||
/** The attachment for which the {@link SlotPose.sequenceIndex} will be set.
|
||||
*
|
||||
* See {@link VertexAttachment.timelineAttachment}. */
|
||||
getAttachment(): Attachment;
|
||||
/** Sets the time, mode, index, and frame time for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time Seconds between frames. */
|
||||
setFrame(frame: number, time: number, mode: SequenceMode, index: number, delay: number): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
private setupPose;
|
||||
private applyToSlot;
|
||||
}
|
||||
/** Fires an {@link Event} when specific animation times are reached. */
|
||||
export declare class EventTimeline extends Timeline {
|
||||
static propertyIds: string[];
|
||||
/** The event for each key frame. */
|
||||
events: Array<Event>;
|
||||
constructor(frameCount: number);
|
||||
getFrameCount(): number;
|
||||
/** Sets the time in seconds and the event for the specified key frame. */
|
||||
setFrame(frame: number, event: Event): void;
|
||||
/** Fires events for frames > `lastTime` and <= `time`. */
|
||||
apply(skeleton: Skeleton | null, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes the {@link Skeleton.getDrawOrder}. */
|
||||
export declare class DrawOrderTimeline extends Timeline {
|
||||
static readonly propertyID = "14";
|
||||
static propertyIds: string[];
|
||||
/** The draw order for each key frame. See {@link setFrame}. */
|
||||
private readonly drawOrders;
|
||||
constructor(frameCount: number);
|
||||
getFrameCount(): number;
|
||||
/** Sets the time in seconds and the draw order for the specified key frame.
|
||||
* @param drawOrder Ordered {@link Skeleton.slots} indices, or null to use setup pose
|
||||
* draw order. */
|
||||
setFrame(frame: number, time: number, drawOrder: Array<number> | null): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes a subset of the {@link Skeleton.getDrawOrder | draw order}. */
|
||||
export declare class DrawOrderFolderTimeline extends Timeline {
|
||||
static readonly propertyID = "15";
|
||||
private readonly slots;
|
||||
private readonly inFolder;
|
||||
private readonly drawOrders;
|
||||
/** @param slots {@link Skeleton.slots} indices controlled by this timeline, in setup order.
|
||||
* @param slotCount The maximum number of slots in the skeleton. */
|
||||
constructor(frameCount: number, slots: number[], slotCount: number);
|
||||
private static propertyIds;
|
||||
getFrameCount(): number;
|
||||
/** The {@link Skeleton.getSlots} indices that this timeline affects, in setup order. */
|
||||
getSlots(): number[];
|
||||
/** The draw order for each frame. See {@link setFrame}. */
|
||||
getDrawOrders(): Array<Array<number> | null>;
|
||||
/** Sets the time and draw order for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param drawOrder Ordered {@link getSlots} indices, or null to use setup pose order. */
|
||||
setFrame(frame: number, time: number, drawOrder: Array<number> | null): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
private setup;
|
||||
}
|
||||
export interface ConstraintTimeline {
|
||||
/** The index of the constraint in {@link Skeleton.constraints} that will be changed when this timeline is applied, or -1 if
|
||||
* a specific constraint will not be changed. */
|
||||
readonly constraintIndex: number;
|
||||
}
|
||||
export declare function isConstraintTimeline(obj: Timeline & Partial<ConstraintTimeline>): obj is Timeline & ConstraintTimeline;
|
||||
/** Changes {@link IkConstraintPose.mix)}, {@link IkConstraintPose.softness},
|
||||
* {@link IkConstraintPose.bendDirection}, {@link IkConstraintPose.stretch}, and
|
||||
* {@link IkConstraintPose.compress}. */
|
||||
export declare class IkConstraintTimeline extends CurveTimeline implements ConstraintTimeline {
|
||||
readonly constraintIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time, mix, softness, bend direction, compress, and stretch for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param bendDirection 1 or -1. */
|
||||
setFrame(frame: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link TransformConstraintPose.mixRotate}, {@link TransformConstraintPose.mixX},
|
||||
* {@link TransformConstraintPose.mixY}, {@link TransformConstraintPose.mixScaleX},
|
||||
* {@link TransformConstraintPose.mixScaleY}, and {@link TransformConstraintPose.mixShearY}. */
|
||||
export declare class TransformConstraintTimeline extends CurveTimeline implements ConstraintTimeline {
|
||||
/** The index of the transform constraint slot in {@link Skeleton.transformConstraints} that will be changed. */
|
||||
constraintIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time, rotate mix, translate mix, scale mix, and shear mix for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number, mixScaleX: number, mixScaleY: number, mixShearY: number): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** The base class for timelines that change 1 constraint property with a curve. */
|
||||
export declare abstract class ConstraintTimeline1 extends CurveTimeline1 implements ConstraintTimeline {
|
||||
readonly constraintIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number, property: Property);
|
||||
}
|
||||
/** Changes {@link PathConstraintPose.position}. */
|
||||
export declare class PathConstraintPositionTimeline extends ConstraintTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link PathConstraintPose.spacing}. */
|
||||
export declare class PathConstraintSpacingTimeline extends ConstraintTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link PathConstraint.mixRotate}, {@link PathConstraint.mixX}, and
|
||||
* {@link PathConstraint.mixY}. */
|
||||
export declare class PathConstraintMixTimeline extends CurveTimeline implements ConstraintTimeline {
|
||||
readonly constraintIndex: number;
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
getFrameEntries(): number;
|
||||
/** Sets the time and color for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number): void;
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** The base class for most {@link PhysicsConstraint} timelines. */
|
||||
export declare abstract class PhysicsConstraintTimeline extends ConstraintTimeline1 {
|
||||
/** @param constraintIndex -1 for all physics constraints in the skeleton. */
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number, property: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
abstract get(pose: PhysicsConstraintPose): number;
|
||||
abstract set(pose: PhysicsConstraintPose, value: number): void;
|
||||
abstract global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.inertia}. */
|
||||
export declare class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.strength}. */
|
||||
export declare class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.damping}. */
|
||||
export declare class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.massInverse}. The timeline values are not inverted. */
|
||||
export declare class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.wind}. */
|
||||
export declare class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.gravity}. */
|
||||
export declare class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Changes {@link PhysicsConstraintPose.mix}. */
|
||||
export declare class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
get(pose: PhysicsConstraintPose): number;
|
||||
set(pose: PhysicsConstraintPose, value: number): void;
|
||||
global(constraint: PhysicsConstraintData): boolean;
|
||||
}
|
||||
/** Resets a physics constraint when specific animation times are reached. */
|
||||
export declare class PhysicsConstraintResetTimeline extends Timeline implements ConstraintTimeline {
|
||||
private static propertyIds;
|
||||
/** The index of the physics constraint in {@link Skeleton.contraints} that will be reset when this timeline is
|
||||
* applied, or -1 if all physics constraints in the skeleton will be reset. */
|
||||
readonly constraintIndex: number;
|
||||
/** @param constraintIndex -1 for all physics constraints in the skeleton. */
|
||||
constructor(frameCount: number, constraintIndex: number);
|
||||
getFrameCount(): number;
|
||||
/** Sets the time for the specified frame.
|
||||
* @param frame Between 0 and `frameCount`, inclusive. */
|
||||
setFrame(frame: number, time: number): void;
|
||||
/** Resets the physics constraint when frames > `lastTime` and <= `time`. */
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link SliderPose.time}. */
|
||||
export declare class SliderTimeline extends ConstraintTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
/** Changes {@link SliderPose.mix}. */
|
||||
export declare class SliderMixTimeline extends ConstraintTimeline1 {
|
||||
constructor(frameCount: number, bezierCount: number, constraintIndex: number);
|
||||
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, from: MixFrom, add: boolean, out: boolean, appliedPose: boolean): void;
|
||||
}
|
||||
+2270
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,458 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** biome-ignore-all lint/style/noNonNullAssertion: reference runtime expects some nullable to not be null */
|
||||
import { Animation, AttachmentTimeline, MixFrom, RotateTimeline } from "./Animation.js";
|
||||
import type { AnimationStateData } from "./AnimationStateData.js";
|
||||
import type { Event } from "./Event.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import { Interpolation, Pool } from "./Utils.js";
|
||||
/** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies
|
||||
* multiple animations on top of each other (layering).
|
||||
*
|
||||
* See [Applying Animations](http://esotericsoftware.com/spine-applying-animations#AnimationState-API) in the Spine Runtimes Guide. */
|
||||
export declare class AnimationState {
|
||||
static readonly emptyAnimation: Animation;
|
||||
/** The AnimationStateData to look up mix durations. */
|
||||
data: AnimationStateData;
|
||||
/** The list of tracks that have had animations. May contain null entries for tracks that currently have no animation. */
|
||||
readonly tracks: (TrackEntry | null)[];
|
||||
/** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
|
||||
* or faster. Defaults to 1.
|
||||
*
|
||||
* See {@link TrackEntry.timeScale} to affect a single animation. */
|
||||
timeScale: number;
|
||||
unkeyedState: number;
|
||||
readonly events: Event[];
|
||||
readonly listeners: AnimationStateListener[];
|
||||
queue: EventQueue;
|
||||
propertyIds: Map<string, TrackEntry>;
|
||||
animationsChanged: boolean;
|
||||
trackEntryPool: Pool<TrackEntry>;
|
||||
constructor(data: AnimationStateData);
|
||||
/** Increments each track entry {@link TrackEntry.trackTime}, setting queued animations as current if needed. */
|
||||
update(delta: number): void;
|
||||
/** Returns true when all mixing from entries are complete. */
|
||||
updateMixingFrom(to: TrackEntry, delta: number): boolean;
|
||||
/** Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple
|
||||
* skeletons to pose them identically.
|
||||
* @returns True if any animations were applied. */
|
||||
apply(skeleton: Skeleton): boolean;
|
||||
applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
|
||||
/** Applies the attachment timeline and sets {@link Slot.attachmentState}.
|
||||
* @param retain True if the attachment remains after apply, false if temporary for deform timelines. */
|
||||
applyAttachmentTimeline(timeline: AttachmentTimeline, skeleton: Skeleton, time: number, from: MixFrom, retain: boolean): void;
|
||||
/** Applies the rotate timeline, mixing with the current pose while keeping the same rotation direction chosen as the shortest
|
||||
* the first time the mixing was applied. */
|
||||
applyRotateTimeline(timeline: RotateTimeline, skeleton: Skeleton, time: number, alpha: number, from: MixFrom, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
|
||||
queueEvents(entry: TrackEntry, animationTime: number): void;
|
||||
private eventsReverse;
|
||||
/** Removes all animations from all tracks, leaving skeletons in their current pose.
|
||||
*
|
||||
* Usually you want to use {@link setEmptyAnimations} to mix the skeletons back to the setup pose, rather than leaving
|
||||
* them in their current pose. */
|
||||
clearTracks(): void;
|
||||
/** Removes all animations from the track, leaving skeletons in their current pose.
|
||||
*
|
||||
* Usually you want to use {@link setEmptyAnimation} to mix the skeletons back to the setup pose, rather than
|
||||
* leaving them in their current pose. */
|
||||
clearTrack(trackIndex: number): void;
|
||||
setTrack(index: number, current: TrackEntry, interrupt: boolean): void;
|
||||
/** Sets an animation by name.
|
||||
*
|
||||
* See {@link setAnimation}. */
|
||||
setAnimation(trackIndex: number, animationName: string, loop?: boolean): TrackEntry;
|
||||
/** Sets the current animation for a track, discarding any queued animations.
|
||||
*
|
||||
* If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
|
||||
* from).
|
||||
* @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. In either case {@link TrackEntry.trackEnd} determines when the track is cleared.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after the {@link AnimationStateListener.dispose} event occurs. */
|
||||
setAnimation(trackIndex: number, animation: Animation, loop?: boolean): TrackEntry;
|
||||
private setAnimation1;
|
||||
/** Sets the current animation for a track, discarding any queued animations.
|
||||
*
|
||||
* If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
|
||||
* from).
|
||||
* @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. In either case {@link TrackEntry.getTrackEnd} determines when the track is cleared.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after the {@link AnimationStateListener.dispose} event occurs. */
|
||||
private setAnimation2;
|
||||
/** Queues an animation by name.
|
||||
*
|
||||
* See {@link addAnimation}. */
|
||||
addAnimation(trackIndex: number, animationName: string, loop?: boolean, delay?: number): TrackEntry;
|
||||
/** Adds an animation to be played after the current or last queued animation for a track. If the track has no entries, this is
|
||||
* equivalent to calling {@link setAnimation}.
|
||||
* @param delay If > 0, sets {@link TrackEntry.delay}. If <= 0, the delay set is the duration of the previous track entry
|
||||
* minus any mix duration (from {@link data}) plus the specified `delay` (ie the mix ends at (when
|
||||
* `delay` = 0) or before (when `delay` < 0) the previous track entry duration). If the
|
||||
* previous entry is looping, its next loop completion is used instead of its duration.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after the {@link AnimationStateListener.dispose} event occurs. */
|
||||
addAnimation(trackIndex: number, animation: Animation, loop?: boolean, delay?: number): TrackEntry;
|
||||
private addAnimation1;
|
||||
private addAnimation2;
|
||||
/** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's
|
||||
* {@link TrackEntry.mixduration}. An empty animation has no timelines and serves as a placeholder for mixing in or out.
|
||||
*
|
||||
* Mixing out is done by setting an empty animation with a mix duration using either {@link setEmptyAnimation},
|
||||
* {@link setEmptyAnimations}, or {@link addEmptyAnimation}. Mixing to an empty animation causes
|
||||
* the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
|
||||
* transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
|
||||
* 0 still needs to be applied one more time to mix out, so the properties it was animating are reverted.
|
||||
*
|
||||
* Mixing in is done by first setting an empty animation, then adding an animation using
|
||||
* {@link addAnimation} with the desired delay (an empty animation has a duration of 0) and on
|
||||
* the returned track entry, set the {@link TrackEntry.setMixDuration}. Mixing from an empty animation causes the new
|
||||
* animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value
|
||||
* from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new animation.
|
||||
*
|
||||
* See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
setEmptyAnimation(trackIndex: number, mixDuration?: number): TrackEntry;
|
||||
/** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
|
||||
* {@link TrackEntry.mixDuration}. If the track has no entries, it is equivalent to calling
|
||||
* {@link setEmptyAnimation}.
|
||||
*
|
||||
* See {@link setEmptyAnimation} and
|
||||
* <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine Runtimes
|
||||
* Guide.
|
||||
* @param delay If > 0, sets {@link TrackEntry.delay}. If <= 0, the delay set is the duration of the previous track entry minus
|
||||
* any mix duration plus the specified `delay` (ie the mix ends at (when `delay` = 0) or before
|
||||
* (when `delay` < 0) the previous track entry duration). If the previous entry is looping, its next loop
|
||||
* completion is used instead of its duration.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after the {@link AnimationStateListener.dispose} event occurs. */
|
||||
addEmptyAnimation(trackIndex: number, mixDuration?: number, delay?: number): TrackEntry;
|
||||
/** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||
*
|
||||
* See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
setEmptyAnimations(mixDuration?: number): void;
|
||||
expandToIndex(index: number): TrackEntry | null;
|
||||
/** @param last May be null. */
|
||||
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry | null): TrackEntry;
|
||||
/** Removes {@link TrackEntry.next} and all entries after it for the specified entry. */
|
||||
clearNext(entry: TrackEntry): void;
|
||||
_animationsChanged(): void;
|
||||
computeHold(entry: TrackEntry, track: TrackEntry): void;
|
||||
private from;
|
||||
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
|
||||
getTrack(trackIndex: number): TrackEntry | null;
|
||||
/** Adds a listener to receive events for all track entries. */
|
||||
addListener(listener: AnimationStateListener): void;
|
||||
/** Removes the listener added with {@link addListener}. */
|
||||
removeListener(listener: AnimationStateListener): void;
|
||||
/** Removes all listeners added with {@link addListener}. */
|
||||
clearListeners(): void;
|
||||
/** Discards all listener notifications that have not yet been delivered. This can be useful to call from an
|
||||
* {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery
|
||||
* are not wanted because new animations are being set. */
|
||||
clearListenerNotifications(): void;
|
||||
}
|
||||
/** Stores settings and other state for the playback of an animation on an {@link AnimationState} track.
|
||||
*
|
||||
* References to a track entry must not be kept after the {@link AnimationStateListener.dispose} event occurs. */
|
||||
export declare class TrackEntry {
|
||||
/** The animation to apply for this track entry. */
|
||||
animation: Animation | null;
|
||||
previous: TrackEntry | null;
|
||||
/** The animation queued to start after this animation, or null. `next` makes up a linked list. */
|
||||
next: TrackEntry | null;
|
||||
/** The track entry for the previous animation when mixing to this animation, or null if no mixing is currently occurring.
|
||||
* When mixing from multiple animations, `mixingFrom` makes up a doubly linked list. */
|
||||
mixingFrom: TrackEntry | null;
|
||||
/** The track entry for the next animation when mixing from this animation, or null if no mixing is currently occurring.
|
||||
* When mixing to multiple animations, `mixingTo` makes up a doubly linked list. */
|
||||
mixingTo: TrackEntry | null;
|
||||
/** The listener for events generated by this track entry, or null.
|
||||
*
|
||||
* A track entry returned from {@link AnimationState.setAnimation} is already the current animation
|
||||
* for the track, so the callback for listener {@link AnimationStateListener.start} will not be called. */
|
||||
listener: AnimationStateListener | null;
|
||||
/** The index of the track where this track entry is either current or queued.
|
||||
*
|
||||
* See {@link AnimationState.getTrack}. */
|
||||
trackIndex: number;
|
||||
/** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. */
|
||||
loop: boolean;
|
||||
/** When true, timelines in this animation that support additive have their values added to the setup or current pose values
|
||||
* instead of replacing them. Additive can be set for a new track entry only before {@link AnimationState.apply}
|
||||
* is next called. */
|
||||
additive: boolean;
|
||||
/** If true, the animation will be applied in reverse. */
|
||||
reverse: boolean;
|
||||
/** If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
|
||||
* shortest rotation direction may change during the mix.
|
||||
*
|
||||
* If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
|
||||
* of the mix. Defaults to false.
|
||||
*
|
||||
* See {@link resetRotationDirections}. */
|
||||
shortestRotation: boolean;
|
||||
keepHold: boolean;
|
||||
/** When the interpolated mix percentage is less than the `eventThreshold` , event timelines are applied while
|
||||
* this animation is being mixed out. Defaults to 0, so event timelines are not applied while this animation is being mixed
|
||||
* out. */
|
||||
eventThreshold: number;
|
||||
/** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
|
||||
* applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
|
||||
* animation is being mixed out. */
|
||||
mixAttachmentThreshold: number;
|
||||
/** When the computed alpha is greater than `alphaAttachmentThreshold`, attachment timelines are applied. The
|
||||
* computed alpha includes {@link alpha} and the interpolated mix percentage. Defaults to 0, so attachment timelines are
|
||||
* always applied. */
|
||||
alphaAttachmentThreshold: number;
|
||||
/** When the interpolated mix percentage is less than the `mixAttachmentThreshold`, attachment timelines are
|
||||
* applied while this animation is being mixed out. Defaults to 0, so attachment timelines are not applied while this
|
||||
* animation is being mixed out. */
|
||||
mixDrawOrderThreshold: number;
|
||||
/** The time in seconds for the first frame of this animation, both initially and after looping. Defaults to 0.
|
||||
*
|
||||
* When setting `animationStart` time, {@link animationLast} can be set to the same value to avoid firing events
|
||||
* from the start of the animation. */
|
||||
animationStart: number;
|
||||
/** The time in seconds for the last frame of this animation. Past this time, non-looping animations hold the pose at this
|
||||
* time while looping animations will loop back to {@link animationStart}. Defaults to the {@link Animation.duration}. */
|
||||
animationEnd: number;
|
||||
/** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. For example, when
|
||||
* this animation is applied, event timelines will fire all events between the `animationLast` time (exclusive)
|
||||
* and `animationTime` (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this
|
||||
* animation is applied. */
|
||||
animationLast: number;
|
||||
nextAnimationLast: number;
|
||||
/** Seconds to postpone playing the animation. Must be >= 0. When this track entry is the current track entry,
|
||||
* `delay` postpones incrementing the {@link trackTime}. When this track entry is queued, `delay` is
|
||||
* the time from the start of the previous animation to when this track entry will become the current track entry (ie when
|
||||
* the previous track entry {@link trackTime} >= this track entry's `delay`).
|
||||
*
|
||||
* {@link timeScale} affects the delay.
|
||||
*
|
||||
* When passing `delay` <= 0 to {@link AnimationState.addAnimation} this
|
||||
* `delay` is set using a mix duration from {@link AnimationStateData}. To change the {@link mixDuration}
|
||||
* afterward, use {@link setMixDuration} so this `delay` is adjusted. */
|
||||
delay: number;
|
||||
/** The time in seconds this track entry has been the current track entry, starting at 0 and increasing forever. Compare to
|
||||
* {@link getAnimationTime}, which is always between {@link animationStart} and {@link animationEnd}.
|
||||
*
|
||||
* The track time can be set to start the animation at a time other than 0, without affecting looping. When doing so,
|
||||
* {@link animationLast} can be set to the same value to avoid firing events from the start of the animation.
|
||||
*
|
||||
* To set the time an animation starts and loops, use {@link animationStart} and {@link animationEnd}. */
|
||||
trackTime: number;
|
||||
trackLast: number;
|
||||
nextTrackLast: number;
|
||||
/** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float
|
||||
* value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time
|
||||
* is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
|
||||
* properties keyed by the animation are set to the setup pose and the track is cleared.
|
||||
*
|
||||
* Usually you want to use {@link AnimationState.addEmptyAnimation} rather than have the animation
|
||||
* abruptly cease being applied, leaving the current pose. */
|
||||
trackEnd: number;
|
||||
/** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or
|
||||
* faster. Defaults to 1.
|
||||
*
|
||||
* Values < 0 are not supported. To play an animation in reverse, use {@link reverse}.
|
||||
*
|
||||
* {@link mixTime} is not affected by track entry time scale, so {@link mixDuration} may need to be adjusted to match the
|
||||
* animation speed.
|
||||
*
|
||||
* When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
|
||||
* {@link delay} is set using the mix duration from {@link AnimationState.data}, assuming time scale to be 1. If the time
|
||||
* scale is not 1, the delay may need to be adjusted.
|
||||
*
|
||||
* See {@link AnimationState.timeScale} to affect all animations. */
|
||||
timeScale: number;
|
||||
/** Values < 1 mix this animation with the skeleton's current pose (either the setup pose or the pose from lower tracks).
|
||||
* Defaults to 1, which overwrites the skeleton's current pose with this animation.
|
||||
*
|
||||
* Alpha should be 1 on track 0.
|
||||
*
|
||||
* See {@link getAlphaAttachmentThreshold}. */
|
||||
alpha: number;
|
||||
/** Seconds elapsed from 0 to the {@link mixDuration} when mixing from the previous animation to this animation. May
|
||||
* be slightly more than `mixDuration` when the mix is complete. */
|
||||
mixTime: number;
|
||||
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
||||
* {@link AnimationStateData.getMix} based on the animation before this animation (if any).
|
||||
*
|
||||
* A mix duration of 0 still needs to be applied one more time to mix out, so the the properties it was animating are
|
||||
* reverted. A mix duration of 0 can be set at any time to end the mix on the next
|
||||
* {@link AnimationState.update | update}.
|
||||
*
|
||||
* The `mixDuration` can be set manually rather than use the value from
|
||||
* {@link AnimationStateData.getMix}. In that case, the `mixDuration` can be set for a new
|
||||
* track entry only before {@link AnimationState.update} is next called.
|
||||
*
|
||||
* When using {@link AnimationState.addAnimation} with a `delay` <= 0, the
|
||||
* {@link getDelay} is set using the mix duration from {@link AnimationState.data}. If `mixDuration` is set
|
||||
* afterward, the delay needs to be adjusted:
|
||||
*
|
||||
* <pre>
|
||||
* entry.mixDuration = 0.25;<br>
|
||||
* entry.delay = entry.previous.getTrackComplete() - entry.mixDuration + 0;
|
||||
* </pre>
|
||||
*
|
||||
* Alternatively, use {@link setMixDuration} to set both the mix duration and recompute the delay:<br>
|
||||
*
|
||||
* <pre>
|
||||
entry.setMixDuration(0.25f, 0); // mixDuration, delay
|
||||
* </pre>
|
||||
*/
|
||||
mixDuration: number;
|
||||
totalAlpha: number;
|
||||
mixInterpolation: Interpolation;
|
||||
/** Sets both {@link getMixDuration} and {@link getDelay}.
|
||||
* @param delay If > 0, sets {@link getDelay}. If <= 0, the delay set is the duration of the previous track entry minus
|
||||
* the specified mix duration plus the specified `delay` (ie the mix ends at (when `delay` =
|
||||
* 0) or before (when `delay` < 0) the previous track entry duration). If the previous entry is
|
||||
* looping, its next loop completion is used instead of its duration. */
|
||||
setMixDuration(mixDuration: number, delay?: number): void;
|
||||
/** The interpolation to apply to the mix percentage ({@link mixTime} / {@link mixDuration}) when mixing from the previous
|
||||
* animation to this animation. Defaults to linear. */
|
||||
setMixInterpolation(mixInterpolation: Interpolation): void;
|
||||
mix(): number;
|
||||
/** For each timeline:
|
||||
* - Bits 0-1: MixFrom.
|
||||
* - Bit 2, HOLD: 0 = mix out using alphaMix, 1 = apply full alpha to prevent dipping. Timeline is first on its track to
|
||||
* set the property and the next entry (mixingTo) also sets it. When held, timelineHoldMix's mix controls how the hold fades
|
||||
* out (for 3+ entry chains where the chain eventually stops setting the property). */
|
||||
timelineMode: number[];
|
||||
timelineHoldMix: TrackEntry[];
|
||||
timelinesRotation: number[];
|
||||
reset(): void;
|
||||
/** Uses {@link trackTime} to compute the `animationTime`, which is always between {@link animationStart} and
|
||||
* {@link animationEnd}. When `trackTime` is 0, `animationTime` is equal to the
|
||||
* `animationStart` time. */
|
||||
getAnimationTime(): number;
|
||||
setAnimationLast(animationLast: number): void;
|
||||
/** Returns true if at least one loop has been completed.
|
||||
*
|
||||
* See {@link AnimationStateListener.complete}. */
|
||||
isComplete(): boolean;
|
||||
/** When {@link shortestRotation} is false, this clears the directions for mixing this entry's rotation. This can be useful
|
||||
* to avoid bones rotating the long way around when using {@link getAlpha} and starting animations on other tracks.
|
||||
*
|
||||
* Mixing involves finding a rotation between two others. There are two possible solutions: the short or the long way
|
||||
* around. When the two rotations change over time, which direction is the short or long way can also change. If the short
|
||||
* way was always chosen, bones flip to the other side when that direction became the long way. TrackEntry chooses the short
|
||||
* way the first time it is applied and remembers that direction. Resetting that direction makes it choose a new short way
|
||||
* on the next apply. */
|
||||
resetRotationDirections(): void;
|
||||
/** If this track entry is non-looping, this is the track time in seconds when {@link animationEnd} is reached, or the
|
||||
* current {@link trackTime} if it has already been reached.
|
||||
*
|
||||
* If this track entry is looping, this is the track time when this animation will reach its next {@link animationEnd} (the
|
||||
* next loop completion). */
|
||||
getTrackComplete(): number;
|
||||
/** Returns true if this track entry has been applied at least once.
|
||||
*
|
||||
* See {@link AnimationState.apply}. */
|
||||
wasApplied(): boolean;
|
||||
/** Returns true if there is a {@link next} track entry and it will become the current track entry during the next
|
||||
* {@link AnimationState.update}. */
|
||||
isNextReady(): boolean;
|
||||
}
|
||||
export declare class EventQueue {
|
||||
objects: Array<EventType | TrackEntry | Event>;
|
||||
drainDisabled: boolean;
|
||||
animState: AnimationState;
|
||||
constructor(animState: AnimationState);
|
||||
start(entry: TrackEntry): void;
|
||||
interrupt(entry: TrackEntry): void;
|
||||
end(entry: TrackEntry): void;
|
||||
dispose(entry: TrackEntry): void;
|
||||
complete(entry: TrackEntry): void;
|
||||
event(entry: TrackEntry, event: Event): void;
|
||||
drain(): void;
|
||||
clear(): void;
|
||||
}
|
||||
export declare enum EventType {
|
||||
start = 0,
|
||||
interrupt = 1,
|
||||
end = 2,
|
||||
dispose = 3,
|
||||
complete = 4,
|
||||
event = 5
|
||||
}
|
||||
/** The interface to implement for receiving TrackEntry events. It is always safe to call AnimationState methods when receiving
|
||||
* events.
|
||||
*
|
||||
* TrackEntry events are collected during {@link AnimationState.update} and {@link AnimationState.apply} and
|
||||
* fired only after those methods are finished.
|
||||
*
|
||||
* See {@link TrackEntry.listener} and
|
||||
* {@link AnimationState.addListener}. */
|
||||
export interface AnimationStateListener {
|
||||
/** Invoked when this entry has been set as the current entry. {@link end} will occur when this entry will no
|
||||
* longer be applied.
|
||||
*
|
||||
* When this event is triggered by calling {@link AnimationState.setAnimation}, take care not to
|
||||
* call {@link AnimationState.update} until after the TrackEntry has been configured. */
|
||||
start?: (entry: TrackEntry) => void;
|
||||
/** Invoked when another entry has replaced this entry as the current entry. This entry may continue being applied for
|
||||
* mixing. */
|
||||
interrupt?: (entry: TrackEntry) => void;
|
||||
/** Invoked when this entry will never be applied again. This only occurs if this entry has previously been set as the
|
||||
* current entry ({@link start} was invoked). */
|
||||
end?: (entry: TrackEntry) => void;
|
||||
/** Invoked when this entry will be disposed. This may occur without the entry ever being set as the current entry.
|
||||
* References to the entry should not be kept after dispose is called, as it may be destroyed or reused. */
|
||||
dispose?: (entry: TrackEntry) => void;
|
||||
/** Invoked every time this entry's animation completes a loop. This may occur during mixing (after
|
||||
* {@link interrupt}).
|
||||
*
|
||||
* If this entry's {@link TrackEntry.mixingTo} is not null, this entry is mixing out (it is not the current entry).
|
||||
*
|
||||
* Because this event is triggered at the end of {@link AnimationState.apply}, any animations set in response to
|
||||
* the event won't be applied until the next time the AnimationState is applied. */
|
||||
complete?: (entry: TrackEntry) => void;
|
||||
/** Invoked when this entry's animation triggers an event. */
|
||||
event?: (entry: TrackEntry, event: Event) => void;
|
||||
}
|
||||
export declare abstract class AnimationStateAdapter implements AnimationStateListener {
|
||||
start(entry: TrackEntry): void;
|
||||
interrupt(entry: TrackEntry): void;
|
||||
end(entry: TrackEntry): void;
|
||||
dispose(entry: TrackEntry): void;
|
||||
complete(entry: TrackEntry): void;
|
||||
event(entry: TrackEntry, event: Event): void;
|
||||
}
|
||||
export declare const CURRENT = 0;
|
||||
export declare const SETUP = 1;
|
||||
export declare const FIRST = 2;
|
||||
export declare const MODE = 3;
|
||||
export declare const HOLD = 4;
|
||||
export declare const ATTACH_SETUP = 1;
|
||||
export declare const ATTACH_RETAIN = 2;
|
||||
+1210
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,53 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Animation } from "./Animation.js";
|
||||
import type { SkeletonData } from "./SkeletonData.js";
|
||||
import type { StringMap } from "./Utils.js";
|
||||
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed on the same track. */
|
||||
export declare class AnimationStateData {
|
||||
/** The SkeletonData to look up animations when they are specified by name. */
|
||||
skeletonData: SkeletonData;
|
||||
animationToMixTime: StringMap<number>;
|
||||
/** The mix duration to use when no mix duration has been defined between two animations. */
|
||||
defaultMix: number;
|
||||
constructor(skeletonData: SkeletonData);
|
||||
/** Sets a mix duration by animation name.
|
||||
*
|
||||
* See {@link setMix}. */
|
||||
setMix(fromName: string, to: string, duration: number): void;
|
||||
/** Sets the mix duration when changing from the specified animation to the other.
|
||||
*
|
||||
* See {@link TrackEntry.mixDuration}. */
|
||||
setMix(from: Animation, to: Animation, duration: number): void;
|
||||
private setMix1;
|
||||
private setMix2;
|
||||
/** Returns the mix duration to use when changing from the specified animation to the other on the same track, or the
|
||||
* {@link defaultMix} if no mix duration has been set. */
|
||||
getMix(from: Animation, to: Animation): number;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed on the same track. */
|
||||
export class AnimationStateData {
|
||||
/** The SkeletonData to look up animations when they are specified by name. */
|
||||
skeletonData;
|
||||
animationToMixTime = {};
|
||||
/** The mix duration to use when no mix duration has been defined between two animations. */
|
||||
defaultMix = 0;
|
||||
constructor(skeletonData) {
|
||||
if (!skeletonData)
|
||||
throw new Error("skeletonData cannot be null.");
|
||||
this.skeletonData = skeletonData;
|
||||
}
|
||||
setMix(from, to, duration) {
|
||||
if (typeof from === "string")
|
||||
return this.setMix1(from, to, duration);
|
||||
return this.setMix2(from, to, duration);
|
||||
}
|
||||
setMix1(fromName, toName, duration) {
|
||||
const from = this.skeletonData.findAnimation(fromName);
|
||||
if (!from)
|
||||
throw new Error(`Animation not found: ${fromName}`);
|
||||
const to = this.skeletonData.findAnimation(toName);
|
||||
if (!to)
|
||||
throw new Error(`Animation not found: ${toName}`);
|
||||
this.setMix2(from, to, duration);
|
||||
}
|
||||
setMix2(from, to, duration) {
|
||||
if (!from)
|
||||
throw new Error("from cannot be null.");
|
||||
if (!to)
|
||||
throw new Error("to cannot be null.");
|
||||
const key = `${from.name}.${to.name}`;
|
||||
this.animationToMixTime[key] = duration;
|
||||
}
|
||||
/** Returns the mix duration to use when changing from the specified animation to the other on the same track, or the
|
||||
* {@link defaultMix} if no mix duration has been set. */
|
||||
getMix(from, to) {
|
||||
const key = `${from.name}.${to.name}`;
|
||||
const value = this.animationToMixTime[key];
|
||||
return value === undefined ? this.defaultMix : value;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5pbWF0aW9uU3RhdGVEYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0FuaW1hdGlvblN0YXRlRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFRL0UsMkhBQTJIO0FBQzNILE1BQU0sT0FBTyxrQkFBa0I7SUFDOUIsOEVBQThFO0lBQzlFLFlBQVksQ0FBZTtJQUUzQixrQkFBa0IsR0FBc0IsRUFBRSxDQUFDO0lBRTNDLDRGQUE0RjtJQUM1RixVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBRWYsWUFBYSxZQUEwQjtRQUN0QyxJQUFJLENBQUMsWUFBWTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztJQUNsQyxDQUFDO0lBWUQsTUFBTSxDQUFFLElBQXdCLEVBQUUsRUFBc0IsRUFBRSxRQUFnQjtRQUN6RSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVE7WUFDM0IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbkQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFlLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVPLE9BQU8sQ0FBRSxRQUFnQixFQUFFLE1BQWMsRUFBRSxRQUFnQjtRQUNsRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDL0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRU8sT0FBTyxDQUFFLElBQWUsRUFBRSxFQUFhLEVBQUUsUUFBZ0I7UUFDaEUsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEVBQUU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDL0MsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO0lBQ3pDLENBQUM7SUFFRDs2REFDeUQ7SUFDekQsTUFBTSxDQUFFLElBQWUsRUFBRSxFQUFhO1FBQ3JDLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNDLE9BQU8sS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ3RELENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBBbmltYXRpb24gfSBmcm9tIFwiLi9BbmltYXRpb24uanNcIjtcbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uU3RhdGUsIFRyYWNrRW50cnkgfSBmcm9tIFwiLi9BbmltYXRpb25TdGF0ZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbkRhdGEgfSBmcm9tIFwiLi9Ta2VsZXRvbkRhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgU3RyaW5nTWFwIH0gZnJvbSBcIi4vVXRpbHMuanNcIjtcblxuXG4vKiogU3RvcmVzIG1peCAoY3Jvc3NmYWRlKSBkdXJhdGlvbnMgdG8gYmUgYXBwbGllZCB3aGVuIHtAbGluayBBbmltYXRpb25TdGF0ZX0gYW5pbWF0aW9ucyBhcmUgY2hhbmdlZCBvbiB0aGUgc2FtZSB0c
Line truncated
|
||||
@@ -0,0 +1,103 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Texture } from "./Texture.js";
|
||||
import { TextureAtlas } from "./TextureAtlas.js";
|
||||
import type { Disposable, StringMap } from "./Utils.js";
|
||||
type AssetData = (Uint8Array | string | Texture | TextureAtlas | object) & Partial<Disposable>;
|
||||
type AssetCallback<T extends AssetData> = (path: string, data: T) => void;
|
||||
type ErrorCallback = (path: string, message: string) => void;
|
||||
export type TextureLoader = (image: HTMLImageElement | ImageBitmap, pma?: boolean) => Texture;
|
||||
export declare class AssetManagerBase implements Disposable {
|
||||
private textureLoader;
|
||||
private pathPrefix;
|
||||
private downloader;
|
||||
private cache;
|
||||
private errors;
|
||||
private toLoad;
|
||||
private loaded;
|
||||
private texturePmaInfo;
|
||||
constructor(textureLoader: TextureLoader, pathPrefix?: string, downloader?: Downloader, cache?: AssetCache);
|
||||
private start;
|
||||
private success;
|
||||
private error;
|
||||
loadAll(): Promise<AssetManagerBase>;
|
||||
setRawDataURI(path: string, data: string): void;
|
||||
loadBinary(path: string, success?: (path: string, binary: Uint8Array) => void, error?: (path: string, message: string) => void): void;
|
||||
loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, message: string) => void): void;
|
||||
loadJson(path: string, success?: (path: string, object: object) => void, error?: (path: string, message: string) => void): void;
|
||||
reuseAssets<T extends AssetData>(path: string, success?: AssetCallback<T>, error?: ErrorCallback): boolean;
|
||||
loadTexture(path: string, success?: AssetCallback<Texture>, error?: ErrorCallback): void;
|
||||
loadTextureAtlas(path: string, success?: AssetCallback<TextureAtlas>, error?: ErrorCallback, fileAlias?: Record<string, string>): void;
|
||||
loadTextureAtlasButNoTextures(path: string, success?: AssetCallback<TextureAtlas>, error?: ErrorCallback): void;
|
||||
loadBinaryAsync(path: string): Promise<unknown>;
|
||||
loadJsonAsync(path: string): Promise<unknown>;
|
||||
loadTextureAsync(path: string): Promise<Texture>;
|
||||
loadTextureAtlasAsync(path: string): Promise<unknown>;
|
||||
loadTextureAtlasButNoTexturesAsync(path: string): Promise<TextureAtlas>;
|
||||
setCache(cache: AssetCache): void;
|
||||
get(path: string): AssetData;
|
||||
require(path: string): AssetData;
|
||||
remove(path: string): AssetData;
|
||||
removeAll(): void;
|
||||
isLoadingComplete(): boolean;
|
||||
getToLoad(): number;
|
||||
getLoaded(): number;
|
||||
dispose(): void;
|
||||
disposeAsset(path: string): void;
|
||||
hasErrors(): boolean;
|
||||
getErrors(): StringMap<string>;
|
||||
private disposeAssetInternal;
|
||||
private createTextureAtlas;
|
||||
private createTexture;
|
||||
private texturePath;
|
||||
}
|
||||
export declare class AssetCache {
|
||||
assets: StringMap<AssetData>;
|
||||
assetsRefCount: StringMap<number>;
|
||||
assetsLoaded: StringMap<Promise<AssetData | undefined>>;
|
||||
static AVAILABLE_CACHES: Map<string, AssetCache>;
|
||||
static getCache(id: string): AssetCache;
|
||||
addAsset<T extends AssetData>(path: string, asset: T): Promise<T>;
|
||||
getAsset<T extends AssetData>(path: string): Promise<T> | undefined;
|
||||
}
|
||||
type DownloaderSuccessCallback<T extends AssetData = AssetData> = (data: T) => void;
|
||||
type DownloaderErrorCallback = (status: number, responseText: string) => void;
|
||||
export declare class Downloader {
|
||||
private callbacks;
|
||||
rawDataUris: StringMap<string>;
|
||||
dataUriToString(dataUri: string): string;
|
||||
base64ToUint8Array(base64: string): Uint8Array;
|
||||
dataUriToUint8Array(dataUri: string): Uint8Array;
|
||||
downloadText(url: string, success: DownloaderSuccessCallback<string>, error: DownloaderErrorCallback): void;
|
||||
downloadJson(url: string, success: DownloaderSuccessCallback<object>, error: DownloaderErrorCallback): void;
|
||||
downloadBinary(url: string, success: (data: Uint8Array) => void, error: DownloaderErrorCallback): void;
|
||||
private start;
|
||||
private finish;
|
||||
}
|
||||
export {};
|
||||
@@ -0,0 +1,518 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { TextureAtlas } from "./TextureAtlas.js";
|
||||
export class AssetManagerBase {
|
||||
textureLoader;
|
||||
pathPrefix;
|
||||
downloader;
|
||||
cache;
|
||||
errors = {};
|
||||
toLoad = 0;
|
||||
loaded = 0;
|
||||
texturePmaInfo = {};
|
||||
constructor(textureLoader, pathPrefix = "", downloader = new Downloader(), cache = new AssetCache()) {
|
||||
this.textureLoader = textureLoader;
|
||||
this.pathPrefix = pathPrefix;
|
||||
this.downloader = downloader;
|
||||
this.cache = cache;
|
||||
}
|
||||
start(path) {
|
||||
this.toLoad++;
|
||||
return this.pathPrefix + path;
|
||||
}
|
||||
success(callback, path, asset) {
|
||||
this.toLoad--;
|
||||
this.loaded++;
|
||||
this.cache.assets[path] = asset;
|
||||
this.cache.assetsRefCount[path] = (this.cache.assetsRefCount[path] || 0) + 1;
|
||||
if (callback)
|
||||
callback(path, asset);
|
||||
}
|
||||
error(callback, path, message) {
|
||||
this.toLoad--;
|
||||
this.loaded++;
|
||||
this.errors[path] = message;
|
||||
if (callback)
|
||||
callback(path, message);
|
||||
}
|
||||
loadAll() {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const check = () => {
|
||||
if (this.isLoadingComplete()) {
|
||||
if (this.hasErrors())
|
||||
reject(this.errors);
|
||||
else
|
||||
resolve(this);
|
||||
return;
|
||||
}
|
||||
requestAnimationFrame(check);
|
||||
};
|
||||
requestAnimationFrame(check);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
setRawDataURI(path, data) {
|
||||
this.downloader.rawDataUris[this.pathPrefix + path] = data;
|
||||
}
|
||||
loadBinary(path, success = () => { }, error = () => { }) {
|
||||
path = this.start(path);
|
||||
if (this.reuseAssets(path, success, error))
|
||||
return;
|
||||
this.cache.assetsLoaded[path] = new Promise((resolve, reject) => {
|
||||
this.downloader.downloadBinary(path, (data) => {
|
||||
this.success(success, path, data);
|
||||
resolve(data);
|
||||
}, (status, responseText) => {
|
||||
const errorMsg = `Couldn't load binary ${path}: status ${status}, ${responseText}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
});
|
||||
});
|
||||
}
|
||||
loadText(path, success = () => { }, error = () => { }) {
|
||||
path = this.start(path);
|
||||
this.downloader.downloadText(path, (data) => {
|
||||
this.success(success, path, data);
|
||||
}, (status, responseText) => {
|
||||
this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`);
|
||||
});
|
||||
}
|
||||
loadJson(path, success = () => { }, error = () => { }) {
|
||||
path = this.start(path);
|
||||
if (this.reuseAssets(path, success, error))
|
||||
return;
|
||||
this.cache.assetsLoaded[path] = new Promise((resolve, reject) => {
|
||||
this.downloader.downloadJson(path, (data) => {
|
||||
this.success(success, path, data);
|
||||
resolve(data);
|
||||
}, (status, responseText) => {
|
||||
const errorMsg = `Couldn't load JSON ${path}: status ${status}, ${responseText}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
});
|
||||
});
|
||||
}
|
||||
reuseAssets(path, success = () => { }, error = () => { }) {
|
||||
const loadedStatus = this.cache.getAsset(path);
|
||||
const alreadyExistsOrLoading = loadedStatus !== undefined;
|
||||
if (alreadyExistsOrLoading) {
|
||||
this.cache.assetsLoaded[path] = loadedStatus
|
||||
.then(data => {
|
||||
// necessary when user preloads an image into the cache.
|
||||
// texture loader is not avaiable in the cache, so we transform in GLTexture at first use
|
||||
data = (data instanceof Image || data instanceof ImageBitmap) ? this.textureLoader(data) : data;
|
||||
this.success(success, path, data);
|
||||
return data;
|
||||
})
|
||||
.catch(errorMsg => {
|
||||
this.error(error, path, errorMsg);
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
return alreadyExistsOrLoading;
|
||||
}
|
||||
loadTexture(path, success = () => { }, error = () => { }) {
|
||||
path = this.start(path);
|
||||
if (this.reuseAssets(path, success, error))
|
||||
return;
|
||||
const pma = this.texturePmaInfo[path];
|
||||
this.cache.assetsLoaded[path] = new Promise((resolve, reject) => {
|
||||
const isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document);
|
||||
const isWebWorker = !isBrowser; // && typeof importScripts !== 'undefined';
|
||||
if (isWebWorker) {
|
||||
fetch(path, { mode: "cors" }).then((response) => {
|
||||
if (response.ok)
|
||||
return response.blob();
|
||||
const errorMsg = `Couldn't load image: ${path}`;
|
||||
this.error(error, path, `Couldn't load image: ${path}`);
|
||||
reject(errorMsg);
|
||||
}).then((blob) => {
|
||||
return blob ? createImageBitmap(blob, { premultiplyAlpha: "none", colorSpaceConversion: "none" }) : null;
|
||||
}).then((bitmap) => {
|
||||
if (bitmap) {
|
||||
const texture = this.createTexture(path, pma, bitmap);
|
||||
this.success(success, path, texture);
|
||||
resolve(texture);
|
||||
}
|
||||
;
|
||||
});
|
||||
}
|
||||
else {
|
||||
const image = new Image();
|
||||
image.crossOrigin = "anonymous";
|
||||
image.onload = () => {
|
||||
const texture = this.createTexture(path, pma, image);
|
||||
this.success(success, path, texture);
|
||||
resolve(texture);
|
||||
};
|
||||
image.onerror = () => {
|
||||
const errorMsg = `Couldn't load image: ${path}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
};
|
||||
if (this.downloader.rawDataUris[path])
|
||||
path = this.downloader.rawDataUris[path];
|
||||
image.src = path;
|
||||
}
|
||||
});
|
||||
}
|
||||
loadTextureAtlas(path, success = () => { }, error = () => { }, fileAlias) {
|
||||
const index = path.lastIndexOf("/");
|
||||
const parent = index >= 0 ? path.substring(0, index + 1) : "";
|
||||
path = this.start(path);
|
||||
if (this.reuseAssets(path, success, error))
|
||||
return;
|
||||
this.cache.assetsLoaded[path] = new Promise((resolve, reject) => {
|
||||
this.downloader.downloadText(path, (atlasText) => {
|
||||
try {
|
||||
const atlas = this.createTextureAtlas(atlasText, parent, path, fileAlias);
|
||||
let toLoad = atlas.pages.length, abort = false;
|
||||
if (toLoad === 0) {
|
||||
this.success(success, path, atlas);
|
||||
resolve(atlas);
|
||||
return;
|
||||
}
|
||||
for (const page of atlas.pages) {
|
||||
this.loadTexture(this.texturePath(parent, page.name, fileAlias), (imagePath, texture) => {
|
||||
if (!abort) {
|
||||
page.setTexture(texture);
|
||||
if (--toLoad === 0) {
|
||||
this.success(success, path, atlas);
|
||||
resolve(atlas);
|
||||
}
|
||||
}
|
||||
}, (imagePath, message) => {
|
||||
if (!abort) {
|
||||
const errorMsg = `Couldn't load texture ${path} page image: ${imagePath}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
}
|
||||
abort = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
}
|
||||
}, (status, responseText) => {
|
||||
const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
});
|
||||
});
|
||||
}
|
||||
loadTextureAtlasButNoTextures(path, success = () => { }, error = () => { }) {
|
||||
const index = path.lastIndexOf("/");
|
||||
const parent = index >= 0 ? path.substring(0, index + 1) : "";
|
||||
path = this.start(path);
|
||||
if (this.reuseAssets(path, success, error))
|
||||
return;
|
||||
this.cache.assetsLoaded[path] = new Promise((resolve, reject) => {
|
||||
this.downloader.downloadText(path, (atlasText) => {
|
||||
try {
|
||||
const atlas = this.createTextureAtlas(atlasText, parent, path);
|
||||
this.success(success, path, atlas);
|
||||
resolve(atlas);
|
||||
}
|
||||
catch (e) {
|
||||
const errorMsg = `Couldn't parse texture atlas ${path}: ${e.message}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
}
|
||||
}, (status, responseText) => {
|
||||
const errorMsg = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`;
|
||||
this.error(error, path, errorMsg);
|
||||
reject(errorMsg);
|
||||
});
|
||||
});
|
||||
}
|
||||
async loadBinaryAsync(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadBinary(path, (_, binary) => resolve(binary), (_, message) => reject(message));
|
||||
});
|
||||
}
|
||||
async loadJsonAsync(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadJson(path, (_, object) => resolve(object), (_, message) => reject(message));
|
||||
});
|
||||
}
|
||||
async loadTextureAsync(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadTexture(path, (_, texture) => resolve(texture), (_, message) => reject(message));
|
||||
});
|
||||
}
|
||||
async loadTextureAtlasAsync(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadTextureAtlas(path, (_, atlas) => resolve(atlas), (_, message) => reject(message));
|
||||
});
|
||||
}
|
||||
async loadTextureAtlasButNoTexturesAsync(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loadTextureAtlasButNoTextures(path, (_, atlas) => resolve(atlas), (_, message) => reject(message));
|
||||
});
|
||||
}
|
||||
setCache(cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
get(path) {
|
||||
return this.cache.assets[this.pathPrefix + path];
|
||||
}
|
||||
require(path) {
|
||||
path = this.pathPrefix + path;
|
||||
const asset = this.cache.assets[path];
|
||||
if (asset)
|
||||
return asset;
|
||||
const error = this.errors[path];
|
||||
throw Error(`Asset not found: ${path}${error ? `\n${error}` : ""}`);
|
||||
}
|
||||
remove(path) {
|
||||
path = this.pathPrefix + path;
|
||||
const asset = this.cache.assets[path];
|
||||
if (asset.dispose)
|
||||
asset.dispose();
|
||||
delete this.cache.assets[path];
|
||||
delete this.cache.assetsRefCount[path];
|
||||
delete this.cache.assetsLoaded[path];
|
||||
return asset;
|
||||
}
|
||||
removeAll() {
|
||||
for (const path in this.cache.assets) {
|
||||
const asset = this.cache.assets[path];
|
||||
if (asset.dispose)
|
||||
asset.dispose();
|
||||
}
|
||||
this.cache.assets = {};
|
||||
this.cache.assetsLoaded = {};
|
||||
this.cache.assetsRefCount = {};
|
||||
}
|
||||
isLoadingComplete() {
|
||||
return this.toLoad === 0;
|
||||
}
|
||||
getToLoad() {
|
||||
return this.toLoad;
|
||||
}
|
||||
getLoaded() {
|
||||
return this.loaded;
|
||||
}
|
||||
dispose() {
|
||||
this.removeAll();
|
||||
}
|
||||
// dispose asset only if it's not used by others
|
||||
disposeAsset(path) {
|
||||
const asset = this.cache.assets[path];
|
||||
if (asset instanceof TextureAtlas) {
|
||||
asset.dispose();
|
||||
return;
|
||||
}
|
||||
this.disposeAssetInternal(path);
|
||||
}
|
||||
hasErrors() {
|
||||
return Object.keys(this.errors).length > 0;
|
||||
}
|
||||
getErrors() {
|
||||
return this.errors;
|
||||
}
|
||||
disposeAssetInternal(path) {
|
||||
if (this.cache.assetsRefCount[path] > 0 && --this.cache.assetsRefCount[path] === 0) {
|
||||
return this.remove(path);
|
||||
}
|
||||
}
|
||||
createTextureAtlas(atlasText, parentPath, path, fileAlias) {
|
||||
const atlas = new TextureAtlas(atlasText);
|
||||
atlas.dispose = () => {
|
||||
if (this.cache.assetsRefCount[path] <= 0)
|
||||
return;
|
||||
this.disposeAssetInternal(path);
|
||||
for (const page of atlas.pages) {
|
||||
page.texture?.dispose();
|
||||
}
|
||||
};
|
||||
for (const page of atlas.pages) {
|
||||
const texturePath = this.texturePath(parentPath, page.name, fileAlias);
|
||||
this.texturePmaInfo[this.pathPrefix + texturePath] = page.pma;
|
||||
}
|
||||
return atlas;
|
||||
}
|
||||
createTexture(path, pma, image) {
|
||||
const texture = this.textureLoader(image, pma);
|
||||
const textureDispose = texture.dispose.bind(texture);
|
||||
texture.dispose = () => {
|
||||
if (this.disposeAssetInternal(path))
|
||||
textureDispose();
|
||||
};
|
||||
return texture;
|
||||
}
|
||||
texturePath(parentPath, pageName, fileAlias) {
|
||||
if (!fileAlias)
|
||||
return parentPath + pageName;
|
||||
return fileAlias[pageName];
|
||||
}
|
||||
}
|
||||
export class AssetCache {
|
||||
assets = {};
|
||||
assetsRefCount = {};
|
||||
assetsLoaded = {};
|
||||
static AVAILABLE_CACHES = new Map();
|
||||
static getCache(id) {
|
||||
const cache = AssetCache.AVAILABLE_CACHES.get(id);
|
||||
if (cache)
|
||||
return cache;
|
||||
const newCache = new AssetCache();
|
||||
AssetCache.AVAILABLE_CACHES.set(id, newCache);
|
||||
return newCache;
|
||||
}
|
||||
async addAsset(path, asset) {
|
||||
this.assetsLoaded[path] = Promise.resolve(asset);
|
||||
this.assets[path] = asset;
|
||||
return asset;
|
||||
}
|
||||
getAsset(path) {
|
||||
return this.assetsLoaded[path];
|
||||
}
|
||||
}
|
||||
export class Downloader {
|
||||
callbacks = {};
|
||||
rawDataUris = {};
|
||||
dataUriToString(dataUri) {
|
||||
if (!dataUri.startsWith("data:")) {
|
||||
throw new Error("Not a data URI.");
|
||||
}
|
||||
let base64Idx = dataUri.indexOf("base64,");
|
||||
if (base64Idx !== -1) {
|
||||
base64Idx += "base64,".length;
|
||||
return atob(dataUri.substr(base64Idx));
|
||||
}
|
||||
else {
|
||||
return dataUri.substr(dataUri.indexOf(",") + 1);
|
||||
}
|
||||
}
|
||||
base64ToUint8Array(base64) {
|
||||
var binary_string = window.atob(base64);
|
||||
var len = binary_string.length;
|
||||
var bytes = new Uint8Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
bytes[i] = binary_string.charCodeAt(i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
dataUriToUint8Array(dataUri) {
|
||||
if (!dataUri.startsWith("data:")) {
|
||||
throw new Error("Not a data URI.");
|
||||
}
|
||||
let base64Idx = dataUri.indexOf("base64,");
|
||||
if (base64Idx === -1)
|
||||
throw new Error("Not a binary data URI.");
|
||||
base64Idx += "base64,".length;
|
||||
return this.base64ToUint8Array(dataUri.substr(base64Idx));
|
||||
}
|
||||
downloadText(url, success, error) {
|
||||
if (this.start(url, success, error))
|
||||
return;
|
||||
const rawDataUri = this.rawDataUris[url];
|
||||
// we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL
|
||||
if (rawDataUri && !rawDataUri.includes(".")) {
|
||||
try {
|
||||
this.finish(url, 200, this.dataUriToString(rawDataUri));
|
||||
}
|
||||
catch (e) {
|
||||
this.finish(url, 400, JSON.stringify(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
const request = new XMLHttpRequest();
|
||||
request.overrideMimeType("text/html");
|
||||
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||
const done = () => {
|
||||
this.finish(url, request.status, request.responseText);
|
||||
};
|
||||
request.onload = done;
|
||||
request.onerror = done;
|
||||
request.send();
|
||||
}
|
||||
downloadJson(url, success, error) {
|
||||
this.downloadText(url, (data) => {
|
||||
success(JSON.parse(data));
|
||||
}, error);
|
||||
}
|
||||
downloadBinary(url, success, error) {
|
||||
if (this.start(url, success, error))
|
||||
return;
|
||||
const rawDataUri = this.rawDataUris[url];
|
||||
// we assume if a "." is included in a raw data uri, it is used to rewrite an asset URL
|
||||
if (rawDataUri && !rawDataUri.includes(".")) {
|
||||
try {
|
||||
this.finish(url, 200, this.dataUriToUint8Array(rawDataUri));
|
||||
}
|
||||
catch (e) {
|
||||
this.finish(url, 400, JSON.stringify(e));
|
||||
}
|
||||
return;
|
||||
}
|
||||
const request = new XMLHttpRequest();
|
||||
request.open("GET", rawDataUri ? rawDataUri : url, true);
|
||||
request.responseType = "arraybuffer";
|
||||
const onerror = () => {
|
||||
this.finish(url, request.status, request.response);
|
||||
};
|
||||
request.onload = () => {
|
||||
if (request.status === 200 || request.status === 0)
|
||||
this.finish(url, 200, new Uint8Array(request.response));
|
||||
else
|
||||
onerror();
|
||||
};
|
||||
request.onerror = onerror;
|
||||
request.send();
|
||||
}
|
||||
start(url, success, error) {
|
||||
let callbacks = this.callbacks[url];
|
||||
try {
|
||||
if (callbacks)
|
||||
return true;
|
||||
this.callbacks[url] = callbacks = [];
|
||||
}
|
||||
finally {
|
||||
callbacks.push(success, error);
|
||||
}
|
||||
}
|
||||
finish(url, status, data) {
|
||||
const callbacks = this.callbacks[url];
|
||||
delete this.callbacks[url];
|
||||
if (status === 200 || status === 0) {
|
||||
for (let i = 0, n = callbacks.length; i < n; i += 2)
|
||||
callbacks[i](data);
|
||||
}
|
||||
else {
|
||||
for (let i = 1, n = callbacks.length; i < n; i += 2)
|
||||
callbacks[i](status, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyQmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Bc3NldE1hbmFnZXJCYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFTakQsTUFBTSxPQUFPLGdCQUFnQjtJQU9uQjtJQUNBO0lBQ0E7SUFDQTtJQVRELE1BQU0sR0FBc0IsRUFBRSxDQUFDO0lBQy9CLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ1gsY0FBYyxHQUE0QixFQUFFLENBQUM7SUFFckQsWUFDUyxhQUE0QixFQUM1QixhQUFxQixFQUFFLEVBQ3ZCLGFBQWEsSUFBSSxVQUFVLEVBQUUsRUFDN0IsUUFBUSxJQUFJLFVBQVUsRUFBRTtRQUh4QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1QixlQUFVLEdBQVYsVUFBVSxDQUFhO1FBQ3ZCLGVBQVUsR0FBVixVQUFVLENBQW1CO1FBQzdCLFVBQUssR0FBTCxLQUFLLENBQW1CO0lBQ2pDLENBQUM7SUFFTyxLQUFLLENBQUUsSUFBWTtRQUMxQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZCxPQUFPLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQy9CLENBQUM7SUFFTyxPQUFPLENBQXVCLFFBQTBCLEVBQUUsSUFBWSxFQUFFLEtBQVE7UUFDdkYsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFj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
Line truncated
|
||||
@@ -0,0 +1,59 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { AttachmentLoader } from "./attachments/AttachmentLoader.js";
|
||||
import { BoundingBoxAttachment } from "./attachments/BoundingBoxAttachment.js";
|
||||
import { ClippingAttachment } from "./attachments/ClippingAttachment.js";
|
||||
import { MeshAttachment } from "./attachments/MeshAttachment.js";
|
||||
import { PathAttachment } from "./attachments/PathAttachment.js";
|
||||
import { PointAttachment } from "./attachments/PointAttachment.js";
|
||||
import { RegionAttachment } from "./attachments/RegionAttachment.js";
|
||||
import type { Sequence } from "./attachments/Sequence.js";
|
||||
import type { Skin } from "./Skin.js";
|
||||
import type { TextureAtlas } from "./TextureAtlas.js";
|
||||
/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link TextureAtlas}.
|
||||
*
|
||||
* See [Loading skeleton data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the
|
||||
* Spine Runtimes Guide. */
|
||||
export declare class AtlasAttachmentLoader implements AttachmentLoader {
|
||||
atlas: TextureAtlas;
|
||||
allowMissingRegions: boolean;
|
||||
constructor(atlas: TextureAtlas, allowMissingRegions?: boolean);
|
||||
/** Sets each {@link Sequence.regions} by calling {@link findRegion} for each texture region using
|
||||
* {@link Sequence.getPath}. */
|
||||
protected findRegions(name: string, basePath: string, sequence: Sequence): void;
|
||||
/** Looks for the region with the specified path. If not found and {@link allowMissingRegions} is false, an error is
|
||||
* raised. */
|
||||
protected findRegion(name: string, path: string): import("./TextureAtlas.js").TextureAtlasRegion | null;
|
||||
newRegionAttachment(skin: Skin, placeholder: string, name: string, path: string, sequence: Sequence): RegionAttachment;
|
||||
newMeshAttachment(skin: Skin, placeholder: string, name: string, path: string, sequence: Sequence): MeshAttachment;
|
||||
newBoundingBoxAttachment(skin: Skin, placeholder: string, name: string): BoundingBoxAttachment;
|
||||
newPathAttachment(skin: Skin, placeholder: string, name: string): PathAttachment;
|
||||
newPointAttachment(skin: Skin, placeholder: string, name: string): PointAttachment;
|
||||
newClippingAttachment(skin: Skin, placeholder: string, name: string): ClippingAttachment;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BoundingBoxAttachment } from "./attachments/BoundingBoxAttachment.js";
|
||||
import { ClippingAttachment } from "./attachments/ClippingAttachment.js";
|
||||
import { MeshAttachment } from "./attachments/MeshAttachment.js";
|
||||
import { PathAttachment } from "./attachments/PathAttachment.js";
|
||||
import { PointAttachment } from "./attachments/PointAttachment.js";
|
||||
import { RegionAttachment } from "./attachments/RegionAttachment.js";
|
||||
/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link TextureAtlas}.
|
||||
*
|
||||
* See [Loading skeleton data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the
|
||||
* Spine Runtimes Guide. */
|
||||
export class AtlasAttachmentLoader {
|
||||
atlas;
|
||||
allowMissingRegions;
|
||||
constructor(atlas, allowMissingRegions = false) {
|
||||
this.atlas = atlas;
|
||||
this.allowMissingRegions = allowMissingRegions;
|
||||
}
|
||||
/** Sets each {@link Sequence.regions} by calling {@link findRegion} for each texture region using
|
||||
* {@link Sequence.getPath}. */
|
||||
findRegions(name, basePath, sequence) {
|
||||
const regions = sequence.regions;
|
||||
for (let i = 0, n = regions.length; i < n; i++)
|
||||
regions[i] = this.findRegion(name, sequence.getPath(basePath, i));
|
||||
}
|
||||
/** Looks for the region with the specified path. If not found and {@link allowMissingRegions} is false, an error is
|
||||
* raised. */
|
||||
findRegion(name, path) {
|
||||
const region = this.atlas.findRegion(path);
|
||||
if (!region && !this.allowMissingRegions)
|
||||
throw new Error(`Region not found in atlas: ${path} (attachment: ${name})`);
|
||||
return region;
|
||||
}
|
||||
newRegionAttachment(skin, placeholder, name, path, sequence) {
|
||||
this.findRegions(name, path, sequence);
|
||||
return new RegionAttachment(name, sequence);
|
||||
}
|
||||
newMeshAttachment(skin, placeholder, name, path, sequence) {
|
||||
this.findRegions(name, path, sequence);
|
||||
return new MeshAttachment(name, sequence);
|
||||
}
|
||||
newBoundingBoxAttachment(skin, placeholder, name) {
|
||||
return new BoundingBoxAttachment(name);
|
||||
}
|
||||
newPathAttachment(skin, placeholder, name) {
|
||||
return new PathAttachment(name);
|
||||
}
|
||||
newPointAttachment(skin, placeholder, name) {
|
||||
return new PointAttachment(name);
|
||||
}
|
||||
newClippingAttachment(skin, placeholder, name) {
|
||||
return new ClippingAttachment(name);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXRsYXNBdHRhY2htZW50TG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0F0bGFzQXR0YWNobWVudExvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFLckU7OzsyQkFHMkI7QUFDM0IsTUFBTSxPQUFPLHFCQUFxQjtJQUNqQyxLQUFLLENBQWU7SUFDcEIsbUJBQW1CLENBQVU7SUFFN0IsWUFBYSxLQUFtQixFQUFFLG1CQUFtQixHQUFHLEtBQUs7UUFDNUQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLG1CQUFtQixDQUFDO0lBQ2hELENBQUM7SUFFRDttQ0FDK0I7SUFDckIsV0FBVyxDQUFFLElBQVksRUFBRSxRQUFnQixFQUFFLFFBQWtCO1FBQ3hFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDN0MsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEO2lCQUNhO0lBQ0gsVUFBVSxDQUFFLElBQVksRUFBRSxJQUFZO1FBQy9DLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CO1lBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLElBQUksaUJBQWlCLElBQUksR0FBRyxDQUFDLENBQUM7UUFDN0UsT0FBTyxNQUFNLENBQUM7SUFDZixDQUFDO0lBRUQsbUJBQW1CLENBQUUsSUFBVSxFQUFFLFdBQW1CLEVBQUUsSUFBWSxFQUFFLElBQVksRUFBRSxRQUFrQjtRQUNuRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdkMsT0FBTyxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsaUJBQWlCLENBQUUsSUFBVSxFQUFFLFdBQW1CLEVBQUUsSUFBWSxFQUFFLElBQVksRUFBRSxRQUFrQjtRQUNqRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdkMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELHdCQUF3QixDQUFFLElBQVUsRUFBRSxXQUFtQixFQUFFLElBQVk7UUFDdEUsT0FBTyxJQUFJLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxpQkFBaUIsQ0FBRSxJQUFVLEVBQUUsV0FBbUIsRUFBRSxJQUFZO1FBQy9ELE9BQU8sSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELGtCQUFrQixDQUFFLElBQVUsRUFBRSxXQUFtQixFQUFFLElBQVk7UUFDaEUsT0FBTyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQscUJBQXFCLENBQUUsSUFBVSxFQUFFLFdBQW1CLEVBQUUsSUFBWTtRQUNuRSxPQUFPLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckMsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqK
Line truncated
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { BoneData } from "./BoneData.js";
|
||||
import { BonePose } from "./BonePose.js";
|
||||
import { PosedActive } from "./PosedActive.js";
|
||||
/** A node in a skeleton's hierarchy with a transform that affects its children and their attachments. A bone has a number of
|
||||
* poses:
|
||||
* - {@link data}: The setup pose.
|
||||
* - {@link pose}: The unconstrained local pose. Set by animations and application code.
|
||||
* - {@link appliedPose}: The local pose to use for rendering. Possibly modified by constraints.
|
||||
* - World transform: the local pose combined with the parent world transform. Computed on a pose by
|
||||
* {@link BonePose.updateWorldTransform} and {@link Skeleton.updateWorldTransform}.
|
||||
*/
|
||||
export declare class Bone extends PosedActive<BoneData, BonePose> {
|
||||
/** The parent bone, or null if this is the root bone. */
|
||||
parent: Bone | null;
|
||||
/** The immediate children of this bone. */
|
||||
children: Bone[];
|
||||
sorted: boolean;
|
||||
constructor(data: BoneData, parent: Bone | null);
|
||||
/** Copy constructor. Does not copy the {@link children} bones. */
|
||||
copy(parent: Bone | null): Bone;
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BonePose } from "./BonePose.js";
|
||||
import { PosedActive } from "./PosedActive.js";
|
||||
/** A node in a skeleton's hierarchy with a transform that affects its children and their attachments. A bone has a number of
|
||||
* poses:
|
||||
* - {@link data}: The setup pose.
|
||||
* - {@link pose}: The unconstrained local pose. Set by animations and application code.
|
||||
* - {@link appliedPose}: The local pose to use for rendering. Possibly modified by constraints.
|
||||
* - World transform: the local pose combined with the parent world transform. Computed on a pose by
|
||||
* {@link BonePose.updateWorldTransform} and {@link Skeleton.updateWorldTransform}.
|
||||
*/
|
||||
export class Bone extends PosedActive {
|
||||
/** The parent bone, or null if this is the root bone. */
|
||||
parent = null;
|
||||
/** The immediate children of this bone. */
|
||||
children = [];
|
||||
sorted = false;
|
||||
constructor(data, parent) {
|
||||
super(data, new BonePose(), new BonePose());
|
||||
this.parent = parent;
|
||||
this.appliedPose.bone = this;
|
||||
this.constrainedPose.bone = this;
|
||||
}
|
||||
/** Copy constructor. Does not copy the {@link children} bones. */
|
||||
copy(parent) {
|
||||
const copy = new Bone(this.data, parent);
|
||||
copy.pose.set(this.pose);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Cb25lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUcvQzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLElBQUssU0FBUSxXQUErQjtJQUN4RCx5REFBeUQ7SUFDekQsTUFBTSxHQUFnQixJQUFJLENBQUM7SUFFM0IsMkNBQTJDO0lBQzNDLFFBQVEsR0FBRyxFQUFZLENBQUM7SUFFeEIsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUVmLFlBQWEsSUFBYyxFQUFFLE1BQW1CO1FBQy9DLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxRQUFRLEVBQUUsRUFBRSxJQUFJLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNsQyxDQUFDO0lBRUQsa0VBQWtFO0lBQ2xFLElBQUksQ0FBRSxNQUFtQjtRQUN4QixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixPQUFPLElBQUksQ0FBQztJQUNiLENBQUM7Q0FFRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBCb25lRGF0YSB9IGZyb20gXCIuL0JvbmVEYXRhLmpzXCI7XG5pbXBvcnQgeyBCb25lUG9zZSB9IGZyb20gXCIuL0JvbmVQb3NlLmpzXCI7XG5pbXBvcnQgeyBQb3NlZEFjdGl2ZSB9IGZyb20gXCIuL1Bvc2VkQWN0aXZlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcblxuLyoqIEEgbm9kZSBpbiBhIHNrZWxldG9uJ3MgaGllcmFyY2h5IHdpdGggYSB0cmFuc2Zvcm0gdGhhdCBhZmZlY3RzIGl0cyBjaGlsZHJlbiBhbmQgdGhlaXIgYXR0YWNobWVudHMuIEEgYm9uZSBoYXMgYSBudW1iZXIgb2ZcbiAqIHBvc2VzOlxuICogLSB7QGxpbmsgZGF0YX06IFRoZSBzZXR1cCBwb3NlLlxuICogLSB7QGxpbmsgcG9zZX06IFRoZSB1bmNvbnN0cmFpbmVkIGxvY2FsIHBvc2UuIFNldCBieSBhbmltYXRpb25zIGFuZCBhcHBsaWNhdGlvbiBjb2RlLlxuICogLSB7QGxpbmsgYXBwbGllZFBvc2V9OiBUaGUgbG9jYWwgcG9zZSB0byB1c2UgZm9yIHJlbmRlcmluZy4gUG9zc2libHkgbW9kaWZpZWQgYnkgY29uc3RyYWludHMuXG4gKiAtIFdvcmxkIHRyYW5zZm9ybTogdGhlIGxvY2FsIHBvc2UgY29tYmluZWQgd2l0aCB0aGUgcGFyZW50IHdvcmxkIHRyYW5zZm9ybS4gQ29tcHV0ZWQgb24gYSBwb3NlIGJ5XG4gKiB7QGxpbmsgQm9uZVBvc2UudXBkYXRlV29ybGRUcmFuc2Zvcm19IGFuZCB7QGxpbmsgU2tlbGV0b24udXBkYXRlV29ybGRUcmFuc2Zvcm19LlxuICovXG5leHBvcnQgY2xhc3MgQm9uZSBleHRlbmRzIFBvc2VkQWN0aXZlPEJvbmVEYXRhLCBCb25lUG9zZT4ge1xuXHQvKiogVGhlIHBhcmVudCBib25lLCBvciBudWxsIGlmIHRoaXMgaXMgdGhlIHJvb3QgYm9uZS4gKi9cblx0cGFyZW50OiBCb25lIHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIFRoZSBpbW1lZGlhdGUgY2hpbGRyZW4gb2YgdGhpcyBib25lLiAqL1xuXHRjaGlsZHJlbiA9IFtdIGFzIEJvbmVbXTtcblxuXHRzb3J0ZWQgPSBmYWxzZTtcblxuXHRjb25zdHJ1Y3RvciAoZGF0YTogQm9uZURhdGEsIHBhcmVudDogQm9uZSB8IG51bGwpIHtcblx0XHRzdXBlcihkYXRhLCBuZXcgQm9uZVBvc2UoKSwgbmV3IEJvbmVQb3NlKCkpO1xuXHRcdHRoaXMucGFyZW50ID0gcGFyZW50O1xuXHRcdHRoa
Line truncated
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BonePose } from "./BonePose.js";
|
||||
import { PosedData } from "./PosedData.js";
|
||||
import { Color } from "./Utils.js";
|
||||
/** The setup pose for a bone. */
|
||||
export declare class BoneData extends PosedData<BonePose> {
|
||||
/** The index of the bone in {@link Skeleton.bones}. */
|
||||
index: number;
|
||||
/** The parent bone, or null if this bone is the root. */
|
||||
parent: BoneData | null;
|
||||
/** The bone's length. */
|
||||
length: number;
|
||||
/** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually
|
||||
* rendered at runtime. */
|
||||
readonly color: Color;
|
||||
/** The bone icon name as it was in Spine, or null if nonessential data was not exported. */
|
||||
icon?: string;
|
||||
/** The bone icon's display size scale, or 1 if nonessential data was not exported. */
|
||||
iconSize: number;
|
||||
/** The bone icon's display rotation in degrees, or 0 if nonessential data was not exported. */
|
||||
iconRotation: number;
|
||||
/** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */
|
||||
visible: boolean;
|
||||
constructor(index: number, name: string, parent: BoneData | null);
|
||||
copy(parent: BoneData | null): BoneData;
|
||||
}
|
||||
/** Determines how a bone inherits world transforms from parent bones. */
|
||||
export declare enum Inherit {
|
||||
Normal = 0,
|
||||
OnlyTranslation = 1,
|
||||
NoRotationOrReflection = 2,
|
||||
NoScale = 3,
|
||||
NoScaleOrReflection = 4
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BonePose } from "./BonePose.js";
|
||||
import { PosedData } from "./PosedData.js";
|
||||
import { Color } from "./Utils.js";
|
||||
/** The setup pose for a bone. */
|
||||
export class BoneData extends PosedData {
|
||||
/** The index of the bone in {@link Skeleton.bones}. */
|
||||
index = 0;
|
||||
/** The parent bone, or null if this bone is the root. */
|
||||
parent = null;
|
||||
/** The bone's length. */
|
||||
length = 0;
|
||||
// Nonessential.
|
||||
/** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually
|
||||
* rendered at runtime. */
|
||||
color = new Color();
|
||||
/** The bone icon name as it was in Spine, or null if nonessential data was not exported. */
|
||||
icon;
|
||||
/** The bone icon's display size scale, or 1 if nonessential data was not exported. */
|
||||
iconSize = 1;
|
||||
/** The bone icon's display rotation in degrees, or 0 if nonessential data was not exported. */
|
||||
iconRotation = 0;
|
||||
/** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */
|
||||
visible = false;
|
||||
constructor(index, name, parent) {
|
||||
super(name, new BonePose());
|
||||
if (index < 0)
|
||||
throw new Error("index must be >= 0.");
|
||||
if (!name)
|
||||
throw new Error("name cannot be null.");
|
||||
this.index = index;
|
||||
this.parent = parent;
|
||||
}
|
||||
copy(parent) {
|
||||
const copy = new BoneData(this.index, this.name, parent);
|
||||
copy.length = this.length;
|
||||
copy.setupPose.set(this.setupPose);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
/** Determines how a bone inherits world transforms from parent bones. */
|
||||
export var Inherit;
|
||||
(function (Inherit) {
|
||||
Inherit[Inherit["Normal"] = 0] = "Normal";
|
||||
Inherit[Inherit["OnlyTranslation"] = 1] = "OnlyTranslation";
|
||||
Inherit[Inherit["NoRotationOrReflection"] = 2] = "NoRotationOrReflection";
|
||||
Inherit[Inherit["NoScale"] = 3] = "NoScale";
|
||||
Inherit[Inherit["NoScaleOrReflection"] = 4] = "NoScaleOrReflection";
|
||||
})(Inherit || (Inherit = {}));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9uZURhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQm9uZURhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFbkMsaUNBQWlDO0FBQ2pDLE1BQU0sT0FBTyxRQUFTLFNBQVEsU0FBbUI7SUFDaEQsdURBQXVEO0lBQ3ZELEtBQUssR0FBVyxDQUFDLENBQUM7SUFFbEIseURBQXlEO0lBQ3pELE1BQU0sR0FBb0IsSUFBSSxDQUFDO0lBRS9CLHlCQUF5QjtJQUN6QixNQUFNLEdBQVcsQ0FBQyxDQUFDO0lBRW5CLGdCQUFnQjtJQUNoQjs4QkFDMEI7SUFDakIsS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7SUFFN0IsNEZBQTRGO0lBQzVGLElBQUksQ0FBVTtJQUVkLHNGQUFzRjtJQUN0RixRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRWIsK0ZBQStGO0lBQy9GLFlBQVksR0FBRyxDQUFDLENBQUM7SUFFakIsbUhBQW1IO0lBQ25ILE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsWUFBYSxLQUFhLEVBQUUsSUFBWSxFQUFFLE1BQXVCO1FBQ2hFLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLElBQUksS0FBSyxHQUFHLENBQUM7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdEIsQ0FBQztJQUVELElBQUksQ0FBRSxNQUF1QjtRQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyxPQUFPLElBQUksQ0FBQztJQUNiLENBQUM7Q0FDRDtBQUVELHlFQUF5RTtBQUN6RSxNQUFNLENBQU4sSUFBWSxPQUF5RjtBQUFyRyxXQUFZLE9BQU87SUFBRyx5Q0FBTSxDQUFBO0lBQUUsMkRBQWUsQ0FBQTtJQUFFLHlFQUFzQixDQUFBO0lBQUUsMkNBQU8sQ0FBQTtJQUFFLG1FQUFtQixDQUFBO0FBQUMsQ0FBQyxFQUF6RixPQUFPLEtBQVAsT0FBTyxRQUFrRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgQm9uZVBvc2UgfSBmcm9tIFwiLi9Cb25lUG9zZS5qc1wiO1xuaW1wb3J0IHsgUG9zZWREYXRhIH0gZnJvbSBcIi4vUG9zZWREYXRhLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcbmltcG9ydCB7IENvbG9yIH0gZnJvbSBcIi4vVXRpbHMuanNcIjtcblxuLyoqIFRoZSBzZXR1cCBwb3NlIGZvciBhIGJvbmUuICovXG5leHBvcnQgY2xhc3MgQm9uZURhdGEgZXh0ZW5kcyBQb3NlZERhdGE8Qm9uZVBvc2U+IHtcblx0LyoqIFRoZSBpbmRleCBvZiB0aGUgYm9uZSBpbiB7QGxpbmsgU2tlbGV0b24uYm9uZXN9LiAqL1xuXHRpbmRleDogbnVtYmVyID0gMDtcblxuXHQvKiogVGhlIHBhcmVudCBib25lLCBvciBudWxsIGlmIHRoaXMgYm9uZSBpcyB0aGUgcm9vdC4gKi9cblx0cGFyZW50OiBCb25lRGF0YSB8IG51bGwgPSBudWxsO1xuXG5cdC8qKiBUaGUgYm9uZSdzIGxlbmd0aC4gKi9cblx0bGVuZ3RoOiBudW1iZXIgPSAwO1xuXG5cdC8vIE5vbmVzc2VudGlhbC5cblx0LyoqIFRoZSBjb2xvciBvZiB0aGUgYm9uZSBhcyBpdCB3YXMgaW4gU3BpbmUuIEF2YWlsYWJsZSBvb
Line truncated
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Bone } from "./Bone.js";
|
||||
import { Inherit } from "./BoneData.js";
|
||||
import type { Physics } from "./Physics.js";
|
||||
import type { Pose } from "./Pose.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { Update } from "./Update.js";
|
||||
import { type Vector2 } from "./Utils.js";
|
||||
/** The applied local pose and world transform for a bone. This is the {@link Bone.getPose} with constraints applied and the
|
||||
* world transform computed by {@link Skeleton.updateWorldTransform} and {@link updateWorldTransform}.
|
||||
*
|
||||
* If the world transform is changed, call {@link updateLocalTransform} before using the local transform. The local
|
||||
* transform may be needed by other code (eg to apply another constraint).
|
||||
*
|
||||
* After changing the world transform, call {@link updateWorldTransform} on every descendant bone. It may be more
|
||||
* convenient to modify the local transform instead, then call {@link Skeleton.updateWorldTransform} to update the world
|
||||
* transforms for all bones and apply constraints. */
|
||||
export declare class BonePose implements Pose<BonePose>, Update {
|
||||
bone: Bone;
|
||||
/** The local x translation. */
|
||||
x: number;
|
||||
/** The local y translation. */
|
||||
y: number;
|
||||
/** The local rotation in degrees, counter clockwise. */
|
||||
rotation: number;
|
||||
/** The local scaleX. */
|
||||
scaleX: number;
|
||||
/** The local scaleY. */
|
||||
scaleY: number;
|
||||
/** The local shearX. */
|
||||
shearX: number;
|
||||
/** The local shearY. */
|
||||
shearY: number;
|
||||
inherit: Inherit;
|
||||
/** The world transform `[a b][c d]` x-axis x component. */
|
||||
a: number;
|
||||
/** The world transform `[a b][c d]` y-axis x component. */
|
||||
b: number;
|
||||
/** The world transform `[a b][c d]` x-axis y component. */
|
||||
c: number;
|
||||
/** The world transform `[a b][c d]` y-axis y component. */
|
||||
d: number;
|
||||
/** The world X position. If changed, {@link updateLocalTransform} should be called. */
|
||||
worldY: number;
|
||||
/** The world Y position. If changed, {@link updateLocalTransform} should be called. */
|
||||
worldX: number;
|
||||
world: number;
|
||||
local: number;
|
||||
set(pose: BonePose): void;
|
||||
setPosition(x: number, y: number): void;
|
||||
setScale(scaleX: number, scaleY: number): void;
|
||||
setScale(scale: number): void;
|
||||
/** Determines how parent world transforms affect this bone. */
|
||||
getInherit(): Inherit;
|
||||
setInherit(inherit: Inherit): void;
|
||||
/** Called by {@link Skeleton.updateCache} to compute the world transform, if needed. */
|
||||
update(skeleton: Skeleton, physics: Physics): void;
|
||||
/** Computes the world transform using the parent bone's world transform and this applied local pose. Child bones are not
|
||||
* updated.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
updateWorldTransform(skeleton: Skeleton): void;
|
||||
/** Computes the local transform values from the world transform.
|
||||
*
|
||||
* If the world transform is modified (by a constraint, {@link rotateWorld}, etc) then this method should be called so
|
||||
* the local transform matches the world transform. The local transform may be needed by other code (eg to apply another
|
||||
* constraint).
|
||||
*
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
|
||||
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
|
||||
updateLocalTransform(skeleton: Skeleton): void;
|
||||
private set4;
|
||||
private set5;
|
||||
/** If the world transform has been modified by constraints and the local transform no longer matches,
|
||||
* {@link updateLocalTransform} is called. Call this after {@link Skeleton.updateWorldTransform} before
|
||||
* using the applied local transform. */
|
||||
validateLocalTransform(skeleton: Skeleton): void;
|
||||
modifyLocal(skeleton: Skeleton): void;
|
||||
modifyWorld(skeleton: Skeleton): void;
|
||||
private resetWorld;
|
||||
/** The world rotation for the X axis, calculated using {@link a} and {@link c}. This is the direction the bone is
|
||||
* pointing. */
|
||||
getWorldRotationX(): number;
|
||||
/** The world rotation for the Y axis, calculated using {@link b} and {@link d}. */
|
||||
getWorldRotationY(): number;
|
||||
/** The magnitude (always positive) of the world scale X, calculated using {@link a} and {@link c}. */
|
||||
getWorldScaleX(): number;
|
||||
/** The magnitude (always positive) of the world scale Y, calculated using {@link b} and {@link d}. */
|
||||
getWorldScaleY(): number;
|
||||
/** Transforms a point from world coordinates to the bone's local coordinates. */
|
||||
worldToLocal(world: Vector2): Vector2;
|
||||
/** Transforms a point from the bone's local coordinates to world coordinates. */
|
||||
localToWorld(local: Vector2): Vector2;
|
||||
/** Transforms a point from world coordinates to the parent bone's local coordinates. */
|
||||
worldToParent(world: Vector2): Vector2;
|
||||
/** Transforms a point from the parent bone's coordinates to world coordinates. */
|
||||
parentToWorld(world: Vector2): Vector2;
|
||||
/** Transforms a world rotation to a local rotation. */
|
||||
worldToLocalRotation(worldRotation: number): number;
|
||||
/** Transforms a local rotation to a world rotation. */
|
||||
localToWorldRotation(localRotation: number): number;
|
||||
/** Rotates the world transform the specified amount. */
|
||||
rotateWorld(degrees: number): void;
|
||||
}
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Inherit } from "./BoneData.js";
|
||||
import { MathUtils } from "./Utils.js";
|
||||
/** The applied local pose and world transform for a bone. This is the {@link Bone.getPose} with constraints applied and the
|
||||
* world transform computed by {@link Skeleton.updateWorldTransform} and {@link updateWorldTransform}.
|
||||
*
|
||||
* If the world transform is changed, call {@link updateLocalTransform} before using the local transform. The local
|
||||
* transform may be needed by other code (eg to apply another constraint).
|
||||
*
|
||||
* After changing the world transform, call {@link updateWorldTransform} on every descendant bone. It may be more
|
||||
* convenient to modify the local transform instead, then call {@link Skeleton.updateWorldTransform} to update the world
|
||||
* transforms for all bones and apply constraints. */
|
||||
export class BonePose {
|
||||
bone;
|
||||
/** The local x translation. */
|
||||
x = 0;
|
||||
/** The local y translation. */
|
||||
y = 0;
|
||||
/** The local rotation in degrees, counter clockwise. */
|
||||
rotation = 0;
|
||||
/** The local scaleX. */
|
||||
scaleX = 0;
|
||||
/** The local scaleY. */
|
||||
scaleY = 0;
|
||||
/** The local shearX. */
|
||||
shearX = 0;
|
||||
/** The local shearY. */
|
||||
shearY = 0;
|
||||
inherit = Inherit.Normal;
|
||||
/** The world transform `[a b][c d]` x-axis x component. */
|
||||
a = 0;
|
||||
/** The world transform `[a b][c d]` y-axis x component. */
|
||||
b = 0;
|
||||
/** The world transform `[a b][c d]` x-axis y component. */
|
||||
c = 0;
|
||||
/** The world transform `[a b][c d]` y-axis y component. */
|
||||
d = 0;
|
||||
/** The world X position. If changed, {@link updateLocalTransform} should be called. */
|
||||
worldY = 0;
|
||||
/** The world Y position. If changed, {@link updateLocalTransform} should be called. */
|
||||
worldX = 0;
|
||||
world = 0;
|
||||
local = 0;
|
||||
set(pose) {
|
||||
if (pose == null)
|
||||
throw new Error("pose cannot be null.");
|
||||
this.x = pose.x;
|
||||
this.y = pose.y;
|
||||
this.rotation = pose.rotation;
|
||||
this.scaleX = pose.scaleX;
|
||||
this.scaleY = pose.scaleY;
|
||||
this.shearX = pose.shearX;
|
||||
this.shearY = pose.shearY;
|
||||
this.inherit = pose.inherit;
|
||||
}
|
||||
setPosition(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
setScale(scaleOrX, scaleY) {
|
||||
this.scaleX = scaleOrX;
|
||||
this.scaleY = scaleY === undefined ? scaleOrX : scaleY;
|
||||
}
|
||||
/** Determines how parent world transforms affect this bone. */
|
||||
getInherit() {
|
||||
return this.inherit;
|
||||
}
|
||||
setInherit(inherit) {
|
||||
if (inherit == null)
|
||||
throw new Error("inherit cannot be null.");
|
||||
this.inherit = inherit;
|
||||
}
|
||||
/** Called by {@link Skeleton.updateCache} to compute the world transform, if needed. */
|
||||
update(skeleton, physics) {
|
||||
if (this.world !== skeleton._update)
|
||||
this.updateWorldTransform(skeleton);
|
||||
}
|
||||
/** Computes the world transform using the parent bone's world transform and this applied local pose. Child bones are not
|
||||
* updated.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
updateWorldTransform(skeleton) {
|
||||
if (this.local === skeleton._update)
|
||||
this.updateLocalTransform(skeleton);
|
||||
else
|
||||
this.world = skeleton._update;
|
||||
const rotation = this.rotation;
|
||||
const scaleX = this.scaleX;
|
||||
const scaleY = this.scaleY;
|
||||
const shearX = this.shearX;
|
||||
const shearY = this.shearY;
|
||||
if (!this.bone.parent) { // Root bone.
|
||||
const sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
const rx = (rotation + shearX) * MathUtils.degRad;
|
||||
const ry = (rotation + 90 + shearY) * MathUtils.degRad;
|
||||
this.a = Math.cos(rx) * scaleX * sx;
|
||||
this.b = Math.cos(ry) * scaleY * sx;
|
||||
this.c = Math.sin(rx) * scaleX * sy;
|
||||
this.d = Math.sin(ry) * scaleY * sy;
|
||||
this.worldX = this.x * sx + skeleton.x;
|
||||
this.worldY = this.y * sy + skeleton.y;
|
||||
return;
|
||||
}
|
||||
const parent = this.bone.parent.appliedPose;
|
||||
let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
||||
this.worldX = pa * this.x + pb * this.y + parent.worldX;
|
||||
this.worldY = pc * this.x + pd * this.y + parent.worldY;
|
||||
switch (this.inherit) {
|
||||
case Inherit.Normal: {
|
||||
const rx = (rotation + shearX) * MathUtils.degRad;
|
||||
const ry = (rotation + 90 + shearY) * MathUtils.degRad;
|
||||
const la = Math.cos(rx) * scaleX;
|
||||
const lb = Math.cos(ry) * scaleY;
|
||||
const lc = Math.sin(rx) * scaleX;
|
||||
const ld = Math.sin(ry) * scaleY;
|
||||
this.a = pa * la + pb * lc;
|
||||
this.b = pa * lb + pb * ld;
|
||||
this.c = pc * la + pd * lc;
|
||||
this.d = pc * lb + pd * ld;
|
||||
return;
|
||||
}
|
||||
case Inherit.OnlyTranslation: {
|
||||
const sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
const rx = (rotation + shearX) * MathUtils.degRad;
|
||||
const ry = (rotation + 90 + shearY) * MathUtils.degRad;
|
||||
this.a = Math.cos(rx) * scaleX * sx;
|
||||
this.b = Math.cos(ry) * scaleY * sx;
|
||||
this.c = Math.sin(rx) * scaleX * sy;
|
||||
this.d = Math.sin(ry) * scaleY * sy;
|
||||
break;
|
||||
}
|
||||
case Inherit.NoRotationOrReflection: {
|
||||
const sx = skeleton.scaleX, sy = skeleton.scaleY, sxi = 1 / sx, syi = 1 / sy;
|
||||
pa *= sxi;
|
||||
pc *= syi;
|
||||
let s = pa * pa + pc * pc;
|
||||
let r = 0;
|
||||
if (s > MathUtils.epsilon2) {
|
||||
s = Math.abs(pa * pd * syi - pb * sxi * pc) / s;
|
||||
pb = pc * s;
|
||||
pd = pa * s;
|
||||
r = rotation - MathUtils.atan2Deg(pc, pa);
|
||||
}
|
||||
else {
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
r = rotation - 90 + MathUtils.atan2Deg(pd, pb);
|
||||
}
|
||||
const rx = (r + shearX) * MathUtils.degRad;
|
||||
const ry = (r + shearY + 90) * MathUtils.degRad;
|
||||
const la = Math.cos(rx) * scaleX;
|
||||
const lb = Math.cos(ry) * scaleY;
|
||||
const lc = Math.sin(rx) * scaleX;
|
||||
const ld = Math.sin(ry) * scaleY;
|
||||
this.a = (pa * la - pb * lc) * sx;
|
||||
this.b = (pa * lb - pb * ld) * sx;
|
||||
this.c = (pc * la + pd * lc) * sy;
|
||||
this.d = (pc * lb + pd * ld) * sy;
|
||||
break;
|
||||
}
|
||||
case Inherit.NoScale:
|
||||
case Inherit.NoScaleOrReflection: {
|
||||
const sx = skeleton.scaleX, sy = skeleton.scaleY, sxi = 1 / sx, syi = 1 / sy;
|
||||
const r = rotation * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r);
|
||||
let za = (pa * cos + pb * sin) * sxi;
|
||||
let zc = (pc * cos + pd * sin) * syi;
|
||||
const s = 1 / Math.sqrt(za * za + zc * zc);
|
||||
za *= s;
|
||||
zc *= s;
|
||||
let zb = -zc, zd = za;
|
||||
if (this.inherit === Inherit.NoScale && pa * pd - pb * pc < 0 !== (sx < 0 !== sy < 0)) {
|
||||
zb = -zb;
|
||||
zd = -zd;
|
||||
}
|
||||
const rx = shearX * MathUtils.degRad;
|
||||
const ry = (90 + shearY) * MathUtils.degRad;
|
||||
const la = Math.cos(rx) * scaleX;
|
||||
const lb = Math.cos(ry) * scaleY;
|
||||
const lc = Math.sin(rx) * scaleX;
|
||||
const ld = Math.sin(ry) * scaleY;
|
||||
this.a = (za * la + zb * lc) * sx;
|
||||
this.b = (za * lb + zb * ld) * sx;
|
||||
this.c = (zc * la + zd * lc) * sy;
|
||||
this.d = (zc * lb + zd * ld) * sy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Computes the local transform values from the world transform.
|
||||
*
|
||||
* If the world transform is modified (by a constraint, {@link rotateWorld}, etc) then this method should be called so
|
||||
* the local transform matches the world transform. The local transform may be needed by other code (eg to apply another
|
||||
* constraint).
|
||||
*
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
|
||||
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
|
||||
updateLocalTransform(skeleton) {
|
||||
this.local = 0;
|
||||
this.world = skeleton._update;
|
||||
const sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
if (!this.bone.parent) {
|
||||
const sxi = 1 / sx, syi = 1 / sy;
|
||||
this.x = (this.worldX - skeleton.x) * sxi;
|
||||
this.y = (this.worldY - skeleton.y) * syi;
|
||||
this.set5(this.a * sxi, this.b * sxi, this.c * syi, this.d * syi, 0);
|
||||
return;
|
||||
}
|
||||
const parent = this.bone.parent.appliedPose;
|
||||
let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
|
||||
const pad = pa * pd - pb * pc, pid = 1 / (pa * pd - pb * pc);
|
||||
const ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;
|
||||
const dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY;
|
||||
this.x = dx * ia - dy * ib;
|
||||
this.y = dy * id - dx * ic;
|
||||
switch (this.inherit) {
|
||||
case Inherit.Normal:
|
||||
this.set5(ia * this.a - ib * this.c, ia * this.b - ib * this.d, id * this.c - ic * this.a, id * this.d - ic * this.b, 0);
|
||||
break;
|
||||
case Inherit.OnlyTranslation: {
|
||||
const sxi = 1 / sx, syi = 1 / sy;
|
||||
this.set5(this.a * sxi, this.b * sxi, this.c * syi, this.d * syi, 0);
|
||||
break;
|
||||
}
|
||||
case Inherit.NoRotationOrReflection: {
|
||||
const sxi = 1 / sx, syi = 1 / sy;
|
||||
pa *= sxi;
|
||||
pc *= syi;
|
||||
const wa = this.a * sxi, wb = this.b * sxi, wc = this.c * syi, wd = this.d * syi;
|
||||
const s = 1 / (pa * pa + pc * pc), det = 1 / Math.abs(pad * sxi * syi);
|
||||
this.set5((pa * wa + pc * wc) * s, (pa * wb + pc * wd) * s, (pa * wc - pc * wa) * det, (pa * wd - pc * wb) * det, MathUtils.atan2Deg(pc, pa));
|
||||
break;
|
||||
}
|
||||
case Inherit.NoScale:
|
||||
case Inherit.NoScaleOrReflection: {
|
||||
const sxi = 1 / sx, syi = 1 / sy;
|
||||
const wa = this.a * sxi, wb = this.b * sxi, wc = this.c * syi, wd = this.d * syi;
|
||||
let tx = pd * this.a - pb * this.c, ty = pa * this.c - pc * this.a;
|
||||
if (pad < 0) {
|
||||
tx = -tx;
|
||||
ty = -ty;
|
||||
}
|
||||
let r = MathUtils.atan2Deg(ty, tx);
|
||||
this.rotation = r;
|
||||
r *= MathUtils.degRad;
|
||||
const cos = Math.cos(r), sin = Math.sin(r);
|
||||
let za = (pa * cos + pb * sin) * sxi;
|
||||
let zc = (pc * cos + pd * sin) * syi;
|
||||
const s = 1 / Math.sqrt(za * za + zc * zc);
|
||||
za *= s;
|
||||
zc *= s;
|
||||
const si = this.inherit === Inherit.NoScale && pad < 0 !== (sx < 0 !== sy < 0) ? -1 : 1;
|
||||
this.set4(za * wa + zc * wc, za * wb + zc * wd, (za * wc - zc * wa) * si, (za * wd - zc * wb) * si);
|
||||
}
|
||||
}
|
||||
}
|
||||
set4(ra, rb, rc, rd) {
|
||||
const x = ra * ra + rc * rc, y = rb * rb + rd * rd;
|
||||
if (x > MathUtils.epsilon2) {
|
||||
this.shearX = MathUtils.atan2Deg(rc, ra);
|
||||
this.scaleX = Math.sqrt(x);
|
||||
}
|
||||
else {
|
||||
this.shearX = 0;
|
||||
this.scaleX = 0;
|
||||
}
|
||||
this.scaleY = Math.sqrt(y);
|
||||
if (y > MathUtils.epsilon2) {
|
||||
this.shearY = MathUtils.atan2Deg(rd, rb);
|
||||
if (ra * rd - rb * rc < 0) {
|
||||
this.scaleY = -this.scaleY;
|
||||
this.shearY += 90;
|
||||
}
|
||||
else
|
||||
this.shearY -= 90;
|
||||
if (this.shearY > 180)
|
||||
this.shearY -= 360;
|
||||
else if (this.shearY <= -180) //
|
||||
this.shearY += 360;
|
||||
}
|
||||
else
|
||||
this.shearY = 0;
|
||||
}
|
||||
set5(ra, rb, rc, rd, ro) {
|
||||
this.shearX = 0;
|
||||
const x = ra * ra + rc * rc, y = rb * rb + rd * rd;
|
||||
if (x > MathUtils.epsilon2) {
|
||||
const r = MathUtils.atan2Deg(rc, ra);
|
||||
this.rotation = r + ro;
|
||||
this.scaleX = Math.sqrt(x);
|
||||
this.scaleY = Math.sqrt(y);
|
||||
if (y > MathUtils.epsilon2) {
|
||||
this.shearY = MathUtils.atan2Deg(rd, rb);
|
||||
if (ra * rd - rb * rc < 0) {
|
||||
this.scaleY = -this.scaleY;
|
||||
this.shearY += 90 - r;
|
||||
}
|
||||
else
|
||||
this.shearY -= 90 + r;
|
||||
if (this.shearY > 180)
|
||||
this.shearY -= 360;
|
||||
else if (this.shearY <= -180) //
|
||||
this.shearY += 360;
|
||||
}
|
||||
else
|
||||
this.shearY = 0;
|
||||
}
|
||||
else {
|
||||
this.scaleX = 0;
|
||||
this.scaleY = Math.sqrt(y);
|
||||
this.shearY = 0;
|
||||
this.rotation = y > MathUtils.epsilon2 ? MathUtils.atan2Deg(rd, rb) - 90 + ro : ro;
|
||||
}
|
||||
}
|
||||
/** If the world transform has been modified by constraints and the local transform no longer matches,
|
||||
* {@link updateLocalTransform} is called. Call this after {@link Skeleton.updateWorldTransform} before
|
||||
* using the applied local transform. */
|
||||
validateLocalTransform(skeleton) {
|
||||
if (this.local === skeleton._update)
|
||||
this.updateLocalTransform(skeleton);
|
||||
}
|
||||
modifyLocal(skeleton) {
|
||||
if (this.local === skeleton._update)
|
||||
this.updateLocalTransform(skeleton);
|
||||
this.world = 0;
|
||||
this.resetWorld(skeleton, skeleton._update);
|
||||
}
|
||||
modifyWorld(skeleton) {
|
||||
const update = skeleton._update;
|
||||
this.local = update;
|
||||
this.world = update;
|
||||
this.resetWorld(skeleton, update);
|
||||
}
|
||||
resetWorld(skeleton, update) {
|
||||
const children = this.bone.children;
|
||||
for (let i = 0, n = children.length; i < n; i++) {
|
||||
const child = children[i].appliedPose;
|
||||
if (child.world === update) {
|
||||
if (child.local === update)
|
||||
child.updateLocalTransform(skeleton);
|
||||
child.world = 0;
|
||||
child.resetWorld(skeleton, update);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** The world rotation for the X axis, calculated using {@link a} and {@link c}. This is the direction the bone is
|
||||
* pointing. */
|
||||
getWorldRotationX() {
|
||||
return MathUtils.atan2Deg(this.c, this.a);
|
||||
}
|
||||
/** The world rotation for the Y axis, calculated using {@link b} and {@link d}. */
|
||||
getWorldRotationY() {
|
||||
return MathUtils.atan2Deg(this.d, this.b);
|
||||
}
|
||||
/** The magnitude (always positive) of the world scale X, calculated using {@link a} and {@link c}. */
|
||||
getWorldScaleX() {
|
||||
return Math.sqrt(this.a * this.a + this.c * this.c);
|
||||
}
|
||||
/** The magnitude (always positive) of the world scale Y, calculated using {@link b} and {@link d}. */
|
||||
getWorldScaleY() {
|
||||
return Math.sqrt(this.b * this.b + this.d * this.d);
|
||||
}
|
||||
// public Matrix3 getWorldTransform (Matrix3 worldTransform) {
|
||||
// if (worldTransform == null) throw new IllegalArgumentException("worldTransform cannot be null.");
|
||||
// float[] val = worldTransform.val;
|
||||
// val[M00] = a;
|
||||
// val[M01] = b;
|
||||
// val[M10] = c;
|
||||
// val[M11] = d;
|
||||
// val[M02] = worldX;
|
||||
// val[M12] = worldY;
|
||||
// val[M20] = 0;
|
||||
// val[M21] = 0;
|
||||
// val[M22] = 1;
|
||||
// return worldTransform;
|
||||
// }
|
||||
/** Transforms a point from world coordinates to the bone's local coordinates. */
|
||||
worldToLocal(world) {
|
||||
if (world == null)
|
||||
throw new Error("world cannot be null.");
|
||||
const det = this.a * this.d - this.b * this.c;
|
||||
const x = world.x - this.worldX, y = world.y - this.worldY;
|
||||
world.x = (x * this.d - y * this.b) / det;
|
||||
world.y = (y * this.a - x * this.c) / det;
|
||||
return world;
|
||||
}
|
||||
/** Transforms a point from the bone's local coordinates to world coordinates. */
|
||||
localToWorld(local) {
|
||||
if (local == null)
|
||||
throw new Error("local cannot be null.");
|
||||
const x = local.x, y = local.y;
|
||||
local.x = x * this.a + y * this.b + this.worldX;
|
||||
local.y = x * this.c + y * this.d + this.worldY;
|
||||
return local;
|
||||
}
|
||||
/** Transforms a point from world coordinates to the parent bone's local coordinates. */
|
||||
worldToParent(world) {
|
||||
if (world == null)
|
||||
throw new Error("world cannot be null.");
|
||||
return this.bone.parent == null ? world : this.bone.parent.appliedPose.worldToLocal(world);
|
||||
}
|
||||
/** Transforms a point from the parent bone's coordinates to world coordinates. */
|
||||
parentToWorld(world) {
|
||||
if (world == null)
|
||||
throw new Error("world cannot be null.");
|
||||
return this.bone.parent == null ? world : this.bone.parent.appliedPose.localToWorld(world);
|
||||
}
|
||||
/** Transforms a world rotation to a local rotation. */
|
||||
worldToLocalRotation(worldRotation) {
|
||||
worldRotation *= MathUtils.degRad;
|
||||
const sin = Math.sin(worldRotation), cos = Math.cos(worldRotation);
|
||||
return MathUtils.atan2Deg(this.a * sin - this.c * cos, this.d * cos - this.b * sin) + this.rotation - this.shearX;
|
||||
}
|
||||
/** Transforms a local rotation to a world rotation. */
|
||||
localToWorldRotation(localRotation) {
|
||||
localRotation = (localRotation - this.rotation - this.shearX) * MathUtils.degRad;
|
||||
const sin = Math.sin(localRotation), cos = Math.cos(localRotation);
|
||||
return MathUtils.atan2Deg(cos * this.c + sin * this.d, cos * this.a + sin * this.b);
|
||||
}
|
||||
/** Rotates the world transform the specified amount. */
|
||||
rotateWorld(degrees) {
|
||||
degrees *= MathUtils.degRad;
|
||||
const sin = Math.sin(degrees), cos = Math.cos(degrees);
|
||||
const ra = this.a, rb = this.b;
|
||||
this.a = cos * ra - sin * this.c;
|
||||
this.b = cos * rb - sin * this.d;
|
||||
this.c = sin * ra + cos * this.c;
|
||||
this.d = sin * rb + cos * this.d;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm9uZVBvc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQm9uZVBvc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFLeEMsT0FBTyxFQUFFLFNBQVMsRUFBZ0IsTUFBTSxZQUFZLENBQUM7QUFFckQ7Ozs7Ozs7O3FEQVFxRDtBQUNyRCxNQUFNLE9BQU8sUUFBUTtJQUNwQixJQUFJLENBQVE7SUFFWiwrQkFBK0I7SUFDL0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVOLCtCQUErQjtJQUMvQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRU4sd0RBQXdEO0lBQ3hELFFBQVEsR0FBRyxDQUFDLENBQUM7SUFFYix3QkFBd0I7SUFDeEIsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLHdCQUF3QjtJQUN4QixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsd0JBQXdCO0lBQ3hCLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCx3QkFBd0I7SUFDeEIsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO0lBRXpCLDJEQUEyRDtJQUMzRCxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRU4sMkRBQTJEO0lBQzNELENBQUMsR0FBRyxDQUFDLENBQUM7SUFFTiwyREFBMkQ7SUFDM0QsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVOLDJEQUEyRDtJQUMzRCxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRU4sdUZBQXVGO0lBQ3ZGLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCx1RkFBdUY7SUFDdkYsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDVixLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBRVYsR0FBRyxDQUFFLElBQWM7UUFDbEIsSUFBSSxJQUFJ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
Line truncated
|
||||
@@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { ConstraintData } from "./ConstraintData.js";
|
||||
import type { Physics } from "./Physics.js";
|
||||
import type { Pose } from "./Pose.js";
|
||||
import { PosedActive } from "./PosedActive.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { Update } from "./Update.js";
|
||||
export declare abstract class Constraint<T extends Constraint<T, D, P>, D extends ConstraintData<T, P>, P extends Pose<P>> extends PosedActive<D, P> implements Update {
|
||||
constructor(data: D, pose: P, constrained: P);
|
||||
abstract copy(skeleton: Skeleton): T;
|
||||
abstract sort(skeleton: Skeleton): void;
|
||||
abstract update(skeleton: Skeleton, physics: Physics): void;
|
||||
isSourceActive(): boolean;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { PosedActive } from "./PosedActive.js";
|
||||
export class Constraint extends PosedActive {
|
||||
constructor(data, pose, constrained) {
|
||||
super(data, pose, constrained);
|
||||
}
|
||||
isSourceActive() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uc3RyYWludC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25zdHJhaW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUsvRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFJL0MsTUFBTSxPQUFnQixVQUlyQixTQUFRLFdBQWlCO0lBRXpCLFlBQWEsSUFBTyxFQUFFLElBQU8sRUFBRSxXQUFjO1FBQzVDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFRRCxjQUFjO1FBQ2IsT0FBTyxJQUFJLENBQUM7SUFDYixDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB0eXBlIHsgQ29uc3RyYWludERhdGEgfSBmcm9tIFwiLi9Db25zdHJhaW50RGF0YS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBQaHlzaWNzIH0gZnJvbSBcIi4vUGh5c2ljcy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBQb3NlIH0gZnJvbSBcIi4vUG9zZS5qc1wiO1xuaW1wb3J0IHsgUG9zZWRBY3RpdmUgfSBmcm9tIFwiLi9Qb3NlZEFjdGl2ZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFVwZGF0ZSB9IGZyb20gXCIuL1VwZGF0ZS5qc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29uc3RyYWludDxcblx0VCBleHRlbmRzIENvbnN0cmFpbnQ8VCwgRCwgUD4sXG5cdEQgZXh0ZW5kcyBDb25zdHJhaW50RGF0YTxULCBQPixcblx0UCBleHRlbmRzIFBvc2U8UD4+XG5cdGV4dGVuZHMgUG9zZWRBY3RpdmU8RCwgUD4gaW1wbGVtZW50cyBVcGRhdGUge1xuXG5cdGNvbnN0cnVjdG9yIChkYXRhOiBELCBwb3NlOiBQLCBjb25zdHJhaW5lZDogUCkge1xuXHRcdHN1cGVyKGRhdGEsIHBvc2UsIGNvbnN0cmFpbmVkKTtcblx0fVxuXG5cdGFic3RyYWN0IGNvcHkgKHNrZWxldG9uOiBTa2VsZXRvbik6IFQ7XG5cblx0YWJzdHJhY3Qgc29ydCAoc2tlbGV0b246IFNrZWxldG9uKTogdm9pZDtcblxuXHRhYnN0cmFjdCB1cGRhdGUgKHNrZWxldG9uOiBTa2VsZXRvbiwgcGh5c2ljczogUGh5c2ljcyk6IHZvaWQ7XG5cblx0aXNTb3VyY2VBY3RpdmUgKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG4iXX0=
|
||||
@@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Constraint } from "./Constraint.js";
|
||||
import type { Pose } from "./Pose.js";
|
||||
import { PosedData } from "./PosedData.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
/** The base class for all constraint datas. */
|
||||
export declare abstract class ConstraintData<T extends Constraint<T, ConstraintData<T, P>, P>, P extends Pose<P>> extends PosedData<P> {
|
||||
constructor(name: string, setup: P);
|
||||
abstract create(skeleton: Skeleton): T;
|
||||
}
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link BonePose.scaleX} is set. */
|
||||
export declare enum ScaleYMode {
|
||||
/** scaleY is not changed. */
|
||||
None = 0,
|
||||
/** scaleY is multiplied by the scaleX factor, preserving the bone's aspect ratio. */
|
||||
Uniform = 1,
|
||||
/** scaleY is divided by the scaleX factor, preserving the bone's area. */
|
||||
Volume = 2
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { PosedData } from "./PosedData.js";
|
||||
/** The base class for all constraint datas. */
|
||||
export class ConstraintData extends PosedData {
|
||||
constructor(name, setup) {
|
||||
super(name, setup);
|
||||
}
|
||||
}
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link BonePose.scaleX} is set. */
|
||||
export var ScaleYMode;
|
||||
(function (ScaleYMode) {
|
||||
/** scaleY is not changed. */
|
||||
ScaleYMode[ScaleYMode["None"] = 0] = "None";
|
||||
/** scaleY is multiplied by the scaleX factor, preserving the bone's aspect ratio. */
|
||||
ScaleYMode[ScaleYMode["Uniform"] = 1] = "Uniform";
|
||||
/** scaleY is divided by the scaleX factor, preserving the bone's area. */
|
||||
ScaleYMode[ScaleYMode["Volume"] = 2] = "Volume";
|
||||
})(ScaleYMode || (ScaleYMode = {}));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uc3RyYWludERhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvQ29uc3RyYWludERhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSy9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUczQywrQ0FBK0M7QUFDL0MsTUFBTSxPQUFnQixjQUdyQixTQUFRLFNBQVk7SUFFcEIsWUFBYSxJQUFZLEVBQUUsS0FBUTtRQUNsQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3BCLENBQUM7Q0FHRDtBQUVELDhGQUE4RjtBQUM5RixNQUFNLENBQU4sSUFBWSxVQU9YO0FBUEQsV0FBWSxVQUFVO0lBQ3JCLDZCQUE2QjtJQUM3QiwyQ0FBSSxDQUFBO0lBQ0oscUZBQXFGO0lBQ3JGLGlEQUFPLENBQUE7SUFDUCwwRUFBMEU7SUFDMUUsK0NBQU0sQ0FBQTtBQUNQLENBQUMsRUFQVyxVQUFVLEtBQVYsVUFBVSxRQU9yQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBCb25lUG9zZSB9IGZyb20gXCIuL0JvbmVQb3NlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENvbnN0cmFpbnQgfSBmcm9tIFwiLi9Db25zdHJhaW50LmpzXCI7XG5pbXBvcnQgdHlwZSB7IFBvc2UgfSBmcm9tIFwiLi9Qb3NlLmpzXCI7XG5pbXBvcnQgeyBQb3NlZERhdGEgfSBmcm9tIFwiLi9Qb3NlZERhdGEuanNcIjtcbmltcG9ydCB0eXBlIHsgU2tlbGV0b24gfSBmcm9tIFwiLi9Ta2VsZXRvbi5qc1wiO1xuXG4vKiogVGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBjb25zdHJhaW50IGRhdGFzLiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvbnN0cmFpbnREYXRhPFxuXHRUIGV4dGVuZHMgQ29uc3RyYWludDxULCBDb25zdHJhaW50RGF0YTxULCBQPiwgUD4sXG5cdFAgZXh0ZW5kcyBQb3NlPFA+PlxuXHRleHRlbmRzIFBvc2VkRGF0YTxQPiB7XG5cblx0Y29uc3RydWN0b3IgKG5hbWU6IHN0cmluZywgc2V0dXA6IFApIHtcblx0XHRzdXBlcihuYW1lLCBzZXR1cCk7XG5cdH1cblxuXHRhYnN0cmFjdCBjcmVhdGUgKHNrZWxldG9uOiBTa2VsZXRvbik6IFQ7XG59XG5cbi8qKiBEZXRlcm1pbmVzIGhvdyB0aGUge0BsaW5rIEJvbmVQb3NlLnNjYWxlWX0gY2hhbmdlcyB3aGVuIHtAbGluayBCb25lUG9zZS5zY2FsZVh9IGlzIHNldC4gKi9cbmV4cG9ydCBlbnVtIFNjYWxlWU1vZGUge1xuXHQvKiogc2NhbGVZIGlzIG5vdCBjaGFuZ2VkLiAqL1xuXHROb25lLFxuXHQvKiogc2NhbGVZIGlzIG11bHRpcGxpZWQgYnkgdGhlIHNjYWxlWCBmYWN0b3IsIHByZXNlcnZpbmcgdGhlIGJvbmUncyBhc3BlY3QgcmF0aW8uICovXG5cdFVuaWZvcm0sXG5cdC8qKiBzY2FsZVkgaXMgZGl2aWRlZCBieSB0aGUgc2NhbGVYIGZhY3RvciwgcHJlc2VydmluZyB0aGUgYm9uZSdzIGFyZWEuICovXG5cdFZvbHVtZVxufVxuIl19
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Slot } from "./Slot.js";
|
||||
/** Stores the skeleton's draw order, which is the order that each slot's attachment is rendered. */
|
||||
export declare class DrawOrder {
|
||||
readonly _setupPose: Slot[];
|
||||
/** The unconstrained draw order, set by animations and application code. */
|
||||
readonly pose: Slot[];
|
||||
readonly constrainedPose: Slot[];
|
||||
/** The constrained draw order for rendering. If no constraints modify the draw order, this is the same as {@link pose}.
|
||||
* Otherwise it is a copy of {@link pose} modified by constraints. */
|
||||
appliedPose: Slot[];
|
||||
constructor(setupPose: Slot[]);
|
||||
/** Sets the unconstrained draw order to the setup pose order. */
|
||||
setupPose(): void;
|
||||
/** Sets the applied pose to the unconstrained pose, for when no constraints will modify the draw order. */
|
||||
unconstrained(): void;
|
||||
/** Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints. */
|
||||
constrained(): void;
|
||||
/** Copies the unconstrained pose to the constrained pose, as a starting point for constraints to be applied. */
|
||||
resetConstrained(): void;
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Utils } from "./Utils.js";
|
||||
/** Stores the skeleton's draw order, which is the order that each slot's attachment is rendered. */
|
||||
export class DrawOrder {
|
||||
_setupPose;
|
||||
/** The unconstrained draw order, set by animations and application code. */
|
||||
pose;
|
||||
constrainedPose;
|
||||
/** The constrained draw order for rendering. If no constraints modify the draw order, this is the same as {@link pose}.
|
||||
* Otherwise it is a copy of {@link pose} modified by constraints. */
|
||||
appliedPose;
|
||||
constructor(setupPose) {
|
||||
this._setupPose = setupPose;
|
||||
this.pose = [...setupPose];
|
||||
this.constrainedPose = [];
|
||||
this.appliedPose = this.pose;
|
||||
}
|
||||
/** Sets the unconstrained draw order to the setup pose order. */
|
||||
setupPose() {
|
||||
this.pose.length = this._setupPose.length;
|
||||
Utils.arrayCopy(this._setupPose, 0, this.pose, 0, this._setupPose.length);
|
||||
}
|
||||
/** Sets the applied pose to the unconstrained pose, for when no constraints will modify the draw order. */
|
||||
unconstrained() {
|
||||
this.appliedPose = this.pose;
|
||||
}
|
||||
/** Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints. */
|
||||
constrained() {
|
||||
this.appliedPose = this.constrainedPose;
|
||||
}
|
||||
/** Copies the unconstrained pose to the constrained pose, as a starting point for constraints to be applied. */
|
||||
resetConstrained() {
|
||||
this.constrainedPose.length = this.pose.length;
|
||||
Utils.arrayCopy(this.pose, 0, this.constrainedPose, 0, this.pose.length);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRHJhd09yZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0RyYXdPcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVuQyxvR0FBb0c7QUFDcEcsTUFBTSxPQUFPLFNBQVM7SUFDWixVQUFVLENBQVM7SUFFNUIsNEVBQTRFO0lBQ25FLElBQUksQ0FBUztJQUNiLGVBQWUsQ0FBUztJQUVqQzt5RUFDcUU7SUFDckUsV0FBVyxDQUFTO0lBRXBCLFlBQWEsU0FBaUI7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQzlCLENBQUM7SUFFRCxpRUFBaUU7SUFDakUsU0FBUztRQUNSLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQzFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsMkdBQTJHO0lBQzNHLGFBQWE7UUFDWixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDOUIsQ0FBQztJQUVELHdIQUF3SDtJQUN4SCxXQUFXO1FBQ1YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxnSEFBZ0g7SUFDaEgsZ0JBQWdCO1FBQ2YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDL0MsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFFLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBTbG90IH0gZnJvbSBcIi4vU2xvdC5qc1wiO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tIFwiLi9VdGlscy5qc1wiO1xuXG4vKiogU3RvcmVzIHRoZSBza2VsZXRvbidzIGRyYXcgb3JkZXIsIHdoaWNoIGlzIHRoZSBvcmRlciB0aGF0IGVhY2ggc2xvdCdzIGF0dGFjaG1lbnQgaXMgcmVuZGVyZWQuICovXG5leHBvcnQgY2xhc3MgRHJhd09yZGVyIHtcblx0cmVhZG9ubHkgX3NldHVwUG9zZTogU2xvdFtdO1xuXG5cdC8qKiBUaGUgdW5jb25zdHJhaW5lZCBkcmF3IG9yZGVyLCBzZXQgYnkgYW5pbWF0aW9ucyBhbmQgYXBwbGljYXRpb24gY29kZS4gKi9cblx0cmVhZG9ubHkgcG9zZTogU2xvdFtdO1xuXHRyZWFkb25seSBjb25zdHJhaW5lZFBvc2U6IFNsb3RbXTtcblxuXHQvKiogVGhlIGNvbnN0cmFpbmVkIGRyYXcgb3JkZXIgZm9yIHJlbmRlcmluZy4gSWYgbm8gY29uc3RyYWludHMgbW9kaWZ5IHRoZSBkcmF3IG9yZGVyLCB0aGlzIGlzIHRoZSBzYW1lIGFzIHtAbGluayBwb3NlfS5cblx0ICogT3RoZXJ3aXNlIGl0IGlzIGEgY29weSBvZiB7QGxpbmsgcG9zZX0gbW9kaWZpZWQgYnkgY29uc3RyYWludHMuICovXG5cdGFwcGxpZWRQb3NlOiBTbG90W107XG5cblx0Y29uc3RydWN0b3IgKHNldHVwUG9zZTogU2xvdFtdKSB7XG5cdFx0dGhpcy5fc2V0dXBQb3NlID0gc2V0dXBQb3NlO1xuXHRcdHRoaXMucG9zZSA9IFsuLi5zZXR1cFBvc2VdO1xuXHRcdHRoaXMuY29uc3RyYWluZWRQb3NlID0gW107XG5cdFx0dGhpcy5hcHBsaWVkUG9zZSA9IHRoaXMucG9zZTtcblx0fVxuXG5cdC8qKiBTZXRzIHRoZSB1bmNvbnN0cmFpbmVkIGRyYXcgb3JkZXIgdG8gdGhlIHNldHVwI
Line truncated
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { EventData } from "./EventData.js";
|
||||
/** Fired by {@link EventTimeline} when specific animation times are reached.
|
||||
*
|
||||
* See Timeline {@link Timeline.apply},
|
||||
* AnimationStateListener {@link AnimationStateListener.event}, and
|
||||
* [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */
|
||||
export declare class Event {
|
||||
/** The animation time this event was keyed, or -1 for the setup pose. */
|
||||
time: number;
|
||||
readonly data: EventData;
|
||||
/** The integer payload for this event. */
|
||||
intValue: number;
|
||||
/** The float payload for this event. */
|
||||
floatValue: number;
|
||||
stringValue: string | null;
|
||||
/** If an audio path is set, the volume for the audio. */
|
||||
volume: number;
|
||||
/** If an audio path is set, the left/right balance for the audio. */
|
||||
balance: number;
|
||||
constructor(time: number, data: EventData);
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Fired by {@link EventTimeline} when specific animation times are reached.
|
||||
*
|
||||
* See Timeline {@link Timeline.apply},
|
||||
* AnimationStateListener {@link AnimationStateListener.event}, and
|
||||
* [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */
|
||||
export class Event {
|
||||
/** The animation time this event was keyed, or -1 for the setup pose. */
|
||||
time = 0;
|
||||
data;
|
||||
/** The integer payload for this event. */
|
||||
intValue = 0;
|
||||
/** The float payload for this event. */
|
||||
floatValue = 0;
|
||||
stringValue = null;
|
||||
/** If an audio path is set, the volume for the audio. */
|
||||
volume = 0;
|
||||
/** If an audio path is set, the left/right balance for the audio. */
|
||||
balance = 0;
|
||||
constructor(time, data) {
|
||||
if (!data)
|
||||
throw new Error("data cannot be null.");
|
||||
this.time = time;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvRXZlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBTy9FOzs7O2lGQUlpRjtBQUNqRixNQUFNLE9BQU8sS0FBSztJQUVqQix5RUFBeUU7SUFDekUsSUFBSSxHQUFXLENBQUMsQ0FBQztJQUVSLElBQUksQ0FBWTtJQUV6QiwwQ0FBMEM7SUFDMUMsUUFBUSxHQUFXLENBQUMsQ0FBQztJQUVyQix3Q0FBd0M7SUFDeEMsVUFBVSxHQUFXLENBQUMsQ0FBQztJQUV2QixXQUFXLEdBQWtCLElBQUksQ0FBQztJQUVsQyx5REFBeUQ7SUFDekQsTUFBTSxHQUFXLENBQUMsQ0FBQztJQUVuQixxRUFBcUU7SUFDckUsT0FBTyxHQUFXLENBQUMsQ0FBQztJQUVwQixZQUFhLElBQVksRUFBRSxJQUFlO1FBQ3pDLElBQUksQ0FBQyxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG5pbXBvcnQgdHlwZSB7IEV2ZW50VGltZWxpbmUsIFRpbWVsaW5lIH0gZnJvbSBcIi4vQW5pbWF0aW9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEFuaW1hdGlvblN0YXRlTGlzdGVuZXIgfSBmcm9tIFwiLi9BbmltYXRpb25TdGF0ZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBFdmVudERhdGEgfSBmcm9tIFwiLi9FdmVudERhdGEuanNcIjtcblxuLyoqIEZpcmVkIGJ5IHtAbGluayBFdmVudFRpbWVsaW5lfSB3aGVuIHNwZWNpZmljIGFuaW1hdGlvbiB0aW1lcyBhcmUgcmVhY2hlZC5cbiAqXG4gKiBTZWUgVGltZWxpbmUge0BsaW5rIFRpbWVsaW5lLmFwcGx5fSxcbiAqIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIge0BsaW5rIEFuaW1hdGlvblN0YXRlTGlzdGVuZXIuZXZlbnR9LCBhbmRcbiAqIFtFdmVudHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1ldmVudHMpIGluIHRoZSBTcGluZSBVc2VyIEd1aWRlLiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50IHtcblxuXHQvKiogVGhlIGFuaW1hdGlvbiB0aW1lIHRoaXMgZXZlbnQgd2FzIGtleWVkLCBvciAtMSBmb3IgdGhlIHNldHVwIHBvc2UuICovXG5cdHRpbWU6IG51bWJlciA9IDA7XG5cblx0cmVhZG9ubHkgZGF0YTogRXZlbnREYXRhO1xuXG5cdC8qKiBUaGUgaW50ZWdlciBwYXlsb2FkIGZvciB0aGlzIGV2ZW50LiAqL1xuXHRpbnRWYWx1ZTogbnVtYmVyID0gMDtcblxuXHQvKiogVGhlIGZsb2F0IHBheWxvYWQgZm9yIHRoaXMgZXZlbnQuICovXG5cdGZsb2F0VmFsdWU6IG51bWJlciA9IDA7XG5cblx0c3RyaW5nVmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG5cdC8qKiBJZiBhbiBhdWRpbyBwYXRoIGlzIHNldCwgdGhlIHZvbHVtZSBmb3IgdGhlIGF1ZGlvLiAqL1xuXHR2b2x1bWU6IG51bWJlciA9IDA7XG5cblx0LyoqIElmIGFuIGF1ZGlvIHBhdGggaXMgc2V0LCB0aGUgbGVmdC9yaWdodCBiYWxhbmNlIGZvciB0aGUgYXVkaW8uICovXG5cdGJhbGFuY2U6IG51bWJlciA9IDA7XG5cblx0Y29uc3RydWN0b3IgKHRpbWU6IG51bWJlciwgZGF0YTogRXZlbnREYXRhKSB7XG5cdFx0aWYgKCFkYXRhKSB0aHJvdyBuZXcgRXJyb3IoXCJkYXRhIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHR0aGlzLnRpbWUgPSB0aW1lO1xuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdH1cbn1cbiJdfQ==
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Event } from "./Event.js";
|
||||
/** Stores the setup pose values for an {@link Event}.
|
||||
*
|
||||
* See [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */
|
||||
export declare class EventData {
|
||||
/** The name of the event, unique across all events in the skeleton.
|
||||
*
|
||||
* See {@link SkeletonData.findEvent}. */
|
||||
name: string;
|
||||
_audioPath: string | null;
|
||||
/** Path to an audio file relative to the audio folder as defined in Spine. */
|
||||
get audioPath(): string;
|
||||
set audioPath(audioPath: string | null);
|
||||
/** The setup values that are shared by all events with this data. */
|
||||
readonly setupPose: Event;
|
||||
constructor(name: string);
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Event } from "./Event.js";
|
||||
/** Stores the setup pose values for an {@link Event}.
|
||||
*
|
||||
* See [Events](http://esotericsoftware.com/spine-events) in the Spine User Guide. */
|
||||
export class EventData {
|
||||
/** The name of the event, unique across all events in the skeleton.
|
||||
*
|
||||
* See {@link SkeletonData.findEvent}. */
|
||||
name;
|
||||
_audioPath = null;
|
||||
/** Path to an audio file relative to the audio folder as defined in Spine. */
|
||||
get audioPath() {
|
||||
// biome-ignore lint/style/noNonNullAssertion: can't be null after initialization
|
||||
return this._audioPath;
|
||||
}
|
||||
set audioPath(audioPath) {
|
||||
if (audioPath == null)
|
||||
throw new Error("audioPath cannot be null.");
|
||||
this._audioPath = audioPath;
|
||||
}
|
||||
/** The setup values that are shared by all events with this data. */
|
||||
setupPose = new Event(-1, this);
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXZlbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0V2ZW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUduQzs7cUZBRXFGO0FBQ3JGLE1BQU0sT0FBTyxTQUFTO0lBQ3JCOzs2Q0FFeUM7SUFDekMsSUFBSSxDQUFTO0lBRWIsVUFBVSxHQUFrQixJQUFJLENBQUM7SUFDakMsOEVBQThFO0lBQzlFLElBQUksU0FBUztRQUNaLGlGQUFpRjtRQUNqRixPQUFPLElBQUksQ0FBQyxVQUFXLENBQUM7SUFDekIsQ0FBQztJQUVELElBQUksU0FBUyxDQUFFLFNBQXdCO1FBQ3RDLElBQUksU0FBUyxJQUFJLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7SUFDN0IsQ0FBQztJQUVELHFFQUFxRTtJQUM1RCxTQUFTLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFekMsWUFBYSxJQUFZO1FBQ3hCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tIFwiLi9FdmVudC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbkRhdGEgfSBmcm9tIFwiLi9Ta2VsZXRvbkRhdGEuanNcIjtcblxuLyoqIFN0b3JlcyB0aGUgc2V0dXAgcG9zZSB2YWx1ZXMgZm9yIGFuIHtAbGluayBFdmVudH0uXG4gKlxuICogU2VlIFtFdmVudHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1ldmVudHMpIGluIHRoZSBTcGluZSBVc2VyIEd1aWRlLiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50RGF0YSB7XG5cdC8qKiBUaGUgbmFtZSBvZiB0aGUgZXZlbnQsIHVuaXF1ZSBhY3Jvc3MgYWxsIGV2ZW50cyBpbiB0aGUgc2tlbGV0b24uXG5cdCAqXG5cdCAqIFNlZSB7QGxpbmsgU2tlbGV0b25EYXRhLmZpbmRFdmVudH0uICovXG5cdG5hbWU6IHN0cmluZztcblxuXHRfYXVkaW9QYXRoOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblx0LyoqIFBhdGggdG8gYW4gYXVkaW8gZmlsZSByZWxhdGl2ZSB0byB0aGUgYXVkaW8gZm9sZGVyIGFzIGRlZmluZWQgaW4gU3BpbmUuICovXG5cdGdldCBhdWRpb1BhdGggKCk6IHN0cmluZyB7XG5cdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvbm9Ob25OdWxsQXNzZXJ0aW9uOiBjYW4ndCBiZSBudWxsIGFmdGVyIGluaXRpYWxpemF0aW9uXG5cdFx0cmV0dXJuIHRoaXMuX2F1ZGlvUGF0aCE7XG5cdH1cblxuXHRzZXQgYXVkaW9QYXRoIChhdWRpb1BhdGg6IHN0cmluZyB8IG51bGwpIHtcblx0XHRpZiAoYXVkaW9QYXRoID09IG51bGwpIHRocm93IG5ldyBFcnJvcihcImF1ZGlvUGF0aCBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0dGhpcy5fYXVkaW9QYXRoID0gYXVkaW9QYXRoO1xuXHR9XG5cblx0LyoqIFRoZSBzZXR1cCB2YWx1ZXMgdGhhdCBhcmUgc2hhcmVkIGJ5IGFsbCBldmVudHMgd2l0aCB0aGlzIGRhdGEuICovXG5cdHJlYWRvbmx5IHNldHVwUG9zZSA9IG5ldyBFdmVudCgtMSwgdGhpcyk7XG5cblx0Y29uc3RydWN0b3IgKG5hbWU6IHN0cmluZykge1xuXHRcdHRoaXMubmFtZSA9IG5hbWU7XG5cdH1cbn1cbiJdfQ==
|
||||
@@ -0,0 +1,60 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Bone } from "./Bone.js";
|
||||
import type { BonePose } from "./BonePose.js";
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { ScaleYMode } from "./ConstraintData.js";
|
||||
import type { IkConstraintData } from "./IkConstraintData.js";
|
||||
import { IkConstraintPose } from "./IkConstraintPose.js";
|
||||
import type { Physics } from "./Physics.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
/** Adjusts the local rotation of 1 or 2 constrained bones so the world position of the tip of the last bone is as close to the
|
||||
* target bone as possible.
|
||||
*
|
||||
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
|
||||
export declare class IkConstraint extends Constraint<IkConstraint, IkConstraintData, IkConstraintPose> {
|
||||
/** The 1 or 2 bones that will be modified by this IK constraint. */
|
||||
readonly bones: Array<BonePose>;
|
||||
/** The bone that is the IK target. */
|
||||
target: Bone;
|
||||
constructor(data: IkConstraintData, skeleton: Skeleton);
|
||||
copy(skeleton: Skeleton): IkConstraint;
|
||||
update(skeleton: Skeleton, physics: Physics): void;
|
||||
sort(skeleton: Skeleton): void;
|
||||
isSourceActive(): boolean;
|
||||
/** Applies 1 bone IK. The target is specified in the world coordinate system. */
|
||||
static apply(skeleton: Skeleton, bone: BonePose, targetX: number, targetY: number, compress: boolean, stretch: boolean, scaleYMode: ScaleYMode, mix: number): void;
|
||||
/** Applies 2 bone IK. The target is specified in the world coordinate system.
|
||||
* @param child A direct descendant of the parent bone. */
|
||||
static apply(skeleton: Skeleton, parent: BonePose, child: BonePose, targetX: number, targetY: number, bendDir: number, stretch: boolean, scaleYMode: ScaleYMode, softness: number, mix: number): void;
|
||||
private static apply1;
|
||||
/** Applies 2 bone IK. The target is specified in the world coordinate system.
|
||||
* @param child A direct descendant of the parent bone. */
|
||||
private static apply2;
|
||||
}
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Inherit } from "./BoneData.js";
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { ScaleYMode } from "./ConstraintData.js";
|
||||
import { IkConstraintPose } from "./IkConstraintPose.js";
|
||||
import { MathUtils } from "./Utils.js";
|
||||
/** Adjusts the local rotation of 1 or 2 constrained bones so the world position of the tip of the last bone is as close to the
|
||||
* target bone as possible.
|
||||
*
|
||||
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
|
||||
export class IkConstraint extends Constraint {
|
||||
/** The 1 or 2 bones that will be modified by this IK constraint. */
|
||||
bones;
|
||||
/** The bone that is the IK target. */
|
||||
target;
|
||||
constructor(data, skeleton) {
|
||||
super(data, new IkConstraintPose(), new IkConstraintPose());
|
||||
if (!skeleton)
|
||||
throw new Error("skeleton cannot be null.");
|
||||
this.bones = [];
|
||||
for (const boneData of data.bones)
|
||||
this.bones.push(skeleton.bones[boneData.index].constrainedPose);
|
||||
this.target = skeleton.bones[data.target.index];
|
||||
}
|
||||
copy(skeleton) {
|
||||
var copy = new IkConstraint(this.data, skeleton);
|
||||
copy.pose.set(this.pose);
|
||||
return copy;
|
||||
}
|
||||
update(skeleton, physics) {
|
||||
const p = this.appliedPose;
|
||||
if (p.mix === 0)
|
||||
return;
|
||||
const target = this.target.appliedPose;
|
||||
const bones = this.bones;
|
||||
switch (bones.length) {
|
||||
case 1:
|
||||
IkConstraint.apply(skeleton, bones[0], target.worldX, target.worldY, p.compress, p.stretch, this.data.scaleYMode, p.mix);
|
||||
break;
|
||||
case 2:
|
||||
IkConstraint.apply(skeleton, bones[0], bones[1], target.worldX, target.worldY, p.bendDirection, p.stretch, this.data.scaleYMode, p.softness, p.mix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sort(skeleton) {
|
||||
skeleton.sortBone(this.target);
|
||||
const parent = this.bones[0].bone;
|
||||
skeleton.sortBone(parent);
|
||||
skeleton._updateCache.push(this);
|
||||
parent.sorted = false;
|
||||
skeleton.sortReset(parent.children);
|
||||
skeleton.constrained(parent);
|
||||
if (this.bones.length > 1)
|
||||
skeleton.constrained(this.bones[1].bone);
|
||||
}
|
||||
isSourceActive() {
|
||||
return this.target.active;
|
||||
}
|
||||
static apply(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode, softness, mix) {
|
||||
if (typeof targetXorChild === "number")
|
||||
IkConstraint.apply1(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode);
|
||||
else
|
||||
IkConstraint.apply2(skeleton, boneOrParent, targetXorChild, targetYOrTargetX, compressOrTargetY, stretchOrBendDir, scaleYModeOrStretch, mixOrScaleYMode, softness, mix);
|
||||
}
|
||||
static apply1(skeleton, bone, targetX, targetY, compress, stretch, scaleYMode, mix) {
|
||||
bone.modifyLocal(skeleton);
|
||||
// biome-ignore lint/style/noNonNullAssertion: reference runtime
|
||||
const p = bone.bone.parent.appliedPose;
|
||||
let pa = p.a, pb = p.b, pc = p.c, pd = p.d;
|
||||
let rotationIK = -bone.shearX - bone.rotation, tx = 0, ty = 0;
|
||||
switch (bone.inherit) {
|
||||
case Inherit.OnlyTranslation:
|
||||
tx = (targetX - bone.worldX) * MathUtils.signum(skeleton.scaleX);
|
||||
ty = (targetY - bone.worldY) * MathUtils.signum(skeleton.scaleY);
|
||||
break;
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: reference runtime
|
||||
case Inherit.NoRotationOrReflection: {
|
||||
const s = Math.abs(pa * pd - pb * pc) / Math.max(MathUtils.epsilon, pa * pa + pc * pc);
|
||||
const sa = pa / skeleton.scaleX;
|
||||
const sc = pc / skeleton.scaleY;
|
||||
pb = -sc * s * skeleton.scaleX;
|
||||
pd = sa * s * skeleton.scaleY;
|
||||
rotationIK += MathUtils.atan2Deg(sc, sa);
|
||||
}
|
||||
// Fall through
|
||||
default: {
|
||||
const x = targetX - p.worldX, y = targetY - p.worldY;
|
||||
const d = pa * pd - pb * pc;
|
||||
if (Math.abs(d) <= MathUtils.epsilon) {
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
}
|
||||
else {
|
||||
tx = (x * pd - y * pb) / d - bone.x;
|
||||
ty = (y * pa - x * pc) / d - bone.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
rotationIK += MathUtils.atan2Deg(ty, tx);
|
||||
if (bone.scaleX < 0)
|
||||
rotationIK += 180;
|
||||
if (rotationIK > 180)
|
||||
rotationIK -= 360;
|
||||
else if (rotationIK <= -180)
|
||||
rotationIK += 360;
|
||||
bone.rotation += rotationIK * mix;
|
||||
if (compress || stretch) {
|
||||
switch (bone.inherit) {
|
||||
case Inherit.NoScale:
|
||||
case Inherit.NoScaleOrReflection:
|
||||
tx = targetX - bone.worldX;
|
||||
ty = targetY - bone.worldY;
|
||||
}
|
||||
const b = bone.bone.data.length * bone.scaleX;
|
||||
if (b > MathUtils.epsilon) {
|
||||
const dd = tx * tx + ty * ty;
|
||||
if ((compress && dd < b * b) || (stretch && dd > b * b)) {
|
||||
const s = (Math.sqrt(dd) / b - 1) * mix + 1;
|
||||
bone.scaleX *= s;
|
||||
switch (scaleYMode) {
|
||||
case ScaleYMode.Uniform:
|
||||
bone.scaleY *= s;
|
||||
break;
|
||||
case ScaleYMode.Volume: bone.scaleY /= s < 0.7 ? 0.25 + 0.642857 * s : s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Applies 2 bone IK. The target is specified in the world coordinate system.
|
||||
* @param child A direct descendant of the parent bone. */
|
||||
static apply2(skeleton, parent, child, targetX, targetY, bendDir, stretch, scaleYMode, softness, mix) {
|
||||
if (parent.inherit !== Inherit.Normal || child.inherit !== Inherit.Normal)
|
||||
return;
|
||||
parent.modifyLocal(skeleton);
|
||||
child.modifyLocal(skeleton);
|
||||
let px = parent.x, py = parent.y, psx = parent.scaleX, psy = parent.scaleY, csx = child.scaleX;
|
||||
let os1 = 0, os2 = 0, s2 = 0;
|
||||
if (psx < 0) {
|
||||
psx = -psx;
|
||||
os1 = 180;
|
||||
s2 = -1;
|
||||
}
|
||||
else {
|
||||
os1 = 0;
|
||||
s2 = 1;
|
||||
}
|
||||
if (psy < 0) {
|
||||
psy = -psy;
|
||||
s2 = -s2;
|
||||
}
|
||||
if (csx < 0) {
|
||||
csx = -csx;
|
||||
os2 = 180;
|
||||
}
|
||||
else
|
||||
os2 = 0;
|
||||
let cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d;
|
||||
const u = Math.abs(psx - psy) <= MathUtils.epsilon;
|
||||
if (!u || stretch) {
|
||||
child.y = 0;
|
||||
cwx = a * child.x + parent.worldX;
|
||||
cwy = c * child.x + parent.worldY;
|
||||
}
|
||||
else {
|
||||
cwx = a * child.x + b * child.y + parent.worldX;
|
||||
cwy = c * child.x + d * child.y + parent.worldY;
|
||||
}
|
||||
// biome-ignore lint/style/noNonNullAssertion: reference runtime
|
||||
const pp = parent.bone.parent.appliedPose;
|
||||
a = pp.a;
|
||||
b = pp.b;
|
||||
c = pp.c;
|
||||
d = pp.d;
|
||||
let id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;
|
||||
id = Math.abs(id) <= MathUtils.epsilon ? 0 : 1 / id;
|
||||
const dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
|
||||
let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.bone.data.length * csx, a1, a2;
|
||||
if (l1 < MathUtils.epsilon) {
|
||||
IkConstraint.apply(skeleton, parent, targetX, targetY, false, stretch, ScaleYMode.None, mix);
|
||||
child.rotation = 0;
|
||||
return;
|
||||
}
|
||||
x = targetX - pp.worldX;
|
||||
y = targetY - pp.worldY;
|
||||
let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py;
|
||||
let dd = tx * tx + ty * ty;
|
||||
if (softness !== 0) {
|
||||
softness *= psx * (csx + 1) * 0.5;
|
||||
const td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness;
|
||||
if (sd > 0) {
|
||||
let p = Math.min(1, sd / (softness * 2)) - 1;
|
||||
p = (sd - softness * (1 - p * p)) / td;
|
||||
tx -= p * tx;
|
||||
ty -= p * ty;
|
||||
dd = tx * tx + ty * ty;
|
||||
}
|
||||
}
|
||||
// biome-ignore lint/suspicious/noConfusingLabels: reference runtime
|
||||
outer: if (u) {
|
||||
l2 *= psx;
|
||||
let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
|
||||
if (cos < -1) {
|
||||
cos = -1;
|
||||
a2 = Math.PI * bendDir;
|
||||
}
|
||||
else if (cos > 1) {
|
||||
cos = 1;
|
||||
a2 = 0;
|
||||
if (stretch) {
|
||||
a = (Math.sqrt(dd) / (l1 + l2) - 1) * mix + 1;
|
||||
parent.scaleX *= a;
|
||||
switch (scaleYMode) {
|
||||
case ScaleYMode.Uniform:
|
||||
parent.scaleY *= a;
|
||||
break;
|
||||
case ScaleYMode.Volume: parent.scaleY /= a < 0.7 ? 0.25 + 0.642857 * a : a;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
a2 = Math.acos(cos) * bendDir;
|
||||
a = l1 + l2 * cos;
|
||||
b = l2 * Math.sin(a2);
|
||||
a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b);
|
||||
}
|
||||
else {
|
||||
a = psx * l2;
|
||||
b = psy * l2;
|
||||
const aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
|
||||
c = bb * l1 * l1 + aa * dd - aa * bb;
|
||||
const c1 = -2 * bb * l1, c2 = bb - aa;
|
||||
d = c1 * c1 - 4 * c2 * c;
|
||||
if (d >= 0) {
|
||||
let q = Math.sqrt(d);
|
||||
if (c1 < 0)
|
||||
q = -q;
|
||||
q = -(c1 + q) * 0.5;
|
||||
let r0 = q / c2, r1 = c / q;
|
||||
const r = Math.abs(r0) < Math.abs(r1) ? r0 : r1;
|
||||
r0 = dd - r * r;
|
||||
if (r0 >= 0) {
|
||||
y = Math.sqrt(r0) * bendDir;
|
||||
a1 = ta - Math.atan2(y, r);
|
||||
a2 = Math.atan2(y / psy, (r - l1) / psx);
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
let minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
|
||||
let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
|
||||
c = -a * l1 / (aa - bb);
|
||||
if (c >= -1 && c <= 1) {
|
||||
c = Math.acos(c);
|
||||
x = a * Math.cos(c) + l1;
|
||||
y = b * Math.sin(c);
|
||||
d = x * x + y * y;
|
||||
if (d < minDist) {
|
||||
minAngle = c;
|
||||
minDist = d;
|
||||
minX = x;
|
||||
minY = y;
|
||||
}
|
||||
if (d > maxDist) {
|
||||
maxAngle = c;
|
||||
maxDist = d;
|
||||
maxX = x;
|
||||
maxY = y;
|
||||
}
|
||||
}
|
||||
if (dd <= (minDist + maxDist) * 0.5) {
|
||||
a1 = ta - Math.atan2(minY * bendDir, minX);
|
||||
a2 = minAngle * bendDir;
|
||||
}
|
||||
else {
|
||||
a1 = ta - Math.atan2(maxY * bendDir, maxX);
|
||||
a2 = maxAngle * bendDir;
|
||||
}
|
||||
}
|
||||
const os = Math.atan2(child.y, child.x) * s2;
|
||||
a1 = (a1 - os) * MathUtils.radDeg + os1 - parent.rotation;
|
||||
if (a1 > 180)
|
||||
a1 -= 360;
|
||||
else if (a1 <= -180) //
|
||||
a1 += 360;
|
||||
parent.rotation += a1 * mix;
|
||||
a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - child.rotation;
|
||||
if (a2 > 180)
|
||||
a2 -= 360;
|
||||
else if (a2 <= -180) //
|
||||
a2 += 360;
|
||||
child.rotation += a2 * mix;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0lrQ29uc3RyYWludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWpELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBR3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFdkM7OztxR0FHcUc7QUFDckcsTUFBTSxPQUFPLFlBQWEsU0FBUSxVQUE0RDtJQUM3RixvRUFBb0U7SUFDM0QsS0FBSyxDQUFrQjtJQUVoQyxzQ0FBc0M7SUFDdEMsTUFBTSxDQUFPO0lBRWIsWUFBYSxJQUFzQixFQUFFLFFBQWtCO1FBQ3RELEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxnQkFBZ0IsRUFBRSxFQUFFLElBQUksZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxLQUFLLEdBQUcsRUFBZ0IsQ0FBQztRQUM5QixLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLO1lBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRWpFLElBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELENB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
Line truncated
|
||||
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { BoneData } from "./BoneData.js";
|
||||
import { ConstraintData, ScaleYMode } from "./ConstraintData.js";
|
||||
import { IkConstraint } from "./IkConstraint.js";
|
||||
import { IkConstraintPose } from "./IkConstraintPose.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
/** Stores the setup pose for an {@link IkConstraint}.
|
||||
*
|
||||
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
|
||||
export declare class IkConstraintData extends ConstraintData<IkConstraint, IkConstraintPose> {
|
||||
/** The bones that are constrained by this IK constraint. */
|
||||
bones: BoneData[];
|
||||
private _target;
|
||||
/** The bone that is the IK target. */
|
||||
set target(boneData: BoneData);
|
||||
get target(): BoneData;
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link IkConstraintPose.compress} or
|
||||
* {@link IkConstraintPose.stretch} set {@link BonePose.scaleX}. */
|
||||
_scaleYMode: ScaleYMode;
|
||||
set scaleYMode(scaleYMode: ScaleYMode);
|
||||
get scaleYMode(): ScaleYMode;
|
||||
constructor(name: string);
|
||||
create(skeleton: Skeleton): IkConstraint;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { ConstraintData, ScaleYMode } from "./ConstraintData.js";
|
||||
import { IkConstraint } from "./IkConstraint.js";
|
||||
import { IkConstraintPose } from "./IkConstraintPose.js";
|
||||
/** Stores the setup pose for an {@link IkConstraint}.
|
||||
*
|
||||
* See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. */
|
||||
export class IkConstraintData extends ConstraintData {
|
||||
/** The bones that are constrained by this IK constraint. */
|
||||
bones = [];
|
||||
_target = null;
|
||||
/** The bone that is the IK target. */
|
||||
set target(boneData) { this._target = boneData; }
|
||||
get target() {
|
||||
if (!this._target)
|
||||
throw new Error("target cannot be null.");
|
||||
return this._target;
|
||||
}
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link IkConstraintPose.compress} or
|
||||
* {@link IkConstraintPose.stretch} set {@link BonePose.scaleX}. */
|
||||
_scaleYMode = ScaleYMode.None;
|
||||
set scaleYMode(scaleYMode) { this._scaleYMode = scaleYMode; }
|
||||
get scaleYMode() {
|
||||
if (this._scaleYMode == null)
|
||||
throw new Error("scaleYMode cannot be null.");
|
||||
return this._scaleYMode;
|
||||
}
|
||||
constructor(name) {
|
||||
super(name, new IkConstraintPose());
|
||||
}
|
||||
create(skeleton) {
|
||||
return new IkConstraint(this, skeleton);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50RGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ja0NvbnN0cmFpbnREYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUkvRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUd6RDs7cUdBRXFHO0FBQ3JHLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxjQUE4QztJQUNuRiw0REFBNEQ7SUFDNUQsS0FBSyxHQUFHLEVBQWdCLENBQUM7SUFFakIsT0FBTyxHQUFvQixJQUFJLENBQUM7SUFDeEMsc0NBQXNDO0lBQ3RDLElBQVcsTUFBTSxDQUFFLFFBQWtCLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ25FLElBQVcsTUFBTTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUE7UUFDNUQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3JCLENBQUM7SUFFRDt3RUFDb0U7SUFDcEUsV0FBVyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUM7SUFDOUIsSUFBVyxVQUFVLENBQUUsVUFBc0IsSUFBSSxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDakYsSUFBVyxVQUFVO1FBQ3BCLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO1FBQzNFLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUN6QixDQUFDO0lBRUQsWUFBYSxJQUFZO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVNLE1BQU0sQ0FBRSxRQUFrQjtRQUNoQyxPQUFPLElBQUksWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN6QyxDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB0eXBlIHsgQm9uZURhdGEgfSBmcm9tIFwiLi9Cb25lRGF0YS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBCb25lUG9zZSB9IGZyb20gXCIuL0JvbmVQb3NlLmpzXCI7XG5pbXBvcnQgeyBDb25zdHJhaW50RGF0YSwgU2NhbGVZTW9kZSB9IGZyb20gXCIuL0NvbnN0cmFpbnREYXRhLmpzXCI7XG5pbXBvcnQgeyBJa0NvbnN0cmFpbnQgfSBmcm9tIFwiLi9Ja0NvbnN0cmFpbnQuanNcIjtcbmltcG9ydCB7IElrQ29uc3RyYWludFBvc2UgfSBmcm9tIFwiLi9Ja0NvbnN0cmFpbnRQb3NlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcblxuLyoqIFN0b3JlcyB0aGUgc2V0dXAgcG9zZSBmb3IgYW4ge0BsaW5rIElrQ29uc3RyYWludH0uXG4gKlxuICogU2VlIFtJSyBjb25zdHJhaW50c10oaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWlrLWNvbnN0cmFpbnRzKSBpbiB0aGUgU3BpbmUgVXNlciBHdWlkZS4gKi9cbmV4cG9ydCBjbGFzcyBJa0NvbnN0cmFpbnREYXRhIGV4dGVuZHMgQ29uc3RyYWludERhdGE8SWtDb25zdHJhaW50LCBJa0NvbnN0cmFpbnRQb3NlPiB7XG5cdC8qKiBUaGUgYm9uZXMgdGhhdCBhcmUgY29uc3RyYWluZWQgYnkgdGhpcyBJSyBjb25zdHJhaW50LiAqL1xuXHRib25lcyA9IFtdIGFzIEJvbmVEYXRhW107XG5cblx0cHJpdmF0ZSBfdGFyZ2V0OiBCb25lRGF0YSB8IG51bGwgPSBudWxsO1xuXHQvKiogVGhlIGJvbmUgdGhhdCBpcyB0aGUgSUsgdGFyZ2V0LiAqL1xuXHRwdWJsaWMgc2V0IHRhcmdldCAoYm9uZURhdGE6IEJvbmVEYXRhKSB7IHRoaXMuX3RhcmdldCA9IGJvbmVEYXRhOyB9XG5cdHB1YmxpYyBnZXQgdGFyZ2V0ICgpIHtcblx0XHRpZiAoIXRoaXMuX3RhcmdldCkgdGhyb3cgbmV3IEVyc
Line truncated
|
||||
@@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
/** Stores a pose for an IK constraint. */
|
||||
export declare class IkConstraintPose implements Pose<IkConstraintPose> {
|
||||
/** For two bone IK, controls the bend direction of the IK bones, either 1 or -1. */
|
||||
bendDirection: number;
|
||||
/** For one bone IK, when true and the target is too close, the bone is scaled to reach it. */
|
||||
compress: boolean;
|
||||
/** When true and the target is out of range, the parent bone is scaled to reach it.
|
||||
*
|
||||
* For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if {@link softness} is > 0,
|
||||
* and 3) if the parent bone has local nonuniform scale, stretch is not applied. */
|
||||
stretch: boolean;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
|
||||
*
|
||||
* For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. */
|
||||
mix: number;
|
||||
/** For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones
|
||||
* will not straighten completely until the target is this far out of range. */
|
||||
softness: number;
|
||||
set(pose: IkConstraintPose): void;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Stores a pose for an IK constraint. */
|
||||
export class IkConstraintPose {
|
||||
/** For two bone IK, controls the bend direction of the IK bones, either 1 or -1. */
|
||||
bendDirection = 0;
|
||||
/** For one bone IK, when true and the target is too close, the bone is scaled to reach it. */
|
||||
compress = false;
|
||||
/** When true and the target is out of range, the parent bone is scaled to reach it.
|
||||
*
|
||||
* For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if {@link softness} is > 0,
|
||||
* and 3) if the parent bone has local nonuniform scale, stretch is not applied. */
|
||||
stretch = false;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
|
||||
*
|
||||
* For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. */
|
||||
mix = 0;
|
||||
/** For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones
|
||||
* will not straighten completely until the target is this far out of range. */
|
||||
softness = 0;
|
||||
set(pose) {
|
||||
this.mix = pose.mix;
|
||||
this.softness = pose.softness;
|
||||
this.bendDirection = pose.bendDirection;
|
||||
this.compress = pose.compress;
|
||||
this.stretch = pose.stretch;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSWtDb25zdHJhaW50UG9zZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ja0NvbnN0cmFpbnRQb3NlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUkvRSwwQ0FBMEM7QUFDMUMsTUFBTSxPQUFPLGdCQUFnQjtJQUM1QixvRkFBb0Y7SUFDcEYsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUVsQiw4RkFBOEY7SUFDOUYsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUVqQjs7O3VGQUdtRjtJQUNuRixPQUFPLEdBQUcsS0FBSyxDQUFDO0lBRWhCOzsySEFFdUg7SUFDdkgsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUVSO21GQUMrRTtJQUMvRSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBRU4sR0FBRyxDQUFFLElBQXNCO1FBQ2pDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDN0IsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgdHlwZSB7IFBvc2UgfSBmcm9tIFwiLi9Qb3NlLmpzXCI7XG5cbi8qKiBTdG9yZXMgYSBwb3NlIGZvciBhbiBJSyBjb25zdHJhaW50LiAqL1xuZXhwb3J0IGNsYXNzIElrQ29uc3RyYWludFBvc2UgaW1wbGVtZW50cyBQb3NlPElrQ29uc3RyYWludFBvc2U+IHtcblx0LyoqIEZvciB0d28gYm9uZSBJSywgY29udHJvbHMgdGhlIGJlbmQgZGlyZWN0aW9uIG9mIHRoZSBJSyBib25lcywgZWl0aGVyIDEgb3IgLTEuICovXG5cdGJlbmREaXJlY3Rpb24gPSAwO1xuXG5cdC8qKiBGb3Igb25lIGJvbmUgSUssIHdoZW4gdHJ1ZSBhbmQgdGhlIHRhcmdldCBpcyB0b28gY2xvc2UsIHRoZSBib25lIGlzIHNjYWxlZCB0byByZWFjaCBpdC4gKi9cblx0Y29tcHJlc3MgPSBmYWxzZTtcblxuXHQvKiogV2hlbiB0cnVlIGFuZCB0aGUgdGFyZ2V0IGlzIG91dCBvZiByYW5nZSwgdGhlIHBhcmVudCBib25lIGlzIHNjYWxlZCB0byByZWFjaCBpdC5cblx0ICpcblx0ICogRm9yIHR3byBib25lIElLOiAxKSB0aGUgY2hpbGQgYm9uZSdzIGxvY2FsIFkgdHJhbnNsYXRpb24gaXMgc2V0IHRvIDAsIDIpIHN0cmV0Y2ggaXMgbm90IGFwcGxpZWQgaWYge0BsaW5rIHNvZnRuZXNzfSBpcyA+IDAsXG5cdCAqIGFuZCAzKSBpZiB0aGUgcGFyZW50IGJvbmUgaGFzIGxvY2FsIG5vbnVuaWZvcm0gc2NhbGUsIHN0cmV0Y2ggaXMgbm90IGFwcGxpZWQuICovXG5cdHN0cmV0Y2ggPSBmYWxzZTtcblxuXHQvKiogQSBwZXJjZW50YWdlICgwLTEpIHRoYXQgY29udHJvbHMgdGhlIG1peCBiZXR3ZWVuIHRoZSBjb25zdHJhaW5lZCBhbmQgdW5jb25zdHJhaW5lZCByb3RhdGlvbi5cblx0ICpcblx0ICogRm9yIHR3byBib25lIElLOiBpZiB0aGUgcGFyZW50IGJvbmUgaGFzIGxvY2FsIG5vbnVuaWZvcm0gc2NhbGUsIHRoZSBjaGlsZCBib25lJ3MgbG9jYWwgWSB0cmFuc2xhdGlvbiBpcyBzZXQgdG8gMC4gKi9cblx0bWl4ID0gMDtcblxuXHQvKiogRm9yIHR3byBib25lIElLLCB0aGUgdGFyZ2V0IGJvbmUncyBkaXN0YW5jZSBmcm9tIHRoZSBtYXhpbXVtIHJlYWNoIG9mIHRoZSBib25lcyB3aGVyZSByb3RhdGlvbiBiZWdpbnMgdG8gc2xvdy4gVGhlIGJvbmVzXG5cdCAqIHdpbGwgbm90IHN0cmFpZ2h0ZW4gY29tcGxldGVseSB1bnRpbCB0aGUgdGFyZ2V0IGlzIHRoaXMgZmFyIG91dCBvZiByYW5nZS4gKi9cblx0c29mdG5lc3MgPSAwO1xuXG5cdHB1YmxpYyBzZXQgKHBvc2U6IElrQ29uc3RyYWludFBvc2UpIHtcblx0XHR0aGlzLm1peCA9IHBvc2UubWl4O1xuXHRcdHRoaXMuc29mdG5lc3MgPSBwb3NlLnNvZnRuZXNzO
Line truncated
|
||||
@@ -0,0 +1,67 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { PathAttachment } from "./attachments/PathAttachment.js";
|
||||
import type { BonePose } from "./BonePose.js";
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { type PathConstraintData } from "./PathConstraintData.js";
|
||||
import { PathConstraintPose } from "./PathConstraintPose.js";
|
||||
import type { Physics } from "./Physics.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { Slot } from "./Slot.js";
|
||||
/** Adjusts the rotation, translation, and scale of the constrained bones so they follow a {@link PathAttachment}.
|
||||
*
|
||||
* See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */
|
||||
export declare class PathConstraint extends Constraint<PathConstraint, PathConstraintData, PathConstraintPose> {
|
||||
static NONE: number;
|
||||
static BEFORE: number;
|
||||
static AFTER: number;
|
||||
/** The path constraint's setup pose data. */
|
||||
data: PathConstraintData;
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
bones: Array<BonePose>;
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
slot: Slot;
|
||||
spaces: number[];
|
||||
positions: number[];
|
||||
world: number[];
|
||||
curves: number[];
|
||||
lengths: number[];
|
||||
segments: number[];
|
||||
constructor(data: PathConstraintData, skeleton: Skeleton);
|
||||
copy(skeleton: Skeleton): PathConstraint;
|
||||
update(skeleton: Skeleton, physics: Physics): void;
|
||||
computeWorldPositions(skeleton: Skeleton, path: PathAttachment, spacesCount: number, tangents: boolean): number[];
|
||||
addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
|
||||
addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
|
||||
addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: Array<number>, o: number, tangents: boolean): void;
|
||||
sort(skeleton: Skeleton): void;
|
||||
private sortPathSlot;
|
||||
private sortPath;
|
||||
isSourceActive(): boolean;
|
||||
}
|
||||
+509
@@ -0,0 +1,509 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { PathAttachment } from "./attachments/PathAttachment.js";
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { PositionMode, RotateMode, SpacingMode } from "./PathConstraintData.js";
|
||||
import { PathConstraintPose } from "./PathConstraintPose.js";
|
||||
import { MathUtils, Utils } from "./Utils.js";
|
||||
/** Adjusts the rotation, translation, and scale of the constrained bones so they follow a {@link PathAttachment}.
|
||||
*
|
||||
* See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */
|
||||
export class PathConstraint extends Constraint {
|
||||
static NONE = -1;
|
||||
static BEFORE = -2;
|
||||
static AFTER = -3;
|
||||
/** The path constraint's setup pose data. */
|
||||
data;
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
bones;
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
slot;
|
||||
spaces = [];
|
||||
positions = [];
|
||||
world = [];
|
||||
curves = [];
|
||||
lengths = [];
|
||||
segments = [];
|
||||
constructor(data, skeleton) {
|
||||
super(data, new PathConstraintPose(), new PathConstraintPose());
|
||||
if (!skeleton)
|
||||
throw new Error("skeleton cannot be null.");
|
||||
this.data = data;
|
||||
this.bones = [];
|
||||
for (const boneData of this.data.bones)
|
||||
this.bones.push(skeleton.bones[boneData.index].constrainedPose);
|
||||
this.slot = skeleton.slots[data.slot.index];
|
||||
}
|
||||
copy(skeleton) {
|
||||
var copy = new PathConstraint(this.data, skeleton);
|
||||
copy.pose.set(this.pose);
|
||||
return copy;
|
||||
}
|
||||
update(skeleton, physics) {
|
||||
const attachment = this.slot.appliedPose.attachment;
|
||||
if (!(attachment instanceof PathAttachment))
|
||||
return;
|
||||
const p = this.appliedPose;
|
||||
const mixRotate = p.mixRotate, mixX = p.mixX, mixY = p.mixY;
|
||||
if (mixRotate === 0 && mixX === 0 && mixY === 0)
|
||||
return;
|
||||
const data = this.data;
|
||||
const tangents = data.rotateMode === RotateMode.Tangent, scale = data.rotateMode === RotateMode.ChainScale;
|
||||
const bones = this.bones;
|
||||
const boneCount = bones.length, spacesCount = tangents ? boneCount : boneCount + 1;
|
||||
const spaces = Utils.setArraySize(this.spaces, spacesCount), lengths = scale ? this.lengths = Utils.setArraySize(this.lengths, boneCount) : [];
|
||||
const spacing = p.spacing;
|
||||
switch (data.spacingMode) {
|
||||
case SpacingMode.Percent:
|
||||
if (scale) {
|
||||
for (let i = 0, n = spacesCount - 1; i < n; i++) {
|
||||
const bone = bones[i];
|
||||
const setupLength = bone.bone.data.length;
|
||||
const x = setupLength * bone.a, y = setupLength * bone.c;
|
||||
lengths[i] = Math.sqrt(x * x + y * y);
|
||||
}
|
||||
}
|
||||
Utils.arrayFill(spaces, 1, spacesCount, spacing);
|
||||
break;
|
||||
case SpacingMode.Proportional: {
|
||||
let sum = 0;
|
||||
for (let i = 0, n = spacesCount - 1; i < n;) {
|
||||
const bone = bones[i];
|
||||
const setupLength = bone.bone.data.length;
|
||||
if (setupLength < MathUtils.epsilon) {
|
||||
if (scale)
|
||||
lengths[i] = 0;
|
||||
spaces[++i] = spacing;
|
||||
}
|
||||
else {
|
||||
const x = setupLength * bone.a, y = setupLength * bone.c;
|
||||
const length = Math.sqrt(x * x + y * y);
|
||||
if (scale)
|
||||
lengths[i] = length;
|
||||
spaces[++i] = length;
|
||||
sum += length;
|
||||
}
|
||||
}
|
||||
if (sum > 0) {
|
||||
sum = spacesCount / sum * spacing;
|
||||
for (let i = 1; i < spacesCount; i++)
|
||||
spaces[i] *= sum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const lengthSpacing = data.spacingMode === SpacingMode.Length;
|
||||
for (let i = 0, n = spacesCount - 1; i < n;) {
|
||||
const bone = bones[i];
|
||||
const setupLength = bone.bone.data.length;
|
||||
if (setupLength < MathUtils.epsilon) {
|
||||
if (scale)
|
||||
lengths[i] = 0;
|
||||
spaces[++i] = spacing;
|
||||
}
|
||||
else {
|
||||
const x = setupLength * bone.a, y = setupLength * bone.c;
|
||||
const length = Math.sqrt(x * x + y * y);
|
||||
if (scale)
|
||||
lengths[i] = length;
|
||||
spaces[++i] = (lengthSpacing ? Math.max(0, setupLength + spacing) : spacing) * length / setupLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const positions = this.computeWorldPositions(skeleton, attachment, spacesCount, tangents);
|
||||
let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
|
||||
let tip = false;
|
||||
if (offsetRotation === 0)
|
||||
tip = data.rotateMode === RotateMode.Chain;
|
||||
else {
|
||||
tip = false;
|
||||
const bone = this.slot.bone.appliedPose;
|
||||
offsetRotation *= bone.a * bone.d - bone.b * bone.c > 0 ? MathUtils.degRad : -MathUtils.degRad;
|
||||
}
|
||||
for (let i = 0, ip = 3; i < boneCount; i++, ip += 3) {
|
||||
const bone = bones[i];
|
||||
bone.modifyWorld(skeleton);
|
||||
bone.worldX += (boneX - bone.worldX) * mixX;
|
||||
bone.worldY += (boneY - bone.worldY) * mixY;
|
||||
const x = positions[ip], y = positions[ip + 1], dx = x - boneX, dy = y - boneY;
|
||||
if (scale) {
|
||||
const length = lengths[i];
|
||||
if (length !== 0) {
|
||||
const s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
}
|
||||
}
|
||||
boneX = x;
|
||||
boneY = y;
|
||||
if (mixRotate > 0) {
|
||||
let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0;
|
||||
if (tangents)
|
||||
r = positions[ip - 1];
|
||||
else if (spaces[i + 1] === 0)
|
||||
r = positions[ip + 2];
|
||||
else
|
||||
r = Math.atan2(dy, dx);
|
||||
r -= Math.atan2(c, a);
|
||||
if (tip) {
|
||||
cos = Math.cos(r);
|
||||
sin = Math.sin(r);
|
||||
const length = bone.bone.data.length;
|
||||
boneX += (length * (cos * a - sin * c) - dx) * mixRotate;
|
||||
boneY += (length * (sin * a + cos * c) - dy) * mixRotate;
|
||||
}
|
||||
else {
|
||||
r += offsetRotation;
|
||||
}
|
||||
if (r > MathUtils.PI)
|
||||
r -= MathUtils.PI2;
|
||||
else if (r < -MathUtils.PI) //
|
||||
r += MathUtils.PI2;
|
||||
r *= mixRotate;
|
||||
cos = Math.cos(r);
|
||||
sin = Math.sin(r);
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
bone.c = sin * a + cos * c;
|
||||
bone.d = sin * b + cos * d;
|
||||
}
|
||||
}
|
||||
}
|
||||
computeWorldPositions(skeleton, path, spacesCount, tangents) {
|
||||
const slot = this.slot;
|
||||
let position = this.appliedPose.position;
|
||||
let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = this.world;
|
||||
const closed = path.closed;
|
||||
let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE;
|
||||
if (!path.constantSpeed) {
|
||||
const lengths = path.lengths;
|
||||
curveCount -= closed ? 1 : 2;
|
||||
const pathLength = lengths[curveCount];
|
||||
if (this.data.positionMode === PositionMode.Percent)
|
||||
position *= pathLength;
|
||||
let multiplier;
|
||||
switch (this.data.spacingMode) {
|
||||
case SpacingMode.Percent:
|
||||
multiplier = pathLength;
|
||||
break;
|
||||
case SpacingMode.Proportional:
|
||||
multiplier = pathLength / spacesCount;
|
||||
break;
|
||||
default: multiplier = 1;
|
||||
}
|
||||
world = Utils.setArraySize(this.world, 8);
|
||||
for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) {
|
||||
const space = spaces[i] * multiplier;
|
||||
position += space;
|
||||
let p = position;
|
||||
if (closed) {
|
||||
p %= pathLength;
|
||||
if (p < 0)
|
||||
p += pathLength;
|
||||
curve = 0;
|
||||
}
|
||||
else if (p < 0) {
|
||||
if (prevCurve !== PathConstraint.BEFORE) {
|
||||
prevCurve = PathConstraint.BEFORE;
|
||||
path.computeWorldVertices(skeleton, slot, 2, 4, world, 0, 2);
|
||||
}
|
||||
this.addBeforePosition(p, world, 0, out, o);
|
||||
continue;
|
||||
}
|
||||
else if (p > pathLength) {
|
||||
if (prevCurve !== PathConstraint.AFTER) {
|
||||
prevCurve = PathConstraint.AFTER;
|
||||
path.computeWorldVertices(skeleton, slot, verticesLength - 6, 4, world, 0, 2);
|
||||
}
|
||||
this.addAfterPosition(p - pathLength, world, 0, out, o);
|
||||
continue;
|
||||
}
|
||||
// Determine curve containing position.
|
||||
for (;; curve++) {
|
||||
const length = lengths[curve];
|
||||
if (p > length)
|
||||
continue;
|
||||
if (curve === 0)
|
||||
p /= length;
|
||||
else {
|
||||
const prev = lengths[curve - 1];
|
||||
p = (p - prev) / (length - prev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (curve !== prevCurve) {
|
||||
prevCurve = curve;
|
||||
if (closed && curve === curveCount) {
|
||||
path.computeWorldVertices(skeleton, slot, verticesLength - 4, 4, world, 0, 2);
|
||||
path.computeWorldVertices(skeleton, slot, 0, 4, world, 4, 2);
|
||||
}
|
||||
else
|
||||
path.computeWorldVertices(skeleton, slot, curve * 6 + 2, 8, world, 0, 2);
|
||||
}
|
||||
this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space === 0));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
// World vertices.
|
||||
if (closed) {
|
||||
verticesLength += 2;
|
||||
world = Utils.setArraySize(this.world, verticesLength);
|
||||
path.computeWorldVertices(skeleton, slot, 2, verticesLength - 4, world, 0, 2);
|
||||
path.computeWorldVertices(skeleton, slot, 0, 2, world, verticesLength - 4, 2);
|
||||
world[verticesLength - 2] = world[0];
|
||||
world[verticesLength - 1] = world[1];
|
||||
}
|
||||
else {
|
||||
curveCount--;
|
||||
verticesLength -= 4;
|
||||
world = Utils.setArraySize(this.world, verticesLength);
|
||||
path.computeWorldVertices(skeleton, slot, 2, verticesLength, world, 0, 2);
|
||||
}
|
||||
// Curve lengths.
|
||||
const curves = Utils.setArraySize(this.curves, curveCount);
|
||||
let pathLength = 0;
|
||||
let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
|
||||
let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0;
|
||||
for (let i = 0, w = 2; i < curveCount; i++, w += 6) {
|
||||
cx1 = world[w];
|
||||
cy1 = world[w + 1];
|
||||
cx2 = world[w + 2];
|
||||
cy2 = world[w + 3];
|
||||
x2 = world[w + 4];
|
||||
y2 = world[w + 5];
|
||||
tmpx = (x1 - cx1 * 2 + cx2) * 0.1875;
|
||||
tmpy = (y1 - cy1 * 2 + cy2) * 0.1875;
|
||||
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;
|
||||
dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;
|
||||
ddfx = tmpx * 2 + dddfx;
|
||||
ddfy = tmpy * 2 + dddfy;
|
||||
dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667;
|
||||
dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667;
|
||||
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx + dddfx;
|
||||
dfy += ddfy + dddfy;
|
||||
pathLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
curves[i] = pathLength;
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
if (this.data.positionMode === PositionMode.Percent)
|
||||
position *= pathLength;
|
||||
let multiplier;
|
||||
switch (this.data.spacingMode) {
|
||||
case SpacingMode.Percent:
|
||||
multiplier = pathLength;
|
||||
break;
|
||||
case SpacingMode.Proportional:
|
||||
multiplier = pathLength / spacesCount;
|
||||
break;
|
||||
default: multiplier = 1;
|
||||
}
|
||||
const segments = this.segments;
|
||||
let curveLength = 0;
|
||||
for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) {
|
||||
const space = spaces[i] * multiplier;
|
||||
position += space;
|
||||
let p = position;
|
||||
if (closed) {
|
||||
p %= pathLength;
|
||||
if (p < 0)
|
||||
p += pathLength;
|
||||
curve = 0;
|
||||
segment = 0;
|
||||
}
|
||||
else if (p < 0) {
|
||||
this.addBeforePosition(p, world, 0, out, o);
|
||||
continue;
|
||||
}
|
||||
else if (p > pathLength) {
|
||||
this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o);
|
||||
continue;
|
||||
}
|
||||
// Determine curve containing position.
|
||||
for (;; curve++) {
|
||||
const length = curves[curve];
|
||||
if (p > length)
|
||||
continue;
|
||||
if (curve === 0)
|
||||
p /= length;
|
||||
else {
|
||||
const prev = curves[curve - 1];
|
||||
p = (p - prev) / (length - prev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Curve segment lengths.
|
||||
if (curve !== prevCurve) {
|
||||
prevCurve = curve;
|
||||
let ii = curve * 6;
|
||||
x1 = world[ii];
|
||||
y1 = world[ii + 1];
|
||||
cx1 = world[ii + 2];
|
||||
cy1 = world[ii + 3];
|
||||
cx2 = world[ii + 4];
|
||||
cy2 = world[ii + 5];
|
||||
x2 = world[ii + 6];
|
||||
y2 = world[ii + 7];
|
||||
tmpx = (x1 - cx1 * 2 + cx2) * 0.03;
|
||||
tmpy = (y1 - cy1 * 2 + cy2) * 0.03;
|
||||
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;
|
||||
dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;
|
||||
ddfx = tmpx * 2 + dddfx;
|
||||
ddfy = tmpy * 2 + dddfy;
|
||||
dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667;
|
||||
dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667;
|
||||
curveLength = Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[0] = curveLength;
|
||||
for (ii = 1; ii < 8; ii++) {
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[ii] = curveLength;
|
||||
}
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[8] = curveLength;
|
||||
dfx += ddfx + dddfx;
|
||||
dfy += ddfy + dddfy;
|
||||
curveLength += Math.sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[9] = curveLength;
|
||||
segment = 0;
|
||||
}
|
||||
// Weight by segment length.
|
||||
p *= curveLength;
|
||||
for (;; segment++) {
|
||||
const length = segments[segment];
|
||||
if (p > length)
|
||||
continue;
|
||||
if (segment === 0)
|
||||
p /= length;
|
||||
else {
|
||||
const prev = segments[segment - 1];
|
||||
p = segment + (p - prev) / (length - prev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space === 0));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
addBeforePosition(p, temp, i, out, o) {
|
||||
const x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);
|
||||
out[o] = x1 + p * Math.cos(r);
|
||||
out[o + 1] = y1 + p * Math.sin(r);
|
||||
out[o + 2] = r;
|
||||
}
|
||||
addAfterPosition(p, temp, i, out, o) {
|
||||
const x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);
|
||||
out[o] = x1 + p * Math.cos(r);
|
||||
out[o + 1] = y1 + p * Math.sin(r);
|
||||
out[o + 2] = r;
|
||||
}
|
||||
addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) {
|
||||
if (p === 0 || Number.isNaN(p)) {
|
||||
out[o] = x1;
|
||||
out[o + 1] = y1;
|
||||
out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);
|
||||
return;
|
||||
}
|
||||
const tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u;
|
||||
const ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p;
|
||||
const x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
|
||||
out[o] = x;
|
||||
out[o + 1] = y;
|
||||
if (tangents) {
|
||||
if (p < 0.001)
|
||||
out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);
|
||||
else
|
||||
out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||
}
|
||||
}
|
||||
sort(skeleton) {
|
||||
const slotIndex = this.slot.data.index;
|
||||
const slotBone = this.slot.bone;
|
||||
if (skeleton.skin != null)
|
||||
this.sortPathSlot(skeleton, skeleton.skin, slotIndex, slotBone);
|
||||
if (skeleton.data.defaultSkin != null && skeleton.data.defaultSkin !== skeleton.skin)
|
||||
this.sortPathSlot(skeleton, skeleton.data.defaultSkin, slotIndex, slotBone);
|
||||
this.sortPath(skeleton, this.slot.pose.attachment, slotBone);
|
||||
const bones = this.bones;
|
||||
const boneCount = this.bones.length;
|
||||
for (let i = 0; i < boneCount; i++) {
|
||||
const bone = bones[i].bone;
|
||||
skeleton.sortBone(bone);
|
||||
skeleton.constrained(bone);
|
||||
}
|
||||
skeleton._updateCache.push(this);
|
||||
for (let i = 0; i < boneCount; i++)
|
||||
skeleton.sortReset(bones[i].bone.children);
|
||||
for (let i = 0; i < boneCount; i++)
|
||||
bones[i].bone.sorted = true;
|
||||
}
|
||||
sortPathSlot(skeleton, skin, slotIndex, slotBone) {
|
||||
const entries = skin.getAttachments();
|
||||
for (let i = 0, n = entries.length; i < n; i++) {
|
||||
const entry = entries[i];
|
||||
if (entry.slotIndex === slotIndex)
|
||||
this.sortPath(skeleton, entry.attachment, slotBone);
|
||||
}
|
||||
}
|
||||
sortPath(skeleton, attachment, slotBone) {
|
||||
if (!(attachment instanceof PathAttachment))
|
||||
return;
|
||||
const pathBones = attachment.bones;
|
||||
if (pathBones == null)
|
||||
skeleton.sortBone(slotBone);
|
||||
else {
|
||||
const bones = skeleton.bones;
|
||||
for (let i = 0, n = pathBones.length; i < n;) {
|
||||
let nn = pathBones[i++];
|
||||
nn += i;
|
||||
while (i < nn)
|
||||
skeleton.sortBone(bones[pathBones[i++]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
isSourceActive() {
|
||||
return this.slot.bone.active;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aENvbnN0cmFpbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUGF0aENvbnN0cmFpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUdqRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUEyQixZQUFZLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBSzdELE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRzlDOzt5R0FFeUc7QUFDekcsTUFBTSxPQUFPLGNBQWUsU0FBUSxVQUFrRTtJQUNyRyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFeEQsNkNBQTZDO0lBQzdDLElBQUksQ0FBcUI7SUFFekIsK0RBQStEO0lBQy9ELEtBQUssQ0FBa0I7SUFFdkIsNEVBQTRFO0lBQzVFLElBQUksQ0FBTztJQUVYLE1BQU0sR0FBRyxFQUFjLENBQUM7SUFBQyxTQUFTLEdBQUcsRUFBYyxDQUFDO0lBQ3BELEtBQUssR0FBRyxFQUFjLENBQUM7SUFBQyxNQUFNLEdBQUcsRUFBYyxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQWMsQ0FBQztJQUMxRSxRQUFRLEdBQUcsRUFBYyxDQUFDO0lBRTFCLFlBQWEsSUFBd0IsRUFBRSxRQUFrQjtRQUN4RCxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksa0JBQWtCLEVBQUUsRUFBRSxJQUFJLGtCQUFrQixF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
Line truncated
|
||||
@@ -0,0 +1,79 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { BoneData } from "./BoneData.js";
|
||||
import { ConstraintData } from "./ConstraintData.js";
|
||||
import { PathConstraint } from "./PathConstraint.js";
|
||||
import { PathConstraintPose } from "./PathConstraintPose.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { SlotData } from "./SlotData.js";
|
||||
/** Stores the setup pose for a {@link PathConstraint}.
|
||||
*
|
||||
* See [path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */
|
||||
export declare class PathConstraintData extends ConstraintData<PathConstraint, PathConstraintPose> {
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
bones: BoneData[];
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
set slot(slotData: SlotData);
|
||||
get slot(): SlotData;
|
||||
private _slot;
|
||||
/** The mode for positioning the first bone on the path. */
|
||||
positionMode: PositionMode;
|
||||
/** The mode for positioning the bones after the first bone on the path. */
|
||||
spacingMode: SpacingMode;
|
||||
/** The mode for adjusting the rotation of the bones. */
|
||||
rotateMode: RotateMode;
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
offsetRotation: number;
|
||||
constructor(name: string);
|
||||
create(skeleton: Skeleton): PathConstraint;
|
||||
}
|
||||
/** Controls how the first bone is positioned along the path.
|
||||
*
|
||||
* See [position](http://esotericsoftware.com/spine-path-constraints#Position) in the Spine User Guide. */
|
||||
export declare enum PositionMode {
|
||||
Fixed = 0,
|
||||
Percent = 1
|
||||
}
|
||||
/** Controls how bones after the first bone are positioned along the path.
|
||||
*
|
||||
* See [spacing](http://esotericsoftware.com/spine-path-constraints#Spacing) in the Spine User Guide. */
|
||||
export declare enum SpacingMode {
|
||||
Length = 0,
|
||||
Fixed = 1,
|
||||
Percent = 2,
|
||||
Proportional = 3
|
||||
}
|
||||
/** Controls how bones are rotated, translated, and scaled to match the path.
|
||||
*
|
||||
* See [rotate mix](http://esotericsoftware.com/spine-path-constraints#Rotate-Mix) in the Spine User Guide. */
|
||||
export declare enum RotateMode {
|
||||
Tangent = 0,
|
||||
Chain = 1,
|
||||
ChainScale = 2
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { ConstraintData } from "./ConstraintData.js";
|
||||
import { PathConstraint } from "./PathConstraint.js";
|
||||
import { PathConstraintPose } from "./PathConstraintPose.js";
|
||||
/** Stores the setup pose for a {@link PathConstraint}.
|
||||
*
|
||||
* See [path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. */
|
||||
export class PathConstraintData extends ConstraintData {
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
bones = [];
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
set slot(slotData) { this._slot = slotData; }
|
||||
get slot() {
|
||||
if (!this._slot)
|
||||
throw new Error("SlotData not set.");
|
||||
else
|
||||
return this._slot;
|
||||
}
|
||||
_slot = null;
|
||||
/** The mode for positioning the first bone on the path. */
|
||||
positionMode = PositionMode.Fixed;
|
||||
/** The mode for positioning the bones after the first bone on the path. */
|
||||
spacingMode = SpacingMode.Fixed;
|
||||
/** The mode for adjusting the rotation of the bones. */
|
||||
rotateMode = RotateMode.Chain;
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
offsetRotation = 0;
|
||||
constructor(name) {
|
||||
super(name, new PathConstraintPose());
|
||||
}
|
||||
create(skeleton) {
|
||||
return new PathConstraint(this, skeleton);
|
||||
}
|
||||
}
|
||||
/** Controls how the first bone is positioned along the path.
|
||||
*
|
||||
* See [position](http://esotericsoftware.com/spine-path-constraints#Position) in the Spine User Guide. */
|
||||
export var PositionMode;
|
||||
(function (PositionMode) {
|
||||
PositionMode[PositionMode["Fixed"] = 0] = "Fixed";
|
||||
PositionMode[PositionMode["Percent"] = 1] = "Percent";
|
||||
})(PositionMode || (PositionMode = {}));
|
||||
/** Controls how bones after the first bone are positioned along the path.
|
||||
*
|
||||
* See [spacing](http://esotericsoftware.com/spine-path-constraints#Spacing) in the Spine User Guide. */
|
||||
export var SpacingMode;
|
||||
(function (SpacingMode) {
|
||||
SpacingMode[SpacingMode["Length"] = 0] = "Length";
|
||||
SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed";
|
||||
SpacingMode[SpacingMode["Percent"] = 2] = "Percent";
|
||||
SpacingMode[SpacingMode["Proportional"] = 3] = "Proportional";
|
||||
})(SpacingMode || (SpacingMode = {}));
|
||||
/** Controls how bones are rotated, translated, and scaled to match the path.
|
||||
*
|
||||
* See [rotate mix](http://esotericsoftware.com/spine-path-constraints#Rotate-Mix) in the Spine User Guide. */
|
||||
export var RotateMode;
|
||||
(function (RotateMode) {
|
||||
RotateMode[RotateMode["Tangent"] = 0] = "Tangent";
|
||||
RotateMode[RotateMode["Chain"] = 1] = "Chain";
|
||||
RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale";
|
||||
})(RotateMode || (RotateMode = {}));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aENvbnN0cmFpbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BhdGhDb25zdHJhaW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUs3RDs7eUdBRXlHO0FBQ3pHLE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxjQUFrRDtJQUN6RiwrREFBK0Q7SUFDL0QsS0FBSyxHQUFHLEVBQWdCLENBQUM7SUFFekIsNEVBQTRFO0lBQzVFLElBQVcsSUFBSSxDQUFFLFFBQWtCLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQy9ELElBQVcsSUFBSTtRQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTs7WUFDaEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFDTyxLQUFLLEdBQW9CLElBQUksQ0FBQztJQUV0QywyREFBMkQ7SUFDM0QsWUFBWSxHQUFpQixZQUFZLENBQUMsS0FBSyxDQUFDO0lBRWhELDJFQUEyRTtJQUMzRSxXQUFXLEdBQWdCLFdBQVcsQ0FBQyxLQUFLLENBQUM7SUFFN0Msd0RBQXdEO0lBQ3hELFVBQVUsR0FBZSxVQUFVLENBQUMsS0FBSyxDQUFDO0lBRTFDLHdEQUF3RDtJQUN4RCxjQUFjLEdBQVcsQ0FBQyxDQUFDO0lBRTNCLFlBQWEsSUFBWTtRQUN4QixLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFTSxNQUFNLENBQUUsUUFBa0I7UUFDaEMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNEO0FBRUQ7OzBHQUUwRztBQUMxRyxNQUFNLENBQU4sSUFBWSxZQUErQjtBQUEzQyxXQUFZLFlBQVk7SUFBRyxpREFBSyxDQUFBO0lBQUUscURBQU8sQ0FBQTtBQUFDLENBQUMsRUFBL0IsWUFBWSxLQUFaLFlBQVksUUFBbUI7QUFFM0M7O3dHQUV3RztBQUN4RyxNQUFNLENBQU4sSUFBWSxXQUFvRDtBQUFoRSxXQUFZLFdBQVc7SUFBRyxpREFBTSxDQUFBO0lBQUUsK0NBQUssQ0FBQTtJQUFFLG1EQUFPLENBQUE7SUFBRSw2REFBWSxDQUFBO0FBQUMsQ0FBQyxFQUFwRCxXQUFXLEtBQVgsV0FBVyxRQUF5QztBQUVoRTs7OEdBRThHO0FBQzlHLE1BQU0sQ0FBTixJQUFZLFVBQXlDO0FBQXJELFdBQVksVUFBVTtJQUFHLGlEQUFPLENBQUE7SUFBRSw2Q0FBSyxDQUFBO0lBQUUsdURBQVUsQ0FBQTtBQUFDLENBQUMsRUFBekMsVUFBVSxLQUFWLFVBQVUsUUFBK0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB0eXBlIHsgQm9uZURhdGEgfSBmcm9tIFwiLi9Cb25lRGF0YS5qc1wiO1xuaW1wb3J0IHsgQ29uc3RyYWludERhdGEgfSBmcm9tIFwiLi9Db25zdHJhaW50RGF0YS5qc1wiO1xuaW1wb3J0IHsgUGF0aENvbnN0cmFpbnQgfSBmcm9tIFwiLi9QYXRoQ29uc3RyYWludC5qc1wiO1xuaW1wb3J0IHsgUGF0aENvbnN0cmFpbnRQb3NlIH0gZnJvbSBcIi4vUGF0aENvbnN0cmFpbnRQb3NlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcbmltcG9ydCB0eXBlIHsgU2xvdERhdGEgfSBmcm9tIFwiLi9TbG90RGF0YS5qc1wiO1xuXG5cbi8qKiBTdG9yZXMgdGhlIHNldHVwIHBvc2UgZm9yIGEge0BsaW5rIFBhdGhDb25zdHJhaW50fS5cbiAqXG4gKiBTZWUgW3BhdGggY29uc3RyYWludHNdKGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1wYXRoLWNvbnN0cmFpbnRzKSBpbiB0aGUgU3BpbmUgVXNlciBHdWlkZS4gKi9cbmV4cG9ydCBjbGFzcyBQYXRoQ29uc3RyYWludERhdGEgZXh0ZW5kcyBDb25zdHJha
Line truncated
|
||||
@@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
/** Stores a pose for a path constraint. */
|
||||
export declare class PathConstraintPose implements Pose<PathConstraintPose> {
|
||||
/** The position along the path. */
|
||||
position: number;
|
||||
/** The spacing between bones. */
|
||||
spacing: number;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
mixRotate: number;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
mixX: number;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
mixY: number;
|
||||
set(pose: PathConstraintPose): void;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Stores a pose for a path constraint. */
|
||||
export class PathConstraintPose {
|
||||
/** The position along the path. */
|
||||
position = 0;
|
||||
/** The spacing between bones. */
|
||||
spacing = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
mixRotate = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
mixX = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
mixY = 0;
|
||||
set(pose) {
|
||||
this.position = pose.position;
|
||||
this.spacing = pose.spacing;
|
||||
this.mixRotate = pose.mixRotate;
|
||||
this.mixX = pose.mixX;
|
||||
this.mixY = pose.mixY;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0aENvbnN0cmFpbnRQb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BhdGhDb25zdHJhaW50UG9zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFJL0UsMkNBQTJDO0FBQzNDLE1BQU0sT0FBTyxrQkFBa0I7SUFDOUIsbUNBQW1DO0lBQ25DLFFBQVEsR0FBVyxDQUFDLENBQUM7SUFFckIsaUNBQWlDO0lBQ2pDLE9BQU8sR0FBVyxDQUFDLENBQUM7SUFFcEIsbUdBQW1HO0lBQ25HLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFFZCx3R0FBd0c7SUFDeEcsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUVULHdHQUF3RztJQUN4RyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBRUYsR0FBRyxDQUFFLElBQXdCO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDdkIsQ0FBQztDQUVEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgdHlwZSB7IFBvc2UgfSBmcm9tIFwiLi9Qb3NlLmpzXCJcblxuLyoqIFN0b3JlcyBhIHBvc2UgZm9yIGEgcGF0aCBjb25zdHJhaW50LiAqL1xuZXhwb3J0IGNsYXNzIFBhdGhDb25zdHJhaW50UG9zZSBpbXBsZW1lbnRzIFBvc2U8UGF0aENvbnN0cmFpbnRQb3NlPiB7XG5cdC8qKiBUaGUgcG9zaXRpb24gYWxvbmcgdGhlIHBhdGguICovXG5cdHBvc2l0aW9uOiBudW1iZXIgPSAwO1xuXG5cdC8qKiBUaGUgc3BhY2luZyBiZXR3ZWVuIGJvbmVzLiAqL1xuXHRzcGFjaW5nOiBudW1iZXIgPSAwO1xuXG5cdC8qKiBBIHBlcmNlbnRhZ2UgKDAtMSkgdGhhdCBjb250cm9scyB0aGUgbWl4IGJldHdlZW4gdGhlIGNvbnN0cmFpbmVkIGFuZCB1bmNvbnN0cmFpbmVkIHJvdGF0aW9uLiAqL1xuXHRtaXhSb3RhdGUgPSAwO1xuXG5cdC8qKiBBIHBlcmNlbnRhZ2UgKDAtMSkgdGhhdCBjb250cm9scyB0aGUgbWl4IGJldHdlZW4gdGhlIGNvbnN0cmFpbmVkIGFuZCB1bmNvbnN0cmFpbmVkIHRyYW5zbGF0aW9uIFguICovXG5cdG1peFggPSAwO1xuXG5cdC8qKiBBIHBlcmNlbnRhZ2UgKDAtMSkgdGhhdCBjb250cm9scyB0aGUgbWl4IGJldHdlZW4gdGhlIGNvbnN0cmFpbmVkIGFuZCB1bmNvbnN0cmFpbmVkIHRyYW5zbGF0aW9uIFkuICovXG5cdG1peFkgPSAwO1xuXG5cdHB1YmxpYyBzZXQgKHBvc2U6IFBhdGhDb25zdHJhaW50UG9zZSkge1xuXHRcdHRoaXMucG9zaXRpb24gPSBwb3NlLnBvc2l0aW9uO1xuXHRcdHRoaXMuc3BhY2luZyA9IHBvc2Uuc3BhY2luZztcblx0XHR0aGlzLm1peFJvdGF0ZSA9IHBvc2UubWl4Um90YXRlO1xuXHRcdHRoaXMubWl4WCA9IHBvc2UubWl4WDtcblx0XHR0aGlzLm1peFkgPSBwb3NlLm1peFk7XG5cdH1cblxufVxuIl19
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Determines how physics and other non-deterministic updates are applied. */
|
||||
export declare enum Physics {
|
||||
/** Physics are not updated or applied. */
|
||||
none = 0,
|
||||
/** Physics are {@link PhysicsConstraint.reset | reset}. */
|
||||
reset = 1,
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
update = 2,
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
pose = 3
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Determines how physics and other non-deterministic updates are applied. */
|
||||
export var Physics;
|
||||
(function (Physics) {
|
||||
/** Physics are not updated or applied. */
|
||||
Physics[Physics["none"] = 0] = "none";
|
||||
/** Physics are {@link PhysicsConstraint.reset | reset}. */
|
||||
Physics[Physics["reset"] = 1] = "reset";
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
Physics[Physics["update"] = 2] = "update";
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
Physics[Physics["pose"] = 3] = "pose";
|
||||
})(Physics || (Physics = {}));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9QaHlzaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSw4RUFBOEU7QUFDOUUsTUFBTSxDQUFOLElBQVksT0FZWDtBQVpELFdBQVksT0FBTztJQUNsQiwwQ0FBMEM7SUFDMUMscUNBQUksQ0FBQTtJQUVKLDJEQUEyRDtJQUMzRCx1Q0FBSyxDQUFBO0lBRUwsZ0VBQWdFO0lBQ2hFLHlDQUFNLENBQUE7SUFFTixvRUFBb0U7SUFDcEUscUNBQUksQ0FBQTtBQUNMLENBQUMsRUFaVyxPQUFPLEtBQVAsT0FBTyxRQVlsQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBQaHlzaWNzQ29uc3RyYWludCB9IGZyb20gXCIuL1BoeXNpY3NDb25zdHJhaW50LmpzXCI7XG4vKiogRGV0ZXJtaW5lcyBob3cgcGh5c2ljcyBhbmQgb3RoZXIgbm9uLWRldGVybWluaXN0aWMgdXBkYXRlcyBhcmUgYXBwbGllZC4gKi9cbmV4cG9ydCBlbnVtIFBoeXNpY3Mge1xuXHQvKiogUGh5c2ljcyBhcmUgbm90IHVwZGF0ZWQgb3IgYXBwbGllZC4gKi9cblx0bm9uZSxcblxuXHQvKiogUGh5c2ljcyBhcmUge0BsaW5rIFBoeXNpY3NDb25zdHJhaW50LnJlc2V0IHwgcmVzZXR9LiAqL1xuXHRyZXNldCxcblxuXHQvKiogUGh5c2ljcyBhcmUgdXBkYXRlZCBhbmQgdGhlIHBvc2UgZnJvbSBwaHlzaWNzIGlzIGFwcGxpZWQuICovXG5cdHVwZGF0ZSxcblxuXHQvKiogUGh5c2ljcyBhcmUgbm90IHVwZGF0ZWQgYnV0IHRoZSBwb3NlIGZyb20gcGh5c2ljcyBpcyBhcHBsaWVkLiAqL1xuXHRwb3NlXG59XG4iXX0=
|
||||
@@ -0,0 +1,76 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { BonePose } from "./BonePose.js";
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { Physics } from "./Physics.js";
|
||||
import type { PhysicsConstraintData } from "./PhysicsConstraintData.js";
|
||||
import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
|
||||
import { Skeleton } from "./Skeleton.js";
|
||||
/** Applies physics to a bone.
|
||||
*
|
||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
export declare class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsConstraintData, PhysicsConstraintPose> {
|
||||
bone: BonePose;
|
||||
_reset: boolean;
|
||||
ux: number;
|
||||
uy: number;
|
||||
cx: number;
|
||||
cy: number;
|
||||
tx: number;
|
||||
ty: number;
|
||||
xOffset: number;
|
||||
xLag: number;
|
||||
xVelocity: number;
|
||||
yOffset: number;
|
||||
yLag: number;
|
||||
yVelocity: number;
|
||||
rotateOffset: number;
|
||||
rotateLag: number;
|
||||
rotateVelocity: number;
|
||||
scaleOffset: number;
|
||||
scaleLag: number;
|
||||
scaleVelocity: number;
|
||||
remaining: number;
|
||||
lastTime: number;
|
||||
constructor(data: PhysicsConstraintData, skeleton: Skeleton);
|
||||
copy(skeleton: Skeleton): PhysicsConstraint;
|
||||
/** Resets all physics state that was the result of previous movement. Use this after moving a bone to prevent physics from
|
||||
* reacting to the movement. */
|
||||
reset(skeleton: Skeleton): void;
|
||||
/** Translates the physics constraint so the next {@link update} forces are applied as if the bone moved an
|
||||
* additional amount in world space. */
|
||||
translate(x: number, y: number): void;
|
||||
/** Rotates the physics constraint so the next {@link update} forces are applied as if the bone rotated
|
||||
* around the specified point in world space. */
|
||||
rotate(x: number, y: number, degrees: number): void;
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
update(skeleton: Skeleton, physics: Physics): void;
|
||||
sort(skeleton: Skeleton): void;
|
||||
isSourceActive(): boolean;
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Constraint } from "./Constraint.js";
|
||||
import { ScaleYMode } from "./ConstraintData.js";
|
||||
import { Physics } from "./Physics.js";
|
||||
import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
|
||||
import { Skeleton } from "./Skeleton.js";
|
||||
import { MathUtils } from "./Utils.js";
|
||||
/** Applies physics to a bone.
|
||||
*
|
||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
export class PhysicsConstraint extends Constraint {
|
||||
bone;
|
||||
_reset = true;
|
||||
ux = 0;
|
||||
uy = 0;
|
||||
cx = 0;
|
||||
cy = 0;
|
||||
tx = 0;
|
||||
ty = 0;
|
||||
xOffset = 0;
|
||||
xLag = 0;
|
||||
xVelocity = 0;
|
||||
yOffset = 0;
|
||||
yLag = 0;
|
||||
yVelocity = 0;
|
||||
rotateOffset = 0;
|
||||
rotateLag = 0;
|
||||
rotateVelocity = 0;
|
||||
scaleOffset = 0;
|
||||
scaleLag = 0;
|
||||
scaleVelocity = 0;
|
||||
remaining = 0;
|
||||
lastTime = 0;
|
||||
constructor(data, skeleton) {
|
||||
super(data, new PhysicsConstraintPose(), new PhysicsConstraintPose());
|
||||
if (skeleton == null)
|
||||
throw new Error("skeleton cannot be null.");
|
||||
this.bone = skeleton.bones[data.bone.index].constrainedPose;
|
||||
}
|
||||
copy(skeleton) {
|
||||
var copy = new PhysicsConstraint(this.data, skeleton);
|
||||
copy.pose.set(this.pose);
|
||||
return copy;
|
||||
}
|
||||
/** Resets all physics state that was the result of previous movement. Use this after moving a bone to prevent physics from
|
||||
* reacting to the movement. */
|
||||
reset(skeleton) {
|
||||
this.remaining = 0;
|
||||
this.lastTime = skeleton.time;
|
||||
this._reset = true;
|
||||
this.xOffset = 0;
|
||||
this.xLag = 0;
|
||||
this.xVelocity = 0;
|
||||
this.yOffset = 0;
|
||||
this.yLag = 0;
|
||||
this.yVelocity = 0;
|
||||
this.rotateOffset = 0;
|
||||
this.rotateLag = 0;
|
||||
this.rotateVelocity = 0;
|
||||
this.scaleOffset = 0;
|
||||
this.scaleLag = 0;
|
||||
this.scaleVelocity = 0;
|
||||
}
|
||||
/** Translates the physics constraint so the next {@link update} forces are applied as if the bone moved an
|
||||
* additional amount in world space. */
|
||||
translate(x, y) {
|
||||
this.ux -= x;
|
||||
this.uy -= y;
|
||||
this.cx -= x;
|
||||
this.cy -= y;
|
||||
}
|
||||
/** Rotates the physics constraint so the next {@link update} forces are applied as if the bone rotated
|
||||
* around the specified point in world space. */
|
||||
rotate(x, y, degrees) {
|
||||
const r = degrees * MathUtils.degRad, cos = Math.cos(r), sin = Math.sin(r);
|
||||
const dx = this.cx - x, dy = this.cy - y;
|
||||
this.translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy);
|
||||
}
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
update(skeleton, physics) {
|
||||
const p = this.appliedPose;
|
||||
const mix = p.mix;
|
||||
if (mix === 0)
|
||||
return;
|
||||
const x = this.data.x > 0, y = this.data.y > 0, rotateOrShearX = this.data.rotate > 0 || this.data.shearX > 0, scaleX = this.data.scaleX > 0;
|
||||
const bone = this.bone;
|
||||
let l = bone.bone.data.length, t = this.data.step, z = 0;
|
||||
if (physics === Physics.none)
|
||||
return;
|
||||
bone.modifyWorld(skeleton);
|
||||
switch (physics) {
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: fall through expected
|
||||
case Physics.reset:
|
||||
this.reset(skeleton); // Fall through.
|
||||
case Physics.update: {
|
||||
const delta = Math.max(skeleton.time - this.lastTime, 0), aa = this.remaining;
|
||||
this.remaining += delta;
|
||||
this.lastTime = skeleton.time;
|
||||
const bx = bone.worldX, by = bone.worldY;
|
||||
if (this._reset) {
|
||||
this._reset = false;
|
||||
this.ux = bx;
|
||||
this.uy = by;
|
||||
}
|
||||
else {
|
||||
let a = this.remaining, i = p.inertia, f = skeleton.data.referenceScale, d = -1, m = 0, e = 0, qx = this.data.limit * delta, qy = qx * Math.abs(skeleton.scaleY);
|
||||
qx *= Math.abs(skeleton.scaleX);
|
||||
if (x || y) {
|
||||
if (x) {
|
||||
const u = (this.ux - bx) * i;
|
||||
this.xOffset += u > qx ? qx : u < -qx ? -qx : u;
|
||||
this.ux = bx;
|
||||
}
|
||||
if (y) {
|
||||
const u = (this.uy - by) * i;
|
||||
this.yOffset += u > qy ? qy : u < -qy ? -qy : u;
|
||||
this.uy = by;
|
||||
}
|
||||
if (a >= t) {
|
||||
const xs = this.xOffset, ys = this.yOffset;
|
||||
d = p.damping ** (60 * t);
|
||||
m = t * p.massInverse;
|
||||
e = p.strength;
|
||||
const w = f * p.wind, g = f * p.gravity;
|
||||
const ax = (w * skeleton.windX + g * skeleton.gravityX) * skeleton.scaleX;
|
||||
const ay = (w * skeleton.windY + g * skeleton.gravityY) * skeleton.scaleY;
|
||||
do {
|
||||
if (x) {
|
||||
this.xVelocity += (ax - this.xOffset * e) * m;
|
||||
this.xOffset += this.xVelocity * t;
|
||||
this.xVelocity *= d;
|
||||
}
|
||||
if (y) {
|
||||
this.yVelocity -= (ay + this.yOffset * e) * m;
|
||||
this.yOffset += this.yVelocity * t;
|
||||
this.yVelocity *= d;
|
||||
}
|
||||
a -= t;
|
||||
} while (a >= t);
|
||||
this.xLag = this.xOffset - xs;
|
||||
this.yLag = this.yOffset - ys;
|
||||
}
|
||||
z = Math.max(0, 1 - a / t);
|
||||
if (x)
|
||||
bone.worldX += (this.xOffset - this.xLag * z) * mix * this.data.x;
|
||||
if (y)
|
||||
bone.worldY += (this.yOffset - this.yLag * z) * mix * this.data.y;
|
||||
}
|
||||
if (rotateOrShearX || scaleX) {
|
||||
let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0, dx = this.cx - bone.worldX, dy = this.cy - bone.worldY;
|
||||
if (dx > qx)
|
||||
dx = qx;
|
||||
else if (dx < -qx) //
|
||||
dx = -qx;
|
||||
if (dy > qy)
|
||||
dy = qy;
|
||||
else if (dy < -qy) //
|
||||
dy = -qy;
|
||||
a = this.remaining;
|
||||
if (rotateOrShearX) {
|
||||
mr = (this.data.rotate + this.data.shearX) * mix;
|
||||
z = this.rotateLag * Math.max(0, 1 - aa / t);
|
||||
let r = Math.atan2(dy + this.ty, dx + this.tx) - ca - (this.rotateOffset - z) * mr;
|
||||
this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i;
|
||||
r = (this.rotateOffset - z) * mr + ca;
|
||||
c = Math.cos(r);
|
||||
s = Math.sin(r);
|
||||
if (scaleX) {
|
||||
r = l * bone.getWorldScaleX();
|
||||
if (r > 0)
|
||||
this.scaleOffset += (dx * c + dy * s) * i / r;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c = Math.cos(ca);
|
||||
s = Math.sin(ca);
|
||||
const r = l * bone.getWorldScaleX() - this.scaleLag * Math.max(0, 1 - aa / t);
|
||||
if (r > 0)
|
||||
this.scaleOffset += (dx * c + dy * s) * i / r;
|
||||
}
|
||||
if (a >= t) {
|
||||
if (d === -1) {
|
||||
d = p.damping ** (60 * t);
|
||||
m = t * p.massInverse;
|
||||
e = p.strength;
|
||||
}
|
||||
const ax = p.wind * skeleton.windX + p.gravity * skeleton.gravityX;
|
||||
const ay = (p.wind * skeleton.windY + p.gravity * skeleton.gravityY) * Skeleton.yDir;
|
||||
const rs = this.rotateOffset, ss = this.scaleOffset, h = l / f;
|
||||
while (true) {
|
||||
a -= t;
|
||||
if (scaleX) {
|
||||
this.scaleVelocity += (ax * c - ay * s - this.scaleOffset * e) * m;
|
||||
this.scaleOffset += this.scaleVelocity * t;
|
||||
this.scaleVelocity *= d;
|
||||
}
|
||||
if (rotateOrShearX) {
|
||||
this.rotateVelocity -= ((ax * s + ay * c) * h + this.rotateOffset * e) * m;
|
||||
this.rotateOffset += this.rotateVelocity * t;
|
||||
this.rotateVelocity *= d;
|
||||
if (a < t)
|
||||
break;
|
||||
const r = this.rotateOffset * mr + ca;
|
||||
c = Math.cos(r);
|
||||
s = Math.sin(r);
|
||||
}
|
||||
else if (a < t) //
|
||||
break;
|
||||
}
|
||||
this.rotateLag = this.rotateOffset - rs;
|
||||
this.scaleLag = this.scaleOffset - ss;
|
||||
}
|
||||
z = Math.max(0, 1 - a / t);
|
||||
}
|
||||
this.remaining = a;
|
||||
}
|
||||
this.cx = bone.worldX;
|
||||
this.cy = bone.worldY;
|
||||
break;
|
||||
}
|
||||
case Physics.pose:
|
||||
z = Math.max(0, 1 - this.remaining / t);
|
||||
if (x)
|
||||
bone.worldX += (this.xOffset - this.xLag * z) * mix * this.data.x;
|
||||
if (y)
|
||||
bone.worldY += (this.yOffset - this.yLag * z) * mix * this.data.y;
|
||||
}
|
||||
if (rotateOrShearX) {
|
||||
let o = (this.rotateOffset - this.rotateLag * z) * mix, s = 0, c = 0, a = 0;
|
||||
if (this.data.shearX > 0) {
|
||||
let r = 0;
|
||||
if (this.data.rotate > 0) {
|
||||
r = o * this.data.rotate;
|
||||
s = Math.sin(r);
|
||||
c = Math.cos(r);
|
||||
a = bone.b;
|
||||
bone.b = c * a - s * bone.d;
|
||||
bone.d = s * a + c * bone.d;
|
||||
}
|
||||
r += o * this.data.shearX;
|
||||
s = Math.sin(r);
|
||||
c = Math.cos(r);
|
||||
a = bone.a;
|
||||
bone.a = c * a - s * bone.c;
|
||||
bone.c = s * a + c * bone.c;
|
||||
}
|
||||
else {
|
||||
o *= this.data.rotate;
|
||||
s = Math.sin(o);
|
||||
c = Math.cos(o);
|
||||
a = bone.a;
|
||||
bone.a = c * a - s * bone.c;
|
||||
bone.c = s * a + c * bone.c;
|
||||
a = bone.b;
|
||||
bone.b = c * a - s * bone.d;
|
||||
bone.d = s * a + c * bone.d;
|
||||
}
|
||||
}
|
||||
if (scaleX) {
|
||||
let s = 1 + (this.scaleOffset - this.scaleLag * z) * mix * this.data.scaleX;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
switch (this.data.scaleYMode) {
|
||||
case ScaleYMode.Uniform:
|
||||
bone.b *= s;
|
||||
bone.d *= s;
|
||||
break;
|
||||
case ScaleYMode.Volume:
|
||||
s = Math.abs(s);
|
||||
s = s >= 0.7 ? 1 / s : 4 - 3.67347 * s;
|
||||
bone.b *= s;
|
||||
bone.d *= s;
|
||||
}
|
||||
}
|
||||
if (physics !== Physics.pose) {
|
||||
this.tx = l * bone.a;
|
||||
this.ty = l * bone.c;
|
||||
}
|
||||
}
|
||||
sort(skeleton) {
|
||||
const bone = this.bone.bone;
|
||||
skeleton.sortBone(bone);
|
||||
skeleton._updateCache.push(this);
|
||||
skeleton.sortReset(bone.children);
|
||||
skeleton.constrained(bone);
|
||||
}
|
||||
isSourceActive() {
|
||||
return this.bone.bone.active;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljc0NvbnN0cmFpbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUGh5c2ljc0NvbnN0cmFpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV2QyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFHdkM7OzBIQUUwSDtBQUMxSCxNQUFNLE9BQU8saUJBQWtCLFNBQVEsVUFBMkU7SUFDakgsSUFBSSxDQUFXO0lBRWYsTUFBTSxHQUFHLElBQUksQ0FBQztJQUNkLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDUCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1AsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNQLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDUCxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1AsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNQLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ1QsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDWixJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ1QsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLFlBQVksR0FBRyxDQUFDLENBQUM7SUFDakIsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDbkIsV0FBVyxHQUFHLENB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
Line truncated
|
||||
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { BoneData } from "./BoneData.js";
|
||||
import { ConstraintData, ScaleYMode } from "./ConstraintData.js";
|
||||
import { PhysicsConstraint } from "./PhysicsConstraint.js";
|
||||
import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
/** Stores the setup pose for a {@link PhysicsConstraint}.
|
||||
*
|
||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
export declare class PhysicsConstraintData extends ConstraintData<PhysicsConstraint, PhysicsConstraintPose> {
|
||||
/** The bone constrained by this physics constraint. */
|
||||
set bone(boneData: BoneData);
|
||||
get bone(): BoneData;
|
||||
private _bone;
|
||||
/** Physics influence on x translation, 0-1. */
|
||||
x: number;
|
||||
/** Physics influence on y translation, 0-1. */
|
||||
y: number;
|
||||
/** Physics influence on rotation, 0-1. */
|
||||
rotate: number;
|
||||
/** Physics influence on scaleX, 0-1. */
|
||||
scaleX: number;
|
||||
/** Physics influence on shearX, 0-1. */
|
||||
shearX: number;
|
||||
/** Movement greater than the limit will not have a greater affect on physics. */
|
||||
limit: number;
|
||||
/** The time in milliseconds required to advanced the physics simulation one step. */
|
||||
step: number;
|
||||
/** True when this constraint's inertia is controlled by global slider timelines. */
|
||||
inertiaGlobal: boolean;
|
||||
/** True when this constraint's strength is controlled by global slider timelines. */
|
||||
strengthGlobal: boolean;
|
||||
/** True when this constraint's damping is controlled by global slider timelines. */
|
||||
dampingGlobal: boolean;
|
||||
/** True when this constraint's mass is controlled by global slider timelines. */
|
||||
massGlobal: boolean;
|
||||
/** True when this constraint's wind is controlled by global slider timelines. */
|
||||
windGlobal: boolean;
|
||||
/** True when this constraint's gravity is controlled by global slider timelines. */
|
||||
gravityGlobal: boolean;
|
||||
/** True when this constraint's mix is controlled by global slider timelines. */
|
||||
mixGlobal: boolean;
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link BonePose.scaleX} sets
|
||||
* {@link BonePose.scaleX}. */
|
||||
private _scaleYMode;
|
||||
get scaleYMode(): ScaleYMode;
|
||||
set scaleYMode(scaleYMode: ScaleYMode);
|
||||
constructor(name: string);
|
||||
create(skeleton: Skeleton): PhysicsConstraint;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { ConstraintData, ScaleYMode } from "./ConstraintData.js";
|
||||
import { PhysicsConstraint } from "./PhysicsConstraint.js";
|
||||
import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
|
||||
/** Stores the setup pose for a {@link PhysicsConstraint}.
|
||||
*
|
||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
export class PhysicsConstraintData extends ConstraintData {
|
||||
/** The bone constrained by this physics constraint. */
|
||||
set bone(boneData) { this._bone = boneData; }
|
||||
get bone() {
|
||||
if (!this._bone)
|
||||
throw new Error("BoneData not set.");
|
||||
else
|
||||
return this._bone;
|
||||
}
|
||||
_bone = null;
|
||||
/** Physics influence on x translation, 0-1. */
|
||||
x = 0;
|
||||
/** Physics influence on y translation, 0-1. */
|
||||
y = 0;
|
||||
/** Physics influence on rotation, 0-1. */
|
||||
rotate = 0;
|
||||
/** Physics influence on scaleX, 0-1. */
|
||||
scaleX = 0;
|
||||
/** Physics influence on shearX, 0-1. */
|
||||
shearX = 0;
|
||||
/** Movement greater than the limit will not have a greater affect on physics. */
|
||||
limit = 0;
|
||||
/** The time in milliseconds required to advanced the physics simulation one step. */
|
||||
step = 0;
|
||||
/** True when this constraint's inertia is controlled by global slider timelines. */
|
||||
inertiaGlobal = false;
|
||||
/** True when this constraint's strength is controlled by global slider timelines. */
|
||||
strengthGlobal = false;
|
||||
/** True when this constraint's damping is controlled by global slider timelines. */
|
||||
dampingGlobal = false;
|
||||
/** True when this constraint's mass is controlled by global slider timelines. */
|
||||
massGlobal = false;
|
||||
/** True when this constraint's wind is controlled by global slider timelines. */
|
||||
windGlobal = false;
|
||||
/** True when this constraint's gravity is controlled by global slider timelines. */
|
||||
gravityGlobal = false;
|
||||
/** True when this constraint's mix is controlled by global slider timelines. */
|
||||
mixGlobal = false;
|
||||
/** Determines how the {@link BonePose.scaleY} changes when {@link BonePose.scaleX} sets
|
||||
* {@link BonePose.scaleX}. */
|
||||
_scaleYMode = ScaleYMode.None;
|
||||
get scaleYMode() {
|
||||
return this._scaleYMode;
|
||||
}
|
||||
set scaleYMode(scaleYMode) {
|
||||
if (scaleYMode == null)
|
||||
throw new Error("scaleYMode cannot be null.");
|
||||
this._scaleYMode = scaleYMode;
|
||||
}
|
||||
constructor(name) {
|
||||
super(name, new PhysicsConstraintPose());
|
||||
}
|
||||
create(skeleton) {
|
||||
return new PhysicsConstraint(this, skeleton);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljc0NvbnN0cmFpbnREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BoeXNpY3NDb25zdHJhaW50RGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFJL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUluRTs7MEhBRTBIO0FBQzFILE1BQU0sT0FBTyxxQkFBc0IsU0FBUSxjQUF3RDtJQUNsRyx1REFBdUQ7SUFDdkQsSUFBVyxJQUFJLENBQUUsUUFBa0IsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDL0QsSUFBVyxJQUFJO1FBQ2QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBOztZQUNoRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUNPLEtBQUssR0FBb0IsSUFBSSxDQUFDO0lBRXRDLCtDQUErQztJQUMvQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRU4sK0NBQStDO0lBQy9DLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFTiwwQ0FBMEM7SUFDMUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUVYLHdDQUF3QztJQUN4QyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRVgsd0NBQXdDO0lBQ3hDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFWCxpRkFBaUY7SUFDakYsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUVWLHFGQUFxRjtJQUNyRixJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBRVQsb0ZBQW9GO0lBQ3BGLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFFdEIscUZBQXFGO0lBQ3JGLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFdkIsb0ZBQW9GO0lBQ3BGLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFFdEIsaUZBQWlGO0lBQ2pGLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFFbkIsaUZBQWlGO0lBQ2pGLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFFbkIsb0ZBQW9GO0lBQ3BGLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFFdEIsZ0ZBQWdGO0lBQ2hGLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFFbEI7a0NBQzhCO0lBQ3RCLFdBQVcsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO0lBQ3RDLElBQUksVUFBVTtRQUNiLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUN6QixDQUFDO0lBQ0QsSUFBSSxVQUFVLENBQUUsVUFBc0I7UUFDckMsSUFBSSxVQUFVLElBQUksSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQsWUFBYSxJQUFZO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVNLE1BQU0sQ0FBRSxRQUFrQjtRQUNoQyxPQUFPLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzlDLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBCb25lRGF0YSB9IGZyb20gXCIuL0JvbmVEYXRhLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEJvbmVQb3NlIH0gZnJvbSBcIi4vQm9uZVBvc2UuanNcIjtcbmltcG9ydCB7IENvbnN0cmFpbnREYXRhLCBTY2FsZVlNb2RlIH0gZnJvbSBcIi4vQ29uc3RyYWludERhdGEuanNcIjtcbmltcG9ydCB7IFBoeXNpY3NDb25zdHJhaW50IH0gZnJvbSBcIi4vUGh5c2ljc0NvbnN0cmFpbnQuanNcIjtcbmltcG9ydCB7IFBoeXNpY3NDb25zdHJhaW50UG9zZSB9IGZyb20gXCIuL1BoeXNpY3NDb25zdHJhaW50UG9zZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5cblxuLyoqIFN0b3JlcyB0aGUgc2V0dXAgcG9zZSBmb3IgYSB7QGxpbmsgU
Line truncated
|
||||
@@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
/** Stores a pose for a physics constraint. */
|
||||
export declare class PhysicsConstraintPose implements Pose<PhysicsConstraintPose> {
|
||||
/** Controls how much bone movement is converted into physics movement. */
|
||||
inertia: number;
|
||||
/** The amount of force used to return properties to the unconstrained value. */
|
||||
strength: number;
|
||||
/** Reduces the speed of physics movements, with more of a reduction at higher speeds. */
|
||||
damping: number;
|
||||
/** Determines susceptibility to acceleration. */
|
||||
massInverse: number;
|
||||
/** Applies a constant force along the {@link Skeleton.windX}, {@link Skeleton.windY} vector. */
|
||||
wind: number;
|
||||
/** Applies a constant force along the {@link Skeleton.gravityX}, {@link Skeleton.gravityY} vector. */
|
||||
gravity: number;
|
||||
/** A percentage (0+) that controls the mix between the constrained and unconstrained poses. */
|
||||
mix: number;
|
||||
set(pose: PhysicsConstraintPose): void;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** Stores a pose for a physics constraint. */
|
||||
export class PhysicsConstraintPose {
|
||||
/** Controls how much bone movement is converted into physics movement. */
|
||||
inertia = 0;
|
||||
/** The amount of force used to return properties to the unconstrained value. */
|
||||
strength = 0;
|
||||
/** Reduces the speed of physics movements, with more of a reduction at higher speeds. */
|
||||
damping = 0;
|
||||
/** Determines susceptibility to acceleration. */
|
||||
massInverse = 0;
|
||||
/** Applies a constant force along the {@link Skeleton.windX}, {@link Skeleton.windY} vector. */
|
||||
wind = 0;
|
||||
/** Applies a constant force along the {@link Skeleton.gravityX}, {@link Skeleton.gravityY} vector. */
|
||||
gravity = 0;
|
||||
/** A percentage (0+) that controls the mix between the constrained and unconstrained poses. */
|
||||
mix = 0;
|
||||
set(pose) {
|
||||
this.inertia = pose.inertia;
|
||||
this.strength = pose.strength;
|
||||
this.damping = pose.damping;
|
||||
this.massInverse = pose.massInverse;
|
||||
this.wind = pose.wind;
|
||||
this.gravity = pose.gravity;
|
||||
this.mix = pose.mix;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGh5c2ljc0NvbnN0cmFpbnRQb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BoeXNpY3NDb25zdHJhaW50UG9zZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFLL0UsOENBQThDO0FBQzlDLE1BQU0sT0FBTyxxQkFBcUI7SUFFakMsMEVBQTBFO0lBQzFFLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFFWixnRkFBZ0Y7SUFDaEYsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUViLHlGQUF5RjtJQUN6RixPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBRVosaURBQWlEO0lBQ2pELFdBQVcsR0FBRyxDQUFDLENBQUM7SUFFaEIsZ0dBQWdHO0lBQ2hHLElBQUksR0FBRyxDQUFDLENBQUM7SUFFVCxzR0FBc0c7SUFDdEcsT0FBTyxHQUFHLENBQUMsQ0FBQztJQUVaLCtGQUErRjtJQUMvRixHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBRUQsR0FBRyxDQUFFLElBQTJCO1FBQ3RDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNwQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzVCLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNyQixDQUFDO0NBR0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB0eXBlIHsgUG9zZSB9IGZyb20gXCIuL1Bvc2UuanNcIlxuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5cbi8qKiBTdG9yZXMgYSBwb3NlIGZvciBhIHBoeXNpY3MgY29uc3RyYWludC4gKi9cbmV4cG9ydCBjbGFzcyBQaHlzaWNzQ29uc3RyYWludFBvc2UgaW1wbGVtZW50cyBQb3NlPFBoeXNpY3NDb25zdHJhaW50UG9zZT4ge1xuXG5cdC8qKiBDb250cm9scyBob3cgbXVjaCBib25lIG1vdmVtZW50IGlzIGNvbnZlcnRlZCBpbnRvIHBoeXNpY3MgbW92ZW1lbnQuICovXG5cdGluZXJ0aWEgPSAwO1xuXG5cdC8qKiBUaGUgYW1vdW50IG9mIGZvcmNlIHVzZWQgdG8gcmV0dXJuIHByb3BlcnRpZXMgdG8gdGhlIHVuY29uc3RyYWluZWQgdmFsdWUuICovXG5cdHN0cmVuZ3RoID0gMDtcblxuXHQvKiogUmVkdWNlcyB0aGUgc3BlZWQgb2YgcGh5c2ljcyBtb3ZlbWVudHMsIHdpdGggbW9yZSBvZiBhIHJlZHVjdGlvbiBhdCBoaWdoZXIgc3BlZWRzLiAqL1xuXHRkYW1waW5nID0gMDtcblxuXHQvKiogRGV0ZXJtaW5lcyBzdXNjZXB0aWJpbGl0eSB0byBhY2NlbGVyYXRpb24uICovXG5cdG1hc3NJbnZlcnNlID0gMDtcblxuXHQvKiogQXBwbGllcyBhIGNvbnN0YW50IGZvcmNlIGFsb25nIHRoZSB7QGxpbmsgU2tlbGV0b24ud2luZFh9LCB7QGxpbmsgU2tlbGV0b24ud2luZFl9IHZlY3Rvci4gKi9cblx0d2luZCA9IDA7XG5cblx0LyoqIEFwcGxpZXMgYSBjb25zdGFudCBmb3JjZSBhbG9uZyB0aGUge0BsaW5rIFNrZWxldG9uLmdyYXZpdHlYfSwge0BsaW5rIFNrZWxldG9uLmdyYXZpdHlZfSB2ZWN0b3IuICovXG5cdGdyYXZpdHkgPSAwO1xuXG5cdC8qKiBBIHBlcmNlbnRhZ2UgKDArKSB0aGF0IGNvbnRyb2xzIHRoZSBtaXggYmV0d2VlbiB0aGUgY29uc3RyYWluZWQgYW5kIHVuY29uc3RyYWluZWQgcG9zZXMuICovXG5cdG1peCA9IDA7XG5cblx0cHVibGljIHNldCAocG9zZTogUGh5c2ljc0NvbnN0cmFpbnRQb3NlKSB7XG5cdFx0dGhpcy5pbmVydGlhID0gcG9zZS5pbmVydGlhO1xuXHRcdHRoaXMuc3RyZW5ndGggPSBwb3NlLnN0cmVuZ3RoO1xuXHRcdHRoaXMuZGFtcGluZyA9IHBvc2UuZGFtcGluZztcblx0XHR0aGlzLm1hc3NJb
Line truncated
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** An interface for an object representing a pose. */
|
||||
export interface Pose<P> {
|
||||
/** Sets this pose to the specified pose. */
|
||||
set(pose: P): void;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
export {};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9zZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Qb3NlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRSIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqIEFuIGludGVyZmFjZSBmb3IgYW4gb2JqZWN0IHJlcHJlc2VudGluZyBhIHBvc2UuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvc2U8UD4ge1xuXHQvKiogU2V0cyB0aGlzIHBvc2UgdG8gdGhlIHNwZWNpZmllZCBwb3NlLiAqL1xuXHRzZXQgKHBvc2U6IFApOiB2b2lkO1xufVxuIl19
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
import type { PosedData } from "./PosedData.js";
|
||||
/** The base class for an object with a number of poses:
|
||||
* - {@link data}: The setup pose.
|
||||
* - {@link pose}: The unconstrained pose. Set by animations and application code.
|
||||
* - {@link appliedPose}: The pose to use for rendering. Possibly modified by constraints.
|
||||
*/
|
||||
export declare abstract class Posed<D extends PosedData<P>, P extends Pose<P>> {
|
||||
/** The constraint's setup pose data. */
|
||||
readonly data: D;
|
||||
readonly pose: P;
|
||||
readonly constrainedPose: P;
|
||||
appliedPose: P;
|
||||
constructor(data: D, pose: P, constrainedPose: P);
|
||||
/** Sets the unconstrained pose to the setup pose. */
|
||||
setupPose(): void;
|
||||
/** The setup pose data. May be shared with multiple instances. */
|
||||
getData(): D;
|
||||
/** The unconstrained pose for this object, set by animations and application code. */
|
||||
getPose(): P;
|
||||
/** The pose to use for rendering. If no constraints modify this pose, this is the same as {@link pose}. Otherwise it is a
|
||||
* copy of {@link pose} modified by constraints. */
|
||||
getAppliedPose(): P;
|
||||
/** Sets the applied pose to the unconstrained pose, for when no constraints will modify the pose. */
|
||||
unconstrained(): void;
|
||||
/** Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints. */
|
||||
constrained(): void;
|
||||
/** Sets the constrained pose to the unconstrained pose, as a starting point for constraints to be applied. */
|
||||
resetConstrained(): void;
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** The base class for an object with a number of poses:
|
||||
* - {@link data}: The setup pose.
|
||||
* - {@link pose}: The unconstrained pose. Set by animations and application code.
|
||||
* - {@link appliedPose}: The pose to use for rendering. Possibly modified by constraints.
|
||||
*/
|
||||
export class Posed {
|
||||
/** The constraint's setup pose data. */
|
||||
data;
|
||||
pose;
|
||||
constrainedPose;
|
||||
appliedPose;
|
||||
constructor(data, pose, constrainedPose) {
|
||||
if (data == null)
|
||||
throw new Error("data cannot be null.");
|
||||
this.data = data;
|
||||
this.pose = pose;
|
||||
this.constrainedPose = constrainedPose;
|
||||
this.appliedPose = pose;
|
||||
}
|
||||
/** Sets the unconstrained pose to the setup pose. */
|
||||
setupPose() {
|
||||
this.pose.set(this.data.setupPose);
|
||||
}
|
||||
/** The setup pose data. May be shared with multiple instances. */
|
||||
getData() {
|
||||
return this.data;
|
||||
}
|
||||
/** The unconstrained pose for this object, set by animations and application code. */
|
||||
getPose() {
|
||||
return this.pose;
|
||||
}
|
||||
/** The pose to use for rendering. If no constraints modify this pose, this is the same as {@link pose}. Otherwise it is a
|
||||
* copy of {@link pose} modified by constraints. */
|
||||
getAppliedPose() {
|
||||
return this.appliedPose;
|
||||
}
|
||||
/** Sets the applied pose to the unconstrained pose, for when no constraints will modify the pose. */
|
||||
unconstrained() {
|
||||
this.appliedPose = this.pose;
|
||||
}
|
||||
/** Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints. */
|
||||
constrained() {
|
||||
this.appliedPose = this.constrainedPose;
|
||||
}
|
||||
/** Sets the constrained pose to the unconstrained pose, as a starting point for constraints to be applied. */
|
||||
resetConstrained() {
|
||||
this.constrainedPose.set(this.pose);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9zZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUG9zZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSy9FOzs7O0dBSUc7QUFDSCxNQUFNLE9BQWdCLEtBQUs7SUFJMUIsd0NBQXdDO0lBQy9CLElBQUksQ0FBSTtJQUNSLElBQUksQ0FBSTtJQUNSLGVBQWUsQ0FBSTtJQUM1QixXQUFXLENBQUk7SUFFZixZQUFhLElBQU8sRUFBRSxJQUFPLEVBQUUsZUFBa0I7UUFDaEQsSUFBSSxJQUFJLElBQUksSUFBSTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUN2QyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUN6QixDQUFDO0lBRUQscURBQXFEO0lBQzlDLFNBQVM7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxrRUFBa0U7SUFDM0QsT0FBTztRQUNiLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNsQixDQUFDO0lBRUQsc0ZBQXNGO0lBQy9FLE9BQU87UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbEIsQ0FBQztJQUVEO3VEQUNtRDtJQUM1QyxjQUFjO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUN6QixDQUFDO0lBRUQscUdBQXFHO0lBQ3JHLGFBQWE7UUFDWixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDOUIsQ0FBQztJQUVELHdIQUF3SDtJQUN4SCxXQUFXO1FBQ1YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ3pDLENBQUM7SUFFRCw4R0FBOEc7SUFDOUcsZ0JBQWdCO1FBQ2YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Q0FFRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBQb3NlIH0gZnJvbSBcIi4vUG9zZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBQb3NlZERhdGEgfSBmcm9tIFwiLi9Qb3NlZERhdGEuanNcIjtcblxuLyoqIFRoZSBiYXNlIGNsYXNzIGZvciBhbiBvYmplY3Qgd2l0aCBhIG51bWJlciBvZiBwb3NlczpcbiAqIC0ge0BsaW5rIGRhdGF9OiBUaGUgc2V0dXAgcG9zZS5cbiAqIC0ge0BsaW5rIHBvc2V9OiBUaGUgdW5jb25zdHJhaW5lZCBwb3NlLiBTZXQgYnkgYW5pbWF0aW9ucyBhbmQgYXBwbGljYXRpb24gY29kZS5cbiAqIC0ge0BsaW5rIGFwcGxpZWRQb3NlfTogVGhlIHBvc2UgdG8gdXNlIGZvciByZW5kZXJpbmcuIFBvc3NpYmx5IG1vZGlmaWVkIGJ5IGNvbnN0cmFpbnRzLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUG9zZWQ8XG5cdEQgZXh0ZW5kcyBQb3NlZERhdGE8UD4sXG5cdFAgZXh0ZW5kcyBQb3NlPFA+PiB7XG5cblx0LyoqIFRoZSBjb25zdHJhaW50J3Mgc2V0dXAgcG9zZSBkYXRhLiAqL1xuXHRyZWFkb25seSBkYXRhOiBEO1xuXHRyZWFkb25seSBwb3NlOiBQO1xuXHRyZWFkb25seSBjb25zdHJhaW5lZFBvc2U6IFA7XG5cdGFwcGxpZWRQb3NlOiBQO1xuXG5cdGNvbnN0cnVjdG9yIChkYXRhOiBELCBwb3NlOiBQLCBjb25zdHJhaW5lZFBvc2U6IFApIHtcblx0XHRpZiAoZGF0YSA9PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoXCJkYXRhIGNhbm5vdCBiZSBudWxsLlwiKTtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHRcdHRoaXMucG9zZSA9IHBvc2U7XG5cdFx0dGhpcy5jb25zdHJhaW5lZFBvc2UgPSBjb25zdHJhaW5lZFBvc2U7XG5cdFx0dGhpcy5hcHBsaWVkUG9zZSA9IHBvc2U7XG5cdH1cblxuXHQvKiogU2V0cyB0aGUgdW5jb25zdHJhaW5lZCBwb3NlIHRvIHRoZSBzZXR1cCBwb
Line truncated
|
||||
@@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
import { Posed } from "./Posed.js";
|
||||
import type { PosedData } from "./PosedData.js";
|
||||
/** A posed object that may be active or inactive. */
|
||||
export declare abstract class PosedActive<D extends PosedData<P>, P extends Pose<P>> extends Posed<D, P> {
|
||||
active: boolean;
|
||||
protected constructor(data: D, pose: P, constrained: P);
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton.updateWorldTransform} because a skin is required and the
|
||||
* {@link Skeleton.skin active skin} does not contain this item. See {@link Skin.bones}, {@link Skin.constraints},
|
||||
* {@link PosedData.skinRequired}, and {@link Skeleton.updateCache}. */
|
||||
isActive(): boolean;
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Posed } from "./Posed.js";
|
||||
/** A posed object that may be active or inactive. */
|
||||
export class PosedActive extends Posed {
|
||||
active = false;
|
||||
constructor(data, pose, constrained) {
|
||||
super(data, pose, constrained);
|
||||
this.setupPose();
|
||||
}
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton.updateWorldTransform} because a skin is required and the
|
||||
* {@link Skeleton.skin active skin} does not contain this item. See {@link Skin.bones}, {@link Skin.constraints},
|
||||
* {@link PosedData.skinRequired}, and {@link Skeleton.updateCache}. */
|
||||
isActive() {
|
||||
return this.active;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9zZWRBY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvUG9zZWRBY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRy9FLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFNbkMscURBQXFEO0FBQ3JELE1BQU0sT0FBZ0IsV0FHckIsU0FBUSxLQUFXO0lBRW5CLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFFZixZQUF1QixJQUFPLEVBQUUsSUFBTyxFQUFFLFdBQWM7UUFDdEQsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7OzJFQUd1RTtJQUNoRSxRQUFRO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3BCLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XG4gKiBMYXN0IHVwZGF0ZWQgQXByaWwgNSwgMjAyNS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDI1LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcbiAqXG4gKiBJbnRlZ3JhdGlvbiBvZiB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvciBvdGhlcndpc2UgY3JlYXRpbmdcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxuICogaHR0cDovL2Vzb3Rlcmljc29mdHdhcmUuY29tL3NwaW5lLWVkaXRvci1saWNlbnNlXG4gKlxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXG4gKiBvciBvdGhlcndpc2UgY3JlYXRlIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIChjb2xsZWN0aXZlbHksXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcbiAqIGluY2x1ZGUgdGhpcyBsaWNlbnNlIGFuZCBjb3B5cmlnaHQgbm90aWNlLlxuICpcbiAqIFRIRSBTUElORSBSVU5USU1FUyBBUkUgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZXG4gKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG4gKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTllcbiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4gKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsXG4gKiBCVVNJTkVTUyBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4gKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAqIFRIRSBTUElORSBSVU5USU1FUywgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuaW1wb3J0IHR5cGUgeyBQb3NlIH0gZnJvbSBcIi4vUG9zZS5qc1wiO1xuaW1wb3J0IHsgUG9zZWQgfSBmcm9tIFwiLi9Qb3NlZC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBQb3NlZERhdGEgfSBmcm9tIFwiLi9Qb3NlZERhdGEuanNcIjtcblxuaW1wb3J0IHR5cGUgeyBTa2VsZXRvbiB9IGZyb20gXCIuL1NrZWxldG9uLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNraW4gfSBmcm9tIFwiLi9Ta2luLmpzXCI7XG5cbi8qKiBBIHBvc2VkIG9iamVjdCB0aGF0IG1heSBiZSBhY3RpdmUgb3IgaW5hY3RpdmUuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUG9zZWRBY3RpdmU8XG5cdEQgZXh0ZW5kcyBQb3NlZERhdGE8UD4sXG5cdFAgZXh0ZW5kcyBQb3NlPFA+PlxuXHRleHRlbmRzIFBvc2VkPEQsIFA+IHtcblxuXHRhY3RpdmUgPSBmYWxzZTtcblxuXHRwcm90ZWN0ZWQgY29uc3RydWN0b3IgKGRhdGE6IEQsIHBvc2U6IFAsIGNvbnN0cmFpbmVkOiBQKSB7XG5cdFx0c3VwZXIoZGF0YSwgcG9zZSwgY29uc3RyYWluZWQpO1xuXHRcdHRoaXMuc2V0dXBQb3NlKCk7XG5cdH1cblxuXHQvKiogUmV0dXJucyBmYWxzZSB3aGVuIHRoaXMgY29uc3RyYWludCB3b24ndCBiZSB1cGRhdGVkIGJ5XG5cdCAqIHtAbGluayBTa2VsZXRvbi51cGRhdGVXb3JsZFRyYW5zZm9ybX0gYmVjYXVzZSBhIHNraW4gaXMgcmVxdWlyZWQgYW5kIHRoZVxuXHQgKiB7QGxpbmsgU2tlbGV0b24uc2tpbiBhY3RpdmUgc2tpbn0gZG9lcyBub3QgY29udGFpbiB0aGlzIGl0ZW0uIFNlZSB7QGxpbmsgU2tpbi5ib25lc30sIHtAbGluayBTa2luLmNvbnN0cmFpbnRzfSxcblx0ICoge0BsaW5rIFBvc2VkRGF0YS5za2luUmVxdWlyZWR9LCBhbmQge0BsaW5rIFNrZWxldG9uLnVwZGF0ZUNhY2hlfS4gKi9cblx0cHVibGljIGlzQWN0aXZlICgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5hY3RpdmU7XG5cdH1cbn1cbiJdfQ==
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Pose } from "./Pose.js";
|
||||
/** The base class for storing setup data for a posed object. May be shared with multiple instances. */
|
||||
export declare abstract class PosedData<P extends Pose<P>> {
|
||||
readonly name: string;
|
||||
readonly setupPose: P;
|
||||
/** When true, {@link Skeleton.updateWorldTransform} only updates this constraint if the {@link Skeleton.skin}
|
||||
* contains this constraint.
|
||||
*
|
||||
* See {@link Skin.constraints}. */
|
||||
skinRequired: boolean;
|
||||
constructor(name: string, setupPose: P);
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
/** The base class for storing setup data for a posed object. May be shared with multiple instances. */
|
||||
export class PosedData {
|
||||
name;
|
||||
setupPose;
|
||||
/** When true, {@link Skeleton.updateWorldTransform} only updates this constraint if the {@link Skeleton.skin}
|
||||
* contains this constraint.
|
||||
*
|
||||
* See {@link Skin.constraints}. */
|
||||
skinRequired = false;
|
||||
constructor(name, setupPose) {
|
||||
if (name == null)
|
||||
throw new Error("name cannot be null.");
|
||||
this.name = name;
|
||||
this.setupPose = setupPose;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUG9zZWREYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1Bvc2VkRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFNL0UsdUdBQXVHO0FBQ3ZHLE1BQU0sT0FBZ0IsU0FBUztJQUNyQixJQUFJLENBQVM7SUFFYixTQUFTLENBQUk7SUFFdEI7Ozt1Q0FHbUM7SUFDbkMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUVyQixZQUFhLElBQVksRUFBRSxTQUFZO1FBQ3RDLElBQUksSUFBSSxJQUFJLElBQUk7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDNUIsQ0FBQztDQUVEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgdHlwZSB7IFBvc2UgfSBmcm9tIFwiLi9Qb3NlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFNrZWxldG9uIH0gZnJvbSBcIi4vU2tlbGV0b24uanNcIjtcbmltcG9ydCB0eXBlIHsgU2tpbiB9IGZyb20gXCIuL1NraW4uanNcIjtcblxuLyoqIFRoZSBiYXNlIGNsYXNzIGZvciBzdG9yaW5nIHNldHVwIGRhdGEgZm9yIGEgcG9zZWQgb2JqZWN0LiBNYXkgYmUgc2hhcmVkIHdpdGggbXVsdGlwbGUgaW5zdGFuY2VzLiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFBvc2VkRGF0YTxQIGV4dGVuZHMgUG9zZTxQPj4ge1xuXHRyZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cblx0cmVhZG9ubHkgc2V0dXBQb3NlOiBQO1xuXG5cdC8qKiBXaGVuIHRydWUsIHtAbGluayBTa2VsZXRvbi51cGRhdGVXb3JsZFRyYW5zZm9ybX0gb25seSB1cGRhdGVzIHRoaXMgY29uc3RyYWludCBpZiB0aGUge0BsaW5rIFNrZWxldG9uLnNraW59XG5cdCAqIGNvbnRhaW5zIHRoaXMgY29uc3RyYWludC5cblx0ICpcblx0ICogU2VlIHtAbGluayBTa2luLmNvbnN0cmFpbnRzfS4gKi9cblx0c2tpblJlcXVpcmVkID0gZmFsc2U7XG5cblx0Y29uc3RydWN0b3IgKG5hbWU6IHN0cmluZywgc2V0dXBQb3NlOiBQKSB7XG5cdFx0aWYgKG5hbWUgPT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKFwibmFtZSBjYW5ub3QgYmUgbnVsbC5cIik7XG5cdFx0dGhpcy5uYW1lID0gbmFtZTtcblx0XHR0aGlzLnNldHVwUG9zZSA9IHNldHVwUG9zZTtcblx0fVxuXG59XG4iXX0=
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Attachment } from "./attachments/Attachment.js";
|
||||
import { Bone } from "./Bone.js";
|
||||
import type { Constraint } from "./Constraint.js";
|
||||
import { DrawOrder } from "./DrawOrder.js";
|
||||
import type { Physics } from "./Physics.js";
|
||||
import { PhysicsConstraint } from "./PhysicsConstraint.js";
|
||||
import type { Posed } from "./Posed.js";
|
||||
import type { SkeletonClipping } from "./SkeletonClipping.js";
|
||||
import type { SkeletonData } from "./SkeletonData.js";
|
||||
import type { Skin } from "./Skin.js";
|
||||
import { Slot } from "./Slot.js";
|
||||
import { Color, Vector2 } from "./Utils.js";
|
||||
/** Stores bones and slots to be posed by animations and application code. Multiple skeleton instances can share the same
|
||||
* {@link SkeletonData}, including animations, attachments, and skins.
|
||||
*
|
||||
* After posing, call {@link updateWorldTransform} to apply constraints and compute world transforms for rendering.
|
||||
*
|
||||
* See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */
|
||||
export declare class Skeleton {
|
||||
private static quadTriangles;
|
||||
static yDown: boolean;
|
||||
static get yDir(): number;
|
||||
/** The skeleton's setup pose data. */
|
||||
readonly data: SkeletonData;
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
readonly bones: Array<Bone>;
|
||||
/** The skeleton's slots. To add a slot, also add it to {@link DrawOrder.pose}. */
|
||||
readonly slots: Array<Slot>;
|
||||
/** The skeleton's draw order. Use {@link DrawOrder.appliedPose} for rendering and {@link DrawOrder.pose} for changing the draw
|
||||
* order. */
|
||||
readonly drawOrder: DrawOrder;
|
||||
/** The skeleton's constraints. */
|
||||
readonly constraints: Array<Constraint<any, any, any>>;
|
||||
/** The skeleton's physics constraints. */
|
||||
readonly physics: Array<PhysicsConstraint>;
|
||||
/** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link updateCache}. */
|
||||
readonly _updateCache: any[];
|
||||
readonly resetCache: Array<Posed<any, any>>;
|
||||
/** The skeleton's current skin. May be null. */
|
||||
skin: Skin | null;
|
||||
/** The color to tint all the skeleton's attachments. */
|
||||
readonly color: Color;
|
||||
/** Scales the entire skeleton on the X axis.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
scaleX: number;
|
||||
private _scaleY;
|
||||
/** Scales the entire skeleton on the Y axis.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
get scaleY(): number;
|
||||
set scaleY(scaleY: number);
|
||||
/** Sets the skeleton X position, which is added to the root bone worldX position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
x: number;
|
||||
/** Sets the skeleton Y position, which is added to the root bone worldY position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
y: number;
|
||||
/** Returns the skeleton's time, is used for time-based manipulations, such as {@link PhysicsConstraint}.
|
||||
*
|
||||
* See {@link _update}. */
|
||||
time: number;
|
||||
/** The x component of a vector that defines the direction {@link PhysicsConstraintPose.wind} is applied. */
|
||||
windX: number;
|
||||
/** The y component of a vector that defines the direction {@link PhysicsConstraintPose.wind} is applied. */
|
||||
windY: number;
|
||||
/** The x component of a vector that defines the direction {@link PhysicsConstraintPose.gravity} is applied. */
|
||||
gravityX: number;
|
||||
/** The y component of a vector that defines the direction {@link PhysicsConstraintPose.gravity} is applied. */
|
||||
gravityY: number;
|
||||
_update: number;
|
||||
constructor(data: SkeletonData);
|
||||
/** Caches information about bones and constraints. Must be called if the {@link skin} is modified or if bones, constraints,
|
||||
* or weighted path attachments are added or removed. */
|
||||
updateCache(): void;
|
||||
constrained(object: Posed<any, any>): void;
|
||||
sortBone(bone: Bone): void;
|
||||
sortReset(bones: Array<Bone>): void;
|
||||
/** Updates the world transform for each bone and applies all constraints.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
updateWorldTransform(physics: Physics): void;
|
||||
/** Sets the bones, constraints, and slots to their setup pose values. */
|
||||
setupPose(): void;
|
||||
/** Sets the bones and constraints to their setup pose values. */
|
||||
setupPoseBones(): void;
|
||||
/** Sets the slots and draw order to their setup pose values. */
|
||||
setupPoseSlots(): void;
|
||||
/** Returns the root bone, or null if the skeleton has no bones. */
|
||||
getRootBone(): Bone | null;
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* repeatedly. */
|
||||
findBone(boneName: string): Bone | null;
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* repeatedly. */
|
||||
findSlot(slotName: string): Slot | null;
|
||||
/** Sets a skin by name.
|
||||
*
|
||||
* See {@link setSkin}. */
|
||||
setSkin(skinName: string): void;
|
||||
/** Sets the skin used to look up attachments before looking in {@link SkeletonData.defaultSkin}. If the skin is changed,
|
||||
* {@link updateCache} is called.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
|
||||
* {@link setupPoseSlots}. Also, often {@link AnimationState.apply} is called before the next time the skeleton is
|
||||
* rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. */
|
||||
setSkin(newSkin: Skin | null): void;
|
||||
private setSkinByName;
|
||||
private setSkinBySkin;
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot name and attachment
|
||||
* name.
|
||||
*
|
||||
* See {@link getAttachment}. */
|
||||
getAttachment(slotName: string, placeholder: string): Attachment | null;
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot index and
|
||||
* attachment name. First the skin is checked and if the attachment was not found, the default skin is checked.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide. */
|
||||
getAttachment(slotIndex: number, placeholder: string): Attachment | null;
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot name and attachment
|
||||
* name.
|
||||
*
|
||||
* See {@link getAttachment}.
|
||||
* @returns May be null. */
|
||||
private getAttachmentByName;
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot index and
|
||||
* attachment name. First the skin is checked and if the attachment was not found, the default skin is checked.
|
||||
*
|
||||
* See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide.
|
||||
* @returns May be null. */
|
||||
private getAttachmentByIndex;
|
||||
/** A convenience method to set an attachment by finding the slot with {@link findSlot}, finding the attachment with
|
||||
* {@link getAttachment}, then setting the slot's {@link Slot.attachment}.
|
||||
* @param placeholder May be null to clear the slot's attachment. */
|
||||
setAttachment(slotName: string, placeholder: string | null): void;
|
||||
/** Finds a constraint of the specified type by comparing each constraints's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times. */
|
||||
findConstraint<T extends Constraint<any, any, any>>(constraintName: string, type: abstract new (...args: any[]) => T): T | null;
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose.
|
||||
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size An output value, the width and height of the AABB.
|
||||
* @param temp Working memory to temporarily store attachments' computed world vertices. */
|
||||
getBoundsRect(clipper?: SkeletonClipping): {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose. Optionally applies
|
||||
* clipping.
|
||||
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size An output value, the width and height of the AABB.
|
||||
* @param temp Working memory to temporarily store attachments' computed world vertices.
|
||||
* @param clipper {@link SkeletonClipping} to use. If `null`, no clipping is applied. */
|
||||
getBounds(offset: Vector2, size: Vector2, temp?: Array<number>, clipper?: SkeletonClipping | null): void;
|
||||
/** Scales the entire skeleton on the X and Y axes.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
setScale(scaleX: number, scaleY: number): void;
|
||||
/** Sets the skeleton X and Y position, which is added to the root bone worldX and worldY position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
setPosition(x: number, y: number): void;
|
||||
/** Increments the skeleton's {@link time}. */
|
||||
update(delta: number): void;
|
||||
/** Calls {@link PhysicsConstraint.translate} for each physics constraint. */
|
||||
physicsTranslate(x: number, y: number): void;
|
||||
/** Calls {@link PhysicsConstraint.rotate} for each physics constraint. */
|
||||
physicsRotate(x: number, y: number, degrees: number): void;
|
||||
}
|
||||
+483
@@ -0,0 +1,483 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { ClippingAttachment } from "./attachments/ClippingAttachment.js";
|
||||
import { MeshAttachment } from "./attachments/MeshAttachment.js";
|
||||
import { RegionAttachment } from "./attachments/RegionAttachment.js";
|
||||
import { Bone } from "./Bone.js";
|
||||
import { DrawOrder } from "./DrawOrder.js";
|
||||
import { PhysicsConstraint } from "./PhysicsConstraint.js";
|
||||
import { Slot } from "./Slot.js";
|
||||
import { Color, Utils, Vector2 } from "./Utils.js";
|
||||
/** Stores bones and slots to be posed by animations and application code. Multiple skeleton instances can share the same
|
||||
* {@link SkeletonData}, including animations, attachments, and skins.
|
||||
*
|
||||
* After posing, call {@link updateWorldTransform} to apply constraints and compute world transforms for rendering.
|
||||
*
|
||||
* See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine Runtimes Guide. */
|
||||
export class Skeleton {
|
||||
static quadTriangles = [0, 1, 2, 2, 3, 0];
|
||||
static yDown = false;
|
||||
static get yDir() {
|
||||
return Skeleton.yDown ? -1 : 1;
|
||||
}
|
||||
/** The skeleton's setup pose data. */
|
||||
data;
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
bones;
|
||||
/** The skeleton's slots. To add a slot, also add it to {@link DrawOrder.pose}. */
|
||||
slots;
|
||||
/** The skeleton's draw order. Use {@link DrawOrder.appliedPose} for rendering and {@link DrawOrder.pose} for changing the draw
|
||||
* order. */
|
||||
drawOrder;
|
||||
/** The skeleton's constraints. */
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
constraints;
|
||||
/** The skeleton's physics constraints. */
|
||||
physics;
|
||||
/** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link updateCache}. */
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
_updateCache = [];
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
resetCache = [];
|
||||
/** The skeleton's current skin. May be null. */
|
||||
skin = null;
|
||||
/** The color to tint all the skeleton's attachments. */
|
||||
color;
|
||||
/** Scales the entire skeleton on the X axis.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
scaleX = 1;
|
||||
_scaleY = 1;
|
||||
/** Scales the entire skeleton on the Y axis.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
get scaleY() {
|
||||
return this._scaleY * Skeleton.yDir;
|
||||
}
|
||||
set scaleY(scaleY) {
|
||||
this._scaleY = scaleY;
|
||||
}
|
||||
/** Sets the skeleton X position, which is added to the root bone worldX position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
x = 0;
|
||||
/** Sets the skeleton Y position, which is added to the root bone worldY position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
y = 0;
|
||||
/** Returns the skeleton's time, is used for time-based manipulations, such as {@link PhysicsConstraint}.
|
||||
*
|
||||
* See {@link _update}. */
|
||||
time = 0;
|
||||
/** The x component of a vector that defines the direction {@link PhysicsConstraintPose.wind} is applied. */
|
||||
windX = 1;
|
||||
/** The y component of a vector that defines the direction {@link PhysicsConstraintPose.wind} is applied. */
|
||||
windY = 0;
|
||||
/** The x component of a vector that defines the direction {@link PhysicsConstraintPose.gravity} is applied. */
|
||||
gravityX = 0;
|
||||
/** The y component of a vector that defines the direction {@link PhysicsConstraintPose.gravity} is applied. */
|
||||
gravityY = 1;
|
||||
_update = 0;
|
||||
constructor(data) {
|
||||
if (!data)
|
||||
throw new Error("data cannot be null.");
|
||||
this.data = data;
|
||||
this.bones = [];
|
||||
for (let i = 0; i < data.bones.length; i++) {
|
||||
const boneData = data.bones[i];
|
||||
let bone;
|
||||
if (!boneData.parent)
|
||||
bone = new Bone(boneData, null);
|
||||
else {
|
||||
const parent = this.bones[boneData.parent.index];
|
||||
bone = new Bone(boneData, parent);
|
||||
parent.children.push(bone);
|
||||
}
|
||||
this.bones.push(bone);
|
||||
}
|
||||
this.slots = [];
|
||||
for (const slotData of this.data.slots)
|
||||
this.slots.push(new Slot(slotData, this));
|
||||
this.drawOrder = new DrawOrder(this.slots);
|
||||
this.physics = [];
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
this.constraints = [];
|
||||
for (const constraintData of this.data.constraints) {
|
||||
const constraint = constraintData.create(this);
|
||||
if (constraint instanceof PhysicsConstraint)
|
||||
this.physics.push(constraint);
|
||||
this.constraints.push(constraint);
|
||||
}
|
||||
this.color = new Color(1, 1, 1, 1);
|
||||
this.updateCache();
|
||||
}
|
||||
/** Caches information about bones and constraints. Must be called if the {@link skin} is modified or if bones, constraints,
|
||||
* or weighted path attachments are added or removed. */
|
||||
updateCache() {
|
||||
this._updateCache.length = 0;
|
||||
this.resetCache.length = 0;
|
||||
this.drawOrder.unconstrained();
|
||||
const slots = this.slots;
|
||||
for (let i = 0, n = slots.length; i < n; i++)
|
||||
slots[i].unconstrained();
|
||||
const bones = this.bones;
|
||||
const boneCount = bones.length;
|
||||
for (let i = 0, n = boneCount; i < n; i++) {
|
||||
const bone = bones[i];
|
||||
bone.sorted = bone.data.skinRequired;
|
||||
bone.active = !bone.sorted;
|
||||
bone.unconstrained();
|
||||
}
|
||||
if (this.skin) {
|
||||
const skinBones = this.skin.bones;
|
||||
for (let i = 0, n = this.skin.bones.length; i < n; i++) {
|
||||
let bone = this.bones[skinBones[i].index];
|
||||
do {
|
||||
bone.sorted = false;
|
||||
bone.active = true;
|
||||
bone = bone.parent;
|
||||
} while (bone);
|
||||
}
|
||||
}
|
||||
const constraints = this.constraints;
|
||||
let n = this.constraints.length;
|
||||
for (let i = 0; i < n; i++)
|
||||
constraints[i].unconstrained();
|
||||
for (let i = 0; i < n; i++) {
|
||||
const constraint = constraints[i];
|
||||
constraint.active = constraint.isSourceActive()
|
||||
// biome-ignore lint/complexity/useOptionalChain: changing to this might return undefined
|
||||
&& (!constraint.data.skinRequired || (this.skin != null && this.skin.constraints.includes(constraint.data)));
|
||||
if (constraint.active)
|
||||
constraint.sort(this);
|
||||
}
|
||||
for (let i = 0; i < boneCount; i++)
|
||||
this.sortBone(bones[i]);
|
||||
n = this._updateCache.length;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const updateable = this._updateCache[i];
|
||||
if (updateable instanceof Bone)
|
||||
this._updateCache[i] = updateable.appliedPose;
|
||||
}
|
||||
}
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
constrained(object) {
|
||||
if (object.pose === object.appliedPose) {
|
||||
object.constrained();
|
||||
this.resetCache.push(object);
|
||||
}
|
||||
}
|
||||
sortBone(bone) {
|
||||
if (bone.sorted || !bone.active)
|
||||
return;
|
||||
const parent = bone.parent;
|
||||
if (parent)
|
||||
this.sortBone(parent);
|
||||
bone.sorted = true;
|
||||
this._updateCache.push(bone);
|
||||
}
|
||||
sortReset(bones) {
|
||||
for (let i = 0, n = bones.length; i < n; i++) {
|
||||
const bone = bones[i];
|
||||
if (bone.active) {
|
||||
if (bone.sorted)
|
||||
this.sortReset(bone.children);
|
||||
bone.sorted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Updates the world transform for each bone and applies all constraints.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
updateWorldTransform(physics) {
|
||||
this._update++;
|
||||
if (this.drawOrder.appliedPose === this.drawOrder.constrainedPose)
|
||||
this.drawOrder.resetConstrained();
|
||||
const resetCache = this.resetCache;
|
||||
for (let i = 0, n = this.resetCache.length; i < n; i++)
|
||||
resetCache[i].resetConstrained();
|
||||
const updateCache = this._updateCache;
|
||||
for (let i = 0, n = this._updateCache.length; i < n; i++)
|
||||
updateCache[i].update(this, physics);
|
||||
}
|
||||
/** Sets the bones, constraints, and slots to their setup pose values. */
|
||||
setupPose() {
|
||||
this.setupPoseBones();
|
||||
this.setupPoseSlots();
|
||||
}
|
||||
/** Sets the bones and constraints to their setup pose values. */
|
||||
setupPoseBones() {
|
||||
const bones = this.bones;
|
||||
for (let i = 0, n = bones.length; i < n; i++)
|
||||
bones[i].setupPose();
|
||||
const constraints = this.constraints;
|
||||
for (let i = 0, n = constraints.length; i < n; i++)
|
||||
constraints[i].setupPose();
|
||||
}
|
||||
/** Sets the slots and draw order to their setup pose values. */
|
||||
setupPoseSlots() {
|
||||
this.drawOrder.setupPose();
|
||||
const slots = this.slots;
|
||||
for (let i = 0, n = slots.length; i < n; i++)
|
||||
slots[i].setupPose();
|
||||
}
|
||||
/** Returns the root bone, or null if the skeleton has no bones. */
|
||||
getRootBone() {
|
||||
if (this.bones.length === 0)
|
||||
return null;
|
||||
return this.bones[0];
|
||||
}
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* repeatedly. */
|
||||
findBone(boneName) {
|
||||
if (!boneName)
|
||||
throw new Error("boneName cannot be null.");
|
||||
const bones = this.bones;
|
||||
for (let i = 0, n = bones.length; i < n; i++)
|
||||
if (bones[i].data.name === boneName)
|
||||
return bones[i];
|
||||
return null;
|
||||
}
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* repeatedly. */
|
||||
findSlot(slotName) {
|
||||
if (!slotName)
|
||||
throw new Error("slotName cannot be null.");
|
||||
const slots = this.slots;
|
||||
for (let i = 0, n = slots.length; i < n; i++)
|
||||
if (slots[i].data.name === slotName)
|
||||
return slots[i];
|
||||
return null;
|
||||
}
|
||||
setSkin(newSkin) {
|
||||
if (typeof newSkin === "string")
|
||||
this.setSkinByName(newSkin);
|
||||
else
|
||||
this.setSkinBySkin(newSkin);
|
||||
}
|
||||
;
|
||||
setSkinByName(skinName) {
|
||||
const skin = this.data.findSkin(skinName);
|
||||
if (!skin)
|
||||
throw new Error(`Skin not found: ${skinName}`);
|
||||
this.setSkin(skin);
|
||||
}
|
||||
setSkinBySkin(newSkin) {
|
||||
if (newSkin === this.skin)
|
||||
return;
|
||||
if (newSkin) {
|
||||
if (this.skin)
|
||||
newSkin.attachAll(this, this.skin);
|
||||
else {
|
||||
const slots = this.slots;
|
||||
for (let i = 0, n = slots.length; i < n; i++) {
|
||||
const slot = slots[i];
|
||||
const name = slot.data.attachmentName;
|
||||
if (name) {
|
||||
const attachment = newSkin.getAttachment(i, name);
|
||||
if (attachment)
|
||||
slot.pose.setAttachment(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.skin = newSkin;
|
||||
this.updateCache();
|
||||
}
|
||||
getAttachment(slotNameOrIndex, placeholder) {
|
||||
if (typeof slotNameOrIndex === 'string')
|
||||
return this.getAttachmentByName(slotNameOrIndex, placeholder);
|
||||
return this.getAttachmentByIndex(slotNameOrIndex, placeholder);
|
||||
}
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot name and attachment
|
||||
* name.
|
||||
*
|
||||
* See {@link getAttachment}.
|
||||
* @returns May be null. */
|
||||
getAttachmentByName(slotName, placeholder) {
|
||||
const slot = this.data.findSlot(slotName);
|
||||
if (!slot)
|
||||
throw new Error(`Can't find slot with name ${slotName}`);
|
||||
return this.getAttachment(slot.index, placeholder);
|
||||
}
|
||||
/** Finds an attachment by looking in the {@link skin} and {@link SkeletonData.defaultSkin} using the slot index and
|
||||
* attachment name. First the skin is checked and if the attachment was not found, the default skin is checked.
|
||||
*
|
||||
* See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide.
|
||||
* @returns May be null. */
|
||||
getAttachmentByIndex(slotIndex, placeholder) {
|
||||
if (!placeholder)
|
||||
throw new Error("placeholder cannot be null.");
|
||||
if (this.skin) {
|
||||
const attachment = this.skin.getAttachment(slotIndex, placeholder);
|
||||
if (attachment)
|
||||
return attachment;
|
||||
}
|
||||
if (this.data.defaultSkin)
|
||||
return this.data.defaultSkin.getAttachment(slotIndex, placeholder);
|
||||
return null;
|
||||
}
|
||||
/** A convenience method to set an attachment by finding the slot with {@link findSlot}, finding the attachment with
|
||||
* {@link getAttachment}, then setting the slot's {@link Slot.attachment}.
|
||||
* @param placeholder May be null to clear the slot's attachment. */
|
||||
setAttachment(slotName, placeholder) {
|
||||
if (!slotName)
|
||||
throw new Error("slotName cannot be null.");
|
||||
const slot = this.findSlot(slotName);
|
||||
if (!slot)
|
||||
throw new Error(`Slot not found: ${slotName}`);
|
||||
let attachment = null;
|
||||
if (placeholder) {
|
||||
attachment = this.getAttachment(slot.data.index, placeholder);
|
||||
if (!attachment)
|
||||
throw new Error(`Attachment not found: ${placeholder}, for slot: ${slotName}`);
|
||||
}
|
||||
slot.pose.setAttachment(attachment);
|
||||
}
|
||||
/** Finds a constraint of the specified type by comparing each constraints's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times. */
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
findConstraint(constraintName, type) {
|
||||
if (constraintName == null)
|
||||
throw new Error("constraintName cannot be null.");
|
||||
if (type == null)
|
||||
throw new Error("type cannot be null.");
|
||||
const constraints = this.constraints;
|
||||
for (let i = 0, n = constraints.length; i < n; i++) {
|
||||
const constraint = constraints[i];
|
||||
if (constraint instanceof type && constraint.data.name === constraintName)
|
||||
return constraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose.
|
||||
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size An output value, the width and height of the AABB.
|
||||
* @param temp Working memory to temporarily store attachments' computed world vertices. */
|
||||
getBoundsRect(clipper) {
|
||||
const offset = new Vector2();
|
||||
const size = new Vector2();
|
||||
this.getBounds(offset, size, undefined, clipper);
|
||||
return { x: offset.x, y: offset.y, width: size.x, height: size.y };
|
||||
}
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose. Optionally applies
|
||||
* clipping.
|
||||
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size An output value, the width and height of the AABB.
|
||||
* @param temp Working memory to temporarily store attachments' computed world vertices.
|
||||
* @param clipper {@link SkeletonClipping} to use. If `null`, no clipping is applied. */
|
||||
getBounds(offset, size, temp = new Array(2), clipper = null) {
|
||||
if (!offset)
|
||||
throw new Error("offset cannot be null.");
|
||||
if (!size)
|
||||
throw new Error("size cannot be null.");
|
||||
const drawOrder = this.drawOrder.appliedPose;
|
||||
const slots = drawOrder;
|
||||
let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
|
||||
for (let i = 0, n = drawOrder.length; i < n; i++) {
|
||||
const slot = slots[i];
|
||||
if (!slot.bone.active)
|
||||
continue;
|
||||
let verticesLength = 0;
|
||||
let vertices = null;
|
||||
let triangles = null;
|
||||
const attachment = slot.appliedPose.attachment;
|
||||
if (attachment) {
|
||||
if (attachment instanceof RegionAttachment) {
|
||||
verticesLength = 8;
|
||||
vertices = Utils.setArraySize(temp, verticesLength, 0);
|
||||
attachment.computeWorldVertices(slot, attachment.getOffsets(slot.appliedPose), vertices, 0, 2);
|
||||
triangles = Skeleton.quadTriangles;
|
||||
}
|
||||
else if (attachment instanceof MeshAttachment) {
|
||||
verticesLength = attachment.worldVerticesLength;
|
||||
vertices = Utils.setArraySize(temp, verticesLength, 0);
|
||||
attachment.computeWorldVertices(this, slot, 0, verticesLength, vertices, 0, 2);
|
||||
triangles = attachment.triangles;
|
||||
}
|
||||
else if (attachment instanceof ClippingAttachment && clipper) {
|
||||
clipper.clipEnd(slot);
|
||||
clipper.clipStart(this, slot, attachment);
|
||||
continue;
|
||||
}
|
||||
if (vertices && triangles) {
|
||||
if (clipper?.isClipping() && clipper.clipTriangles(vertices, triangles, triangles.length)) {
|
||||
vertices = clipper.clippedVertices;
|
||||
verticesLength = clipper.clippedVertices.length;
|
||||
}
|
||||
for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) {
|
||||
const x = vertices[ii], y = vertices[ii + 1];
|
||||
minX = Math.min(minX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxX = Math.max(maxX, x);
|
||||
maxY = Math.max(maxY, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (clipper)
|
||||
clipper.clipEnd(slot);
|
||||
}
|
||||
if (clipper)
|
||||
clipper.clipEnd();
|
||||
offset.set(minX, minY);
|
||||
size.set(maxX - minX, maxY - minY);
|
||||
}
|
||||
/** Scales the entire skeleton on the X and Y axes.
|
||||
*
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
setScale(scaleX, scaleY) {
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
/** Sets the skeleton X and Y position, which is added to the root bone worldX and worldY position.
|
||||
*
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
setPosition(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
/** Increments the skeleton's {@link time}. */
|
||||
update(delta) {
|
||||
this.time += delta;
|
||||
}
|
||||
/** Calls {@link PhysicsConstraint.translate} for each physics constraint. */
|
||||
physicsTranslate(x, y) {
|
||||
const constraints = this.physics;
|
||||
for (let i = 0, n = constraints.length; i < n; i++)
|
||||
constraints[i].translate(x, y);
|
||||
}
|
||||
/** Calls {@link PhysicsConstraint.rotate} for each physics constraint. */
|
||||
physicsRotate(x, y, degrees) {
|
||||
const constraints = this.physics;
|
||||
for (let i = 0, n = constraints.length; i < n; i++)
|
||||
constraints[i].rotate(x, y, degrees);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU2tlbGV0b24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBSS9FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNyRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQU0zRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxLQUFLLEVBQXdCLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFekU7Ozs7O2tJQUtrSTtBQUNsSSxNQUFNLE9BQU8sUUFBUTtJQUNaLE1BQU0sQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xELE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLE1BQU0sS0FBSyxJQUFJO1FBQ2QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxzQ0FBc0M7SUFDN0IsSUFBSSxDQUFlO0lBRTVCLHlGQUF5RjtJQUNoRixLQUFLLENBQWM7SUFFNUIsa0ZBQWtGO0lBQ3pFLEtBQUssQ0FBYztJQUU1QjtnQkFDWTtJQUNILFNBQVMsQ0FBWTtJ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
Line truncated
|
||||
@@ -0,0 +1,68 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { AttachmentLoader } from "./attachments/AttachmentLoader.js";
|
||||
import { SkeletonData } from "./SkeletonData.js";
|
||||
/** Loads skeleton data in the Spine binary format.
|
||||
*
|
||||
* See [Spine binary format](http://esotericsoftware.com/spine-binary-format) and
|
||||
* [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine
|
||||
* Runtimes Guide. */
|
||||
export declare class SkeletonBinary {
|
||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
||||
* runtime than were used in Spine.
|
||||
*
|
||||
* See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */
|
||||
scale: number;
|
||||
attachmentLoader: AttachmentLoader;
|
||||
private linkedMeshes;
|
||||
constructor(attachmentLoader: AttachmentLoader);
|
||||
readSkeletonData(binary: Uint8Array | ArrayBuffer): SkeletonData;
|
||||
private readSkin;
|
||||
private readAttachment;
|
||||
private readSequence;
|
||||
private readVertices;
|
||||
private readFloatArray;
|
||||
private readShortArray;
|
||||
private readAnimation;
|
||||
}
|
||||
export declare class BinaryInput {
|
||||
strings: string[];
|
||||
private index;
|
||||
private buffer;
|
||||
constructor(data: Uint8Array | ArrayBuffer, strings?: string[], index?: number, buffer?: DataView);
|
||||
readByte(): number;
|
||||
readUnsignedByte(): number;
|
||||
readShort(): number;
|
||||
readInt32(): number;
|
||||
readInt(optimizePositive: boolean): number;
|
||||
readStringRef(): string | null;
|
||||
readString(): string | null;
|
||||
readFloat(): number;
|
||||
readBoolean(): boolean;
|
||||
}
|
||||
+1508
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BoundingBoxAttachment } from "./attachments/BoundingBoxAttachment.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import { type NumberArrayLike } from "./Utils.js";
|
||||
/** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are
|
||||
* provided along with convenience methods for doing hit detection. */
|
||||
export declare class SkeletonBounds {
|
||||
/** The left edge of the axis aligned bounding box. */
|
||||
minX: number;
|
||||
/** The bottom edge of the axis aligned bounding box. */
|
||||
minY: number;
|
||||
/** The right edge of the axis aligned bounding box. */
|
||||
maxX: number;
|
||||
/** The top edge of the axis aligned bounding box. */
|
||||
maxY: number;
|
||||
/** The visible bounding boxes. */
|
||||
boundingBoxes: BoundingBoxAttachment[];
|
||||
/** The world vertices for the bounding box polygons. */
|
||||
polygons: NumberArrayLike[];
|
||||
private polygonPool;
|
||||
/** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding
|
||||
* box's polygon.
|
||||
* @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the
|
||||
* SkeletonBounds AABB methods will always return true. */
|
||||
update(skeleton: Skeleton, updateAabb: boolean): void;
|
||||
aabbCompute(): void;
|
||||
/** Returns true if the axis aligned bounding box contains the point. */
|
||||
aabbContainsPoint(x: number, y: number): boolean;
|
||||
/** Returns true if the axis aligned bounding box intersects the line segment. */
|
||||
aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
|
||||
/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
|
||||
aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
|
||||
/** 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} returns true. */
|
||||
containsPoint(x: number, y: number): BoundingBoxAttachment | null;
|
||||
/** Returns true if the polygon contains the point. */
|
||||
containsPointPolygon(polygon: NumberArrayLike, x: number, y: number): boolean;
|
||||
/** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it
|
||||
* is usually more efficient to only call this method if {@link aabbIntersectsSegment} returns
|
||||
* true. */
|
||||
intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment | null;
|
||||
/** Returns true if the polygon contains any part of the line segment. */
|
||||
intersectsSegmentPolygon(polygon: NumberArrayLike, x1: number, y1: number, x2: number, y2: number): boolean;
|
||||
/** Returns the polygon for the specified bounding box, or null. */
|
||||
getPolygon(boundingBox: BoundingBoxAttachment): NumberArrayLike | null;
|
||||
/** The width of the axis aligned bounding box. */
|
||||
getWidth(): number;
|
||||
/** The height of the axis aligned bounding box. */
|
||||
getHeight(): number;
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { BoundingBoxAttachment } from "./attachments/BoundingBoxAttachment.js";
|
||||
import { Pool, Utils } from "./Utils.js";
|
||||
/** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are
|
||||
* provided along with convenience methods for doing hit detection. */
|
||||
export class SkeletonBounds {
|
||||
/** The left edge of the axis aligned bounding box. */
|
||||
minX = 0;
|
||||
/** The bottom edge of the axis aligned bounding box. */
|
||||
minY = 0;
|
||||
/** The right edge of the axis aligned bounding box. */
|
||||
maxX = 0;
|
||||
/** The top edge of the axis aligned bounding box. */
|
||||
maxY = 0;
|
||||
/** The visible bounding boxes. */
|
||||
boundingBoxes = [];
|
||||
/** The world vertices for the bounding box polygons. */
|
||||
polygons = [];
|
||||
polygonPool = new Pool(() => {
|
||||
return Utils.newFloatArray(16);
|
||||
});
|
||||
/** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding
|
||||
* box's polygon.
|
||||
* @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the
|
||||
* SkeletonBounds AABB methods will always return true. */
|
||||
update(skeleton, updateAabb) {
|
||||
if (!skeleton)
|
||||
throw new Error("skeleton cannot be null.");
|
||||
const boundingBoxes = this.boundingBoxes;
|
||||
const polygons = this.polygons;
|
||||
const polygonPool = this.polygonPool;
|
||||
const slots = skeleton.slots;
|
||||
const slotCount = slots.length;
|
||||
boundingBoxes.length = 0;
|
||||
polygonPool.freeAll(polygons);
|
||||
polygons.length = 0;
|
||||
for (let i = 0; i < slotCount; i++) {
|
||||
const slot = slots[i];
|
||||
if (!slot.bone.active)
|
||||
continue;
|
||||
const attachment = slot.appliedPose.attachment;
|
||||
if (attachment instanceof BoundingBoxAttachment) {
|
||||
boundingBoxes.push(attachment);
|
||||
let polygon = polygonPool.obtain();
|
||||
if (polygon.length !== attachment.worldVerticesLength) {
|
||||
polygon = Utils.newFloatArray(attachment.worldVerticesLength);
|
||||
}
|
||||
polygons.push(polygon);
|
||||
attachment.computeWorldVertices(skeleton, slot, 0, attachment.worldVerticesLength, polygon, 0, 2);
|
||||
}
|
||||
}
|
||||
if (updateAabb) {
|
||||
this.aabbCompute();
|
||||
}
|
||||
else {
|
||||
this.minX = Number.POSITIVE_INFINITY;
|
||||
this.minY = Number.POSITIVE_INFINITY;
|
||||
this.maxX = Number.NEGATIVE_INFINITY;
|
||||
this.maxY = Number.NEGATIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
aabbCompute() {
|
||||
let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
|
||||
const polygons = this.polygons;
|
||||
for (let i = 0, n = polygons.length; i < n; i++) {
|
||||
const polygon = polygons[i];
|
||||
const vertices = polygon;
|
||||
for (let ii = 0, nn = polygon.length; ii < nn; ii += 2) {
|
||||
const x = vertices[ii];
|
||||
const 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(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(x1, y1, x2, y2) {
|
||||
const minX = this.minX;
|
||||
const minY = this.minY;
|
||||
const maxX = this.maxX;
|
||||
const maxY = this.maxY;
|
||||
if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
|
||||
return false;
|
||||
const m = (y2 - y1) / (x2 - x1);
|
||||
let y = m * (minX - x1) + y1;
|
||||
if (y > minY && y < maxY)
|
||||
return true;
|
||||
y = m * (maxX - x1) + y1;
|
||||
if (y > minY && y < maxY)
|
||||
return true;
|
||||
let 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(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} returns true. */
|
||||
containsPoint(x, y) {
|
||||
const polygons = this.polygons;
|
||||
for (let i = 0, n = polygons.length; i < n; i++)
|
||||
if (this.containsPointPolygon(polygons[i], x, y))
|
||||
return this.boundingBoxes[i];
|
||||
return null;
|
||||
}
|
||||
/** Returns true if the polygon contains the point. */
|
||||
containsPointPolygon(polygon, x, y) {
|
||||
const vertices = polygon;
|
||||
const nn = polygon.length;
|
||||
let prevIndex = nn - 2;
|
||||
let inside = false;
|
||||
for (let ii = 0; ii < nn; ii += 2) {
|
||||
const vertexY = vertices[ii + 1];
|
||||
const prevY = vertices[prevIndex + 1];
|
||||
if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
|
||||
const vertexX = vertices[ii];
|
||||
if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x)
|
||||
inside = !inside;
|
||||
}
|
||||
prevIndex = ii;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
/** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it
|
||||
* is usually more efficient to only call this method if {@link aabbIntersectsSegment} returns
|
||||
* true. */
|
||||
intersectsSegment(x1, y1, x2, y2) {
|
||||
const polygons = this.polygons;
|
||||
for (let i = 0, n = polygons.length; i < n; i++)
|
||||
if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2))
|
||||
return this.boundingBoxes[i];
|
||||
return null;
|
||||
}
|
||||
/** Returns true if the polygon contains any part of the line segment. */
|
||||
intersectsSegmentPolygon(polygon, x1, y1, x2, y2) {
|
||||
const vertices = polygon;
|
||||
const nn = polygon.length;
|
||||
const width12 = x1 - x2, height12 = y1 - y2;
|
||||
const det1 = x1 * y2 - y1 * x2;
|
||||
let x3 = vertices[nn - 2], y3 = vertices[nn - 1];
|
||||
for (let ii = 0; ii < nn; ii += 2) {
|
||||
const x4 = vertices[ii], y4 = vertices[ii + 1];
|
||||
const det2 = x3 * y4 - y3 * x4;
|
||||
const width34 = x3 - x4, height34 = y3 - y4;
|
||||
const det3 = width12 * height34 - height12 * width34;
|
||||
const x = (det1 * width34 - width12 * det2) / det3;
|
||||
if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
|
||||
const 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;
|
||||
}
|
||||
/** Returns the polygon for the specified bounding box, or null. */
|
||||
getPolygon(boundingBox) {
|
||||
if (!boundingBox)
|
||||
throw new Error("boundingBox cannot be null.");
|
||||
const index = this.boundingBoxes.indexOf(boundingBox);
|
||||
return index === -1 ? null : this.polygons[index];
|
||||
}
|
||||
/** The width of the axis aligned bounding box. */
|
||||
getWidth() {
|
||||
return this.maxX - this.minX;
|
||||
}
|
||||
/** The height of the axis aligned bounding box. */
|
||||
getHeight() {
|
||||
return this.maxY - this.minY;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25Cb3VuZHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU2tlbGV0b25Cb3VuZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsrRUEyQitFO0FBRS9FLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRS9FLE9BQU8sRUFBd0IsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUUvRDtzRUFDc0U7QUFDdEUsTUFBTSxPQUFPLGNBQWM7SUFFMUIsc0RBQXNEO0lBQ3RELElBQUksR0FBRyxDQUFDLENBQUM7SUFFVCx3REFBd0Q7SUFDeEQsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUVULHVEQUF1RDtJQUN2RCxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBRVQscURBQXFEO0lBQ3JELElBQUksR0FBRyxDQUFDLENBQUM7SUFFVCxrQ0FBa0M7SUFDbEMsYUFBYSxHQUFHLEVBQTZCLENBQUM7SUFFOUMsd0RBQXdEO0lBQ3hELFFBQVEsR0FBRyxFQUF1QixDQUFDO0lBRTNCLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBa0IsR0FBRyxFQUFFO1FBQ3BELE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUMsQ0FBQztJQUVIOzs7d0VBR29FO0lBQ3BFLE1BQU0sQ0FBRSxRQUFrQixFQUFFLFVBQW1CO1FBQzlDLElBQUksQ0FBQyxRQUFRO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUMvQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3JDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENB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
Line truncated
|
||||
@@ -0,0 +1,67 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { ClippingAttachment } from "./attachments/ClippingAttachment.js";
|
||||
import type { Skeleton } from "./Skeleton.js";
|
||||
import type { Slot } from "./Slot.js";
|
||||
import { type Color, type NumberArrayLike } from "./Utils.js";
|
||||
export declare class SkeletonClipping {
|
||||
private triangulator;
|
||||
private clippingPolygon;
|
||||
private clippingPolygons;
|
||||
private clipOutput;
|
||||
clippedVertices: number[];
|
||||
/** An empty array unless {@link clipTrianglesUnpacked} was used. **/
|
||||
clippedUVs: number[];
|
||||
clippedTriangles: number[];
|
||||
inverseVertices: number[];
|
||||
_clippedVerticesTyped: Float32Array;
|
||||
_clippedUVsTyped: Float32Array;
|
||||
_clippedTrianglesTyped: Uint16Array;
|
||||
clippedVerticesTyped: Float32Array;
|
||||
clippedUVsTyped: Float32Array;
|
||||
clippedTrianglesTyped: Uint16Array;
|
||||
clippedVerticesLength: number;
|
||||
clippedUVsLength: number;
|
||||
clippedTrianglesLength: number;
|
||||
private scratch;
|
||||
private inverse;
|
||||
private clipAttachment;
|
||||
clipStart(skeleton: Skeleton, slot: Slot, clip: ClippingAttachment): void;
|
||||
clipEnd(slot?: Slot): void;
|
||||
isClipping(): boolean;
|
||||
clipTriangles(vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): boolean;
|
||||
clipTriangles(vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean, stride: number): boolean;
|
||||
private clipTrianglesNoRender;
|
||||
private clipTrianglesRender;
|
||||
clipTrianglesUnpacked(vertices: NumberArrayLike, vertexStart: number, triangles: NumberArrayLike | Uint16Array, trianglesLength: number, uvs: NumberArrayLike, stride?: number): boolean;
|
||||
private clip;
|
||||
private clipInverse;
|
||||
private makeClockwise;
|
||||
private makeConvex;
|
||||
}
|
||||
@@ -0,0 +1,821 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { Triangulator } from "./Triangulator.js";
|
||||
import { Utils } from "./Utils.js";
|
||||
export class SkeletonClipping {
|
||||
triangulator = null;
|
||||
clippingPolygon = [];
|
||||
clippingPolygons = [];
|
||||
clipOutput = [];
|
||||
clippedVertices = [];
|
||||
/** An empty array unless {@link clipTrianglesUnpacked} was used. **/
|
||||
clippedUVs = [];
|
||||
clippedTriangles = [];
|
||||
inverseVertices = [];
|
||||
_clippedVerticesTyped = new Float32Array(1024);
|
||||
_clippedUVsTyped = new Float32Array(1024);
|
||||
_clippedTrianglesTyped = new Uint16Array(1024);
|
||||
clippedVerticesTyped = new Float32Array(0);
|
||||
clippedUVsTyped = new Float32Array(0);
|
||||
clippedTrianglesTyped = new Uint16Array(0);
|
||||
clippedVerticesLength = 0;
|
||||
clippedUVsLength = 0;
|
||||
clippedTrianglesLength = 0;
|
||||
scratch = [];
|
||||
inverse = false;
|
||||
clipAttachment = null;
|
||||
clipStart(skeleton, slot, clip) {
|
||||
if (this.clipAttachment)
|
||||
return;
|
||||
const n = clip.worldVerticesLength;
|
||||
this.clipAttachment = clip;
|
||||
this.inverse = clip.inverse;
|
||||
const vertices = Utils.setArraySize(this.clippingPolygon, n);
|
||||
clip.computeWorldVertices(skeleton, slot, 0, n, vertices, 0, 2);
|
||||
const clippingPolygon = this.clippingPolygon;
|
||||
const convex = this.makeClockwise(clippingPolygon);
|
||||
if (convex || this.inverse || clip.convex) {
|
||||
if (!convex)
|
||||
this.makeConvex(clippingPolygon);
|
||||
this.clippingPolygon.push(clippingPolygon[0], clippingPolygon[1]);
|
||||
this.clippingPolygons.push(clippingPolygon);
|
||||
}
|
||||
else {
|
||||
if (this.triangulator === null)
|
||||
this.triangulator = new Triangulator();
|
||||
this.clippingPolygons.push(...this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)));
|
||||
}
|
||||
}
|
||||
clipEnd(slot) {
|
||||
if (!this.clipAttachment)
|
||||
return;
|
||||
if (slot && this.clipAttachment.endSlot !== slot.data)
|
||||
return;
|
||||
this.clipAttachment = null;
|
||||
this.clippingPolygons.length = 0;
|
||||
}
|
||||
isClipping() {
|
||||
return this.clipAttachment != null;
|
||||
}
|
||||
clipTriangles(vertices, triangles, trianglesLength, uvs, light, dark, twoColor, stride) {
|
||||
return (uvs && light && dark && typeof twoColor === 'boolean' && typeof stride === 'number')
|
||||
? this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor, stride)
|
||||
: this.clipTrianglesNoRender(vertices, triangles, trianglesLength);
|
||||
}
|
||||
clipTrianglesNoRender(vertices, triangles, trianglesLength) {
|
||||
const clippedVertices = this.clippedVertices;
|
||||
clippedVertices.length = 0;
|
||||
const clippedTriangles = this.clippedTriangles;
|
||||
clippedTriangles.length = 0;
|
||||
let index = 0;
|
||||
if (this.inverse) {
|
||||
const polygon = this.clippingPolygons[0];
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let t = triangles[i] << 1;
|
||||
const x1 = vertices[t], y1 = vertices[t + 1];
|
||||
t = triangles[i + 1] << 1;
|
||||
const x2 = vertices[t], y2 = vertices[t + 1];
|
||||
t = triangles[i + 2] << 1;
|
||||
const x3 = vertices[t], y3 = vertices[t + 1];
|
||||
this.clipInverse(x1, y1, x2, y2, x3, y3, polygon);
|
||||
const iv = this.inverseVertices;
|
||||
for (let offset = 0, nn = this.inverseVertices.length; offset < nn;) {
|
||||
const polygonSize = iv[offset++];
|
||||
let vertexCount = polygonSize >> 1, s = clippedVertices.length;
|
||||
const cv = Utils.setArraySize(clippedVertices, s + polygonSize);
|
||||
Utils.arrayCopy(iv, offset, cv, s, polygonSize);
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3 * (vertexCount - 2));
|
||||
for (let ii = 1; ii < vertexCount - 1; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = index + ii;
|
||||
ct[s + 2] = index + ii + 1;
|
||||
}
|
||||
index += vertexCount;
|
||||
offset += polygonSize;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const clipOutput = this.clipOutput;
|
||||
const polygons = this.clippingPolygons;
|
||||
const polygonsCount = polygons.length;
|
||||
let clipOutputItems = null;
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let t = triangles[i] << 1;
|
||||
const x1 = vertices[t], y1 = vertices[t + 1];
|
||||
t = triangles[i + 1] << 1;
|
||||
const x2 = vertices[t], y2 = vertices[t + 1];
|
||||
t = triangles[i + 2] << 1;
|
||||
const x3 = vertices[t], y3 = vertices[t + 1];
|
||||
for (let p = 0; p < polygonsCount; p++) {
|
||||
let s = clippedVertices.length;
|
||||
if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p])) {
|
||||
clipOutputItems = this.clipOutput;
|
||||
const clipOutputLength = clipOutput.length;
|
||||
if (clipOutputLength === 0)
|
||||
continue;
|
||||
let clipOutputCount = clipOutputLength >> 1;
|
||||
const cv = Utils.setArraySize(clippedVertices, s + clipOutputLength);
|
||||
Utils.arrayCopy(clipOutputItems, 0, cv, s, clipOutputLength);
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
|
||||
clipOutputCount--;
|
||||
for (let ii = 1; ii < clipOutputCount; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + ii);
|
||||
ct[s + 2] = (index + ii + 1);
|
||||
}
|
||||
index += clipOutputCount;
|
||||
}
|
||||
else {
|
||||
const cv = Utils.setArraySize(clippedVertices, s + 3 * 2);
|
||||
cv[s] = x1;
|
||||
cv[s + 1] = y1;
|
||||
cv[s + 2] = x2;
|
||||
cv[s + 3] = y2;
|
||||
cv[s + 4] = x3;
|
||||
cv[s + 5] = y3;
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3);
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + 1);
|
||||
ct[s + 2] = (index + 2);
|
||||
index += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return clipOutputItems != null;
|
||||
}
|
||||
clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor, stride) {
|
||||
const clippedVertices = this.clippedVertices;
|
||||
clippedVertices.length = 0;
|
||||
const clippedTriangles = this.clippedTriangles;
|
||||
clippedTriangles.length = 0;
|
||||
let index = 0;
|
||||
if (this.inverse) {
|
||||
const polygon = this.clippingPolygons[0];
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let t0 = triangles[i], t1 = triangles[i + 1], t2 = triangles[i + 2];
|
||||
const x1 = vertices[t0 * stride], y1 = vertices[t0 * stride + 1];
|
||||
const x2 = vertices[t1 * stride], y2 = vertices[t1 * stride + 1];
|
||||
const x3 = vertices[t2 * stride], y3 = vertices[t2 * stride + 1];
|
||||
this.clipInverse(x1, y1, x2, y2, x3, y3, polygon);
|
||||
const nn = this.inverseVertices.length;
|
||||
if (nn === 0)
|
||||
continue;
|
||||
const u1 = uvs[t0 <<= 1], v1 = uvs[t0 + 1];
|
||||
const u2 = uvs[t1 <<= 1], v2 = uvs[t1 + 1];
|
||||
const u3 = uvs[t2 <<= 1], v3 = uvs[t2 + 1];
|
||||
const d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1, d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
||||
const iv = this.inverseVertices;
|
||||
for (let offset = 0; offset < nn;) {
|
||||
const polygonSize = iv[offset++];
|
||||
const vertexCount = polygonSize >> 1;
|
||||
let s = clippedVertices.length;
|
||||
const cv = Utils.setArraySize(clippedVertices, s + vertexCount * stride);
|
||||
for (let ii = 0; ii < polygonSize; ii += 2, s += stride) {
|
||||
const x = iv[offset + ii], y = iv[offset + ii + 1];
|
||||
cv[s] = x;
|
||||
cv[s + 1] = y;
|
||||
cv[s + 2] = light.r;
|
||||
cv[s + 3] = light.g;
|
||||
cv[s + 4] = light.b;
|
||||
cv[s + 5] = light.a;
|
||||
const c0 = x - x3, c1 = y - y3, a = (d0 * c0 + d1 * c1) * d, b = (d4 * c0 + d2 * c1) * d, c = 1 - a - b;
|
||||
cv[s + 6] = u1 * a + u2 * b + u3 * c;
|
||||
cv[s + 7] = v1 * a + v2 * b + v3 * c;
|
||||
if (twoColor) {
|
||||
cv[s + 8] = dark.r;
|
||||
cv[s + 9] = dark.g;
|
||||
cv[s + 10] = dark.b;
|
||||
cv[s + 11] = dark.a;
|
||||
}
|
||||
}
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3 * (vertexCount - 2));
|
||||
for (let ii = 1; ii < vertexCount - 1; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = index + ii;
|
||||
ct[s + 2] = index + ii + 1;
|
||||
}
|
||||
index += vertexCount;
|
||||
offset += polygonSize;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const clipOutput = this.clipOutput;
|
||||
const polygons = this.clippingPolygons;
|
||||
const polygonsCount = this.clippingPolygons.length;
|
||||
let clipOutputItems = null;
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let t = triangles[i];
|
||||
const x1 = vertices[t * stride], y1 = vertices[t * stride + 1];
|
||||
const u1 = uvs[t << 1], v1 = uvs[(t << 1) + 1];
|
||||
t = triangles[i + 1];
|
||||
const x2 = vertices[t * stride], y2 = vertices[t * stride + 1];
|
||||
const u2 = uvs[t << 1], v2 = uvs[(t << 1) + 1];
|
||||
t = triangles[i + 2];
|
||||
const x3 = vertices[t * stride], y3 = vertices[t * stride + 1];
|
||||
const u3 = uvs[t << 1], v3 = uvs[(t << 1) + 1];
|
||||
let d0 = 0, d1 = 0, d2 = 0, d4 = 0, d = 0;
|
||||
for (let p = 0; p < polygonsCount; p++) {
|
||||
let s = clippedVertices.length;
|
||||
if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p])) {
|
||||
clipOutputItems = this.clipOutput;
|
||||
const clipOutputLength = clipOutput.length;
|
||||
if (clipOutputLength === 0)
|
||||
continue;
|
||||
let clipOutputCount = clipOutputLength >> 1;
|
||||
if (d === 0) {
|
||||
d0 = y2 - y3;
|
||||
d1 = x3 - x2;
|
||||
d2 = x1 - x3;
|
||||
d4 = y3 - y1;
|
||||
d = 1 / (d0 * d2 - d1 * d4);
|
||||
}
|
||||
const cv = Utils.setArraySize(clippedVertices, s + clipOutputCount * stride);
|
||||
for (let ii = 0; ii < clipOutputLength; ii += 2, s += stride) {
|
||||
const x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
|
||||
cv[s] = x;
|
||||
cv[s + 1] = y;
|
||||
cv[s + 2] = light.r;
|
||||
cv[s + 3] = light.g;
|
||||
cv[s + 4] = light.b;
|
||||
cv[s + 5] = light.a;
|
||||
const c0 = x - x3, c1 = y - y3, a = (d0 * c0 + d1 * c1) * d, b = (d4 * c0 + d2 * c1) * d, c = 1 - a - b;
|
||||
cv[s + 6] = u1 * a + u2 * b + u3 * c;
|
||||
cv[s + 7] = v1 * a + v2 * b + v3 * c;
|
||||
if (twoColor) {
|
||||
cv[s + 8] = dark.r;
|
||||
cv[s + 9] = dark.g;
|
||||
cv[s + 10] = dark.b;
|
||||
cv[s + 11] = dark.a;
|
||||
}
|
||||
}
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
|
||||
clipOutputCount--;
|
||||
for (let ii = 1; ii < clipOutputCount; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + ii);
|
||||
ct[s + 2] = (index + ii + 1);
|
||||
}
|
||||
index += clipOutputCount + 1;
|
||||
}
|
||||
else {
|
||||
const cv = Utils.setArraySize(clippedVertices, s + 3 * stride);
|
||||
cv[s] = x1;
|
||||
cv[s + 1] = y1;
|
||||
cv[s + 2] = light.r;
|
||||
cv[s + 3] = light.g;
|
||||
cv[s + 4] = light.b;
|
||||
cv[s + 5] = light.a;
|
||||
if (!twoColor) {
|
||||
cv[s + 6] = u1;
|
||||
cv[s + 7] = v1;
|
||||
cv[s + 8] = x2;
|
||||
cv[s + 9] = y2;
|
||||
cv[s + 10] = light.r;
|
||||
cv[s + 11] = light.g;
|
||||
cv[s + 12] = light.b;
|
||||
cv[s + 13] = light.a;
|
||||
cv[s + 14] = u2;
|
||||
cv[s + 15] = v2;
|
||||
cv[s + 16] = x3;
|
||||
cv[s + 17] = y3;
|
||||
cv[s + 18] = light.r;
|
||||
cv[s + 19] = light.g;
|
||||
cv[s + 20] = light.b;
|
||||
cv[s + 21] = light.a;
|
||||
cv[s + 22] = u3;
|
||||
cv[s + 23] = v3;
|
||||
}
|
||||
else {
|
||||
cv[s + 6] = u1;
|
||||
cv[s + 7] = v1;
|
||||
cv[s + 8] = dark.r;
|
||||
cv[s + 9] = dark.g;
|
||||
cv[s + 10] = dark.b;
|
||||
cv[s + 11] = dark.a;
|
||||
cv[s + 12] = x2;
|
||||
cv[s + 13] = y2;
|
||||
cv[s + 14] = light.r;
|
||||
cv[s + 15] = light.g;
|
||||
cv[s + 16] = light.b;
|
||||
cv[s + 17] = light.a;
|
||||
cv[s + 18] = u2;
|
||||
cv[s + 19] = v2;
|
||||
cv[s + 20] = dark.r;
|
||||
cv[s + 21] = dark.g;
|
||||
cv[s + 22] = dark.b;
|
||||
cv[s + 23] = dark.a;
|
||||
cv[s + 24] = x3;
|
||||
cv[s + 25] = y3;
|
||||
cv[s + 26] = light.r;
|
||||
cv[s + 27] = light.g;
|
||||
cv[s + 28] = light.b;
|
||||
cv[s + 29] = light.a;
|
||||
cv[s + 30] = u3;
|
||||
cv[s + 31] = v3;
|
||||
cv[s + 32] = dark.r;
|
||||
cv[s + 33] = dark.g;
|
||||
cv[s + 34] = dark.b;
|
||||
cv[s + 35] = dark.a;
|
||||
}
|
||||
s = clippedTriangles.length;
|
||||
const ct = Utils.setArraySize(clippedTriangles, s + 3);
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + 1);
|
||||
ct[s + 2] = (index + 2);
|
||||
index += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return clipOutputItems != null;
|
||||
}
|
||||
clipTrianglesUnpacked(vertices, vertexStart, triangles, trianglesLength, uvs, stride = 2) {
|
||||
let clippedVertices = this._clippedVerticesTyped;
|
||||
let clippedUVs = this._clippedUVsTyped;
|
||||
let clippedTriangles = this._clippedTrianglesTyped;
|
||||
let index = 0;
|
||||
this.clippedVerticesLength = 0;
|
||||
this.clippedUVsLength = 0;
|
||||
this.clippedTrianglesLength = 0;
|
||||
if (this.inverse) {
|
||||
const polygon = this.clippingPolygons[0];
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let v = triangles[i] * stride;
|
||||
const x1 = vertices[vertexStart + v], y1 = vertices[vertexStart + v + 1];
|
||||
let uv = triangles[i] << 1;
|
||||
const u1 = uvs[uv], v1 = uvs[uv + 1];
|
||||
v = triangles[i + 1] * stride;
|
||||
const x2 = vertices[vertexStart + v], y2 = vertices[vertexStart + v + 1];
|
||||
uv = triangles[i + 1] << 1;
|
||||
const u2 = uvs[uv], v2 = uvs[uv + 1];
|
||||
v = triangles[i + 2] * stride;
|
||||
const x3 = vertices[vertexStart + v], y3 = vertices[vertexStart + v + 1];
|
||||
uv = triangles[i + 2] << 1;
|
||||
const u3 = uvs[uv], v3 = uvs[uv + 1];
|
||||
this.clipInverse(x1, y1, x2, y2, x3, y3, polygon);
|
||||
const nn = this.inverseVertices.length;
|
||||
if (nn === 0)
|
||||
continue;
|
||||
const d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1, d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
||||
const iv = this.inverseVertices;
|
||||
for (let offset = 0; offset < nn;) {
|
||||
const polygonSize = iv[offset++];
|
||||
const vertexCount = polygonSize >> 1;
|
||||
let s = this.clippedVerticesLength;
|
||||
const newLength = s + vertexCount * stride;
|
||||
const newUVLength = this.clippedUVsLength + vertexCount * 2;
|
||||
if (clippedVertices.length < newLength) {
|
||||
this._clippedVerticesTyped = new Float32Array(newLength * 2);
|
||||
this._clippedVerticesTyped.set(clippedVertices.subarray(0, s));
|
||||
clippedVertices = this._clippedVerticesTyped;
|
||||
}
|
||||
if (clippedUVs.length < newUVLength) {
|
||||
this._clippedUVsTyped = new Float32Array(newUVLength * 2);
|
||||
this._clippedUVsTyped.set(clippedUVs.subarray(0, this.clippedUVsLength));
|
||||
clippedUVs = this._clippedUVsTyped;
|
||||
}
|
||||
this.clippedVerticesLength = newLength;
|
||||
this.clippedUVsLength = newUVLength;
|
||||
const cv = this._clippedVerticesTyped;
|
||||
const cu = this._clippedUVsTyped;
|
||||
let uvIndex = newUVLength - vertexCount * 2;
|
||||
for (let ii = 0; ii < polygonSize; ii += 2, s += stride, uvIndex += 2) {
|
||||
const x = iv[offset + ii], y = iv[offset + ii + 1];
|
||||
cv[s] = x;
|
||||
cv[s + 1] = y;
|
||||
const c0 = x - x3, c1 = y - y3, a = (d0 * c0 + d1 * c1) * d, b = (d4 * c0 + d2 * c1) * d, c = 1 - a - b;
|
||||
cu[uvIndex] = u1 * a + u2 * b + u3 * c;
|
||||
cu[uvIndex + 1] = v1 * a + v2 * b + v3 * c;
|
||||
}
|
||||
s = this.clippedTrianglesLength;
|
||||
const newLengthTriangles = s + 3 * (vertexCount - 2);
|
||||
if (clippedTriangles.length < newLengthTriangles) {
|
||||
this._clippedTrianglesTyped = new Uint16Array(newLengthTriangles * 2);
|
||||
this._clippedTrianglesTyped.set(clippedTriangles.subarray(0, s));
|
||||
clippedTriangles = this._clippedTrianglesTyped;
|
||||
}
|
||||
this.clippedTrianglesLength = newLengthTriangles;
|
||||
const ct = clippedTriangles;
|
||||
for (let ii = 1; ii < vertexCount - 1; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = index + ii;
|
||||
ct[s + 2] = index + ii + 1;
|
||||
}
|
||||
index += vertexCount;
|
||||
offset += polygonSize;
|
||||
}
|
||||
}
|
||||
this.clippedVerticesTyped = this._clippedVerticesTyped.subarray(0, this.clippedVerticesLength);
|
||||
this.clippedUVsTyped = this._clippedUVsTyped.subarray(0, this.clippedUVsLength);
|
||||
this.clippedTrianglesTyped = this._clippedTrianglesTyped.subarray(0, this.clippedTrianglesLength);
|
||||
return true;
|
||||
}
|
||||
const clipOutput = this.clipOutput;
|
||||
const polygons = this.clippingPolygons;
|
||||
const polygonsCount = this.clippingPolygons.length;
|
||||
let clipOutputItems = null;
|
||||
for (let i = 0; i < trianglesLength; i += 3) {
|
||||
let t = triangles[i];
|
||||
let v = t * stride;
|
||||
const x1 = vertices[vertexStart + v], y1 = vertices[vertexStart + v + 1];
|
||||
let uv = t << 1;
|
||||
const u1 = uvs[uv], v1 = uvs[uv + 1];
|
||||
t = triangles[i + 1];
|
||||
v = t * stride;
|
||||
const x2 = vertices[vertexStart + v], y2 = vertices[vertexStart + v + 1];
|
||||
uv = t << 1;
|
||||
const u2 = uvs[uv], v2 = uvs[uv + 1];
|
||||
t = triangles[i + 2];
|
||||
v = t * stride;
|
||||
const x3 = vertices[vertexStart + v], y3 = vertices[vertexStart + v + 1];
|
||||
uv = t << 1;
|
||||
const u3 = uvs[uv], v3 = uvs[uv + 1];
|
||||
let d0 = 0, d1 = 0, d2 = 0, d4 = 0, d = 0;
|
||||
for (let p = 0; p < polygonsCount; p++) {
|
||||
let s = this.clippedVerticesLength;
|
||||
if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p])) {
|
||||
clipOutputItems = clipOutput;
|
||||
const clipOutputLength = clipOutput.length;
|
||||
if (clipOutputLength === 0)
|
||||
continue;
|
||||
let clipOutputCount = clipOutputLength >> 1;
|
||||
if (d === 0) {
|
||||
d0 = y2 - y3;
|
||||
d1 = x3 - x2;
|
||||
d2 = x1 - x3;
|
||||
d4 = y3 - y1;
|
||||
d = 1 / (d0 * d2 - d1 * d4);
|
||||
}
|
||||
const newLength = s + clipOutputCount * stride;
|
||||
if (clippedVertices.length < newLength) {
|
||||
this._clippedVerticesTyped = new Float32Array(newLength * 2);
|
||||
this._clippedVerticesTyped.set(clippedVertices.subarray(0, s));
|
||||
this._clippedUVsTyped = new Float32Array((this.clippedUVsLength + clipOutputCount * 2) * 2);
|
||||
this._clippedUVsTyped.set(clippedUVs.subarray(0, this.clippedUVsLength));
|
||||
clippedVertices = this._clippedVerticesTyped;
|
||||
clippedUVs = this._clippedUVsTyped;
|
||||
}
|
||||
const cv = clippedVertices;
|
||||
const cu = clippedUVs;
|
||||
this.clippedVerticesLength = newLength;
|
||||
let uvIndex = this.clippedUVsLength;
|
||||
this.clippedUVsLength = uvIndex + clipOutputCount * 2;
|
||||
for (let ii = 0; ii < clipOutputLength; ii += 2, s += stride, uvIndex += 2) {
|
||||
const x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
|
||||
cv[s] = x;
|
||||
cv[s + 1] = y;
|
||||
const c0 = x - x3, c1 = y - y3, a = (d0 * c0 + d1 * c1) * d, b = (d4 * c0 + d2 * c1) * d, c = 1 - a - b;
|
||||
cu[uvIndex] = u1 * a + u2 * b + u3 * c;
|
||||
cu[uvIndex + 1] = v1 * a + v2 * b + v3 * c;
|
||||
}
|
||||
s = this.clippedTrianglesLength;
|
||||
const newLengthTriangles = s + 3 * (clipOutputCount - 2);
|
||||
if (clippedTriangles.length < newLengthTriangles) {
|
||||
this._clippedTrianglesTyped = new Uint16Array(newLengthTriangles * 2);
|
||||
this._clippedTrianglesTyped.set(clippedTriangles.subarray(0, s));
|
||||
clippedTriangles = this._clippedTrianglesTyped;
|
||||
}
|
||||
this.clippedTrianglesLength = newLengthTriangles;
|
||||
const ct = clippedTriangles;
|
||||
clipOutputCount--;
|
||||
for (let ii = 1; ii < clipOutputCount; ii++, s += 3) {
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + ii);
|
||||
ct[s + 2] = (index + ii + 1);
|
||||
}
|
||||
index += clipOutputCount + 1;
|
||||
}
|
||||
else {
|
||||
let newLength = s + 3 * stride;
|
||||
if (clippedVertices.length < newLength) {
|
||||
this._clippedVerticesTyped = new Float32Array(newLength * 2);
|
||||
this._clippedVerticesTyped.set(clippedVertices.subarray(0, s));
|
||||
clippedVertices = this._clippedVerticesTyped;
|
||||
}
|
||||
clippedVertices[s] = x1;
|
||||
clippedVertices[s + 1] = y1;
|
||||
clippedVertices[s + stride] = x2;
|
||||
clippedVertices[s + stride + 1] = y2;
|
||||
clippedVertices[s + stride * 2] = x3;
|
||||
clippedVertices[s + stride * 2 + 1] = y3;
|
||||
const uvLength = this.clippedUVsLength + 3 * 2;
|
||||
if (clippedUVs.length < uvLength) {
|
||||
this._clippedUVsTyped = new Float32Array(uvLength * 2);
|
||||
this._clippedUVsTyped.set(clippedUVs.subarray(0, this.clippedUVsLength));
|
||||
clippedUVs = this._clippedUVsTyped;
|
||||
}
|
||||
const uvIndex = this.clippedUVsLength;
|
||||
clippedUVs[uvIndex] = u1;
|
||||
clippedUVs[uvIndex + 1] = v1;
|
||||
clippedUVs[uvIndex + 2] = u2;
|
||||
clippedUVs[uvIndex + 3] = v2;
|
||||
clippedUVs[uvIndex + 4] = u3;
|
||||
clippedUVs[uvIndex + 5] = v3;
|
||||
this.clippedVerticesLength = newLength;
|
||||
this.clippedUVsLength = uvLength;
|
||||
s = this.clippedTrianglesLength;
|
||||
newLength = s + 3;
|
||||
if (clippedTriangles.length < newLength) {
|
||||
this._clippedTrianglesTyped = new Uint16Array(newLength * 2);
|
||||
this._clippedTrianglesTyped.set(clippedTriangles.subarray(0, s));
|
||||
clippedTriangles = this._clippedTrianglesTyped;
|
||||
}
|
||||
const ct = clippedTriangles;
|
||||
ct[s] = index;
|
||||
ct[s + 1] = (index + 1);
|
||||
ct[s + 2] = (index + 2);
|
||||
index += 3;
|
||||
this.clippedTrianglesLength = newLength;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.clippedVerticesTyped = this._clippedVerticesTyped.subarray(0, this.clippedVerticesLength);
|
||||
this.clippedUVsTyped = this._clippedUVsTyped.subarray(0, this.clippedUVsLength);
|
||||
this.clippedTrianglesTyped = this._clippedTrianglesTyped.subarray(0, this.clippedTrianglesLength);
|
||||
return clipOutputItems !== null;
|
||||
}
|
||||
clip(x1, y1, x2, y2, x3, y3, polygon) {
|
||||
const originalOutput = this.clipOutput;
|
||||
let clipped = false;
|
||||
// Avoid copy at the end.
|
||||
let input, output;
|
||||
if (polygon.length % 4 >= 2) {
|
||||
input = this.clipOutput;
|
||||
output = this.scratch;
|
||||
}
|
||||
else {
|
||||
input = this.scratch;
|
||||
output = this.clipOutput;
|
||||
}
|
||||
const v = polygon;
|
||||
input.length = 8;
|
||||
const iv = input;
|
||||
iv[0] = x1;
|
||||
iv[1] = y1;
|
||||
iv[2] = x2;
|
||||
iv[3] = y2;
|
||||
iv[4] = x3;
|
||||
iv[5] = y3;
|
||||
iv[6] = x1;
|
||||
iv[7] = y1;
|
||||
output.length = 0;
|
||||
const last = polygon.length - 4;
|
||||
for (let i = 0;; i += 2) {
|
||||
const edgeX = v[i], edgeY = v[i + 1], ex = edgeX - v[i + 2], ey = edgeY - v[i + 3];
|
||||
const outputStart = output.length;
|
||||
const iv = input;
|
||||
x1 = iv[0];
|
||||
y1 = iv[1];
|
||||
let s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
|
||||
for (let ii = 2, nn = input.length - 2; ii <= nn; ii += 2) {
|
||||
x2 = iv[ii];
|
||||
y2 = iv[ii + 1];
|
||||
const s2 = ey * (edgeX - x2) - ex * (edgeY - y2);
|
||||
if (s1 > 0) {
|
||||
if (s2 > 0) // v1 in, v2 in
|
||||
output.push(x2, y2);
|
||||
else { // v1 in, v2 out
|
||||
const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
|
||||
if (t >= 0 && t <= 1) {
|
||||
output.push(x1 + ix * t, y1 + iy * t);
|
||||
clipped = true;
|
||||
}
|
||||
else
|
||||
output.push(x2, y2);
|
||||
}
|
||||
}
|
||||
else if (s2 > 0) { // v1 out, v2 in
|
||||
const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
|
||||
if (t >= 0 && t <= 1) {
|
||||
output.push(x1 + ix * t, y1 + iy * t, x2, y2);
|
||||
clipped = true;
|
||||
}
|
||||
else
|
||||
output.push(x2, y2);
|
||||
}
|
||||
else // v1 out, v2 out
|
||||
clipped = true;
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
s1 = s2;
|
||||
}
|
||||
if (outputStart === output.length) { // All outside.
|
||||
originalOutput.length = 0;
|
||||
return true;
|
||||
}
|
||||
output.push(output[0], output[1]);
|
||||
if (i === last)
|
||||
break;
|
||||
const temp = output;
|
||||
output = input;
|
||||
output.length = 0;
|
||||
input = temp;
|
||||
}
|
||||
if (originalOutput !== output) {
|
||||
originalOutput.length = 0;
|
||||
for (let i = 0, n = output.length - 2; i < n; i++)
|
||||
originalOutput[i] = output[i];
|
||||
}
|
||||
else
|
||||
originalOutput.length = originalOutput.length - 2;
|
||||
return clipped;
|
||||
}
|
||||
clipInverse(x1, y1, x2, y2, x3, y3, polygon) {
|
||||
this.inverseVertices.length = 0;
|
||||
const vLast = polygon.length - 4;
|
||||
let input, output; // Avoid copy at the end.
|
||||
if (polygon.length % 4 >= 2) {
|
||||
input = this.clipOutput;
|
||||
output = this.scratch;
|
||||
}
|
||||
else {
|
||||
input = this.scratch;
|
||||
output = this.clipOutput;
|
||||
}
|
||||
input.length = 8;
|
||||
let v = polygon, iv = input;
|
||||
iv[0] = x1;
|
||||
iv[1] = y1;
|
||||
iv[2] = x2;
|
||||
iv[3] = y2;
|
||||
iv[4] = x3;
|
||||
iv[5] = y3;
|
||||
iv[6] = x1;
|
||||
iv[7] = y1;
|
||||
output.length = 0;
|
||||
for (let i = 0;; i += 2) {
|
||||
const edgeX = v[i], edgeY = v[i + 1], ex = edgeX - v[i + 2], ey = edgeY - v[i + 3];
|
||||
const outputStart = output.length, fragmentStart = this.inverseVertices.length;
|
||||
this.inverseVertices.push(0);
|
||||
iv = input;
|
||||
x1 = iv[0];
|
||||
y1 = iv[1];
|
||||
let s1 = ey * (edgeX - x1) - ex * (edgeY - y1);
|
||||
for (let ii = 2, nn = input.length - 2; ii <= nn; ii += 2) {
|
||||
x2 = iv[ii];
|
||||
y2 = iv[ii + 1];
|
||||
const s2 = ey * (edgeX - x2) - ex * (edgeY - y2);
|
||||
if (s1 > 0) {
|
||||
if (s2 > 0) // v1 in, v2 in
|
||||
output.push(x2, y2);
|
||||
else { // v1 in, v2 out
|
||||
const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
|
||||
if (t >= 0 && t <= 1) {
|
||||
const cx = x1 + ix * t, cy = y1 + iy * t;
|
||||
output.push(cx, cy);
|
||||
this.inverseVertices.push(cx, cy, x2, y2);
|
||||
}
|
||||
else
|
||||
output.push(x2, y2);
|
||||
}
|
||||
}
|
||||
else if (s2 > 0) { // v1 out, v2 in
|
||||
const ix = x2 - x1, iy = y2 - y1, t = s1 / (ix * ey - iy * ex);
|
||||
if (t >= 0 && t <= 1) {
|
||||
const cx = x1 + ix * t, cy = y1 + iy * t;
|
||||
this.inverseVertices.push(cx, cy);
|
||||
output.push(cx, cy, x2, y2);
|
||||
}
|
||||
else
|
||||
output.push(x2, y2);
|
||||
}
|
||||
else // v1 out, v2 out
|
||||
this.inverseVertices.push(x2, y2);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
s1 = s2;
|
||||
}
|
||||
const fragmentSize = this.inverseVertices.length - fragmentStart - 1;
|
||||
if (fragmentSize >= 6)
|
||||
this.inverseVertices[fragmentStart] = fragmentSize;
|
||||
else
|
||||
this.inverseVertices.length = fragmentStart; // Degenerate.
|
||||
if (outputStart === output.length)
|
||||
break; // All outside.
|
||||
output.push(output[0], output[1]);
|
||||
if (i === vLast)
|
||||
break;
|
||||
const temp = output;
|
||||
output = input;
|
||||
output.length = 0;
|
||||
input = temp;
|
||||
}
|
||||
}
|
||||
makeClockwise(polygon) {
|
||||
const v = polygon;
|
||||
const n = polygon.length;
|
||||
let noCW = true, noCCW = true;
|
||||
let area = 0, prevX = v[n - 2], prevY = v[n - 1], currX = v[0], currY = v[1];
|
||||
for (let i = 2; i < n; i += 2) {
|
||||
const nextX = v[i], nextY = v[i + 1];
|
||||
area += currX * nextY - nextX * currY;
|
||||
const cross = (currX - prevX) * (nextY - currY) - (currY - prevY) * (nextX - currX);
|
||||
noCCW = noCCW && cross <= 0;
|
||||
noCW = noCW && cross >= 0;
|
||||
prevX = currX;
|
||||
prevY = currY;
|
||||
currX = nextX;
|
||||
currY = nextY;
|
||||
}
|
||||
area += currX * v[1] - v[0] * currY;
|
||||
const cross = (currX - prevX) * (v[1] - currY) - (currY - prevY) * (v[0] - currX);
|
||||
noCCW = noCCW && cross <= 0;
|
||||
noCW = noCW && cross >= 0;
|
||||
if (area >= 0) {
|
||||
for (let i = 0, lastX = n - 2, half = n >> 1; i < half; i += 2) {
|
||||
const x = v[i], y = v[i + 1];
|
||||
const other = lastX - i;
|
||||
v[i] = v[other];
|
||||
v[i + 1] = v[other + 1];
|
||||
v[other] = x;
|
||||
v[other + 1] = y;
|
||||
}
|
||||
return noCW;
|
||||
}
|
||||
return noCCW;
|
||||
}
|
||||
makeConvex(polygon) {
|
||||
const n = polygon.length;
|
||||
const v = polygon;
|
||||
this.clipOutput.length = n;
|
||||
const sorted = this.clipOutput;
|
||||
sorted[0] = v[0];
|
||||
sorted[1] = v[1];
|
||||
for (let i = 2; i < n; i += 2) {
|
||||
const x = v[i], y = v[i + 1];
|
||||
let p = i - 2;
|
||||
for (; p >= 0 && (sorted[p] > x || (sorted[p] === x && sorted[p + 1] > y)); p -= 2) {
|
||||
sorted[p + 2] = sorted[p];
|
||||
sorted[p + 3] = sorted[p + 1];
|
||||
}
|
||||
sorted[p + 2] = x;
|
||||
sorted[p + 3] = y;
|
||||
}
|
||||
v[0] = sorted[0];
|
||||
v[1] = sorted[1];
|
||||
v[2] = sorted[2];
|
||||
v[3] = sorted[3];
|
||||
let s = 4;
|
||||
for (let i = 4; i < n; i += 2, s += 2) {
|
||||
const x = sorted[i], y = sorted[i + 1];
|
||||
while ((v[s - 2] - v[s - 4]) * (y - v[s - 3]) - (v[s - 1] - v[s - 3]) * (x - v[s - 4]) >= 0) {
|
||||
s -= 2;
|
||||
if (s === 2)
|
||||
break;
|
||||
}
|
||||
v[s] = x;
|
||||
v[s + 1] = y;
|
||||
}
|
||||
v[s] = sorted[n - 4];
|
||||
v[s + 1] = sorted[n - 3];
|
||||
const t = s;
|
||||
s += 2;
|
||||
for (let i = n - 6; i >= 0; i -= 2, s += 2) {
|
||||
const x = sorted[i], y = sorted[i + 1];
|
||||
while ((v[s - 2] - v[s - 4]) * (y - v[s - 3]) - (v[s - 1] - v[s - 3]) * (x - v[s - 4]) >= 0) {
|
||||
s -= 2;
|
||||
if (s === t)
|
||||
break;
|
||||
}
|
||||
v[s] = x;
|
||||
v[s + 1] = y;
|
||||
}
|
||||
polygon.length = s - 2;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25DbGlwcGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Ta2VsZXRvbkNsaXBwaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUsvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFvQyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFckUsTUFBTSxPQUFPLGdCQUFnQjtJQUNwQixZQUFZLEdBQXdCLElBQUksQ0FBQztJQUN6QyxlQUFlLEdBQUcsRUFBYyxDQUFDO0lBQ2pDLGdCQUFnQixHQUFlLEVBQUUsQ0FBQztJQUNsQyxVQUFVLEdBQUcsRUFBYyxDQUFDO0lBQ3BDLGVBQWUsR0FBRyxFQUFjLENBQUM7SUFFakMscUVBQXFFO0lBQ3JFLFVBQVUsR0FBRyxFQUFjLENBQUM7SUFFNUIsZ0JBQWdCLEdBQUcsRUFBYyxDQUFDO0lBQ2xDLGVBQWUsR0FBRyxFQUFjLENBQUM7SUFFakMscUJBQXFCLEdBQWlCLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdELGdCQUFnQixHQUFpQixJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxzQkFBc0IsR0FBZ0IsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUQsb0JBQW9CLEdBQWlCLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pELGVBQWUsR0FBaUIsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEQscUJBQXFCLEdBQWdCLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hELHFCQUFxQixHQUFHLENBQUMsQ0FBQztJQUMxQixnQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFDckIsc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLE9BQU8sR0FBRyxFQUFjLENBQUM7SUFDekIsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUVoQixjQUFjLEdBQThCLElBQUksQ0FBQztJQUV6RCxTQUFTLENBQUUsUUFBa0IsRUFBRSxJQUFVLEVBQUUsSUFBd0I7UUFDbEUsSUFBSSxJQUFJLENBQUMsY0FBYztZQUFFLE9BQU87UUFDaEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO1FBQ25DLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUU1QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDN0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUVuRCxJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsTUFBTTtnQkFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzdDLENBQUM7YUFBTSxDQUFDO1lBQ1AsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLElBQUk7Z0JBQUUsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ3ZFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdILENBQUM7SUFDRixDQUFDO0lBRUQsT0FBTyxDQUFFLElBQVc7UUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTztRQUNqQyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDOUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELFVBQVU7UUFDVCxPQUFPLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFLRCxhQUFhLENBQUUsUUFBeUIsRUFBRSxTQUEwQixFQUFFLGVBQXVCLEVBQzVGLEdBQXFCLEVBQUUsS0FBYSxFQUFFLElBQVksRUFBRSxRQUFrQixFQUFFLE1BQWU7UUFFdkYsT0FBTyxDQUFDLEdBQUcsSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLE9BQU8sUUFBUSxLQUFLLFNBQVMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLENBQUM7WUFDM0YsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO1lBQ3BHLENBQUMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRU8scUJBQXFCLENBQUUsUUFBeUIsRUFBRSxTQUEwQixFQUFFLGVBQXVCO1FBQzVHLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDN0MsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDL0MsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUM1QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFFZCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGVBQWUsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzFCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDN0MsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMxQixNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDMUIsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUM3QyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUVsRCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUNoQyxLQUFLLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBS
Line truncated
|
||||
@@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software or
|
||||
* otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Bone } from "./Bone.js";
|
||||
/** Converts points between Spine skeleton coordinates and host runtime game coordinates. */
|
||||
export interface SkeletonCoordinateConverter {
|
||||
/**
|
||||
* Converts `point` in-place from skeleton coordinates to host runtime game coordinates.
|
||||
* @param point The point to convert.
|
||||
*/
|
||||
skeletonToGame(point: {
|
||||
x: number;
|
||||
y: number;
|
||||
}): void;
|
||||
/**
|
||||
* Converts `point` in-place from host runtime game coordinates to skeleton coordinates.
|
||||
* @param point The point to convert.
|
||||
*/
|
||||
gameToSkeleton(point: {
|
||||
x: number;
|
||||
y: number;
|
||||
}): void;
|
||||
/**
|
||||
* Converts `point` in-place from host runtime game coordinates to the local coordinates of `bone`.
|
||||
* @param point The point to convert.
|
||||
* @param bone The bone whose local coordinates should receive the converted point.
|
||||
*/
|
||||
gameToBone(point: {
|
||||
x: number;
|
||||
y: number;
|
||||
}, bone: Bone): void;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software or
|
||||
* otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
export {};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25Db29yZGluYXRlQ29udmVydGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NrZWxldG9uQ29vcmRpbmF0ZUNvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0UiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvclxuICogb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB0eXBlIHsgQm9uZSB9IGZyb20gXCIuL0JvbmUuanNcIjtcblxuLyoqIENvbnZlcnRzIHBvaW50cyBiZXR3ZWVuIFNwaW5lIHNrZWxldG9uIGNvb3JkaW5hdGVzIGFuZCBob3N0IHJ1bnRpbWUgZ2FtZSBjb29yZGluYXRlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2tlbGV0b25Db29yZGluYXRlQ29udmVydGVyIHtcblx0LyoqXG5cdCAqIENvbnZlcnRzIGBwb2ludGAgaW4tcGxhY2UgZnJvbSBza2VsZXRvbiBjb29yZGluYXRlcyB0byBob3N0IHJ1bnRpbWUgZ2FtZSBjb29yZGluYXRlcy5cblx0ICogQHBhcmFtIHBvaW50IFRoZSBwb2ludCB0byBjb252ZXJ0LlxuXHQgKi9cblx0c2tlbGV0b25Ub0dhbWUgKHBvaW50OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0pOiB2b2lkO1xuXG5cdC8qKlxuXHQgKiBDb252ZXJ0cyBgcG9pbnRgIGluLXBsYWNlIGZyb20gaG9zdCBydW50aW1lIGdhbWUgY29vcmRpbmF0ZXMgdG8gc2tlbGV0b24gY29vcmRpbmF0ZXMuXG5cdCAqIEBwYXJhbSBwb2ludCBUaGUgcG9pbnQgdG8gY29udmVydC5cblx0ICovXG5cdGdhbWVUb1NrZWxldG9uIChwb2ludDogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9KTogdm9pZDtcblxuXHQvKipcblx0ICogQ29udmVydHMgYHBvaW50YCBpbi1wbGFjZSBmcm9tIGhvc3QgcnVudGltZSBnYW1lIGNvb3JkaW5hdGVzIHRvIHRoZSBsb2NhbCBjb29yZGluYXRlcyBvZiBgYm9uZWAuXG5cdCAqIEBwYXJhbSBwb2ludCBUaGUgcG9pbnQgdG8gY29udmVydC5cblx0ICogQHBhcmFtIGJvbmUgVGhlIGJvbmUgd2hvc2UgbG9jYWwgY29vcmRpbmF0ZXMgc2hvdWxkIHJlY2VpdmUgdGhlIGNvbnZlcnRlZCBwb2ludC5cblx0ICovXG5cdGdhbWVUb0JvbmUgKHBvaW50OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0sIGJvbmU6IEJvbmUpOiB2b2lkO1xufVxuIl19
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Animation } from "./Animation.js";
|
||||
import type { BoneData } from "./BoneData.js";
|
||||
import type { ConstraintData } from "./ConstraintData.js";
|
||||
import type { EventData } from "./EventData.js";
|
||||
import type { Skin } from "./Skin.js";
|
||||
import type { SlotData } from "./SlotData.js";
|
||||
/** Stores the setup pose and all of the stateless data for a skeleton.
|
||||
*
|
||||
* See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine Runtimes
|
||||
* Guide. */
|
||||
export declare class SkeletonData {
|
||||
/** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */
|
||||
name: string | null;
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
bones: BoneData[];
|
||||
/** The skeleton's slots in the setup pose draw order. */
|
||||
slots: SlotData[];
|
||||
skins: Skin[];
|
||||
/** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.
|
||||
*
|
||||
* See {@link Skeleton.getAttachmentByName}.
|
||||
* May be null. */
|
||||
defaultSkin: Skin | null;
|
||||
/** The skeleton's events. */
|
||||
events: EventData[];
|
||||
/** The skeleton's animations. */
|
||||
animations: Animation[];
|
||||
/** The skeleton's IK constraints. */
|
||||
constraints: ConstraintData<any, any>[];
|
||||
/** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
x: number;
|
||||
/** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
y: number;
|
||||
/** The width of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
width: number;
|
||||
/** The height of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
height: number;
|
||||
/** Baseline scale factor for applying distance-dependent effects on non-scalable properties, such as angle or scale. Default
|
||||
* is 100. */
|
||||
referenceScale: number;
|
||||
/** The Spine version used to export the skeleton data, or null. */
|
||||
version: string | null;
|
||||
/** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */
|
||||
hash: string | null;
|
||||
/** The dopesheet FPS in Spine. Available only when nonessential data was exported. */
|
||||
fps: number;
|
||||
/** The path to the images folder as defined in Spine. Available only when nonessential data was exported. May be null. */
|
||||
imagesPath: string | null;
|
||||
/** The path to the audio folder as defined in Spine. Available only when nonessential data was exported. May be null. */
|
||||
audioPath: string | null;
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findBone(boneName: string): BoneData | null;
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findSlot(slotName: string): SlotData | null;
|
||||
/** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findSkin(skinName: string): Skin | null;
|
||||
/** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findEvent(eventDataName: string): EventData | null;
|
||||
/** Collects animations used by {@link SliderData slider constraints}.
|
||||
*
|
||||
* Slider animations are designed to be applied by slider constraints rather than on their own. Applications that have a user
|
||||
* choose an animation may want to exclude them. */
|
||||
findSliderAnimations(animations: Animation[]): Animation[];
|
||||
/** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
|
||||
* call it multiple times.
|
||||
* @returns May be null. */
|
||||
findAnimation(animationName: string): Animation | null;
|
||||
/** Finds a constraint of the specified type by comparing each constraints's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times. */
|
||||
findConstraint<T extends ConstraintData<any, any>>(constraintName: string, type: abstract new (...args: any[]) => T): T | null;
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import { SliderData } from "./SliderData.js";
|
||||
/** Stores the setup pose and all of the stateless data for a skeleton.
|
||||
*
|
||||
* See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine Runtimes
|
||||
* Guide. */
|
||||
export class SkeletonData {
|
||||
/** The skeleton's name, which by default is the name of the skeleton data file, if possible. May be null. */
|
||||
name = null;
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
bones = []; // Ordered parents first.
|
||||
/** The skeleton's slots in the setup pose draw order. */
|
||||
slots = []; // Setup pose draw order.
|
||||
skins = [];
|
||||
/** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.
|
||||
*
|
||||
* See {@link Skeleton.getAttachmentByName}.
|
||||
* May be null. */
|
||||
defaultSkin = null;
|
||||
/** The skeleton's events. */
|
||||
events = [];
|
||||
/** The skeleton's animations. */
|
||||
animations = [];
|
||||
/** The skeleton's IK constraints. */
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
constraints = [];
|
||||
/** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
x = 0;
|
||||
/** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
y = 0;
|
||||
/** The width of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
width = 0;
|
||||
/** The height of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
height = 0;
|
||||
/** Baseline scale factor for applying distance-dependent effects on non-scalable properties, such as angle or scale. Default
|
||||
* is 100. */
|
||||
referenceScale = 100;
|
||||
/** The Spine version used to export the skeleton data, or null. */
|
||||
version = null;
|
||||
/** The skeleton data hash. This value will change if any of the skeleton data has changed. May be null. */
|
||||
hash = null;
|
||||
// Nonessential
|
||||
/** The dopesheet FPS in Spine. Available only when nonessential data was exported. */
|
||||
fps = 30;
|
||||
/** The path to the images folder as defined in Spine. Available only when nonessential data was exported. May be null. */
|
||||
imagesPath = null;
|
||||
/** The path to the audio folder as defined in Spine. Available only when nonessential data was exported. May be null. */
|
||||
audioPath = null;
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findBone(boneName) {
|
||||
if (!boneName)
|
||||
throw new Error("boneName cannot be null.");
|
||||
const bones = this.bones;
|
||||
for (let i = 0, n = bones.length; i < n; i++)
|
||||
if (bones[i].name === boneName)
|
||||
return bones[i];
|
||||
return null;
|
||||
}
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findSlot(slotName) {
|
||||
if (!slotName)
|
||||
throw new Error("slotName cannot be null.");
|
||||
const slots = this.slots;
|
||||
for (let i = 0, n = slots.length; i < n; i++)
|
||||
if (slots[i].name === slotName)
|
||||
return slots[i];
|
||||
return null;
|
||||
}
|
||||
/** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findSkin(skinName) {
|
||||
if (!skinName)
|
||||
throw new Error("skinName cannot be null.");
|
||||
const skins = this.skins;
|
||||
for (let i = 0, n = skins.length; i < n; i++)
|
||||
if (skins[i].name === skinName)
|
||||
return skins[i];
|
||||
return null;
|
||||
}
|
||||
/** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @returns May be null. */
|
||||
findEvent(eventDataName) {
|
||||
if (!eventDataName)
|
||||
throw new Error("eventDataName cannot be null.");
|
||||
const events = this.events;
|
||||
for (let i = 0, n = events.length; i < n; i++)
|
||||
if (events[i].name === eventDataName)
|
||||
return events[i];
|
||||
return null;
|
||||
}
|
||||
/** Collects animations used by {@link SliderData slider constraints}.
|
||||
*
|
||||
* Slider animations are designed to be applied by slider constraints rather than on their own. Applications that have a user
|
||||
* choose an animation may want to exclude them. */
|
||||
findSliderAnimations(animations) {
|
||||
const constraints = this.constraints;
|
||||
for (let i = 0, n = this.constraints.length; i < n; i++) {
|
||||
const data = constraints[i];
|
||||
if (data instanceof SliderData && data.animation != null)
|
||||
animations.push(data.animation);
|
||||
}
|
||||
return animations;
|
||||
}
|
||||
/** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
|
||||
* call it multiple times.
|
||||
* @returns May be null. */
|
||||
findAnimation(animationName) {
|
||||
if (!animationName)
|
||||
throw new Error("animationName cannot be null.");
|
||||
const animations = this.animations;
|
||||
for (let i = 0, n = animations.length; i < n; i++)
|
||||
if (animations[i].name === animationName)
|
||||
return animations[i];
|
||||
return null;
|
||||
}
|
||||
// --- Constraints.
|
||||
/** Finds a constraint of the specified type by comparing each constraints's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times. */
|
||||
// biome-ignore lint/suspicious/noExplicitAny: reference runtime does not restrict to specific types
|
||||
findConstraint(constraintName, type) {
|
||||
if (!constraintName)
|
||||
throw new Error("constraintName cannot be null.");
|
||||
if (type == null)
|
||||
throw new Error("type cannot be null.");
|
||||
const constraints = this.constraints;
|
||||
for (let i = 0, n = this.constraints.length; i < n; i++) {
|
||||
const constraint = constraints[i];
|
||||
if (constraint instanceof type && constraint.name === constraintName)
|
||||
return constraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2tlbGV0b25EYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NrZWxldG9uRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFRL0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRzdDOzs7WUFHWTtBQUNaLE1BQU0sT0FBTyxZQUFZO0lBRXhCLDZHQUE2RztJQUM3RyxJQUFJLEdBQWtCLElBQUksQ0FBQztJQUUzQix5RkFBeUY7SUFDekYsS0FBSyxHQUFHLEVBQWdCLENBQUMsQ0FBQyx5QkFBeUI7SUFFbkQseURBQXlEO0lBQ3pELEtBQUssR0FBRyxFQUFnQixDQUFDLENBQUMseUJBQXlCO0lBRW5ELEtBQUssR0FBRyxFQUFZLENBQUM7SUFFckI7OztzQkFHa0I7SUFDbEIsV0FBVyxHQUFnQixJQUFJLENBQUM7SUFFaEMsNkJBQTZCO0lBQzdCLE1BQU0sR0FBRyxFQUFpQixDQUFDO0lBRTNCLGlDQUFpQztJQUNqQyxVQUFVLEdBQUcsRUFBaUIsQ0FBQztJQUUvQixxQ0FBcUM7SUFDckMsb0dBQW9HO0lBQ3BHLFdBQVcsR0FBRyxFQUFnQyxDQUFDO0lBRS9DLHNGQUFzRjtJQUN0RixDQUFDLEdBQVcsQ0FBQyxDQUFDO0lBRWQsc0ZBQXNGO0lBQ3RGLENBQUMsR0FBVyxDQUFDLENBQUM7SUFFZCwrRUFBK0U7SUFDL0UsS0FBSyxHQUFXLENBQUMsQ0FBQztJQUVsQixnRkFBZ0Y7SUFDaEYsTUFBTSxHQUFXLENBQUMsQ0FBQztJQUVuQjtpQkFDYTtJQUNiLGNBQWMsR0FBRyxHQUFHLENBQUM7SUFFckIsbUVBQW1FO0lBQ25FLE9BQU8sR0FBa0IsSUFBSSxDQUFDO0lBRTlCLDJHQUEyRztJQUMzRyxJQUFJLEdBQWtCLElBQUksQ0FBQztJQUUzQixlQUFlO0lBQ2Ysc0ZBQXNGO0lBQ3RGLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFFVCww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
Line truncated
|
||||
@@ -0,0 +1,55 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
import type { Attachment, VertexAttachment } from "./attachments/Attachment.js";
|
||||
import type { AttachmentLoader } from "./attachments/AttachmentLoader.js";
|
||||
import { Sequence } from "./attachments/Sequence.js";
|
||||
import { SkeletonData } from "./SkeletonData.js";
|
||||
import { Skin } from "./Skin.js";
|
||||
/** Loads skeleton data in the Spine JSON format.
|
||||
*
|
||||
* See [Spine JSON format](http://esotericsoftware.com/spine-json-format) and
|
||||
* [JSON and binary data](http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data) in the Spine
|
||||
* Runtimes Guide. */
|
||||
export declare class SkeletonJson {
|
||||
attachmentLoader: AttachmentLoader;
|
||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
||||
* runtime than were used in Spine.
|
||||
*
|
||||
* See [Scaling](http://esotericsoftware.com/spine-loading-skeleton-data#Scaling) in the Spine Runtimes Guide. */
|
||||
scale: number;
|
||||
private readonly linkedMeshes;
|
||||
constructor(attachmentLoader: AttachmentLoader);
|
||||
readSkeletonData(json: string | any): SkeletonData;
|
||||
private fromProperty;
|
||||
private propertyScale;
|
||||
readAttachment(map: any, skin: Skin, slotIndex: number, placeholder: string, skeletonData: SkeletonData): Attachment | null;
|
||||
readSequence(map: object): Sequence;
|
||||
readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
|
||||
readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
|
||||
}
|
||||
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user