babylonjs-serializers 8.41.1 → 8.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babylon.glTF2Serializer.min.js","mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,EAAQG,QAAQ,cACR,mBAAXC,QAAyBA,OAAOC,IAC9CD,OAAO,wBAAyB,CAAC,aAAcJ,GACrB,iBAAZC,QACdA,QAAQ,yBAA2BD,EAAQG,QAAQ,cAEnDJ,EAAkB,YAAIC,EAAQD,EAAc,QAC7C,CATD,CASoB,oBAATO,KAAuBA,KAAyB,oBAAXC,OAAyBA,OAASC,MAAQC,G,kCCT1FP,EAAOD,QAAUQ,C,GCCbC,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaZ,QAGrB,IAAIC,EAASQ,EAAyBE,GAAY,CAGjDX,QAAS,CAAC,GAOX,OAHAc,EAAoBH,GAAUV,EAAQA,EAAOD,QAASU,GAG/CT,EAAOD,OACf,CCrBAU,EAAoBK,EAAI,CAACf,EAASgB,KACjC,IAAI,IAAIC,KAAOD,EACXN,EAAoBQ,EAAEF,EAAYC,KAASP,EAAoBQ,EAAElB,EAASiB,IAC5EE,OAAOC,eAAepB,EAASiB,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3EP,EAAoBa,EAAI,WACvB,GAA0B,iBAAfC,WAAyB,OAAOA,WAC3C,IACC,OAAOjB,MAAQ,IAAIkB,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAXC,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBjB,EAAoBQ,EAAI,CAACU,EAAKC,IAAUV,OAAOW,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFnB,EAAoBuB,EAAKjC,IACH,oBAAXkC,QAA0BA,OAAOC,aAC1ChB,OAAOC,eAAepB,EAASkC,OAAOC,YAAa,CAAEC,MAAO,WAE7DjB,OAAOC,eAAepB,EAAS,aAAc,CAAEoC,OAAO,K,0+ECHhD,IAAIC,EAA2B,E,SCItC,0BAIoB,KAAAC,MAA+C,CAAC,CAmBpE,QAdI,sBAAW,wBAAS,C,IAApB,WACI,OAAO/B,KAAK+B,KAChB,E,gCAKO,YAAAC,cAAP,WACI,IAAK,IAAMtB,KAAOV,KAAK+B,MAAO,CAC1B,IAAMF,EAAQ7B,KAAK+B,MAAMrB,GACnBuB,EAAO,IAAIC,KAAK,CAACL,GAAQ,CAAEM,MAAM,IAAAC,aAAY1B,KACnD,EAAA2B,MAAMC,SAASL,EAAMvB,EACzB,CACJ,EACJ,EAvBA,GCyBW6B,EAAW,WAQpB,OAPAA,EAAW3B,OAAO4B,QAAU,SAAkBC,GAC1C,IAAK,IAAIC,EAAGC,EAAI,EAAGC,EAAIC,UAAUC,OAAQH,EAAIC,EAAGD,IAE5C,IAAK,IAAII,KADTL,EAAIG,UAAUF,GACO/B,OAAOW,UAAUC,eAAeC,KAAKiB,EAAGK,KAAIN,EAAEM,GAAKL,EAAEK,IAE9E,OAAON,CACX,EACOF,EAASS,MAAMhD,KAAM6C,UAC9B,EA0EO,SAASI,EAAUC,EAASC,EAAYC,EAAGC,GAEhD,OAAO,IAAKD,IAAMA,EAAIE,WAAU,SAAUC,EAASC,GAC/C,SAASC,EAAU5B,GAAS,IAAM6B,EAAKL,EAAUM,KAAK9B,GAAS,CAAE,MAAOV,GAAKqC,EAAOrC,EAAI,CAAE,CAC1F,SAASyC,EAAS/B,GAAS,IAAM6B,EAAKL,EAAiB,MAAExB,GAAS,CAAE,MAAOV,GAAKqC,EAAOrC,EAAI,CAAE,CAC7F,SAASuC,EAAKG,GAJlB,IAAehC,EAIagC,EAAOC,KAAOP,EAAQM,EAAOhC,QAJ1CA,EAIyDgC,EAAOhC,MAJhDA,aAAiBuB,EAAIvB,EAAQ,IAAIuB,GAAE,SAAUG,GAAWA,EAAQ1B,EAAQ,KAIjBkC,KAAKN,EAAWG,EAAW,CAC7GF,GAAML,EAAYA,EAAUL,MAAME,EAASC,GAAc,KAAKQ,OAClE,GACF,CAEO,SAASK,EAAYd,EAASe,GACnC,IAAsGC,EAAGC,EAAG1B,EAAxG2B,EAAI,CAAEC,MAAO,EAAGC,KAAM,WAAa,GAAW,EAAP7B,EAAE,GAAQ,MAAMA,EAAE,GAAI,OAAOA,EAAE,EAAI,EAAG8B,KAAM,GAAIC,IAAK,IAAexD,EAAIJ,OAAO6D,QAA4B,mBAAbC,SAA0BA,SAAW9D,QAAQW,WACtL,OAAOP,EAAE2C,KAAOgB,EAAK,GAAI3D,EAAS,MAAI2D,EAAK,GAAI3D,EAAU,OAAI2D,EAAK,GAAsB,mBAAXhD,SAA0BX,EAAEW,OAAOiD,UAAY,WAAa,OAAO5E,IAAM,GAAIgB,EAC1J,SAAS2D,EAAK/B,GAAK,OAAO,SAAUiC,GAAK,OACzC,SAAcC,GACV,GAAIZ,EAAG,MAAM,IAAIa,UAAU,mCAC3B,KAAO/D,IAAMA,EAAI,EAAG8D,EAAG,KAAOV,EAAI,IAAKA,OACnC,GAAIF,EAAI,EAAGC,IAAM1B,EAAY,EAARqC,EAAG,GAASX,EAAU,OAAIW,EAAG,GAAKX,EAAS,SAAO1B,EAAI0B,EAAU,SAAM1B,EAAEhB,KAAK0C,GAAI,GAAKA,EAAER,SAAWlB,EAAIA,EAAEhB,KAAK0C,EAAGW,EAAG,KAAKhB,KAAM,OAAOrB,EAE3J,OADI0B,EAAI,EAAG1B,IAAGqC,EAAK,CAAS,EAARA,EAAG,GAAQrC,EAAEZ,QACzBiD,EAAG,IACP,KAAK,EAAG,KAAK,EAAGrC,EAAIqC,EAAI,MACxB,KAAK,EAAc,OAAXV,EAAEC,QAAgB,CAAExC,MAAOiD,EAAG,GAAIhB,MAAM,GAChD,KAAK,EAAGM,EAAEC,QAASF,EAAIW,EAAG,GAAIA,EAAK,CAAC,GAAI,SACxC,KAAK,EAAGA,EAAKV,EAAEI,IAAIQ,MAAOZ,EAAEG,KAAKS,MAAO,SACxC,QACI,MAAkBvC,GAAZA,EAAI2B,EAAEG,MAAYzB,OAAS,GAAKL,EAAEA,EAAEK,OAAS,KAAkB,IAAVgC,EAAG,IAAsB,IAAVA,EAAG,IAAW,CAAEV,EAAI,EAAG,QAAU,CAC3G,GAAc,IAAVU,EAAG,MAAcrC,GAAMqC,EAAG,GAAKrC,EAAE,IAAMqC,EAAG,GAAKrC,EAAE,IAAM,CAAE2B,EAAEC,MAAQS,EAAG,GAAI,KAAO,CACrF,GAAc,IAAVA,EAAG,IAAYV,EAAEC,MAAQ5B,EAAE,GAAI,CAAE2B,EAAEC,MAAQ5B,EAAE,GAAIA,EAAIqC,EAAI,KAAO,CACpE,GAAIrC,GAAK2B,EAAEC,MAAQ5B,EAAE,GAAI,CAAE2B,EAAEC,MAAQ5B,EAAE,GAAI2B,EAAEI,IAAIS,KAAKH,GAAK,KAAO,CAC9DrC,EAAE,IAAI2B,EAAEI,IAAIQ,MAChBZ,EAAEG,KAAKS,MAAO,SAEtBF,EAAKb,EAAKxC,KAAKyB,EAASkB,EAC5B,CAAE,MAAOjD,GAAK2D,EAAK,CAAC,EAAG3D,GAAIgD,EAAI,CAAG,CAAE,QAAUD,EAAIzB,EAAI,CAAG,CACzD,GAAY,EAARqC,EAAG,GAAQ,MAAMA,EAAG,GAAI,MAAO,CAAEjD,MAAOiD,EAAG,GAAKA,EAAG,QAAK,EAAQhB,MAAM,EAC9E,CAtBgDJ,CAAK,CAACd,EAAGiC,GAAK,CAAG,CAuBnE,CA+DO,SAASK,EAAcC,EAAIC,EAAMC,GACtC,GAAIA,GAA6B,IAArBxC,UAAUC,OAAc,IAAK,IAA4BwC,EAAxB3C,EAAI,EAAG4C,EAAIH,EAAKtC,OAAYH,EAAI4C,EAAG5C,KACxE2C,GAAQ3C,KAAKyC,IACRE,IAAIA,EAAKE,MAAMjE,UAAUkE,MAAMhE,KAAK2D,EAAM,EAAGzC,IAClD2C,EAAG3C,GAAKyC,EAAKzC,IAGrB,OAAOwC,EAAGO,OAAOJ,GAAME,MAAMjE,UAAUkE,MAAMhE,KAAK2D,GACpD,CArE6BxE,OAAO6D,OA2GX7D,OAAO6D,OAoEkB,mBAApBkB,iBAAiCA,gBCxS/D,IAAMC,EAAU,KACVC,EAAqB,IAAI,EAAAC,OAAO,IAAM,IAAM,KAC5CC,EAAmB,KACnBC,EAAQ,EAAAF,OAAOE,QACfC,EAAQ,EAAAH,OAAOI,cA0CrB,SAASC,EAAoBC,GACzB,OAAQA,GACJ,IAAK,aACL,IAAK,YACL,IAAK,aACL,IAAK,aACL,IAAK,aACD,OAAO,EACX,QACI,OAAO,EAEnB,CAOA,SAAeC,EAAoBC,G,sGAE/B,OADMC,EAAkBD,EAAeE,uBACY,IAA3BD,EAAgBE,OAGpCF,EAAgBG,QACT,CAAP,EAAO,OAGLC,EAASJ,EAAgBK,QAG3BR,EAAYE,EAA2BF,SAEtCO,EAAD,MACO,GAAM,EAAAtE,MAAMwE,cAAcN,EAAgBO,OAZ1C,CAAP,EAAO,M,cAYPC,EAAO,SACPX,GAAW,IAAAhE,aAAYmE,EAAgBO,MAAQV,E,qBACxCY,YAAYC,OAAON,IAC1BI,EAAOJ,EAAOA,OAAOlB,MAAMkB,EAAOO,WAAYP,EAAOO,WAAaP,EAAOQ,Y,QADlE,M,cAEAR,aAAkBK,aACzBD,EAAOJ,E,QADA,M,cAEAA,aAAkBzE,KAClB,GAAMyE,EAAOS,eADb,M,cACPL,EAAO,SACPX,EAAWO,EAAOxE,MAAQiE,E,oBACD,iBAAXO,EAAP,MACA,GAAM,EAAAtE,MAAMwE,cAAcF,I,cAAjCI,EAAO,SACPX,GAAW,IAAAhE,aAAYuE,IAAWP,E,oBACC,oBAArBiB,kBAAoCV,aAAkBU,iBAC7D,GAAM,EAAAhF,MAAMwE,cAAcF,EAAOW,MADjC,O,OACPP,EAAO,SACPX,GAAW,IAAAhE,aAAYuE,EAAOW,MAAQlB,E,mBAG1C,OAAIW,GAAQZ,EAAoBC,GACrB,CAAP,EAAO,IAAIlE,KAAK,CAAC6E,GAAO,CAAE5E,KAAMiE,KAG7B,CAAP,EAAO,M,OAWJ,SAASmB,EAAeC,EAAiBC,EAAkBC,GAC9D,GAAID,EAAW5B,EAAmBnE,EAC9B,OAAO,EAGX,IAAMiG,EAAI9B,EAAmBnE,EACvBkG,EAAKJ,EAAUE,GAA6B,EAAM7B,EAAmBnE,GAAK+F,EAAW,EAAM5B,EAAmBnE,EAE9GlB,EAAIoH,EAAIA,EAAI,EAAMD,GADd9B,EAAmBnE,EAAI+F,GAEjC,OAAO,EAAAI,OAAOC,QAAQF,EAAIG,KAAKC,KAAKxH,KAAO,EAAMmH,GAAI,EAAG,EAC5D,CAMO,SAASM,EAAmCC,GAC/C,IAAMV,EAAUU,EAAwBC,aAAaC,cAAcF,EAAwBG,WAAWC,YAAYC,yBAAyBC,MAAM,IAC3IC,EAAUP,EAAwBQ,MAClCC,EAAgB,EAAAd,OAAOC,MAAMI,EAAwBS,cAAe,EAAG5C,GAEvE6C,GAAY,IAAAC,0BAAyBF,GAQ3C,MANgE,CAC5DG,gBAAiB,CAACtB,EAAQ9F,EAAG8F,EAAQxG,EAAGwG,EAAQI,EAAGa,GACnDM,eAAgB,EAChBC,gBAAiBJ,EAIzB,CAOA,SAASK,EAAaC,EAAyBC,GACvCA,EAAgBC,oBAChBF,EAAaG,UAAY,QAClBF,EAAgBG,qBACvBJ,EAAaG,UAAY,OACzBH,EAAaK,YAAcJ,EAAgBK,YAEnD,CAEA,SAASC,EAAmBC,EAAeC,EAAgBC,GAGvD,IAFA,IAAM7C,EAAO,IAAI8C,WAAWH,EAAQC,EAAS,GAEpChH,EAAI,EAAGA,EAAIoE,EAAKjE,OAAQH,GAAQ,EACrCoE,EAAKpE,GAAKoE,EAAKpE,EAAI,GAAKoE,EAAKpE,EAAI,GAAKoE,EAAKpE,EAAI,GAAK,IAKxD,OAFmB,EAAAmH,WAAWC,kBAAkBhD,EAAM2C,EAAOC,EAAQC,EAGzE,CAEA,SAASI,EAA2BC,GAChC,GAAIA,aAAkBJ,WAAY,CAG9B,IAFA,IAAM,EAASI,EAAOnH,OAChB6D,EAAS,IAAIuD,aAAaD,EAAOnH,QAC9BH,EAAI,EAAGA,EAAI,IAAUA,EAC1BgE,EAAOhE,GAAKsH,EAAOtH,GAAK,IAE5B,OAAOgE,CACX,CAAO,GAAIsD,aAAkBC,aACzB,OAAOD,EAEP,MAAM,IAAIE,MAAM,4BAExB,CAMA,iBAOI,WAA6BC,GAAA,KAAAA,UAAAA,EALrB,KAAAC,YAAc,IAAIC,IAGlB,KAAAC,wBAA2F,CAAC,CAE7C,CA66B3D,OA36BW,YAAAC,eAAP,SAAsBlE,G,MAClB,OAAOA,GAA+D,QAA7C,EAAAtG,KAAKqK,YAAYtJ,IAAIuF,EAAemE,iBAAS,QAAY,IACtF,EAEa,YAAAC,4BAAb,SAAyCxC,EAA2CyC,G,qHAC1EC,EAAuB3C,EAAmCC,GAE1D2C,EAAsB,CAAEC,KAAM5C,EAAwB4C,MACb,MAA3C5C,EAAwB6C,iBAA4B7C,EAAwB6C,kBACvE7C,EAAwB8C,kBACzB,EAAA3I,MAAM4I,KAAK/C,EAAwB4C,KAAO,0FAE9CD,EAASK,aAAc,GAGvBP,GACMQ,EAA4B,IAE5BC,EAAiBlD,EAAwBkD,iBAE3CD,EAASlG,KACLjF,KAAKqL,mBAAmBD,GAAgBrH,MAAK,SAACuH,GACtCA,IACAV,EAAqBW,iBAAmBD,EAEhD,MAIF,EAAcpD,EAAwBsD,cAExCL,EAASlG,KACLjF,KAAKqL,mBAAmB,GAAatH,MAAK,SAACuH,GACnCA,IACAT,EAASY,cAAgBH,EACC,IAAtB,EAAYI,QACZb,EAASY,cAAcjD,MAAQ,EAAYkD,OAGvD,MAIFC,EAAkBzD,EAAwByD,mBAE5Cd,EAASe,eAAiB,CAAC,EAAK,EAAK,GAErCT,EAASlG,KACLjF,KAAKqL,mBAAmBM,GAAiB5H,MAAK,SAACuH,GACvCA,IACAT,EAASc,gBAAkBL,EAEnC,OAIFO,EAAiB3D,EAAwB2D,iBAE3CV,EAASlG,KACLjF,KAAKqL,mBAAmBQ,GAAgB9H,MAAK,SAACuH,GAC1C,GAAIA,EAAa,CACb,IAAMQ,EAAkD,CACpDC,MAAOT,EAAYS,OAEvBlB,EAASiB,iBAAmBA,CAChC,CACJ,KAIJX,EAASrI,OAAS,GAClB9C,KAAKoK,UAAU4B,qBAAqBC,IAAI/D,GACxC,GAAM5E,QAAQ4I,IAAIf,KAFlB,OAvDJ,M,OAyDI,S,iBAmBR,OAfIjD,EAAwBQ,MAAQ,GAAOR,EAAwBiE,kBAC3DjE,EAAwBmB,YAAc,EAAA+C,UAAUC,cAChDxB,EAASxB,UAAY,QAErB,EAAAhH,MAAM4I,KAAK/C,EAAwB4C,KAAO,2CAA6C5C,EAAwBmB,UAAUiD,aAI7HpE,EAAwBqE,gBAAkBrE,EAAwBqE,cAAcC,kBAAkBvG,EAAOL,KACzGiF,EAASe,eAAiB1D,EAAwBqE,cAAcE,WAGpE5B,EAASD,qBAAuBA,EAChC3B,EAAa4B,EAAU3C,GAEvB,GAAMlI,KAAK0M,qBAAqB7B,EAAU3C,I,OAI1C,OAJA,UAEMyE,EAAY3M,KAAKoK,UAAUwC,YACvB3H,KAAK4F,GACR,CAAP,EAAO8B,EAAU7J,OAAS,G,QAGhB,YAAA4J,qBAAd,SAAmCxD,EAAyBC,G,wGACvC,SAAMnJ,KAAKoK,UAAUyC,qDAAqD,iBAAkB3D,EAAcC,I,OAI3H,IAJM2D,EAAW,SAEX3B,EAAmD,GAEpD,EAAL,EAAsB,EAAA2B,EAAA,eAAXC,EAAO,KACd5B,EAASlG,KAAKjF,KAAKqL,mBAAmB0B,IAG1C,SAAMzJ,QAAQ4I,IAAIf,I,OAElB,OAFA,SAEA,GAAMnL,KAAKoK,UAAU4C,mCAAmC,iBAAkB9D,EAAcC,I,cAAxF,S,YAUI,YAAA8D,gCAAR,SAAwCC,EAAiCC,EAAiCvD,GACtG,IAEIwD,EACAC,EAHEC,EAAeJ,EAAWA,EAASK,UAAY,CAAE7D,MAAO,EAAGC,OAAQ,GACnE6D,EAAeL,EAAWA,EAASI,UAAY,CAAE7D,MAAO,EAAGC,OAAQ,GAuBzE,OAnBI2D,EAAa5D,MAAQ8D,EAAa9D,OAE9B0D,EADAF,GAAYA,aAAoB,EAAAO,QACd,EAAAC,aAAaC,kBAAkBT,EAAUM,EAAa9D,MAAO8D,EAAa7D,QAAQ,GAElFF,EAAmB+D,EAAa9D,MAAO8D,EAAa7D,OAAQC,GAElFyD,EAAkBF,GACXG,EAAa5D,MAAQ8D,EAAa9D,OAErC2D,EADAF,GAAYA,aAAoB,EAAAM,QACd,EAAAC,aAAaC,kBAAkBR,EAAUG,EAAa5D,MAAO4D,EAAa3D,QAAQ,GAElFF,EAAmB6D,EAAa5D,MAAO4D,EAAa3D,OAAQC,GAElFwD,EAAkBF,IAElBE,EAAkBF,EAClBG,EAAkBF,GAGf,CACHD,SAAUE,EACVD,SAAUE,EAElB,EAWc,YAAAO,2DAAd,SACIxC,EACAyC,EACAC,G,mKAEM3C,EAAW,IAAI3F,MACf4F,GAAkByC,EAApB,MACO,GAAMvK,QAAQE,OAAO,8D,qCA0I5B,MAAO,CAAP,EAAO,U,cAvILoG,EAAyBwB,EAAiBA,EAAe/C,WAAawF,EAA4BA,EAA0BxF,WAAa,OAErI0F,EAAkB/N,KAAKiN,gCAAgC7B,EAAgByC,EAA2BjE,GAElGoE,EAAsC,QAAxB,EAAAD,EAAgBb,gBAAQ,eAAEK,UAE1CU,OAAa,EACbC,OAAwB,EAEtBxE,EAAQsE,EAAYtE,MACpBC,EAASqE,EAAYrE,OAEL,GAAMoE,EAAgBb,SAASiB,eAXrD,O,OAYuB,OADjBC,EAAgB,SACC,GAAML,EAAgBZ,SAASgB,c,cAAhDE,EAAiB,SAEnBD,GACAH,EAAgBjE,EAA2BoE,G,OAD3C,M,OAGO,SAAM9K,QAAQE,OAAO,oD,cAE5B6K,GACAH,EAA2BlE,EAA2BqE,G,QADtD,M,OAGO,SAAM/K,QAAQE,OAAO,gE,QAahC,IAVM2D,EAAa+G,EAAyB/G,WAEtCmH,EAA0B,IAAIzE,WAAW1C,GACzCoH,EAAkB,IAAI1E,WAAW1C,GAGjCqH,EAAe,IAAI,EAAA1I,OAAO,EAAG,EAAG,GAClC2I,EAAc,EACdC,EAAe,EAEVC,EAAI,EAAGA,EAAIhF,IAAUgF,EAC1B,IAASC,EAAI,EAAGA,EAAIlF,IAASkF,EACnBC,EAPK,GAOKnF,EAAQiF,EAAIC,GAEtBzG,EAAe,IAAI,EAAArC,OAAOmI,EAAcY,GAASZ,EAAcY,EAAS,GAAIZ,EAAcY,EAAS,IACpGzG,cAAcwB,EAAMtB,YAAYC,yBAChCuG,SAAShB,EAAQ3F,cAChB4G,EAAgB,IAAI,EAAAjJ,OAAOoI,EAAyBW,GAASX,EAAyBW,EAAS,GAAIX,EAAyBW,EAAS,IACtIzG,cAAcwB,EAAMtB,YAAYC,yBAChCuG,SAAShB,EAAQiB,eAChBC,EAAad,EAAyBW,EAAS,GAAKf,EAAQkB,WAE5DC,EAA6C,CAC/C9G,aAAcA,EACd4G,cAAeA,EACfC,WAAYA,GAGVE,EAAoBlP,KAAKmP,8CAA8CF,GAC7ET,EAAa9M,EAAIqG,KAAKqH,IAAIZ,EAAa9M,EAAGwN,EAAkBG,UAAU3N,GACtE8M,EAAaxN,EAAI+G,KAAKqH,IAAIZ,EAAaxN,EAAGkO,EAAkBG,UAAUrO,GACtEwN,EAAa5G,EAAIG,KAAKqH,IAAIZ,EAAa5G,EAAGsH,EAAkBG,UAAUzH,GACtE6G,EAAc1G,KAAKqH,IAAIX,EAAaS,EAAkBI,UACtDZ,EAAe3G,KAAKqH,IAAIV,EAAcQ,EAAkBtG,WAExD2F,EAAgBM,GAA0C,IAAhCK,EAAkBG,UAAU3N,EACtD6M,EAAgBM,EAAS,GAAqC,IAAhCK,EAAkBG,UAAUrO,EAC1DuN,EAAgBM,EAAS,GAAqC,IAAhCK,EAAkBG,UAAUzH,EAC1D2G,EAAgBM,EAAS,GAAKd,EAAgBb,SAASqC,SAAuC,IAA5BtB,EAAcY,EAAS,GAAW,IAEpGP,EAAwBO,GAAU,EAClCP,EAAwBO,EAAS,GAAoC,IAA/BK,EAAkBtG,UACxD0F,EAAwBO,EAAS,GAAmC,IAA9BK,EAAkBI,SACxDhB,EAAwBO,EAAS,GAAK,IAc9C,IATM,EAAkD,CACpDQ,UAAWb,EACXc,SAAUb,EACV7F,UAAW8F,GAGXc,GAAmC,EACnCC,GAA2B,EAEtBd,EAAI,EAAGA,EAAIhF,IAAUgF,EAC1B,IAASC,EAAI,EAAGA,EAAIlF,IAASkF,EAGzBL,EAFMmB,EAtDK,GAsDgBhG,EAAQiF,EAAIC,KAED,EAAyBS,UAAU3N,EAAIkE,EAAU,EAAyByJ,UAAU3N,EAAI,EAC9H6M,EAAgBmB,EAAoB,IAAM,EAAyBL,UAAUrO,EAAI4E,EAAU,EAAyByJ,UAAUrO,EAAI,EAClIuN,EAAgBmB,EAAoB,IAAM,EAAyBL,UAAUzH,EAAIhC,EAAU,EAAyByJ,UAAUzH,EAAI,EAE5H+H,EAAuB,EAAA7J,OAAO8J,SAChCrB,EAAgBmB,GAChBnB,EAAgBmB,EAAoB,GACpCnB,EAAgBmB,EAAoB,IAElCG,EAAqBF,EAAqBG,aAAalG,EAAMtB,YAAYC,yBAC/EgG,EAAgBmB,GAA4C,IAAvBG,EAAmBnO,EACxD6M,EAAgBmB,EAAoB,GAA4B,IAAvBG,EAAmB7O,EAC5DuN,EAAgBmB,EAAoB,GAA4B,IAAvBG,EAAmBjI,EAEvDiI,EAAmBrD,kBAAkBxG,EAAOJ,KAC7C6J,GAA2B,GAG/BnB,EAAwBoB,EAAoB,IAAM,EAAyB9G,UAAahD,EAAU,EAAyBgD,UAAa,EACxI0F,EAAwBoB,EAAoB,IAAM,EAAyBJ,SAAY1J,EAAU,EAAyB0J,SAAY,EAEvG,EAAAxJ,OAAO8J,SAAS,IAAKtB,EAAwBoB,EAAoB,GAAIpB,EAAwBoB,EAAoB,IAEpHlD,kBAAkBxG,EAAOJ,KACjD4J,GAAmC,GAoBxC,OAfHA,GACArE,EAASlG,MACL,IAAA8K,kBAAiBzB,EAAyB5E,EAAOC,GAAQ5F,MAAK,SAACgD,GAC3D,EAAyBiJ,6BAA+BjJ,CAC5D,KAGJ0I,GACAtE,EAASlG,MACL,IAAA8K,kBAAiBxB,EAAiB7E,EAAOC,GAAQ5F,MAAK,SAACgD,GACnD,EAAyBkJ,qBAAuBlJ,CACpD,KAID,GAAMzD,QAAQ4I,IAAIf,GAAUpH,MAAK,WACpC,OAAO,CACX,K,QAEO,SAAMT,QAAQE,OAAO,2F,QAS5B,YAAA2L,8CAAR,SAAsDF,GAClD,IAAMiB,EAA6BlQ,KAAKmQ,wBAAwBlB,EAAmB9G,cAC7EiI,EAA8BpQ,KAAKmQ,wBAAwBlB,EAAmBF,eAC9ErH,EAA2B,EAAI1H,KAAKqQ,iBAAiBpB,EAAmBF,eACxEO,EAAW/H,EAAe2I,EAA4BE,EAA6B1I,GACnF4I,EAAuBrB,EAAmB9G,aAAaK,MAAMd,GAA4B,EAAM7B,EAAmBnE,GAAKqG,KAAKqH,IAAI,EAAIE,EAAU1J,IAC9I2K,EAAwBtB,EAAmBF,cAAcyB,SAAS3K,EAAmB2C,MAAM,EAAI8G,IAAW9G,MAAM,EAAIT,KAAKqH,IAAIE,EAAU1J,IACzIyJ,EAAY,EAAAvJ,OAAO2K,KAAKH,EAAsBC,EAAuBjB,EAAWA,GASpF,MANiD,CAC7CD,UAHJA,EAAYA,EAAUqB,WAAW,EAAG,EAAGrB,GAInCC,SAAUA,EACV1G,UAAW,EAAIqG,EAAmBD,WAI1C,EAOQ,YAAAmB,wBAAR,SAAgCQ,GAC5B,OAAO5I,KAAKC,KAAK,KAAQ2I,EAAMjP,EAAIiP,EAAMjP,EAAI,KAAQiP,EAAM3P,EAAI2P,EAAM3P,EAAI,KAAQ2P,EAAM/I,EAAI+I,EAAM/I,EACrG,EAOQ,YAAAyI,iBAAR,SAAyBM,GACrB,OAAO5I,KAAKqH,IAAIuB,EAAMjP,EAAGqG,KAAKqH,IAAIuB,EAAM3P,EAAG2P,EAAM/I,GACrD,EAec,YAAAgJ,kDAAd,SACIvB,EACAC,EACA1G,EACAiI,EACAC,EACAC,EACAC,EACAC,EACAtG,G,8HAEMQ,EAA4B,GAE5B+D,EAA2C,CAC7CG,UAAWA,EACXC,SAAUA,EACV1G,UAAWA,GAGX+B,IACIqG,aAA8B,EAAAE,iBAC1BF,EAAmBG,wBAEbC,EAAWP,GAAiBA,EAAcrK,qBAAuBqK,EAAcrK,qBAAsBiE,SAAW,EAChH4G,EACFL,EAAmBG,wBAA0BH,EAAmBG,uBAAuB3K,qBACjFwK,EAAmBG,uBAAuB3K,qBAAsBiE,SAChE,EACJ,EAAW6G,OAAO,UAAGF,GAAQ,OAAGC,KAChCE,EAAcvR,KAAKqK,YAAYtJ,IAAI,IAErCkQ,EAAyB1F,iBAAmBgG,EAE5CpG,EAASlG,MACL,IAAAuM,oBACI,2BACA,IAAAC,yBACIZ,GAAgB,IAAAa,oBAAmBb,EAAe,IAAK,IAAAc,qBAAoB,GAC3Ed,GAAgB,IAAAa,oBAAmBb,EAAe,IAAK,IAAAc,qBAAoB,GAC3Ed,GAAgB,IAAAa,oBAAmBb,EAAe,IAAK,IAAAc,qBAAoB,IAC3E,IAAAD,oBAAmBV,EAAmBG,uBAAwB,IAElEH,EAAmB3I,YACrBtE,MAAK,SAAO6N,GAAa,qC,wDACH,SAAM5R,KAAKqL,mBAAmBuG,EAAe,I,cAA3DL,EAAc,YAEhBN,EAAyB1F,iBAAmBgG,G,gBAMxDV,GACA1F,EAASlG,KACLjF,KAAKqL,mBAAmBwF,GAAe9M,MAAK,SAACwN,GACrCA,IACAN,EAAyB1F,iBAAmBgG,EAEpD,KAIRP,EAAmBa,qCAAuCf,EAC1D3F,EAASlG,KACLjF,KAAKqL,mBAAmByF,GAAiB/M,MAAK,SAACwN,GACvCA,IACAN,EAAyBa,yBAA2BP,EAE5D,MAEGR,GAAoBD,KACrBiB,EAAajB,GAAmBA,EAAgBtK,qBAAuBsK,EAAgBtK,qBAAsBiE,SAAW,EACxHuH,EAAcjB,GAAoBA,EAAiBvK,qBAAuBuK,EAAiBvK,qBAAsBiE,SAAW,EAC5H,EAAW6G,OAAO,UAAGS,GAAU,OAAGC,KAClCT,EAAcvR,KAAKqK,YAAYtJ,IAAI,IAErCkQ,EAAyBa,yBAA2BP,EAEpDpG,EAASlG,MACL,IAAAuM,oBACI,qBACA,IAAAC,yBACIT,EAAmBiB,yBAA0B,IAAAP,oBAAmBV,EAAmBiB,wBAAyB,IAAK,IAAAN,qBAAoB,GACrIZ,GAAmB,IAAAW,oBAAmBX,EAAkB,IAAK,IAAAY,qBAAoB,GACjFb,GAAkB,IAAAY,oBAAmBZ,EAAiB,IAAK,IAAAa,qBAAoB,IAEnFX,EAAmB3I,YACrBtE,MAAK,SAAO6N,GAAa,qC,wDACH,SAAM5R,KAAKqL,mBAAmBuG,EAAe,I,cAA3DL,EAAc,YAEhBN,EAAyBa,yBAA2BP,G,kBAOpEV,GACA1F,EAASlG,KACLjF,KAAKqL,mBAAmBwF,GAAe9M,MAAK,SAACwN,GACrCA,IACAN,EAAyB1F,iBAAmBgG,EAEpD,KAGJT,GACA3F,EAASlG,KACLjF,KAAKqL,mBAAmByF,GAAiB/M,MAAK,SAACwN,GACvCA,IACAN,EAAyBa,yBAA2BP,EAE5D,OAMZpG,EAASrI,OAAS,GAClB9C,KAAKoK,UAAU4B,qBAAqBC,IAAI+E,GACxC,GAAM1N,QAAQ4I,IAAIf,KAFlB,M,OAEA,S,iBAGJ,MAAO,CAAP,EAAO+D,G,QAGH,YAAAgD,mBAAR,SAA2BnF,GACvB,IAAMoF,EAAoB,CAAC,EAC3B,KAAKpF,GAAaA,aAAmB,EAAAU,SACjC,OAAO0E,EAGX,IAAMC,EAAQpS,KAAKqS,wBAAwBtF,EAAQuF,OACrC,QAAVF,IACAD,EAAQC,MAAQA,GAGpB,IAAMG,EAAQvS,KAAKqS,wBAAwBtF,EAAQyF,OAKnD,OAJc,QAAVD,IACAJ,EAAQI,MAAQA,GAGZxF,EAAQ0F,cACZ,KAAK,EAAAhF,QAAQiF,cACTP,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQoF,eACTV,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQqF,eACTX,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQsF,yBACTZ,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQuF,gBACTb,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQwF,0BACTd,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQyF,0BACTf,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQ0F,yBACThB,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQ2F,0BACTjB,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQ4F,wBACTlB,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQ6F,yBACTnB,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KACpB,MAEJ,KAAK,EAAAnF,QAAQ8F,2BACTpB,EAAQQ,UAAY,KACpBR,EAAQS,UAAY,KAK5B,OAAOT,CACX,EAEQ,YAAAE,wBAAR,SAAgCmB,GAC5B,OAAQA,GACJ,KAAK,EAAA/F,QAAQgG,iBACT,OAAO,MAEX,KAAK,EAAAhG,QAAQiG,kBACT,OAAO,MAEX,KAAK,EAAAjG,QAAQkG,mBACT,OAAO,MAEX,QAEI,OADA,EAAAtR,MAAM8H,MAAM,wCAAiCqJ,EAAQ,MAC9C,MAGnB,EASc,YAAAI,iDAAd,SACI5C,EACApG,EACAD,G,qHAEMkJ,EAAoC,CACtC1L,aAAc6I,EAAmB8C,aACjC/E,cAAeiC,EAAmB+C,mBAClC/E,WAAYgC,EAAmBgD,eAG7BnD,EAAgBG,EAAmBiD,eACnCC,EAAsBlD,EAAmBmD,qBACzCC,EAA0CpD,EAAmBqD,0CAC/DH,GAAwBE,EAAxB,MACO,GAAM9Q,QAAQE,OAAO,gH,OAA5B,MAAO,CAAP,EAAO,U,cAGNqN,GAAiBqD,IAAwBvJ,GAC1C3K,KAAKoK,UAAU4B,qBAAqBC,IAAI+E,GAElCsD,EAAetU,KAAKuU,sBAAsB1D,GAAiBqD,GAChC,GAAMlU,KAAK4N,2DAA2DiD,EAAeqD,EAAqBL,KAJ3I,M,cAIMW,EAA2B,SAE3B1H,EAAW9M,KAAKoK,UAAUqK,UAE5BD,EAAyBvE,qBACN,GAAMjQ,KAAK0U,kBAAkB,mBAAY5H,EAAShK,QAAU0R,EAAyBvE,uBADxG,M,OACM0E,EAAa,SACnB/J,EAAqBW,iBAAmBvL,KAAK4U,mBAAmBD,EAAYL,EAAczD,aAAa,EAAbA,EAAegE,kB,wBAGzGL,EAAyBxE,6BACN,GAAMhQ,KAAK0U,kBAAkB,2BAAoB5H,EAAShK,QAAU0R,EAAyBxE,+BADhH,M,OACM2E,EAAa,SACnB/J,EAAqBkH,yBAA2B9R,KAAK4U,mBAAmBD,EAAYL,EAAcJ,aAAmB,EAAnBA,EAAqBW,kB,iBAG3H,MAAO,CAAP,EAAOL,G,OAEP,MAAO,CAAP,EAAOxU,KAAKmP,8CAA8C0E,I,QAIrD,YAAAiB,uBAAb,SAAoC9D,EAAqCrG,G,qHAC/DsG,EAA0D,CAAC,EAE3D/H,EAA0B,CAC5B4B,KAAMkG,EAAmBlG,OAGvBiK,EAAuB/D,EAAmBgE,wBAGtCC,EAAcjE,EAAmB8C,aACjCpL,EAAQsI,EAAmBtI,MAC7BuM,IACAhE,EAAyBnI,gBAAkB,CAACmM,EAAYvT,EAAGuT,EAAYjU,EAAGiU,EAAYrN,EAAGc,KAIvEqM,EACpB,GAAM/U,KAAK4Q,kDACPI,EAAmB8C,aACnB9C,EAAmBkE,UACnBlE,EAAmBmE,WACnBnE,EAAmBiD,eACnBjD,EAAmBoE,iBACnBpE,EAAmBoE,iBACnBpE,EACAC,EACAtG,IAVgB,M,cACpB,W,aAWA,SAAM3K,KAAK4T,iDAAiD5C,EAAoBC,EAA0BtG,I,OAA1G,W,iBAEN,OAdMuE,EAAoB,EAc1B,GAAMlP,KAAKqV,sCAAsCnG,EAAmB8B,EAAoB9H,EAAc+H,EAA0BtG,I,OAChI,OADA,SACA,GAAM3K,KAAK0M,qBAAqBxD,EAAc8H,I,OAI9C,OAJA,UAEMrE,EAAY3M,KAAKoK,UAAUwC,YACvB3H,KAAKiE,GACR,CAAP,EAAOyD,EAAU7J,OAAS,G,QAGhB,YAAAuS,sCAAd,SACInG,EACA8B,EACA9H,EACA+H,EACAtG,G,sHAEA1B,EAAaC,EAAc8H,GAEtB9B,EAAkBG,UAAU7C,kBAAkBxG,EAAOJ,IAAa,EAAAiC,OAAOyN,cAActE,EAAmBtI,MAAO,EAAG9C,KACrHqL,EAAyBnI,gBAAkB,CAACoG,EAAkBG,UAAU3N,EAAGwN,EAAkBG,UAAUrO,EAAGkO,EAAkBG,UAAUzH,EAAGoJ,EAAmBtI,QAG9H,MAA9BwG,EAAkBI,UAAmD,IAA/BJ,EAAkBI,WACxD2B,EAAyBlI,eAAiBmG,EAAkBI,UAE7B,MAA/BJ,EAAkBtG,WAAqD,IAAhCsG,EAAkBtG,YACzDqI,EAAyBjI,gBAAkBkG,EAAkBtG,WAGvB,MAAtCoI,EAAmBjG,iBAA4BiG,EAAmBjG,kBAC7DiG,EAAmBuE,mBACpB,EAAAlT,MAAM4I,KAAK+F,EAAmBlG,KAAO,0FAEzC5B,EAAagC,aAAc,GAG3BP,GACMQ,EAA4B,IAE5B,EAAc6F,aAA8B,EAAAwE,gBAAkBxE,EAAmByE,aAAezE,EAAmB0E,wBAErHvK,EAASlG,KACLjF,KAAKqL,mBAAmB,GAAatH,MAAK,SAACwN,GACnCA,IACArI,EAAauC,cAAgB8F,EACH,IAAtB,EAAY7F,QACZxC,EAAauC,cAAcjD,MAAQ,EAAYkD,OAG3D,MAIF,EAAiBsF,aAA8B,EAAAwE,gBAAkBxE,EAAmB2E,gBAAkB3E,EAAmBiB,0BAE3H9G,EAASlG,KACL,IAAI3B,SAAgC,SAAOC,GAAO,qC,qEAC1CyN,aAA8B,EAAAE,iBAAmBD,EAAyBa,0BAGpEwC,EAAetU,KAAKuU,sBAAsB,GAC1CI,EAAa3U,KAAKoK,UAAUqK,UAAUxD,EAAyBa,yBAAyB/F,OAAOtF,OAC/F6E,EAActL,KAAK4U,mBAAmBD,EAAYL,EAAc,EAAeO,kBACrF7U,KAAKqK,YAAYuL,IAAI,EAAenL,SAAUa,GAC9CtL,KAAKoK,UAAUyL,8BAA8B,WAAYvK,EAAa,GAC/D,CAAP,EAAO/H,EAAQ+H,KARf,M,OAUe,OAAR,EAAA/H,EAAQ,GAAMvD,KAAKqL,mBAAmB,I,OAA7C,MAAO,CAAP,EAAO,gBAAQ,Y,UAEpBtH,MAAK,SAAOwN,GAAW,qC,wCAClBA,IACMzF,EAAkD,CACpDC,MAAOwF,EAAYxF,MACnB+J,SAAUvE,EAAYuE,SACtBC,WAAYxE,EAAYwE,YAG5B7M,EAAa4C,iBAAmBA,EAC5BkF,aAA8B,EAAAwE,gBAC9B1J,EAAiBkK,SAAWhF,EAAmBiF,wBAE/CnK,EAAiBkK,SAAWhF,EAAmBiB,wBAAyBvG,O,eAOtFC,EAAkBqF,aAA8B,EAAAwE,gBAAkBxE,EAAmBkF,iBAAmBlF,EAAmBmF,uBAE7HhL,EAASlG,KACLjF,KAAKqL,mBAAmBM,GAAiB5H,MAAK,SAACwN,GACvCA,IACArI,EAAayC,gBAAkB4F,EAEvC,KAIJpG,EAASrI,OAAS,GAClB9C,KAAKoK,UAAU4B,qBAAqBC,IAAI+E,GACxC,GAAM1N,QAAQ4I,IAAIf,KAFlB,OA/DJ,M,OAiEI,S,wBAIFoB,EAAgByE,aAA8B,EAAAwE,gBAAkBxE,EAAmBoF,eAAiBpF,EAAmBqF,eAC1G7J,kBAAkBvG,EAAOL,KACxCsD,EAAa0C,eAAiBW,EAAcE,WAGhDvD,EAAa0B,qBAAuBqG,E,YAG3B,YAAAqF,2BAAb,SAAwCC,EAAyC5L,G,0GAanD,OAZpBsG,EAA0D,CAAC,EAE3D/H,EAA0B,CAC5B4B,KAAMyL,EAAuBzL,MAG3BmK,EAAcsB,EAAuBlH,UACrC3G,EAAQ6N,EAAuBC,gBACjCvB,IACAhE,EAAyBnI,gBAAkB,CAACmM,EAAYvT,EAAGuT,EAAYjU,EAAGiU,EAAYrN,EAAGc,IAGnE,GAAM1I,KAAK4Q,kDACjC2F,EAAuBlH,UACvBkH,EAAuBE,cACvBF,EAAuBG,kBACvBH,EAAuBhL,iBACvBgL,EAAuBI,qBACvBJ,EAAuBK,yBACvBL,EACAtF,EACAtG,I,OAGJ,OAZMuE,EAAoB,SAY1B,GAAMlP,KAAKqV,sCAAsCnG,EAAmBqH,EAAwBrN,EAAc+H,EAA0BtG,I,OACpI,OADA,SACA,GAAM3K,KAAK0M,qBAAqBxD,EAAcqN,I,OAI9C,OAJA,UAEM5J,EAAY3M,KAAKoK,UAAUwC,YACvB3H,KAAKiE,GACR,CAAP,EAAOyD,EAAU7J,OAAS,G,QAGjB,YAAAuI,mBAAb,Y,yCAAgC/E,EAA6BuQ,G,sBAAA,IAAAA,IAAAA,EAAA,M,2CAEzD,OADIvL,EAActL,KAAKqK,YAAYtJ,IAAI8V,QAAAA,EAAcvQ,EAAemE,WAEzD,CAAP,EAAOa,IAGLgJ,EAAetU,KAAKuU,sBAAsBjO,GAC7B,GAAMtG,KAAK8W,yBAAyBxQ,K,OAMvD,OANMqO,EAAa,SAEnBrJ,EAActL,KAAK4U,mBAAmBD,EAAYL,EAAchO,EAAeuO,kBAC/E7U,KAAKqK,YAAYuL,IAAIiB,QAAAA,EAAcvQ,EAAemE,SAAUa,GAE5DtL,KAAKoK,UAAUyL,8BAA8B,WAAYvK,EAAahF,GAC/D,CAAP,EAAOgF,G,QAGG,YAAAwL,yBAAd,SAAuCxQ,G,+GAuC5B,OAtCDyQ,EAAwD,QAAnC,EAAAzQ,EAA2BF,gBAAQ,QAAI,OAI5D4Q,EAAyBhX,KAAKuK,wBAC9B0M,EAA0B3Q,EAAeE,qBAAsBiE,SACrEuM,EAAuBC,GAA2BD,EAAuBC,IAA4B,CAAC,OAG5E3W,KAFtB4W,EAAoBF,EAAuBC,GAAyBF,MAGpEG,EAAqB,8B,gEAEH,SAAM7Q,EAAoBC,I,eAAlC6Q,EAAQ,WACsB,SAAtBJ,GAAgCI,EAAMhV,OAAS4U,EAAzD,MACO,GAAM/W,KAAK0U,kBAAkBpO,EAAewE,KAAMqM,I,cAkB7D,MAAO,CAAP,EAAO,U,OAHQ,OAXX/Q,EAAW,YACW,SAAtB2Q,IACI5Q,EAAoB4Q,GACpB3Q,EAAW2Q,GAEX3Q,EAAW,YACX,EAAA/D,MAAM4I,KAAK,kCAA2B8L,EAAiB,kCAIzDK,EAAO9Q,EAAeiH,UACb,IAAM,IAAA8J,qBAAoB/Q,I,OACvB,OADZ2D,EAAS,SACG,IAAM,IAAA8F,kBAAiB9F,EAAQmN,EAAK1N,MAAO0N,EAAKzN,OAAQvD,I,OAEnE,OAFDkR,EAAY,SAEX,GAAMtX,KAAK0U,kBAAkBpO,EAAewE,KAAMwM,I,OAG7DN,EAAuBC,GAAyBF,GAAqBG,GAGlE,GAAMA,G,OAAb,MAAO,CAAP,EAAO,U,QAGG,YAAAxC,kBAAd,SAAgC5J,EAAcwM,G,mHACpCC,EAASvX,KAAKoK,UAAUoN,QAG1BxX,KAAKoK,UAAUqN,eACfC,EAAQ,CACJ5M,KAAMA,EACN1E,SAAUkR,EAAUnV,KACpBwV,gBAAYrX,GAEH,GAAMgX,EAAUlQ,gBAN7B,M,cAMML,EAAO,SACP4Q,EAAa3X,KAAKoK,UAAUwN,eAAeC,iBAAiB,IAAIhO,WAAW9C,IACjF/G,KAAKoK,UAAUwN,eAAeE,cAAcJ,EAAOC,G,aAG7CI,EAAWjN,EAAKkN,QAAQ,mBAAoB,KAC5CC,EAliClB,SAAsC7R,GAClC,OAAQA,GACJ,IAAK,aACD,MAAO,OACX,IAAK,YACD,MAAO,OACX,IAAK,aACD,MAAO,QACX,IAAK,aACD,MAAO,QACX,IAAK,aACD,MAAO,QAEnB,CAqhC8B8R,CAA6BZ,EAAUnV,MACrD,EAAW4V,EAAWE,EACtBV,EAAOY,MAAK,SAACT,GAAU,OAAAA,EAAMU,MAAQ,CAAd,MACvB,EAAW,UAAGL,EAAQ,YAAI,EAAA1V,MAAMgW,YAAU,OAAGJ,IAGjDP,EAAQ,CACJ5M,KAAMA,EACNsN,IAAK,GAETpY,KAAKoK,UAAUkO,WAAW,GAAYhB,E,iBAK1C,OAFAC,EAAOtS,KAAKyS,GAEL,CAAP,EAAOH,EAAOzU,OAAS,G,QAGnB,YAAA8R,mBAAR,SAA2BD,EAAoBL,EAAsBO,GACjE,IAAM/H,EAAW9M,KAAKoK,UAAUqK,UAC5B8D,EAAezL,EAAS0L,WAAU,SAAC/V,GAAM,OAAAA,EAAE0P,SAAWmC,GAAgB7R,EAAEgE,SAAWkO,CAA1C,KACvB,IAAlB4D,IACAA,EAAezL,EAAShK,OACxBgK,EAAS7H,KAAK,CACVwB,OAAQkO,EACRxC,QAASmC,KAIjB,IAAMhJ,EAA4B,CAAES,MAAOwM,GAI3C,OAHI1D,IACAvJ,EAAYwK,SAAWjB,GAEpBvJ,CACX,EAEQ,YAAAiJ,sBAAR,SAA8BxH,GAC1B,IAAMoF,EAAUnS,KAAKkS,mBAAmBnF,GAGlC0L,EAAWzY,KAAKoK,UAAUsO,UAC1BpE,EAAemE,EAASD,WAC1B,SAAC9V,GAAM,OAAAA,EAAEkQ,YAAcT,EAAQS,WAAalQ,EAAEiQ,YAAcR,EAAQQ,WAAajQ,EAAE0P,QAAUD,EAAQC,OAAS1P,EAAE6P,QAAUJ,EAAQI,KAA3H,IAEX,OAAsB,IAAlB+B,EACOA,GAGXmE,EAASxT,KAAKkN,GACPsG,EAAS3V,OAAS,EAC7B,EACJ,EAp7BA,GCjNa6V,EAA0B,EAAAC,OAAOC,QAAQ,IAAI,EAAAC,SAAS,EAAG,EAAG,GAAI,EAAAC,WAAWC,WAAY,EAAAF,QAAQG,QAMrG,SAASC,EAAWC,EAAYC,GACnC,KAAMD,aAAgB,EAAAE,eAClB,OAAO,EAIX,GAAID,GAEA,IADeD,EAAKG,iBACR9M,kBAAkB,EAAAoM,OAAOW,iBAAkB,EAAA3T,SACnD,OAAO,OAIX,IADeuT,EAAKG,iBAAiBE,cAAcb,EAAyB,EAAAc,WAAWb,OAAO,IAClFpM,kBAAkB,EAAAoM,OAAOW,iBAAkB,EAAA3T,SACnD,OAAO,EAKf,QAAIuT,aAAgB,EAAAO,cAAgBP,EAAKQ,SAK7C,CCpBO,IAAMC,EAAqB,EAAAd,QAAQe,aAC7BC,EAAkB,EAAAf,WAAWC,WAC7Be,EAAe,EAAAjB,QAAQkB,YAC9BC,EAAmC,IAAI,EAAAnB,SAAS,EAAG,EAAG,GAQrD,SAASoB,EAAoBC,EAA4BC,GACpD,IAAAlT,EAA6CiT,EAAY,WAA7CE,EAAiCF,EAAY,WAAjChY,EAAqBgY,EAAY,KAA3BG,EAAeH,EAAY,WAC3DI,EAAiBJ,EAAa5M,UAC9BiN,EAAgBJ,EAAOK,QAAO,SAACrL,EAAKsL,GACtC,OAAOA,EAAQC,mBAAqBvL,EAAMsL,EAAQC,mBAAqBvL,CAC3E,IAAIkC,OAAOsJ,WAIX,MAAO,CAAE1T,WAAU,EAAEmT,WAAU,EAAEE,eAAc,EAAEpY,KAAI,EAAE0Y,MAHzCL,EAAgBD,EAGgCD,WAAU,EAAEE,cAAa,EAAEM,KAF5EX,EAAaY,UAG9B,CAEO,SAASC,EAAwBC,GACpC,OAAQA,GACJ,IAAK,OAYL,IAAK,OACD,OAAO,EAXX,IAAK,OACD,OAAO,EACX,IAAK,OACD,OAAO,GACX,IAAK,SACD,OAAO,EACX,IAAK,OACD,OAAO,EACX,IAAK,OACD,OAAO,EAInB,CAMO,SAASC,EAA0B/Y,GACtC,OAAQA,GACJ,KAAK,EAAAgZ,aAAaC,aAClB,KAAK,EAAAD,aAAaE,WAClB,KAAK,EAAAF,aAAaG,YAClB,KAAK,EAAAH,aAAaI,UAClB,KAAK,EAAAJ,aAAaK,oBAClB,KAAK,EAAAL,aAAaM,yBAClB,KAAK,EAAAN,aAAaO,oBAClB,KAAK,EAAAP,aAAaQ,yBAClB,KAAK,EAAAR,aAAaS,OAClB,KAAK,EAAAT,aAAaU,QAClB,KAAK,EAAAV,aAAaW,QAClB,KAAK,EAAAX,aAAaY,QAClB,KAAK,EAAAZ,aAAaa,QAClB,KAAK,EAAAb,aAAac,QACd,OAAO,EAEf,OAAO,CACX,CAgEO,SAASC,EAAiBC,GAC7B,OAAQA,GACJ,KAAK,EAAAC,SAASC,iBACV,OAAO,EACX,KAAK,EAAAD,SAASE,sBACV,OAAO,EACX,KAAK,EAAAF,SAASG,oBACV,OAAO,EACX,KAAK,EAAAH,SAASI,kBACd,KAAK,EAAAJ,SAASK,cACV,OAAO,EACX,KAAK,EAAAL,SAASM,iBACV,OAAO,EACX,KAAK,EAAAN,SAASO,iBACV,OAAO,EACX,KAAK,EAAAP,SAASQ,kBACV,OAAO,EAGf,MAAM,IAAIzS,MAAM,6BAAsBgS,GAC1C,CAaO,SAASU,EAAiBC,GAC7B,IAAMha,EAASiF,KAAKC,KAAK8U,EAAQC,EAAID,EAAQC,EAAID,EAAQ3Y,EAAI2Y,EAAQ3Y,EAAI2Y,EAAQE,EAAIF,EAAQE,GACzFla,EAAS,IACTga,EAAQC,GAAKja,EACbga,EAAQ3Y,GAAKrB,EACbga,EAAQE,GAAKla,EAErB,CAEO,SAASma,EAA6Bpb,GAEzC,OADAA,EAAMkb,IAAM,EACLlb,CACX,CAaO,SAASqb,EAA6Brb,GAQzC,GAAIA,EAAMkb,EAAIlb,EAAMkb,EAAIlb,EAAMsC,EAAItC,EAAMsC,EAAI,GAAK,CAC7C,IAAMgZ,EAAOpV,KAAKqV,IAAIvb,EAAMkb,GACtBM,EAAOtV,KAAKqV,IAAIvb,EAAMsC,GAC5B,GAAIgZ,EAAOE,EAAM,CACb,IAAMC,EAAOvV,KAAKuV,KAAKzb,EAAMkb,GAC7Blb,EAAMkb,EAAII,EACVtb,EAAMsC,IAAMmZ,EACZzb,EAAMmb,IAAMM,EACZzb,EAAM+M,GAAK0O,CACf,MACUA,EAAOvV,KAAKuV,KAAKzb,EAAMsC,GAC7BtC,EAAMkb,IAAMO,EACZzb,EAAMsC,EAAIkZ,EACVxb,EAAMmb,GAAKM,EACXzb,EAAM+M,IAAM0O,CAEpB,KAAO,CACH,IAAMC,EAAOxV,KAAKqV,IAAIvb,EAAMmb,GACtBQ,EAAOzV,KAAKqV,IAAIvb,EAAM+M,GACxB2O,EAAOC,GACDF,EAAOvV,KAAKuV,KAAKzb,EAAMmb,GAC7Bnb,EAAMkb,IAAMO,EACZzb,EAAMsC,GAAKmZ,EACXzb,EAAMmb,EAAIO,EACV1b,EAAM+M,IAAM0O,IAENA,EAAOvV,KAAKuV,KAAKzb,EAAM+M,GAC7B/M,EAAMkb,GAAKO,EACXzb,EAAMsC,IAAMmZ,EACZzb,EAAMmb,IAAMM,EACZzb,EAAM+M,EAAI4O,EAElB,CAEA,OAAO3b,CACX,CAMO,SAAS4b,EAAWC,GAEvBA,EAASC,gBAAgBD,EAASV,EAAGU,EAAS9O,EAAG8O,EAASX,GAAIW,EAASvZ,EAC3E,CAQO,SAASyZ,EAAwBzE,EAAa0E,GACjD,IAAMC,EAAoB,EAAAhF,QAAQiF,eAAeF,EAAWG,aAAe,CAAC,EAAG,EAAG,GAAI,EAAG,EAAAvE,WAAWX,QAAQ,IACtGmF,EAAiB,EAAAlF,WAAWgF,eAAeF,EAAWH,UAAY,CAAC,EAAG,EAAG,EAAG,GAAI,EAAG,EAAAjE,WAAWV,WAAW,IACzGmF,EAAe,EAAAtF,OAAOuF,aAAapE,EAAckE,EAAgBH,EAAmB,EAAArE,WAAWb,OAAO,IAEtGoF,EAAc,EAAAlF,QAAQiF,eAAe5E,EAAK6E,aAAe,CAAC,EAAG,EAAG,GAAI,EAAG,EAAAvE,WAAWX,QAAQ,IAC1F4E,EAAW,EAAA3E,WAAWgF,eAAe5E,EAAKuE,UAAY,CAAC,EAAG,EAAG,EAAG,GAAI,EAAG,EAAAjE,WAAWV,WAAW,IAC7FqF,EAAS,EAAAxF,OAAOuF,aAAapE,EAAc2D,EAAUM,EAAa,EAAAvE,WAAWb,OAAO,IAE1FsF,EAAa1E,cAAc4E,EAAQA,GACnCA,EAAOC,eAAU/d,EAAW2d,EAAgBH,GAExCA,EAAkBtR,kBAAkBoN,EAAoB,EAAAhU,gBACjDiY,EAAWG,YAElBH,EAAWG,YAAcF,EAAkBrR,UAG3CwR,EAAezR,kBAAkBsN,EAAiB,EAAAlU,gBAC3CiY,EAAWH,SAElBG,EAAWH,SAAWO,EAAexR,UAGrCoR,EAAWrV,cACJqV,EAAWrV,KAE1B,CAUO,SAAS8V,EAAmBC,EAAqDC,GACpF,KAAMA,aAA6B,EAAAnF,eAC/B,OAAO,EAKX,GADoE,IAA3CmF,EAAkBC,cAAc3b,QAAqD,IAArCyb,EAAYE,cAAc3b,QAAgByb,EAAYG,SAAWF,EAEtI,OAAO,EAIX,IAAM5U,EAAQ2U,EAAYlW,WACpBsW,EAAgBJ,aAAuB,EAAAK,eAAiBhV,EAAMwP,qBAAuBa,EAAmCF,EAE9H,QAAKyE,EAAkBK,QAAQrS,kBAAkBmS,EAAe,EAAA/Y,WAC5D,EAAAkZ,OAAO7T,KAAK,+BAAwBsT,EAAYzT,KAAI,6BAAqB0T,EAAkB1T,KAAI,6BACxF,EAIf,CA8DO,SAASiU,EAAoCC,EAAWC,GAC3D,IAA2B,UAAAre,OAAOse,QAAQF,GAAf,eAAwB,CAAxC,WAACte,EAAG,KAAEmB,EAAK,KACZsd,EAAeF,EAAcve,IAC9B8E,MAAM4Z,QAAQvd,IAAU2D,MAAM4Z,QAAQD,IAAiBE,EAAexd,EAAOsd,IAAkBtd,IAAUsd,WACnGH,EAAOte,EAEtB,CACA,OAAOse,CACX,CAEA,SAASK,EAAeC,EAAmBC,GACvC,OAAOD,EAAOxc,SAAWyc,EAAOzc,QAAUwc,EAAOE,OAAM,SAACC,EAAK9c,GAAM,OAAA8c,IAAQF,EAAO5c,EAAf,GACvE,CC3YA,IAAM+c,EAA0B,IAAIpV,IAA+E,CAC/G,CAACqV,UAAW,SAACnf,EAAGoH,EAAG/C,GAAM,OAAArE,EAAEof,QAAQhY,EAAG/C,EAAb,GACzB,CAACgF,WAAY,SAACgW,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGE,SAASD,EAAIjb,EAAhB,GAC5B,CAACmb,kBAAmB,SAACH,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGE,SAASD,EAAIjb,EAAhB,GACnC,CAACob,WAAY,SAACJ,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGK,SAASJ,EAAIjb,GAAG,EAAnB,GAC5B,CAACsb,YAAa,SAACN,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGO,UAAUN,EAAIjb,GAAG,EAApB,GAC7B,CAACwb,WAAY,SAACR,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGS,SAASR,EAAIjb,GAAG,EAAnB,GAC5B,CAAC0b,YAAa,SAACV,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGW,UAAUV,EAAIjb,GAAG,EAApB,GAC7B,CAACqF,aAAc,SAAC2V,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGY,WAAWX,EAAIjb,GAAG,EAArB,GAC9B,CAAC6b,aAAc,SAACb,EAAIC,EAAIjb,GAAM,OAAAgb,EAAGc,WAAWb,EAAIjb,GAAG,EAArB,KAIlC,aAcI,WAAmBsC,GACfnH,KAAK4gB,MAAQ,IAAI/W,WAAW1C,GAC5BnH,KAAK6gB,UAAY,IAAIC,SAAS9gB,KAAK4gB,MAAMja,QACzC3G,KAAK+gB,YAAc,CACvB,CAmEJ,OAhFW,YAAAC,gBAAP,SAAuBnf,GACnB7B,KAAKihB,iBAAiBpf,EAAMsF,YAE5B,IADA,IAAM+Z,EAAYxB,EAAwB3e,IAAIc,EAAMsf,aAC3Cxe,EAAI,EAAGA,EAAId,EAAMiB,OAAQH,IAC9Bue,EAAUlhB,KAAK6gB,UAAW7gB,KAAK+gB,YAAalf,EAAMc,IAClD3C,KAAK+gB,aAAelf,EAAMuf,iBAElC,EAQA,sBAAW,yBAAU,C,IAArB,WACI,OAAOphB,KAAK+gB,WAChB,E,gCAEO,YAAAM,cAAP,WACI,OAAO,IAAIxX,WAAW7J,KAAK4gB,MAAMja,OAAQ,EAAG3G,KAAK+gB,YACrD,EAEO,YAAAO,WAAP,SAAkBzf,GACd7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUd,SAAS/f,KAAK+gB,YAAalf,GAC1C7B,KAAK+gB,aACT,EAEO,YAAAQ,UAAP,SAAiB1f,GACb7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUjB,QAAQ5f,KAAK+gB,YAAalf,GACzC7B,KAAK+gB,aACT,EAEO,YAAAS,WAAP,SAAkBC,GACdzhB,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUX,SAASlgB,KAAK+gB,YAAaU,GAAO,GACjDzhB,KAAK+gB,aAAe,CACxB,EAEO,YAAAW,YAAP,SAAmB7f,GACf7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUT,UAAUpgB,KAAK+gB,YAAalf,GAAO,GAClD7B,KAAK+gB,aAAe,CACxB,EAEO,YAAAY,WAAP,SAAkBF,GACdzhB,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUP,SAAStgB,KAAK+gB,YAAaU,GAAO,GACjDzhB,KAAK+gB,aAAe,CACxB,EAEO,YAAAa,YAAP,SAAmB/f,GACf7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUL,UAAUxgB,KAAK+gB,YAAalf,GAAO,GAClD7B,KAAK+gB,aAAe,CACxB,EAEO,YAAAc,aAAP,SAAoBhgB,GAChB7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUJ,WAAWzgB,KAAK+gB,YAAalf,GAAO,GACnD7B,KAAK+gB,aAAe,CACxB,EAEO,YAAAe,aAAP,SAAoBjgB,GAChB7B,KAAKihB,iBAAiB,GACtBjhB,KAAK6gB,UAAUF,WAAW3gB,KAAK+gB,YAAalf,GAAO,GACnD7B,KAAK+gB,aAAe,CACxB,EAEQ,YAAAE,iBAAR,SAAyB9Z,GACrB,IAAM4a,EAAgB/hB,KAAKkH,WAAaC,EACxC,GAAI4a,EAAgB/hB,KAAK4gB,MAAMzZ,WAAY,CACvC,IAAM6a,EAAU,IAAInY,WAA2B,EAAhBkY,GAC/BC,EAAQpM,IAAI5V,KAAK4gB,OACjB5gB,KAAK4gB,MAAQoB,EACbhiB,KAAK6gB,UAAY,IAAIC,SAAS9gB,KAAK4gB,MAAMja,OAC7C,CACJ,EACJ,EArFA,GCPA,SAASsb,EAAwB9a,GAC7B,OAAIA,EAAa,GAAM,EACZ,EAEPA,EAAa,GAAM,EACZ,EAEJ,CACX,CAMA,ICgDK+a,EDhDL,0BAIY,KAAAC,kBAAyD,IAAI7X,IAK7D,KAAA8X,wBAAuE,IAAI9X,IAK3E,KAAA+X,sBAAqD,IAAI/X,GAoJrE,QA7IW,YAAAgY,eAAP,SAAsBC,GAElB,IAAIC,EAAkB,EACtBxiB,KAAKmiB,kBAAkBM,SAAQ,SAAC1b,GAC5Byb,GAAmBzb,EAAKI,UAC5B,IAOA,IANA,IAAMub,EAAa,IAAIC,EAAWH,GAMT,MAHEhd,MAAMJ,KAAKpF,KAAKmiB,kBAAkBS,QAAQC,MAAK,SAAClb,EAAGC,GAAM,OAAAqa,EAAwBra,EAAET,YAAc8a,EAAwBta,EAAER,WAAlE,IAG3D,eAAoB,CAAxC,IAAMwQ,EAAU,KACjBA,EAAWzQ,WAAawb,EAAWxb,WACnCqb,EAAYtd,KAAK0S,GAIjB,IAFA,IAAMmL,EAAkBP,EAAYzf,OAAS,EAExB,MADF9C,KAAK+iB,4BAA4BpL,GAC/B,eAAJ,KACNA,WAAamL,EAGxBJ,EAAW1B,gBAAgBhhB,KAAKmiB,kBAAkBphB,IAAI4W,IAEtD3X,KAAKmiB,kBAAkBa,OAAOrL,EAClC,CAEA,OAAO+K,EAAWrB,eACtB,EAQO,YAAAxJ,iBAAP,SAAwB9Q,EAAyBsT,GAC7C,IAAM1C,EAA0B,CAC5BhR,OAAQ,EACRO,gBAAY5G,EACZ6G,WAAYJ,EAAKI,WACjBkT,WAAYA,GAGhB,OADAra,KAAKmiB,kBAAkBvM,IAAI+B,EAAY5Q,GAChC4Q,CACX,EAaO,YAAAsL,eAAP,SACItL,EACAxV,EACA+gB,EACArI,EACA3T,EACAic,EACA7I,GAEAta,KAAKojB,kBAAkBzL,GACvB,IAAM0L,EAAsB,CACxB1L,gBAAYrX,EACZ4iB,cAAeA,EACfrI,MAAOA,EACP1Y,KAAMA,EACNmhB,IAAKH,aAAM,EAANA,EAAQG,IACblU,IAAK+T,aAAM,EAANA,EAAQ/T,IACbkL,WAAYA,EACZpT,WAAYA,GAIhB,OAFAlH,KAAK8X,cAAcuL,EAAU1L,GAC7B3X,KAAKqiB,sBAAsBzM,IAAIyN,EAAU1L,GAClC0L,CACX,EAOO,YAAAvL,cAAP,SAAqBkH,EAAiCrH,GAClD3X,KAAKojB,kBAAkBzL,GACJ3X,KAAK+iB,4BAA4BpL,GACzC1S,KAAK+Z,EACpB,EAMO,YAAAuE,iBAAP,SAAwB5L,GAEpB,IAFJ,WAEyB,MADF3X,KAAK+iB,4BAA4BpL,GAC/B,eAAY,CAA5B,IAAMqH,EAAM,UACa1e,IAAtB0e,EAAOrH,mBACAqH,EAAOrH,UAEtB,CAEA3X,KAAKmiB,kBAAkBa,OAAOrL,GAC9B3X,KAAKoiB,wBAAwBY,OAAOrL,GACpC3X,KAAKqiB,sBAAsBI,SAAQ,SAACe,EAAIH,GAChCG,IAAO7L,SAEqBrX,IAAxB+iB,EAASnc,mBACFmc,EAASnc,WAEpB,EAAKmb,sBAAsBW,OAAOK,GAE1C,GACJ,EAEO,YAAAI,cAAP,SAAqBJ,GACjB,IAAM1L,EAAa3X,KAAKqiB,sBAAsBthB,IAAIsiB,GAElD,OADArjB,KAAKojB,kBAAkBzL,GAChBA,CACX,EAEO,YAAAoL,4BAAP,SAAmCpL,G,MAG/B,OAFA3X,KAAKojB,kBAAkBzL,GACvB3X,KAAKoiB,wBAAwBxM,IAAI+B,EAAwD,QAA5C,EAAA3X,KAAKoiB,wBAAwBrhB,IAAI4W,UAAW,QAAI,IACtF3X,KAAKoiB,wBAAwBrhB,IAAI4W,EAC5C,EAEO,YAAA+L,QAAP,SAAe/L,GAEX,OADA3X,KAAKojB,kBAAkBzL,GAChB3X,KAAKmiB,kBAAkBphB,IAAI4W,EACtC,EAEQ,YAAAyL,kBAAR,SAA0BzL,GACtB,QAAmBrX,IAAfqX,IAA6B3X,KAAKmiB,kBAAkBwB,IAAIhM,GACxD,MAAM,IAAIxN,MAAM,qBAAcwN,EAAU,gCAEhD,EACJ,EAlKA,ICgDA,SAAKuK,GAID,6BAIA,8BACH,CATD,CAAKA,IAAAA,EAAY,KAejB,+BA+9BA,QAz9BmB,EAAA0B,iBAAf,SAAgCrF,GAC5B,OAAOA,IAAgBA,aAAuB,EAAAlF,eAAiBkF,aAAuB,EAAAsF,QAAUtF,aAAuB,EAAAuF,MAC3H,EAYc,EAAAC,qBAAd,SACIC,EACAC,EACAC,EACAC,EACAC,GAEA,GAAIpkB,KAAK4jB,iBAAiBI,GAAuB,CAC7C,IAAMK,EAAmB,GACnBC,EAAsB,GACtBC,EAAYN,EAAUO,UACtBC,EAAkBC,EAAeC,0BAA0BJ,GAC3DK,EAAsBF,EAAeG,qBAAqBN,EAAWL,EAA4BC,GAEjGW,EAAgBF,EAAoBG,kBACpCC,EAAsBJ,EAAoBI,oBAsChD,GApCIA,EACAN,EAAeO,sBACXjB,EACAC,EACAC,EACAO,EAAgBnB,IAChBmB,EAAgBrV,IAChB6U,EAAUiB,eACVd,EACAC,EACAC,EACAG,EACAN,GAGkB,WAAlBW,GAA4E,SAAlBA,EAC1DJ,EAAeS,6BAA6BnB,EAAsBC,EAAWC,EAA4BG,EAAQC,EAASH,GACjG,gBAAlBW,EACPJ,EAAeU,4BAA4BpB,EAAsBC,EAAWC,EAA4BG,EAAQC,EAASH,GAEzHO,EAAeO,sBACXjB,EACAC,EACAC,EACAO,EAAgBnB,IAChBmB,EAAgBrV,IAChB6U,EAAUiB,eACVd,EACAC,EACAC,EACAG,EACAN,GAKRE,EAAOvhB,QAAUwhB,EAAQxhB,OASzB,MARgC,CAC5BuhB,OAAQA,EACRC,QAASA,EACTe,qBAAsBP,EACtBQ,UAAWN,EAAsBP,EAAgBnB,IAAM,EAAAjhB,MAAMkjB,WAAWd,EAAgBnB,IAAMW,EAAUiB,gBACxGM,UAAWR,EAAsBP,EAAgBrV,IAAM,EAAA/M,MAAMkjB,WAAWd,EAAgBrV,IAAM6U,EAAUiB,gBAKpH,CAEA,OAAO,IACX,EAEe,EAAAO,qBAAf,SAAoCxB,GAChC,IAAIC,EAAmE,KACnEwB,EAAmB,OACnBvB,GAAyB,EACvBwB,EAAW1B,EAAU2B,eAAeC,MAAM,KAChD,OAAQF,EAAS,IACb,IAAK,UACDzB,EAA6B,QAC7B,MAEJ,IAAK,WACDA,EAA6B,cAC7B,MAEJ,IAAK,WACDwB,EAAmB,OACnBxB,EAA6B,WAC7B,MAEJ,IAAK,qBACDwB,EAAmB,OACnBvB,GAAgB,EAChBD,EAA6B,WAC7B,MAEJ,IAAK,YACDwB,EAAmB,SACnBxB,EAA6B,UAC7B,MAEJ,QACI,EAAA7hB,MAAM8H,MAAM,0CAAmCwb,EAAS,KAGhE,OAAIzB,EACO,CAAEA,2BAA4BA,EAA4BwB,iBAAkBA,EAAkBvB,cAAeA,IAEpH,EAAA9hB,MAAM8H,MAAM,yEAET,KACX,EAec,EAAA2b,uCAAd,SACIvH,EACAwH,EACAC,EACAC,EACAC,EACAC,EACA5D,EACA6D,EACAhC,EACAiC,EACAC,GAEA,IAAIC,EACJ,GAAI7B,EAAed,iBAAiBrF,IAC5BA,EAAYiI,WACZ,IAAwB,UAAAjI,EAAYiI,WAAZ,eAAwB,CAA3C,IAAMvC,EAAS,KAChB,IAAIqC,GAA0BA,EAAsBrC,GAApD,CAGA,IAAMwC,EAAgB/B,EAAee,qBAAqBxB,GACtDwC,IACAF,EAAgB,CACZzb,KAAMmZ,EAAUnZ,KAChB2N,SAAU,GACViO,SAAU,IAEdhC,EAAeiC,cACX,UAAG1C,EAAUnZ,MACbmZ,EAAU2C,4BAA8Bb,EAAuBQ,EAC/DhI,EACA0F,EACAwC,EAAcf,iBACde,EAAcvC,2BACd+B,EACAE,EACA5D,EACA6D,EACAK,EAActC,cACdC,EACAiC,GAEAE,EAAc9N,SAAS3V,QAAUyjB,EAAcG,SAAS5jB,QACxDkjB,EAAmB/gB,KAAKshB,GAxBhC,CA2BJ,CAGZ,EAec,EAAAM,qDAAd,SACItI,EACAwH,EACAC,EACAC,EACAC,EACAC,EACA5D,EACA6D,EACAhC,EACAiC,EACAC,GAEA,IAAIC,EACJ,GAAIhI,aAAuB,EAAAuI,KAAM,CAC7B,IAAMC,EAAqBxI,EAAYwI,mBACvC,GAAIA,EACA,IAAK,IAAIpkB,EAAI,EAAGA,EAAIokB,EAAmBC,aAAcrkB,EAEjD,IADA,IACwB,MADJokB,EAAmBE,UAAUtkB,GACb6jB,WAAZ,eAAwB,CAA3C,IAAMvC,EAAS,KAChB,IAAIqC,GAA0BA,EAAsBrC,GAApD,CAcA,IAXA,IAAMiD,EAAoB,IAAI,EAAAC,UAC1B,UAAGlD,EAAUnZ,MACb,YACAmZ,EAAUiB,eACVjB,EAAUmD,SACVnD,EAAUoD,SACVpD,EAAUqD,gBAERC,EAAyC,GACzCC,EAAgBvD,EAAUO,UAEvBiD,EAAI,EAAGA,EAAID,EAAc1kB,SAAU2kB,EAExC,IADA,IAAMC,EAAeF,EAAcC,GAC1BE,EAAI,EAAGA,EAAIZ,EAAmBC,aAAcW,EAC7CA,GAAKhlB,EACL4kB,EAAsBtiB,KAAKyiB,GAE3BH,EAAsBtiB,KAAK,CAAE2iB,MAAOF,EAAaE,MAAO/lB,MAAO,IAI3EqlB,EAAkBW,QAAQN,GAAuB,GACjD,IAAMd,EAAgB/B,EAAee,qBAAqByB,GACtDT,IACAF,EAAgB,CACZzb,KAAMoc,EAAkBpc,KACxB2N,SAAU,GACViO,SAAU,IAEdhC,EAAeiC,cACX1C,EAAUnZ,KACVmZ,EAAU2C,4BAA8Bb,EAAuBQ,EAC/DhI,EACA2I,EACAT,EAAcf,iBACde,EAAcvC,2BACd+B,EACAE,EACA5D,EACA6D,EACAK,EAActC,cACdC,EACAiC,EACAU,EAAmBC,YAEnBT,EAAc9N,SAAS3V,QAAUyjB,EAAcG,SAAS5jB,QACxDkjB,EAAmB/gB,KAAKshB,GA/ChC,CAkDJ,CAGZ,CACJ,EAcc,EAAAuB,gDAAd,SACIC,EACAC,EACA/B,EACAE,EACA5D,EACA6D,EACAhC,EACA6D,EACA3B,G,MAEIC,EACJ,GAAIwB,EAAaG,gBAEb,IADA,IAAMA,EAAkBH,EAAaG,gB,WAC1BC,GACP,IAAMC,EAA0D,IAAI9d,IAC9D+d,EAAyC,IAAI/d,IAC7Cge,EAAkC,IAAIC,IACtCC,EAA0BL,EAAehjB,GAAKgjB,EAAe/iB,KACnEmhB,EAAgB,CACZzb,KAAMqd,EAAerd,KACrB4b,SAAU,GACVjO,SAAU,IAEd,I,eAAS9V,GACL,IAAM8lB,EAAkBN,EAAeO,mBAAmB/lB,GACpDgmB,EAASF,EAAgBE,OACzB1E,EAAYwE,EAAgBxE,UAClC,GAAIqC,IAA0BA,EAAsBrC,G,iBAIpD,IAAM2E,EAAuBX,EAAgBtE,IAAIgF,GAEjD,GAAI,EAAK/E,iBAAiB+E,IAA8B,IAAlBA,EAAO7lB,QAAgB,EAAK8gB,iBAAiB+E,EAAO,KAEtF,GADMlC,EAAgB/B,EAAee,qBAAqBgD,EAAgBxE,WACvD,CACf,IAAMD,EAAuB,EAAKJ,iBAAiB+E,GAAUA,EAAS,EAAK/E,iBAAiB+E,EAAO,IAAMA,EAAO,GAAK,KACjH3E,GACAU,EAAeiC,cACX,UAAG1C,EAAUnZ,MACbyb,EACAvC,EACAC,EACAwC,EAAcf,iBACde,EAAcvC,2BACd+B,EACAE,EACA5D,EACA6D,EACAK,EAActC,cACdC,EACAwE,EAGZ,OACG,GAAID,aAAkB,EAAAE,aAAkC,IAAlBF,EAAO7lB,QAAgB6lB,EAAO,aAAc,EAAAE,YAAc,CACnG,IAAMpC,EACN,GADMA,EAAgB/B,EAAee,qBAAqBgD,EAAgBxE,WACvD,CACf,IAAM,EAAqB0E,aAAkB,EAAAE,YAAcF,EAAUA,EAAO,GAC5E,GAAI,EAAoB,CACpB,IAAM,EAA4BZ,EAAae,oBAAoBC,MAAK,SAAChC,GACrE,IAAK,IAAIU,EAAI,EAAGA,EAAIV,EAAmBC,aAAcS,EACjD,GAAIV,EAAmBE,UAAUQ,KAAO,EACpC,OAAO,EAGf,OAAO,CACX,IACA,GAAI,EAA2B,CAC3B,IAAMuB,EAAcjB,EAAa3N,OAAO2O,MAAK,SAACE,GAC1C,OAAQA,EAAclC,qBAAuB,CACjD,IACIiC,IACKZ,EAAgBzE,IAAIqF,IACrBZ,EAAgBxS,IAAIoT,EAAa,IAAI1e,KAET,QAAhC,EAAA8d,EAAgBrnB,IAAIioB,UAAY,SAAEpT,IAAI,EAAoBqO,GAC1DqE,EAAqBrc,IAAI+c,GACzBX,EAAiBzS,IAAIoT,EAAa/E,GAE1C,CACJ,CACJ,CACJ,C,EA5DKthB,EAAI,EAAGA,EAAIwlB,EAAeO,mBAAmB5lB,SAAUH,E,EAAvDA,GAgET2lB,EAAqB7F,SAAQ,SAACwG,GAgB1B,IAfA,IAAMlC,EAAqBkC,EAAKlC,mBAC5BmC,EAA8C,KAC5C1B,EAAiC,GAEjC2B,EADkBd,EAAiBtnB,IAAIkoB,GACDzE,UACtC4E,EAAmBD,EAAoBrmB,OAUpCH,EAAI,EAAGA,EAAIymB,IAAoBzmB,EACpC,IAAK,IAAI8kB,EAAI,EAAGA,EAAIV,EAAmBC,aAAcS,EAAG,CACpD,IAAM4B,EAActC,EAAmBE,UAAUQ,GAC3C6B,EAA0BlB,EAAgBrnB,IAAIkoB,GACpD,GAAIK,EAAyB,CACzB,IAAMC,EAAuBD,EAAwBvoB,IAAIsoB,GACrDE,GACKL,IACDA,EAAyB,IAAI,EAAA/B,UACzB,UAAGgB,EAAerd,KAAI,YAAIme,EAAKne,KAAI,yBACnC,YACAye,EAAqBrE,eACrB,EAAAiC,UAAUqC,oBACVD,EAAqBlC,SACrBkC,EAAqBjC,iBAG7BE,EAAcviB,KAAKskB,EAAqB/E,UAAU7hB,KAElD6kB,EAAcviB,KAAK,CACf2iB,MAAOO,EAAe/iB,KAAQojB,EAA0BY,EAAoBzmB,EAC5Ed,MAAOwnB,EAAYI,UACnBC,UAAWP,EAAoB,GAAGO,UAAY,OAAIppB,EAClDqpB,WAAYR,EAAoB,GAAGQ,WAAa,OAAIrpB,GAGhE,CACJ,CAEJ4oB,EAAwBrB,QAAQL,GAAe,GAC/C,IAAMf,EAAgB/B,EAAee,qBAAqByD,GACtDzC,GACA/B,EAAeiC,cACX,UAAGwB,EAAerd,KAAI,YAAIme,EAAKne,KAAI,yBACnCyb,EACA0C,EACAC,EACAzC,EAAcf,iBACde,EAAcvC,2BACd+B,EACAE,EACA5D,EACA6D,EACAK,EAActC,cACdC,GACA,EACA2C,aAAkB,EAAlBA,EAAoBC,WAGhC,IACIT,EAAcG,SAAS5jB,QAAUyjB,EAAc9N,SAAS3V,QACxDklB,EAAe/iB,KAAKshB,E,SA7IC,MAAA2B,EAAA,e,EAAJ,KAiJjC,EAEe,EAAAvB,cAAf,SACI7b,EACAyb,EACAvC,EACAC,EACAyB,EACAxB,EACA+B,EACAE,EACA5D,EACA6D,EACAjC,EACAC,EACAwE,EACAgB,GAEA,IACIjS,EACA0L,EACAwG,EACAC,EACAC,EACAC,EANEC,EAAgBvF,EAAeX,qBAAqBC,EAAsBC,EAAWC,EAA4BC,EAAeC,GAQtI,GAAI6F,EAAe,CAMf,GAAIL,EAAwB,CAIxB,IAHA,IAAI7d,EAAQ,EACRme,EAAuB,EACrBC,EAAsB,GACrBF,EAAc5F,OAAOvhB,OAAS,GACjConB,EAAeD,EAAc5F,OAAO+F,QAChCre,EAAQ6d,GAA0B,GAClCO,EAAUllB,KAAKilB,GAEnBne,IAEJke,EAAc5F,OAAS8F,CAC3B,CAEA,IAAME,EAAYpE,EAAQllB,IAAIijB,GAGxBsG,EAAY,IAAIpgB,aAAa+f,EAAc5F,QACjD1M,EAAawO,EAActO,iBAAiByS,GAC5CjH,EAAW8C,EAAclD,eAAetL,EAAY,SAAF,KAAoDsS,EAAc5F,OAAOvhB,YAAQxC,EAAW,CAC1IgjB,IAAK,CAAC2G,EAAc3E,WACpBlW,IAAK,CAAC6a,EAAczE,aAExBY,EAAUnhB,KAAKoe,GACfwG,EAAwBzD,EAAUtjB,OAAS,EAG3C,IAAM,EAAqB,IAAI,EAAAiW,WACzB,EAAY,IAAI,EAAAD,QAChB,EAAW,IAAI,EAAAA,QACf,EAAWkL,aAAgC,EAAAH,OAE3C,EAAe7I,EAAwB0K,GACvC,EAAa,IAAIxb,aAAa+f,EAAc3F,QAAQxhB,OAAS,GACnEmnB,EAAc3F,QAAQ7B,SAAQ,SAAU8H,EAAkBxe,GACtD,IAAIye,EAA0BD,EAC9B,OAAQrG,GACJ,IAAK,cACG0E,IACA,EAAA9P,QAAQiF,eAAewM,EAAQ,EAAG,GAClCtN,EAA6B,GAC7B,EAASwN,QAAQD,IAErB,MACJ,IAAK,WACqB,IAAlBD,EAAOznB,OACP,EAAAiW,WAAWgF,eAAewM,EAAQ,EAAG,IAErCC,EAAgB,IAAIhlB,MAAM,GAC1B,EAAAsT,QAAQiF,eAAewM,EAAQ,EAAG,GAClC,EAAAxR,WAAW2R,qBAAqB,EAAW,IAG3C9B,IACA1L,EAA6B,GACzB,GACAO,EAAW,IAInB,EAAmBgN,QAAQD,GAGnC,EAAW5U,IAAI4U,EAAeze,EAAQ,EAC1C,IAGA4L,EAAawO,EAActO,iBAAiB,GAC5CwL,EAAW8C,EAAclD,eAAetL,EAAY+N,EAAkB,KAA6BuE,EAAc3F,QAAQxhB,QACzHsjB,EAAUnhB,KAAKoe,GACfyG,EAAoB1D,EAAUtjB,OAAS,EAGvCinB,EAAmB,CACfjF,cAAemF,EAAc5E,qBAC7BsF,MAAOd,EACPU,OAAQT,GAEZvD,EAAc9N,SAASxT,KAAK8kB,GAG5BC,EAAmB,CACf7X,QAASoU,EAAc9N,SAAS3V,OAAS,EACzC6lB,OAAQ,CACJxP,KAAMkR,EACNO,KAAM1G,IAGdqC,EAAcG,SAASzhB,KAAK+kB,EAChC,CACJ,EAkBe,EAAA/E,sBAAf,SACIjB,EACAC,EACAC,EACA2G,EACAC,EACAC,EACAC,EACA3G,EACAC,EACA2G,EACA9G,GAEA,IAAItiB,EAGAqpB,EAFEC,EAA8B,EAAApS,WAAWC,WAC3CoS,EAAiC,KAEjCC,EAAiC,KACjCC,EAAwC,KACxCC,EAAwC,KACxCC,EAAwC,KACxCC,EAA6B,KACjCR,EAAa3H,IAAM,EAAAjhB,MAAMkjB,WAAWsF,EAAWE,GAI/C,IAFA,IAAMxG,EAAYN,EAAUO,UAEnB7hB,EAAI,EAAG,EAAS4hB,EAAUzhB,OAAQH,EAAI,IAAUA,EAAG,CAIxD,GAHA8oB,EAAW,KACXH,EAAe/G,EAAU5hB,GAErBA,EAAI,EAAI,EAER,GADA4oB,EAAehH,EAAU5hB,EAAI,GACxB2oB,EAAazpB,MAAM6pB,QAAUJ,EAAazpB,MAAM6pB,OAAOH,EAAa1pB,QAAWypB,EAAazpB,QAAU0pB,EAAa1pB,MAAO,CAC3H,GAAU,IAANc,EAIA,SAFA8oB,EAAWH,EAAa1D,KAIhC,MACI6D,EAAWF,EAAa3D,UAEzB,CAGH,GADA4D,EAAejH,EAAU5hB,EAAI,GACxB2oB,EAAazpB,MAAM6pB,QAAUJ,EAAazpB,MAAM6pB,OAAOF,EAAa3pB,QAAWypB,EAAazpB,QAAU2pB,EAAa3pB,MACpH,SAEA4pB,EAAWX,CAEnB,CACA,GAAIW,EACA,IAAK,IAAIvnB,EAAIonB,EAAa1D,MAAO1jB,GAAKunB,EAAUvnB,GAAK8mB,EAEjD,IADAE,EAAO,EAAA7oB,MAAMkjB,WAAWrhB,EAAI6mB,MACfK,EAAb,CAGAA,EAAeF,EACfG,EAAeH,EACf,IAAMS,EAAQ,CACVjrB,IAAK,EACLkrB,YAAa,EACbvE,SAAUpD,EAAUoD,UAExBxlB,EAAQoiB,EAAU4H,aAAa3nB,EAAGynB,GAElCjH,EAAeoH,sBAAsB9H,EAAsBniB,EAAOqpB,EAAMjH,EAAWC,EAA4BiH,EAAiB9G,EAAQC,EAASH,EAVjJ,CAaZ,CACIkH,IACAJ,EAAa7b,IAAMic,EAE3B,EAEe,EAAAU,oCAAf,SACIC,EACAhI,EACAC,EACAC,EACAC,GAEA,IAAM8H,EAA8BvH,EAAewH,gCAAgClI,EAAsBE,EAA4BC,GAE/HwB,EAAW1B,EAAU2B,eAAeC,MAAM,KAC1CsG,EAAgBxG,EAAWA,EAAS,GAAK,GACzC9jB,EAAQsiB,EAAgB,EAAApL,WAAWqT,UAAUH,GAA6BI,YAAc,EAAAvT,QAAQsT,UAAUH,GAEhH,OAAQE,GACJ,IAAK,IACL,IAAK,IACL,IAAK,IACDtqB,EAAMsqB,GAAiBH,EACvB,MAEJ,IAAK,IACAnqB,EAAqB+M,EAAIod,EAC1B,MAEJ,QACI,EAAA3pB,MAAM8H,MAAM,qDAA8CgiB,EAAa,OAI/E,OAAOtqB,CACX,EAEe,EAAAiqB,sBAAf,SACI9H,EACAniB,EACAqpB,EACAjH,EACAC,EACAiH,EACA9G,EACAC,EACAH,GAEA,IAAImI,EACJjI,EAAOpf,KAAKimB,GAEuB,YAA/BhH,GAKAD,EAAUmD,WAAa,EAAAD,UAAUqC,sBACjC3nB,EAAQ7B,KAAK+rB,oCAAoClqB,EAAiBmiB,EAAsBC,EAAWC,EAA4BC,IAGhG,aAA/BD,GACIC,EACAgH,EAAkBtpB,GAElByqB,EAAazqB,EACb,EAAAkX,WAAWwT,0BAA0BD,EAAWnoB,EAAGmoB,EAAWvP,EAAGuP,EAAWtP,EAAGmO,IAEnF7G,EAAQrf,KAAKkmB,EAAgB1e,aAG7B6f,EAAazqB,EACbyiB,EAAQrf,KAAKqnB,EAAW7f,aAnBxB6X,EAAQrf,KAAK,CAACpD,GAqBtB,EAWe,EAAAsjB,6BAAf,SACInB,EACAC,EACAC,EACAG,EACAC,EACAH,GAEA,IAAuB,UAAAF,EAAUO,UAAV,eAAqB,CAAvC,IAAMgI,EAAQ,KACfnI,EAAOpf,KAAKunB,EAAS5E,MAAQ3D,EAAUiB,gBACvCR,EAAe+H,kBAAkBD,EAAUvI,EAAWK,EAASJ,EAA4BF,EAAsBG,EACrH,CACJ,EAWe,EAAAiB,4BAAf,SACIpB,EACAC,EACAC,EACAG,EACAC,EACAH,GAEAF,EAAUO,UAAU/B,SAAQ,SAAU+J,GAClCnI,EAAOpf,KAAKunB,EAAS5E,MAAQ3D,EAAUiB,gBACvCR,EAAegI,kBAAkBxK,EAAayK,UAAWrI,EAASJ,EAA4B,cAA2CsI,EAAUrI,GACnJO,EAAe+H,kBAAkBD,EAAUvI,EAAWK,EAASJ,EAA4BF,EAAsBG,GAEjHO,EAAegI,kBAAkBxK,EAAa0K,WAAYtI,EAASJ,EAA4B,cAA2CsI,EAAUrI,EACxJ,GACJ,EAEe,EAAA+H,gCAAf,SAA+ClI,EAA4BE,EAAwDC,GAC/H,IAAI8H,EACJ,GAAmC,aAA/B/H,EACA,GAAIC,EAAe,CACf,IAAM0I,EAAK7I,EAAuC8I,mBAClDb,GAA+BY,QAAAA,EAAK,EAAA9T,WAAWC,YAAYvM,SAC/D,KAAO,CACH,IAAM/K,EAAcsiB,EAAuCtG,SAC3DuO,GAA+BvqB,QAAAA,EAAK,EAAAoX,QAAQG,QAAQxM,SACxD,MACG,GAAmC,gBAA/ByX,EAAuE,CAC9E,IAAMnhB,EAAcihB,EAAuC+I,SAC3Dd,GAA+BlpB,QAAAA,EAAK,EAAA+V,QAAQG,QAAQxM,SACxD,KAAO,CAEH,IAAM/J,EAAcshB,EAAuCnF,QAC3DoN,GAA+BvpB,QAAAA,EAAK,EAAAoW,QAAQkU,OAAOvgB,SACvD,CACA,OAAOwf,CACX,EAWe,EAAAQ,kBAAf,SACID,EACAvI,EACAK,EACAJ,EACAF,EACAG,GAEA,IAAI8I,EACEC,EAAgBjJ,EAAUmD,SAChC,GAAI8F,IAAkB,EAAA/F,UAAUgG,sBAAuB,CACnD,IAAItrB,EAAQ2qB,EAAS3qB,MAAM4K,UAC3B,GAAmC,aAA/ByX,EAAoE,CACpE,IAAMkJ,EAAQ,EAAAtU,QAAQsT,UAAUvqB,GAEhCA,EAD2B,EAAAkX,WAAWsU,qBAAqBD,EAAMjpB,EAAGipB,EAAMrQ,EAAGqQ,EAAMpQ,GACxDvQ,SAC/B,CACA6X,EAAQrf,KAAKpD,EACjB,MAAO,GAAIqrB,IAAkB,EAAA/F,UAAUqC,qBACnC,GAAmC,YAA/BtF,EACAI,EAAQrf,KAAK,CAACunB,EAAS3qB,aAUvB,GAPAorB,EAA6BjtB,KAAK+rB,oCAC9BS,EAAS3qB,MACTmiB,EACAC,EACAC,EACAC,GAE4B,CAC5B,GAAmC,aAA/BD,EAAoE,CACpE,IAAMoJ,EAAcnJ,EACb8I,EACD,EAAAlU,WAAWsU,qBAAqBJ,EAA2B9oB,EAAG8oB,EAA2BlQ,EAAGkQ,EAA2BjQ,GAAGqP,YAChI/H,EAAQrf,KAAKqoB,EAAY7gB,UAC7B,CACA6X,EAAQrf,KAAKgoB,EAA2BxgB,UAC5C,OAEGygB,IAAkB,EAAA/F,UAAUoG,yBACnCjJ,EAAQrf,KAAMunB,EAAS3qB,MAAqBwqB,YAAY5f,WAExD,EAAApK,MAAM8H,MAAM,6DAEpB,EASe,EAAA0a,qBAAf,SACIN,EACAL,EACAC,GAEA,IAAIY,EAEArkB,EADAskB,GAAsB,EAG1B,GAAmC,aAA/Bd,IAAuEC,EACvE,MAAO,CAAEY,kBAAmB,SAAsCC,qBAAqB,GAG3F,IAAK,IAAIriB,EAAI,EAAG,EAAS4hB,EAAUzhB,OAAQH,EAAI,IAAUA,EAErD,IADAjC,EAAM6jB,EAAU5hB,IACR+mB,WAAahpB,EAAIipB,WACrB,GAAI5E,GACA,GAA0B,gBAAtBA,EAAiE,CACjEA,EAAoB,SACpBC,GAAsB,EACtB,KACJ,OAEAD,EAAoB,mBAGxB,GAAIA,GACA,GAC0B,gBAAtBA,GACCrkB,EAAIokB,eAAuC,IAAtBpkB,EAAIokB,eAA0E,SAAtBC,EAChF,CACEA,EAAoB,SACpBC,GAAsB,EACtB,KACJ,OAGID,EADArkB,EAAIokB,eAAuC,IAAtBpkB,EAAIokB,cACL,OAEA,SASpC,OAJKC,IACDA,EAAoB,UAGjB,CAAEA,kBAAmBA,EAAmBC,oBAAqBA,EACxE,EAYe,EAAA0H,kBAAf,SACIc,EACAlJ,EACAJ,EACAY,EACA0H,EACArI,GAEA,IAAIrH,EACE2Q,EAA8CD,IAAgBtL,EAAayK,UAAYH,EAAS9C,UAAY8C,EAAS7C,WAC3H,GAAsB,gBAAlB7E,EAA6D,CAC7D,GAAmC,aAA/BZ,EACA,GAAIuJ,EACA,GAAItJ,EACArH,EAAW2Q,EAA4BhhB,cACpC,CACH,IAAM2gB,EAAQK,EACd3Q,EAAU,EAAA/D,WAAWsU,qBAAqBD,EAAMjpB,EAAGipB,EAAMrQ,EAAGqQ,EAAMpQ,GAAGvQ,SACzE,MAEAqQ,EAAU,CAAC,EAAG,EAAG,EAAG,QAIpBA,EAFkC,YAA/BoH,EACHuJ,EACU,CAACA,GAED,CAAC,GAGXA,EACWA,EAAyBhhB,UAE1B,CAAC,EAAG,EAAG,GAIzB6X,EAAQrf,KAAK6X,EACjB,CACJ,EAOe,EAAA6H,0BAAf,SAAyCJ,GACrC,IAAIjB,EAAcoK,IACdte,GAAc,IAMlB,OALAmV,EAAU9B,SAAQ,SAAU+J,GACxBlJ,EAAMvb,KAAKub,IAAIA,EAAKkJ,EAAS5E,OAC7BxY,EAAMrH,KAAKqH,IAAIA,EAAKod,EAAS5E,MACjC,IAEO,CAAEtE,IAAKA,EAAKlU,IAAKA,EAC5B,EACJ,EA/9BA,GClEO,SAASue,GACZtE,EACAJ,EACA9C,EACA5D,EACA6D,EACAwC,GAEA,IAAM/kB,EAA2B,CAC7B+pB,WAAY,CAAC,EACbnE,UAAWJ,EAAYI,UACvB3e,KAAMue,EAAYve,MAGhB6O,EAAWsP,EAAKtP,SACtB,IAAKA,EAED,OADA,EAAAtX,MAAM4I,KAAK,+FACJpH,EAGX,IAAMgqB,EAAQjF,GAAwB,EAAI,EAEpCkF,EAAa,EAAAhV,QAAQG,OAEvB8U,EAAc,EAElB,GAAI1E,EAAY2E,aAAc,CAC1B,IAAMC,EAAiB5E,EAAY6E,eAC7BC,EAAoBxU,EAASyU,gBAAgB,EAAAjT,aAAaC,cAEhE,GAAI+S,EAAmB,CACnB,IAAME,EAAe,IAAInkB,aAAaikB,EAAkBrrB,QAClDwgB,EAAM,CAACoK,IAAUA,IAAUA,KAC3Bte,EAAM,EAAC,KAAW,KAAW,KACnC2e,EAAcI,EAAkBrrB,OAAS,EAEzC,IAAK,IAAIH,EADK,EACYA,EAAIorB,IAAeprB,EAAG,CAC5C,IAAM2rB,EAAmB,EAAAxV,QAAQsT,UAAU+B,EAAuB,EAAJxrB,GACxC,EAAAmW,QAAQsT,UAAU6B,EAAoB,EAAJtrB,GAC1C4rB,cAAcD,EAAkBR,GAC9CA,EAAW/Q,GAAK8Q,EAEhBvK,EAAI,GAAKvb,KAAKub,IAAIA,EAAI,GAAIwK,EAAW/Q,GACrC3N,EAAI,GAAKrH,KAAKqH,IAAIA,EAAI,GAAI0e,EAAW/Q,GAErCuG,EAAI,GAAKvb,KAAKub,IAAIA,EAAI,GAAIwK,EAAW3pB,GACrCiL,EAAI,GAAKrH,KAAKqH,IAAIA,EAAI,GAAI0e,EAAW3pB,GAErCmf,EAAI,GAAKvb,KAAKub,IAAIA,EAAI,GAAIwK,EAAW9Q,GACrC5N,EAAI,GAAKrH,KAAKqH,IAAIA,EAAI,GAAI0e,EAAW9Q,GAErCqR,EAAiB,EAAJ1rB,GAASmrB,EAAW/Q,EACjCsR,EAAiB,EAAJ1rB,EAAQ,GAAKmrB,EAAW3pB,EACrCkqB,EAAiB,EAAJ1rB,EAAQ,GAAKmrB,EAAW9Q,CACzC,CAEA,IAAMrF,EAAawO,EAActO,iBAAiBwW,EAAcG,IAC1DnL,EAAW8C,EAAclD,eAAetL,EAAY,OAAF,KAAkDsW,EAAenrB,OAAS,EAAG,EAAG,CAAEwgB,IAAG,EAAElU,IAAG,IAClJgX,EAAUnhB,KAAKoe,GACfxf,EAAO+pB,WAAqB,SAAIxH,EAAUtjB,OAAS,CACvD,MACI,EAAAT,MAAM4I,KAAK,0CAAmCge,EAAKne,KAAI,+DAE/D,CAEA,GAAIue,EAAYoF,WAAY,CACxB,IAAMC,EAAerF,EAAYsF,aAC3BC,EAAkBjV,EAASyU,gBAAgB,EAAAjT,aAAaE,YAE9D,GAAIuT,EAAiB,CACjB,IAAMC,EAAa,IAAI3kB,aAAa0kB,EAAgB9rB,QAGpD,IAFAirB,EAAca,EAAgB9rB,OAAS,EAE9BH,EADK,EACYA,EAAIorB,IAAeprB,EAAG,CAC5C,IAAMmsB,EAAiB,EAAAhW,QAAQsT,UAAUwC,EAAqB,EAAJjsB,GAAO0pB,YAC7C,EAAAvT,QAAQsT,UAAUsC,EAAkB,EAAJ/rB,GAAO0pB,YAC/CkC,cAAcO,EAAgBhB,GAE1Ce,EAAe,EAAJlsB,GAASmrB,EAAW/Q,EAAI8Q,EACnCgB,EAAe,EAAJlsB,EAAQ,GAAKmrB,EAAW3pB,EACnC0qB,EAAe,EAAJlsB,EAAQ,GAAKmrB,EAAW9Q,CACvC,CAEMrF,EAAawO,EAActO,iBAAiBgX,EAAYL,IACxDnL,EAAW8C,EAAclD,eAAetL,EAAY,OAAF,KAAkD+W,EAAa5rB,OAAS,EAAG,GACnIsjB,EAAUnhB,KAAKoe,GACfxf,EAAO+pB,WAAmB,OAAIxH,EAAUtjB,OAAS,CACrD,MACI,EAAAT,MAAM4I,KAAK,wCAAiCge,EAAKne,KAAI,8DAE7D,CAEA,GAAIue,EAAY0F,YAAa,CACzB,IAAMC,EAAgB3F,EAAY4F,cAC5BC,EAAmBvV,EAASyU,gBAAgB,EAAAjT,aAAaG,aAE/D,GAAI4T,EAAkB,CAClBnB,EAAcmB,EAAiBpsB,OAAS,EACxC,IAAMqsB,EAAc,IAAIjlB,aAA2B,EAAd6jB,GAErC,IAASprB,EADK,EACYA,EAAIorB,IAAeprB,EAAG,CAE5C,IAAMysB,EAAkB,EAAAtW,QAAQsT,UAAU8C,EAAsB,EAAJvsB,GAC5Dka,EAAiBuS,GAGjB,IAAMC,EAAe,EAAAvW,QAAQsT,UAAU4C,EAAmB,EAAJrsB,GACtDka,EAAiBwS,GAEjBA,EAAad,cAAca,EAAiBtB,GAC5CqB,EAAgB,EAAJxsB,GAASmrB,EAAW/Q,EAAI8Q,EACpCsB,EAAgB,EAAJxsB,EAAQ,GAAKmrB,EAAW3pB,EACpCgrB,EAAgB,EAAJxsB,EAAQ,GAAKmrB,EAAW9Q,CACxC,CACMrF,EAAawO,EAActO,iBAAiBsX,EAAaX,IACzDnL,EAAW8C,EAAclD,eAAetL,EAAY,OAAF,KAAkDoW,EAAa,GACvH3H,EAAUnhB,KAAKoe,GACfxf,EAAO+pB,WAAoB,QAAIxH,EAAUtjB,OAAS,CACtD,MACI,EAAAT,MAAM4I,KAAK,yCAAkCge,EAAKne,KAAI,+DAE9D,CAEA,GAAIue,EAAYiG,UAAW,CACvB,IAAMC,EAAclG,EAAYmG,YAC1BC,EAAiB9V,EAASyU,gBAAgB,EAAAjT,aAAaI,WACvD5U,EAASgT,EAAS+V,gBAAgB,EAAAvU,aAAaI,WAErD,GAAIkU,GAAkB9oB,EAAQ,CAC1B,IAAMgpB,EAAgBhpB,EAAO4G,UAE7BwgB,EAAc0B,EAAe3sB,OAAS6sB,EACtC,IAAMC,EAAY,IAAI1lB,aAAa6jB,EAAc4B,GAEjD,IAAShtB,EADK,EACYA,EAAIorB,IAAeprB,EACzC,GAAsB,IAAlBgtB,EAAqB,CACrB,IAAME,EAAgB,EAAA/W,QAAQsT,UAAUqD,EAAgB9sB,EAAIgtB,GACzC,EAAA7W,QAAQsT,UAAUmD,EAAa5sB,EAAIgtB,GAE3CpB,cAAcsB,EAAe/B,GACxC8B,EAAc,EAAJjtB,GAASmrB,EAAW/Q,EAC9B6S,EAAc,EAAJjtB,EAAQ,GAAKmrB,EAAW3pB,EAClCyrB,EAAc,EAAJjtB,EAAQ,GAAKmrB,EAAW9Q,CACtC,MAAO,GAAsB,IAAlB2S,EAAqB,CAC5B,IAAMG,EAAc,IAAI,EAAAC,QAClBF,EAAgB,EAAAE,QAAQ3D,UAAUqD,EAAgB9sB,EAAIgtB,GACzC,EAAAI,QAAQ3D,UAAUmD,EAAa5sB,EAAIgtB,GAE3CpB,cAAcsB,EAAeC,GACxCF,EAAc,EAAJjtB,GAASmtB,EAAY/S,EAC/B6S,EAAc,EAAJjtB,EAAQ,GAAKmtB,EAAY3rB,EACnCyrB,EAAc,EAAJjtB,EAAQ,GAAKmtB,EAAY9S,EACnC4S,EAAc,EAAJjtB,EAAQ,GAAKmtB,EAAYlhB,CACvC,MACI,EAAAvM,MAAM4I,KAAK,gEAAyD0kB,IAGtEhY,EAAawO,EAActO,iBAAiB+X,EAxIxC,EAwI+DD,GACnEtM,EAAW8C,EAAclD,eAAetL,EAA8B,IAAlBgY,EAAsB,OAAoB,OAAmB,KAA6B5B,EAAa,GACjK3H,EAAUnhB,KAAKoe,GACfxf,EAAO+pB,WAAoB,QAAIxH,EAAUtjB,OAAS,CACtD,MACI,EAAAT,MAAM4I,KAAK,uCAAgCge,EAAKne,KAAI,6DAE5D,CAEA,OAAOjH,CACX,CCzGA,kBAqBI,WAAmB+kB,EAA+BoH,GAnB1C,KAAAC,oBAAsB,IAAI3lB,IAG1B,KAAA4lB,qBAAuB,IAAI5lB,IAG3B,KAAA6lB,mBAAqB,IAAI7lB,IAEzB,KAAA8lB,oBAAsB,IAAI9lB,IAE1B,KAAA+lB,oBAAsB,IAAI/lB,IAE1B,KAAAgmB,qBAAuB,IAAIhmB,IAE3B,KAAAimB,eAAiB,IAAIhI,IAGrB,KAAAiI,SAAW,IAAIlmB,IAYP,KAAAmmB,8BAAgC,IAAInmB,IAThDtK,KAAK4oB,qBAAuBA,EAC5B5oB,KAAKgwB,mBAAqBA,CAC9B,CAmHJ,OA1GW,YAAAU,mBAAP,SAA0BC,EAAiCC,EAAe/V,EAAehM,EAAgBgiB,G,YACrG,OAAiF,QAA1E,EAA6D,QAA7D,EAAiD,QAAjD,EAAqC,QAArC,EAAA7wB,KAAKiwB,oBAAoBlvB,IAAI4vB,UAAQ,eAAE5vB,IAAI6vB,UAAM,eAAE7vB,IAAI8Z,UAAM,eAAE9Z,IAAI8N,UAAO,eAAE9N,IAAI8vB,EAC3F,EAEO,YAAAC,mBAAP,SAA0BH,EAAiCC,EAAe/V,EAAehM,EAAgBgiB,EAAeE,GACpH,IAAIC,EAAOhxB,KAAKiwB,oBAAoBlvB,IAAI4vB,GACnCK,IACDA,EAAO,IAAI1mB,IACXtK,KAAKiwB,oBAAoBra,IAAI+a,EAASK,IAG1C,IAAIC,EAAOD,EAAKjwB,IAAI6vB,GACfK,IACDA,EAAO,IAAI3mB,IACX0mB,EAAKpb,IAAIgb,EAAOK,IAGpB,IAAIC,EAAOD,EAAKlwB,IAAI8Z,GACfqW,IACDA,EAAO,IAAI5mB,IACX2mB,EAAKrb,IAAIiF,EAAOqW,IAGpB,IAAIC,EAAOD,EAAKnwB,IAAI8N,GACfsiB,IACDA,EAAO,IAAI7mB,IACX4mB,EAAKtb,IAAI/G,EAAQsiB,IAGrBA,EAAKvb,IAAIib,EAAME,EACnB,EAEO,YAAAK,iBAAP,SAAwBjY,GACfnZ,KAAKuwB,eAAe5M,IAAIxK,IACzBnZ,KAAKuwB,eAAetkB,IAAIkN,EAEhC,EAEO,YAAAkY,YAAP,WACI,OAAOrxB,KAAKuwB,cAChB,EAEO,YAAAe,oBAAP,SAA2B3qB,GACvB,OAAO3G,KAAKkwB,qBAAqBnvB,IAAI4F,EACzC,EAEO,YAAA4qB,oBAAP,SAA2B5qB,EAAgBgR,GACvC3X,KAAKkwB,qBAAqBta,IAAIjP,EAAQgR,EAC1C,EAEO,YAAA6Z,sBAAP,SAA6B7qB,EAAgBwT,EAA4BxC,GACrE3X,KAAKowB,oBAAoBxa,IAAIjP,EAAQ,IAAI2D,KACzCtK,KAAKowB,oBAAoBrvB,IAAI4F,GAASiP,IAAIuE,EAAcxC,EAC5D,EAEO,YAAA8Z,sBAAP,SAA6B9qB,EAAgBwT,G,MACzC,OAA2C,QAApC,EAAAna,KAAKowB,oBAAoBrvB,IAAI4F,UAAO,eAAE5F,IAAIoZ,EACrD,EAEO,YAAAuX,kBAAP,SAAyBvX,EAA4ByW,EAAe/V,G,QAChE,OAA4D,QAArD,EAAyC,QAAzC,EAAA7a,KAAKmwB,mBAAmBpvB,IAAIoZ,UAAa,eAAEpZ,IAAI6vB,UAAM,eAAE7vB,IAAI8Z,EACtE,EAEO,YAAA8W,kBAAP,SAAyBxX,EAA4ByW,EAAe/V,EAAekW,GAC/E,IAAIC,EAAOhxB,KAAKmwB,mBAAmBpvB,IAAIoZ,GAClC6W,IACDA,EAAO,IAAI1mB,IACXtK,KAAKmwB,mBAAmBva,IAAIuE,EAAc6W,IAG9C,IAAIC,EAAOD,EAAKjwB,IAAI6vB,GACfK,IACDA,EAAO,IAAI3mB,IACX0mB,EAAKpb,IAAIgb,EAAOK,IAGpBA,EAAKrb,IAAIiF,EAAOkW,EACpB,EAEO,YAAAa,oBAAP,SAA2BzX,GACvB,OAAOna,KAAKswB,qBAAqBvvB,IAAIoZ,KAAiB,CAC1D,EAEO,YAAA0X,uBAAP,SAA8B1X,EAA4B5K,GACtD,OAAOvP,KAAKswB,qBAAqB1a,IAAIuE,EAAc5K,EACvD,EAEO,YAAAuiB,QAAP,SAAe7I,GACX,OAAOjpB,KAAKwwB,SAASzvB,IAAIkoB,EAC7B,EAEO,YAAA8I,QAAP,SAAe9I,EAAoB+I,GAC/BhyB,KAAKwwB,SAAS5a,IAAIqT,EAAM+I,EAC5B,EAEO,YAAAC,oBAAP,SAA2BhJ,EAAoBiJ,GAC3C,IAAMC,EAAenyB,KAAKqwB,oBAAoBtvB,IAAIkoB,IAAS,GAC3DjpB,KAAKqwB,oBAAoBza,IAAIqT,EAAMkJ,IACM,IAArCA,EAAaC,QAAQF,IACrBC,EAAaltB,KAAKitB,EAE1B,EAEO,YAAAG,wBAAP,SAA+BpJ,GAC3B,OAAOjpB,KAAKqwB,oBAAoBtvB,IAAIkoB,EACxC,EACJ,EA3IA,GA8IA,cAmMI,WAAmBlB,EAA8DuK,GAC7E,QADe,IAAAvK,IAAAA,EAAgC,EAAAwK,YAAYC,kBAlM/C,KAAAC,MAAe,CAC3BC,MAAO,CAAErvB,UAAW,sBAAe,EAAAsvB,OAAOC,SAAWC,QAAS,QAGlD,KAAAC,YAA4B,GAC5B,KAAAC,WAA0B,GAC1B,KAAAC,aAA8B,GAC9B,KAAAC,SAAsB,GACtB,KAAAzb,QAAoB,GACpB,KAAA5K,WAA0B,GAC1B,KAAAsmB,QAAmB,GACnB,KAAAC,OAAkB,GAClB,KAAAza,UAAwB,GACxB,KAAA0a,QAAoB,GACpB,KAAAC,OAAkB,GAClB,KAAA5e,UAAwB,GAGxB,KAAA6D,WAA2C,CAAC,EASrD,KAAAb,eAAyB,EAEhB,KAAA6b,kBAAoB,IAAIC,EAAqBvzB,MAE5C,KAAAwzB,YAA4D,CAAC,EAE9D,KAAA5b,eAAiB,IAAI6b,EAEpB,KAAAC,qBAAuB,IAAIppB,IAG3B,KAAAqpB,SAAW,IAAIrpB,IAGhB,KAAAspB,aAAe,IAAItpB,IAClB,KAAAupB,YAAc,IAAIvpB,IAClB,KAAAwpB,gBAAkB,IAAIxpB,IACtB,KAAAypB,SAAW,IAAIzpB,IACf,KAAA0pB,cAAgB,IAAI1pB,IAGrB,KAAA0B,qBAAuB,IAAIuc,KAmJlCR,EACD,MAAM,IAAI5d,MAAM,gCAGpBnK,KAAKi0B,cAAgBlM,EAErB/nB,KAAKk0B,SAAW,GACZC,iBAAkB,WAAM,UACxB7N,sBAAuB,WAAM,UAC7B8N,iBAAkB,SAACC,GAAQ,MAAK,OAAc,QAAd,EAAAA,aAAQ,EAARA,EAAUC,YAAI,eAAEC,MAAM,EACtDnQ,oBAAqB,EAAI,GACzBoQ,8BAA8B,EAC9BC,iBAAiB,EACjBC,qBAAqB,EACrBC,wCAAwC,EACxCC,sBAAuB,QACpBtC,GAGPtyB,KAAK60B,iBACT,CAwnCJ,OAxxCY,YAAAC,gBAAR,SACI3b,EACApD,EACAhK,EACAgpB,GAJJ,WAMI,GAAIhpB,GAASgK,EAAWjT,OACpB,OAAOQ,QAAQC,QAAQ4V,GAG3B,IAAM6b,EAAiBD,EAAYhf,EAAWhK,GAAQoN,GAEtD,OAAK6b,EAKEA,EAAejxB,MAAK,SAAOkxB,GAAO,sE,8BAAMA,EAAU,GAAMj1B,KAAK80B,gBAAgBG,EAASlf,EAAYhK,EAAQ,EAAGgpB,IAArE,M,cAAU,W,aAA0E,O,iBAArF,Y,UAJnC/0B,KAAK80B,gBAAgB3b,EAAMpD,EAAYhK,EAAQ,EAAGgpB,EAKjE,EAGQ,YAAAG,iBAAR,SAA4B/b,EAAS4b,GAEjC,IADA,IAAMhf,EAAyC,GAC5B,MAAAof,EAAaC,gBAAb,eAA8B,CAA5C,IAAM,EAAI,KACXrf,EAAW9Q,KAAKjF,KAAKwzB,YAAY,GACrC,CAEA,OAAOxzB,KAAK80B,gBAAgB3b,EAAMpD,EAAY,EAAGgf,EACrD,EAGO,YAAAM,+BAAP,SAAsCC,EAAiBnc,EAAaoF,EAAmB0H,EAA4B2C,GAAnH,WACI,OAAO5oB,KAAKk1B,iBACR/b,GAEA,SAAClB,EAAWkB,GAAS,OAAAlB,EAAUsd,qBAAuBtd,EAAUsd,oBAAoBD,EAASnc,EAAMoF,EAAa0H,EAAS2C,EAAsB,EAAKhR,eAA/H,GAE7B,EAGO,YAAA5K,mCAAP,SAA0CsoB,EAAiBzqB,EAAqB1B,GAE5E,OAAOnJ,KAAKk1B,iBAAiBrqB,GAAU,SAACoN,EAAWkB,GAAS,OAAAlB,EAAUud,yBAA2Bvd,EAAUud,wBAAwBF,EAASnc,EAAMhQ,EAAtF,GAChE,EASa,YAAA0D,qDAAb,SAAkEyoB,EAAiBzqB,EAAqB1B,G,uGAGpG,OAFMohB,EAAwB,GAE9B,GAAMjnB,QAAQ4I,IACVipB,EAAaC,gBAAgBK,KAAI,SAAO3qB,GAAI,qC,iEAClCmN,EAAYjY,KAAKwzB,YAAY1oB,IAErB4qB,0CACO,GAAMzd,EAAUyd,0CAA0CJ,EAASzqB,EAAU1B,IAD9F,M,OACM2D,EAAW,SACjByd,EAAOtlB,KAAI,MAAXslB,EAAezd,G,8CAK3B,OAXA,SAWO,CAAP,EAAOyd,G,QAGJ,YAAA1U,8BAAP,SAAqCyf,EAAiBhqB,EAA2BhF,GAC7E,IAAmB,UAAA6uB,EAAaC,gBAAb,eAA8B,CAA5C,IAAM,EAAI,KACLnd,EAAYjY,KAAKwzB,YAAY,GAE/Bvb,EAAU0d,mBACV1d,EAAU0d,kBAAkBL,EAAShqB,EAAahF,EAE1D,CACJ,EAEO,YAAAsvB,mCAAP,SAA0CC,GACtC,IAAmB,UAAAV,EAAaC,gBAAb,eAA8B,CAA5C,IAAM,EAAI,KACLnd,EAAYjY,KAAKwzB,YAAY,GAE/Bvb,EAAU6d,yBACV7d,EAAU6d,wBAAwBD,EAAW71B,KAAK4X,eAAgB5X,KAAK+yB,WAE/E,CACJ,EAEa,YAAAgD,kCAAb,W,0GACuB,EAAAZ,EAAaC,gB,wBAAb,YAAd,QACKnd,EAAYjY,KAAKwzB,YAAY,IAErBwC,uBAEV,GAAM/d,EAAU+d,uBAAuBh2B,KAAK4X,iBAF5C,OAHuC,M,OAKvC,S,wBALW,I,+BAUf,YAAAqe,mBAAR,SAA2BC,GACvB,IAAmB,UAAAf,EAAaC,gBAAb,eAA8B,CAA5C,IAAM,EAAI,KACLnd,EAAYjY,KAAKwzB,YAAY,GAC/Bvb,EAAUke,SACVD,EAAOje,EAEf,CACJ,EAEQ,YAAAme,uBAAR,sBACIp2B,KAAKi2B,oBAAmB,SAAChe,G,UACjBA,EAAUoe,WACV,IAAK5D,OAAM6D,iBAAc,EAAdA,eAAmB,KAC6B,IAAvD,EAAK7D,MAAM6D,eAAelE,QAAQna,EAAUnN,OAC5C,EAAK2nB,MAAM6D,eAAerxB,KAAKgT,EAAUnN,MAGzCmN,EAAUse,YACV,IAAK9D,OAAM+D,qBAAkB,EAAlBA,mBAAuB,KAC6B,IAA3D,EAAK/D,MAAM+D,mBAAmBpE,QAAQna,EAAUnN,OAChD,EAAK2nB,MAAM+D,mBAAmBvxB,KAAKgT,EAAUnN,QAIrD,IAAK2nB,OAAM1c,aAAU,EAAVA,WAAe,CAAC,GACvBkC,EAAUwe,aACVxe,EAAUwe,cAGtB,GACJ,EAEQ,YAAA5B,gBAAR,WACI,IAAmB,UAAAM,EAAaC,gBAAb,eAA8B,CAA5C,IAAM,EAAI,KACLnd,EAAYkd,EAAauB,oBAAoB,GAAM12B,MACzDA,KAAKwzB,YAAY,GAAQvb,CAC7B,CACJ,EAyBO,YAAA0e,QAAP,WACI,IAAK,IAAMj2B,KAAOV,KAAKwzB,YACDxzB,KAAKwzB,YAAY9yB,GACzBi2B,SAElB,EAEA,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAKk0B,QAChB,E,gCAEc,EAAA0C,kBAAd,SAAgC9rB,EAActL,EAA+Dq3B,QAAA,IAAAA,IAAAA,EAAA,KACrG1B,EAAa2B,oBAAoBhsB,IACjC,EAAAzI,MAAM4I,KAAK,kCAA2BH,EAAI,oBAG9CqqB,EAAauB,oBAAoB5rB,GAAQtL,EACzC,IAAMu3B,EAAiBF,QAAAA,EAAS,EAChC1B,EAAa6B,iBAAiBlsB,GAAQisB,EAItC,IADA,IAAIE,EAAc9B,EAAaC,gBAAgBtyB,OACtCH,EAAI,EAAGA,EAAIwyB,EAAaC,gBAAgBtyB,OAAQH,IAAK,CAC1D,IAAMu0B,EAAe/B,EAAaC,gBAAgBzyB,GAIlD,GAAIo0B,EAHkB5B,EAAa6B,iBAAiBE,GAGhB,CAChCD,EAAct0B,EACd,KACJ,CACJ,CAEAwyB,EAAaC,gBAAgB+B,OAAOF,EAAa,EAAGnsB,EACxD,EAEc,EAAAgsB,oBAAd,SAAkChsB,GAC9B,IAAKqqB,EAAauB,oBAAoB5rB,GAClC,OAAO,SAEJqqB,EAAauB,oBAAoB5rB,UACjCqqB,EAAa6B,iBAAiBlsB,GAErC,IAAMiB,EAAQopB,EAAaC,gBAAgBhD,QAAQtnB,GAKnD,OAJe,IAAXiB,GACAopB,EAAaC,gBAAgB+B,OAAOprB,EAAO,IAGxC,CACX,EAEQ,YAAAqrB,cAAR,SAAsBC,EAA0BC,EAAmBC,GAC/D,IAAM5wB,EAAkB,CAAEQ,WAAYkwB,GA+CtC,OA7CI1wB,EAAOQ,aACPnH,KAAKyyB,MAAM+E,QAAU,CAAC7wB,IAEtB3G,KAAKmzB,QAAUnzB,KAAKmzB,OAAOrwB,SAC3B9C,KAAKyyB,MAAMvM,MAAQlmB,KAAKmzB,QAExBnzB,KAAKkzB,SAAWlzB,KAAKkzB,QAAQpwB,SAC7B9C,KAAKyyB,MAAMrY,OAASpa,KAAKkzB,SAEzBlzB,KAAKozB,SAAWpzB,KAAKozB,QAAQtwB,SAC7B9C,KAAKyyB,MAAMgF,OAASz3B,KAAKozB,QACzBpzB,KAAKyyB,MAAM7oB,MAAQ,GAEnB5J,KAAKizB,UAAYjzB,KAAKizB,SAASnwB,SAC/B9C,KAAKyyB,MAAMiF,QAAU13B,KAAKizB,UAE1BjzB,KAAKgzB,cAAgBhzB,KAAKgzB,aAAalwB,SACvC9C,KAAKyyB,MAAMlQ,YAAcviB,KAAKgzB,cAE9BhzB,KAAK+yB,YAAc/yB,KAAK+yB,WAAWjwB,SACnC9C,KAAKyyB,MAAMrM,UAAYpmB,KAAK+yB,YAE5B/yB,KAAK8yB,aAAe9yB,KAAK8yB,YAAYhwB,SACrC9C,KAAKyyB,MAAMjM,WAAaxmB,KAAK8yB,aAE7B9yB,KAAK4M,YAAc5M,KAAK4M,WAAW9J,SACnC9C,KAAKyyB,MAAM9lB,UAAY3M,KAAK4M,YAE5B5M,KAAKyU,WAAazU,KAAKyU,UAAU3R,SACjC9C,KAAKyyB,MAAM3lB,SAAW9M,KAAKyU,WAE3BzU,KAAK0Y,WAAa1Y,KAAK0Y,UAAU5V,SACjC9C,KAAKyyB,MAAMha,SAAWzY,KAAK0Y,WAE3B1Y,KAAKqzB,QAAUrzB,KAAKqzB,OAAOvwB,SAC3B9C,KAAKyyB,MAAMkF,MAAQ33B,KAAKqzB,QAExBrzB,KAAKwX,SAAWxX,KAAKwX,QAAQ1U,SAC7B9C,KAAKyyB,MAAMlb,OAASvX,KAAKwX,SAGxBxX,KAAKyX,gBACN9Q,EAAOyR,IAAMkf,EAAW,QAGrBC,EAAcK,KAAKC,UAAU73B,KAAKyyB,MAAO,KAAM,GAAKmF,KAAKC,UAAU73B,KAAKyyB,MACnF,EAEa,YAAAqF,kBAAb,SAA+BC,G,4GACN,SAAM/3B,KAAKg4B,wB,OAchC,GAdMC,EAAe,SACrBj4B,KAAKo2B,yBACC8B,EAAWl4B,KAAKo3B,cAAca,EAAa9wB,WAAY4wB,GAAY,GAEnEI,EAAM,IAAIj2B,KAAK,CAAC+1B,GAAe,CAAE91B,KAAM,6BAEvCi2B,EAAeL,EAAa,QAC5BM,EAAcN,EAAa,QAE3BO,EAAY,IAAIC,GAEZx2B,MAAMq2B,GAAgBF,EAChCI,EAAUv2B,MAAMs2B,GAAeF,EAE3Bn4B,KAAKsY,WACL,IAAWZ,KAAS1X,KAAKsY,WACrBggB,EAAUv2B,MAAM2V,GAAS1X,KAAKsY,WAAWZ,GAIjD,MAAO,CAAP,EAAO4gB,G,QAGG,YAAAN,qBAAd,W,0FACI,SAAMh4B,KAAKw4B,qB,OACX,OADA,SACA,GAAMx4B,KAAK+1B,qC,OACX,OADA,SACO,CAAP,EAAO/1B,KAAK4X,eAAe0K,eAAetiB,KAAKgzB,e,QAQ3C,YAAAyF,YAAR,SAAoBC,GAChB,IAAMC,EAAYD,EAAM,EAGxB,OAF8B,IAAdC,EAAkBA,EAAY,EAAIA,CAGtD,EAEa,YAAAC,iBAAb,SAA8Bb,G,0HAEL,OADrB/3B,KAAKyX,eAAgB,EACA,GAAMzX,KAAKg4B,wB,OAgChC,GAhCMC,EAAe,SACrBj4B,KAAKo2B,yBACC8B,EAAWl4B,KAAKo3B,cAAca,EAAa9wB,YAE3C0xB,EAAcd,EAAa,OAG7Be,EAAaZ,EAASp1B,OAGC,oBAAhBi2B,cACDC,EAAU,IAAID,YACpBE,EAAkBD,EAAQE,OAAOhB,GACjCY,EAAaG,EAAgBn2B,QAE3Bq2B,EAAcn5B,KAAKy4B,YAAYK,GAC/BM,EAAap5B,KAAKy4B,YAAYR,EAAa9wB,YAE3CA,EAAakyB,GAAuCP,EAAaK,EAAclB,EAAa9wB,WAAaiyB,GAEzG1W,EAAa,IAAIC,EAAWxb,IAGvBya,YAAY,YACvBc,EAAWd,YAAY,GACvBc,EAAWd,YAAYza,GAGvBub,EAAWd,YAAYkX,EAAaK,GACpCzW,EAAWd,YAAY,YAGnBqX,EAEAvW,EAAW1B,gBAAgBiY,QAG3B,IADMK,EAAgB,IAAIC,WAAW,GAC5B52B,EAAI,EAAGA,EAAIm2B,IAAcn2B,GACxB62B,EAAWtB,EAASqB,WAAW52B,KAErBu1B,EAASuB,YAAY92B,GACjC+f,EAAWpB,WAAWgY,GAEtB5W,EAAWpB,WAAWkY,GAMlC,IAAS72B,EAAI,EAAGA,EAAIw2B,IAAex2B,EAC/B+f,EAAWpB,WAAW,IAW1B,IAPAoB,EAAWd,YAAYqW,EAAa9wB,WAAaiyB,GACjD1W,EAAWd,YAAY,SAGvBc,EAAW1B,gBAAgBiX,GAGlBt1B,EAAI,EAAGA,EAAIy2B,IAAcz2B,EAC9B+f,EAAWpB,WAAW,GAM1B,OAHMgX,EAAY,IAAIC,GACZx2B,MAAM82B,GAAe,IAAI32B,KAAK,CAACwgB,EAAWrB,iBAAkB,CAAElf,KAAM,6BAEvE,CAAP,EAAOm2B,G,QAGH,YAAAoB,uBAAR,SAA+BvgB,EAAa6K,EAAqC4E,G,MAK7E,GAJK5E,EAAqB2V,gBAAgBntB,kBAAkBoN,EAAoB,EAAAhU,UAC5E,EAAAvD,MAAM4I,KAAK,0DAGV+Y,EAAqB+I,SAASvgB,kBAAkBoN,EAAoB,EAAAhU,SAAU,CAC/E,IAAMoY,EAAc,EAAAvE,WAAWX,QAAQ,GAAG8gB,SAAS5V,EAAqB+I,UACpEnE,GACA3L,EAA6Be,GAGjC7E,EAAK6E,YAAcA,EAAYvR,SACnC,CAEKuX,EAAqBnF,QAAQrS,kBAAkBuN,EAAc,EAAAnU,WAC9DuT,EAAK3Q,MAAQwb,EAAqBnF,QAAQpS,WAG9C,IAAMqgB,GACqC,QAAvC,EAAA9I,EAAqB8I,0BAAkB,eAAE+M,UACzC,EAAA9gB,WAAW+gB,gBAAgB9V,EAAqBtG,SAASX,EAAGiH,EAAqBtG,SAASvZ,EAAG6f,EAAqBtG,SAASV,GAE1H8P,EAAmBtgB,kBAAkBsN,EAAiB,EAAAlU,WACnDgjB,GACA1L,EAA6B4P,GAGjC3T,EAAKuE,SAAWoP,EAAmBT,YAAY5f,UAEvD,EAEQ,YAAAstB,yBAAR,SAAiC5gB,EAAa6gB,EAA6BpR,GAGvE,IAAM5K,EAAc,EAAAvE,WAAWX,QAAQ,GACjCgU,EAAqB,EAAArT,WAAWV,WAAW,GAC3CkhB,EAAoBD,EAAc1gB,iBAExC,GAAI0gB,EAActb,OAAQ,CAEtB,IAAMwb,EAAuBF,EAActb,OAAOpF,iBAAiB6gB,YAAY,EAAA1gB,WAAWb,OAAO,IAC7EqhB,EAAkBzgB,cAAc0gB,EAAsB,EAAAzgB,WAAWb,OAAO,IAChFyF,eAAU/d,EAAWwsB,EAAoB9O,EACzD,MACIic,EAAkB5b,eAAU/d,EAAWwsB,EAAoB9O,GAG1DA,EAAYxR,kBAAkBoN,EAAoB,EAAAhU,WAC/CgjB,GACA3L,EAA6Be,GAEjC7E,EAAK6E,YAAcA,EAAYvR,WAG/Bmc,GACA1L,EAA6B4P,GAM5B9sB,KAAKi0B,cAAc7a,sBACpBqE,EAAWqP,GAGVA,EAAmBtgB,kBAAkBsN,EAAiB,EAAAlU,WACvDuT,EAAKuE,SAAWoP,EAAmBrgB,UAE3C,EAGQ,YAAA2tB,sBAAR,WACI,IAAqB,UAAAp6B,KAAKi0B,cAAcyD,QAAnB,eAA4B,CAA5C,IAAM2C,EAAM,KACPC,EAAsB,CACxBn4B,KAAMk4B,EAAOE,OAAS,EAAA1W,OAAO2W,mBAAqB,cAAyB,gBAO/E,GAJIH,EAAOvvB,OACPwvB,EAAWxvB,KAAOuvB,EAAOvvB,MAGL,gBAApBwvB,EAAWn4B,KACXm4B,EAAWG,YAAc,CACrBC,YAAaL,EAAO/xB,YAAYqyB,eAAeN,GAC/CO,KAAMP,EAAOQ,UAAY,EAAAhX,OAAOiX,uBAAyBT,EAAOU,IAAMV,EAAOU,IAAMV,EAAO/xB,YAAYqyB,eAAeN,GACrHW,MAAOX,EAAOY,KACdC,KAAMb,EAAOc,WAEd,GAAwB,iBAApBb,EAAWn4B,KAAkC,CACpD,IAAMi5B,EAAYf,EAAOgB,WAAahB,EAAOiB,WAAa,IAAOjB,EAAOiB,WAAajB,EAAOgB,WAAmD,GAAtChB,EAAO/xB,YAAYizB,iBACtHC,EAAanB,EAAOoB,aAAepB,EAAOqB,SAAW,IAAOrB,EAAOqB,SAAWrB,EAAOoB,aAAsD,GAAvCpB,EAAO/xB,YAAYqzB,kBAC7HrB,EAAWsB,aAAe,CACtBC,KAAMT,EACNU,KAAMN,EACNR,MAAOX,EAAOY,KACdC,KAAMb,EAAOc,KAErB,CACAn7B,KAAK6zB,YAAYje,IAAIykB,EAAQC,EACjC,CACJ,EAGQ,YAAAyB,wBAAR,WAEI,IADA,IACyB,MADLv2B,MAAMJ,KAAKpF,KAAK6zB,YAAYmI,UACvB,eAAa,CAAjC,IAAMC,EAAU,KACXC,EAAYl8B,KAAK8zB,gBAAgB/yB,IAAIk7B,GAC3C,QAAkB37B,IAAd47B,EAAyB,CACzBl8B,KAAKizB,SAAShuB,KAAKg3B,GACnB,IAAmB,UAAAC,EAAA,eAAJ,KACN7B,OAASr6B,KAAKizB,SAASnwB,OAAS,CAE7C,CACJ,CACJ,EAGQ,YAAAq5B,wBAAR,WACI,IAAuB,UAAAn8B,KAAKi0B,cAAcmI,UAAnB,eAA8B,CAAhD,IAAMC,EAAQ,KACXA,EAASC,MAAMx5B,QAAU,GAK7B9C,KAAK+zB,SAASne,IAAIymB,EADE,CAAEE,OAAQ,IAElC,CACJ,EAEQ,YAAAC,0BAAR,SAAkCC,GAC9B,I,iBAAWJ,GACP,GAAIA,EAASC,MAAMx5B,QAAU,E,iBAI7B,IAAM45B,EAAO,EAAK3I,SAAShzB,IAAIs7B,GAC/B,GAAY/7B,MAARo8B,E,iBAQJ,IAFA,IAAMC,EAA0C,CAAC,EAC7CC,GAAgB,EACXj6B,EAAI,EAAGA,EAAI05B,EAASC,MAAMx5B,SAAUH,EAAG,CAC5C,IAAMk6B,EAAOR,EAASC,MAAM35B,IAET,KADbm6B,EAA2B,QAAf,EAAAD,EAAKE,kBAAU,QAAIp6B,KAEjCg6B,EAAaG,GAAaD,EACtBC,EAAYF,IACZA,EAAeE,GAG3B,CAIA,IADA,IL1mBwC1e,EK0mBlC4e,EAAgC,GAC7BF,EAAY,EAAGA,GAAaF,IAAgBE,EAAW,CAC5D,IACMG,GADAJ,EAAOF,EAAaG,IACCI,mBACrB7S,EAAY4S,EAAgB,EAAKtJ,SAAS5yB,IAAIk8B,QAAiB38B,EACrE,QAAkBA,IAAd+pB,EAAJ,CAIAqS,EAAKH,OAAOt3B,KAAKolB,GAEjB,IAAM8S,EAAaN,EAAKO,+BAA+BvD,QACnD4C,EAAc9Y,IAAIsZ,KLtnBc7e,EKunBI+e,ELtnBpDxkB,EAAwBwhB,YAAY,EAAA1gB,WAAWb,OAAO,IAAIY,cAAc4E,EAAQA,GAAQ5E,cAAcb,EAAyByF,IKwnBnH4e,EAAoB/3B,KAAKk4B,EAPzB,MAFI,EAAA96B,MAAM4I,KAAK,6EAUnB,CAGA,IAAMoyB,EAAe,EAAKrJ,cAAcjzB,IAAI27B,GAG5C,GAAIA,EAAKH,OAAOz5B,OAAS,QAAsBxC,IAAjB+8B,EAA4B,CACtD,IAAM,EAA0B,IAAInzB,aAA0C,GAA7B8yB,EAAoBl6B,QACrEk6B,EAAoBva,SAAQ,SAAC6a,EAAavxB,GACtC,EAAwB6J,IAAI0nB,EAAIC,EAAW,GAARxxB,EACvC,IAEA,IAAM4L,EAAa,EAAKC,eAAeC,iBAAiB,GACxD,EAAKkb,WAAW9tB,KAAK,EAAK2S,eAAeqL,eAAetL,EAAY,OAAF,KAAkDqlB,EAAoBl6B,SACxI45B,EAAKM,oBAAsB,EAAKjK,WAAWjwB,OAAS,EAEpD,EAAKuwB,OAAOpuB,KAAKy3B,GAEjB,IADA,IAAMc,EAAY,EAAKnK,OAAOvwB,OAAS,EACb,MAAAu6B,EAAA,eAAJ,KACNX,KAAOc,CAE3B,C,SA/DmB,MAAAx9B,KAAKi0B,cAAcmI,UAAnB,e,EAAJ,KAiEvB,EAEc,YAAA5D,kBAAd,W,4IAoBI,IAnBM5uB,EAAgB,CAAEsc,MAAO,IAG3BlmB,KAAKi0B,cAAcI,WACbE,EAASv0B,KAAKk0B,SAASE,iBAAiBp0B,KAAKi0B,cAAcI,aAE7DzqB,EAAM2qB,OAASA,GASjBkJ,EAAc,IAAIj4B,MAClBk4B,EAAc,IAAIl4B,MAClBm4B,EAAkB,IAAIn4B,MAEvB,EAAL,EAAuB,EAAAxF,KAAKi0B,cAAc2J,UAAnB,eAAZC,EAAQ,KACX79B,KAAKk0B,SAASQ,sBAAwB10B,KAAKk0B,SAASS,wCAA0Czb,EAAW2kB,EAAU79B,KAAKi0B,cAAc7a,sBACtIukB,EAAgB14B,KAAI,MAApB04B,EAAwBE,EAASpf,eAC1Bze,KAAKi0B,cAAc7a,qBAC1BqkB,EAAYx4B,KAAK44B,GAEjBH,EAAYz4B,KAAK44B,GAQJ,OAJrB79B,KAAKo6B,wBACLp6B,KAAKm8B,0BAEC2B,EAAU,IAAIC,IAAc,GAAM,G,GACxC,KAAAn0B,EAAMsc,OAAMjhB,MAAI,M,MAAK,GAAMjF,KAAKg+B,kBAAkBN,EAAaI,I,OAE1C,OAFrB,oBAAqB,YACfG,EAAU,IAAIF,IAAc,GAAO,G,GACzC,KAAAn0B,EAAMsc,OAAMjhB,MAAI,M,MAAK,GAAMjF,KAAKg+B,kBAAkBP,EAAaQ,I,OAE1C,OAFrB,oBAAqB,YACfC,EAAS,IAAIH,IAAc,GAAO,G,GACxC,KAAAn0B,EAAMsc,OAAMjhB,MAAI,M,MAAK,GAAMjF,KAAKg+B,kBAAkBL,EAAiBO,I,cAAnE,oBAAqB,YAEjBt0B,EAAMsc,MAAMpjB,QACZ9C,KAAKozB,QAAQnuB,KAAK2E,GAGtB5J,KAAK+7B,0BACL/7B,KAAKw8B,0BAA0BsB,EAAQzM,eAEnCrxB,KAAKi0B,cAAc/L,gBAAgBplB,QACnC4hB,GAAeoD,gDACX9nB,KAAKi0B,cACLj0B,KAAK8yB,YACL9yB,KAAK2zB,SACL3zB,KAAK4X,eACL5X,KAAKgzB,aACLhzB,KAAK+yB,WACL/yB,KAAKm+B,qBACLL,EAAQzM,cACRrxB,KAAKk0B,SAAS5N,uB,YAKlB,YAAA8X,kBAAR,SAA0B7f,GACtB,IAAI1a,EAAS7D,KAAK0zB,qBAAqB3yB,IAAIwd,GAO3C,YALeje,IAAXuD,IACAA,EAAS7D,KAAKk0B,SAASC,iBAAiB5V,GACxCve,KAAK0zB,qBAAqB9d,IAAI2I,EAAa1a,IAGxCA,CACX,EAEc,YAAAm6B,kBAAd,SAAgCK,EAA0B1S,G,sGAChDzF,EAAQ,IAAI1gB,MAElBxF,KAAKs+B,eAAeD,EAAkB1S,G,IAEZ,EAAA0S,E,wBAAA,YAAf9f,EAAW,KAElB,GAAMve,KAAKu+B,iBAAiBhgB,EAAa2H,EAAOyF,KAFV,M,OAEtC,S,wBAFsB,I,aAK1B,MAAO,CAAP,EAAOzF,G,QAGH,YAAAsY,gBAAR,SACIjgB,EACAkgB,EACAC,EACAC,EACAhT,GAEA,GAAI3rB,KAAKo+B,kBAAkB7f,IAAgBA,aAAuB,EAAA7E,cAAgB6E,EAAY5E,SAAU,CACpG,IAAMilB,EAAgBrgB,EAAY5E,SAASklB,mBAC3C,GAAID,EACA,IAAK,IAAM9jB,KAAQ8jB,EACf,GAAK1jB,EAA0BJ,GAA/B,CAGA,IAAMX,EAAeykB,EAAc9jB,GACnC6Q,EAAMkG,uBAAuB1X,EAAcoE,EAAYugB,gBACvD,IAAMn4B,EAASwT,EAAavT,QACtBm4B,EAAoBN,EAAyB19B,IAAI4F,IAAW,GAClE83B,EAAyB7oB,IAAIjP,EAAQo4B,IACY,IAA7CA,EAAkB3M,QAAQjY,IAC1B4kB,EAAkB95B,KAAKkV,GAG3B,IAAMC,EAASskB,EAAwB39B,IAAIoZ,IAAiB,GAC5DukB,EAAwB9oB,IAAIuE,EAAcC,IACL,IAAjCA,EAAOgY,QAAQ7T,IACfnE,EAAOnV,KAAKsZ,EAbhB,CAkBR,IAAMwI,EAAqBxI,EAAYwI,mBAEvC,GAAIA,EACA,IAAK,IAAIiY,EAAa,EAAGA,EAAajY,EAAmBC,WAAYgY,IAAc,CAC/E,IAAM3V,EAActC,EAAmBE,UAAU+X,GAE3C5kB,EAASukB,EAAwB59B,IAAIsoB,IAAgB,GAC3DsV,EAAwB/oB,IAAIyT,EAAajP,IACJ,IAAjCA,EAAOgY,QAAQ7T,IACfnE,EAAOnV,KAAKsZ,EAEpB,CAER,CAEA,IAA+B,UAAAA,EAAYE,cAAZ,eAA2B,CAArD,IAAMwgB,EAAgB,KACvBj/B,KAAKw+B,gBAAgBS,EAAkBR,EAA0BC,EAAyBC,EAAyBhT,EACvH,CACJ,EAEQ,YAAA2S,eAAR,SAAuBD,EAA0B1S,GAK7C,IAJA,IAAM8S,EAA2B,IAAIn0B,IAC/Bo0B,EAA0B,IAAIp0B,IAC9B40B,EAAwB,IAAI50B,IAER,MAAA+zB,EAAA,eAAkB,CAAvC,IAAM9f,EAAW,KAClBve,KAAKw+B,gBAAgBjgB,EAAakgB,EAA0BC,EAAyBQ,EAAuBvT,EAChH,CAIA,IAFA,IAAM6L,EAAUhyB,MAAMJ,KAAKq5B,EAAyB7b,Q,WAEzCjc,GACP,IAAMI,EAAOJ,EAAO+c,UACpB,IAAK3c,EACD,MAAM,IAAIoD,MAAM,gCAGpB,IAAMy0B,EAAgBH,EAAyB19B,IAAI4F,GAEnD,IAAKi4B,E,iBAIL,IAAMvkB,EAAaukB,EAAc,GAAGvkB,WACpC,GAAIukB,EAAczmB,MAAK,SAACgC,GAAiB,OAAAA,EAAaE,aAAeA,CAA5B,IACrC,MAAM,IAAIlQ,MAAM,6EAMpB,IAHA,IAAMg1B,ELzpBX,SAA+Bp4B,GAClC,GAAIA,aAAgBvB,MAAO,CACvB,IAAM45B,EAAY,IAAIl1B,aAAanD,GACnC,OAAO,IAAI8C,WAAWu1B,EAAUz4B,OAAQy4B,EAAUl4B,WAAYk4B,EAAUj4B,WAC5E,CAEA,OAAOH,YAAYC,OAAOF,GAAQ,IAAI8C,WAAW9C,EAAKJ,OAAQI,EAAKG,WAAYH,EAAKI,YAAc,IAAI0C,WAAW9C,EACrH,CKkpB0Bs4B,CAAsBt4B,GAAMtB,Q,WAG/B0U,GACP,IAAMC,EAASskB,EAAwB39B,IAAIoZ,GACrC,EAA4ED,EAAoBC,EAAcC,GAA5GlT,EAAU,aAAE,EAAU,aAAEqT,EAAc,iBAAEpY,EAAI,OAAE0Y,EAAK,QAAEP,EAAU,aAEvE,OAF6E,QAIzE,KAAK,EAAAa,aAAaE,WAClB,KAAK,EAAAF,aAAaG,aACd,IAAAgkB,sBAAqBH,EAAOj4B,EAAY,EAAYqT,EAAgBpY,EAAM0Y,EAAOP,GAAY,SAAC0hB,GAC1F,IAAMl5B,EAASiF,KAAKC,KAAKg0B,EAAO,GAAKA,EAAO,GAAKA,EAAO,GAAKA,EAAO,GAAKA,EAAO,GAAKA,EAAO,IAC5F,GAAIl5B,EAAS,EAAG,CACZ,IAAMy8B,EAAY,EAAIz8B,EACtBk5B,EAAO,IAAMuD,EACbvD,EAAO,IAAMuD,EACbvD,EAAO,IAAMuD,CACjB,CACJ,IACA,MAGJ,KAAK,EAAApkB,aAAaI,UACd,IAAMikB,EAAmBplB,EAAOqlB,QAAO,SAACxW,GAAS,OAAAA,EAAKpe,oBAAoB,EAAA60B,kBAAqC,MAAjBzW,EAAKpe,QAAlD,IAAoE/H,OACrH,GAAwB,GAApB08B,EACA,MAGJ,GAAIA,GAAoBplB,EAAOtX,OAAQ,CACnC,EAAAgc,OAAO7T,KAAK,qIACZ,KACJ,CACI9I,GAAQ,EAAAgZ,aAAawkB,eACrB,EAAA7gB,OAAO7T,KAAK,+EAGhB,IAAM,EAAc,IAAI,EAAAnF,OAClB,EAAc,IAAI,EAAA85B,OAClB,EAA0B,EAAK3L,cAAc3rB,YAAYC,yBAE/D,IAAA+2B,sBAAqBH,EAAOj4B,EAAY,EAAYqT,EAAgBpY,EAAM0Y,EAAOP,GAAY,SAAC0hB,GAEpE,IAAlBA,EAAOl5B,QACP,EAAY+8B,UAAU7D,EAAQ,GAC9B,EAAY8D,mBAAmB,EAAa,GAC5C,EAAYrV,QAAQuR,EAAQ,KAE5B,EAAY6D,UAAU7D,EAAQ,GAC9B,EAAY8D,mBAAmB,EAAa,GAC5C,EAAYrV,QAAQuR,EAAQ,GAEpC,I,EAjDe,MAAA4C,EAAA,e,EAAhBzkB,EAAY,MAuDvB,GAAIwR,EAAM/C,qBAAsB,CAC5B,IAA2B,UAAAgW,EAAA,eAAe,CAArC,IAEK,EAA4E1kB,EAF3EC,EAAY,KACJukB,EAAwB39B,IAAIoZ,IACnCjT,EAAU,aAAE,EAAU,aAAEqT,EAAc,iBAAEpY,EAAI,OAAE0Y,EAAK,QAAEP,EAAU,aAEvE,OAFyEQ,EAAI,QAGzE,KAAK,EAAAK,aAAaC,aAClB,KAAK,EAAAD,aAAaE,WAClB,KAAK,EAAAF,aAAaG,aACd,IAAAgkB,sBAAqBH,EAAOj4B,EAAY,EAAYqT,EAAgBpY,EAAM0Y,EAAOP,GAAY,SAAC0hB,GAC1FA,EAAO,IAAMA,EAAO,EACxB,IAGZ,CAGArQ,EAAM8E,8BAA8B7a,IAAIjP,EAAQw4B,EACpD,CAGA,IAAMxnB,EAAa,EAAKC,eAAeC,iBAAiBsnB,EAAO9kB,GAC/DsR,EAAM4F,oBAAoB5qB,EAAQgR,GAKlC,IAHA,IAAMooB,EAAuB,IAAIz1B,IAGN,MAAAs0B,EAAA,eAAe,CAArC,IAEK,EAA0B1kB,EAFzBC,EAAY,KACJukB,EAAwB39B,IAAIoZ,IACnCW,EAAI,OAAEN,EAAa,gBAC3B,OAAQM,GACJ,KAAK,EAAAK,aAAaK,oBAClB,KAAK,EAAAL,aAAaM,yBACd,GAAItB,EAAahY,MAAQ,EAAAgZ,aAAa6kB,MAAO,CACzC,IAAMZ,EAAYjlB,EAAa8lB,aAAazlB,GAC1B,OAAd4kB,GACAW,EAAqBnqB,IAAIuE,EAAcilB,EAE/C,EAGZ,CAEkC,IAA9BW,EAAqB3oB,MACrB,EAAA0H,OAAO7T,KACH,0MAMR,IAFA,IAE2B,MAFKzF,MAAMJ,KAAK26B,EAAqBnd,QAErC,eAAyB,CAA/C,IAAMzI,EAAY,KACbiT,EAAQ2S,EAAqBh/B,IAAIoZ,GAEvC,GAAKiT,EAAL,CAMA,IAFA,IAAM8S,EAAiC9S,ELljCjCjV,MAAK,SAACtW,GAAU,OAAAA,GAAS,GAAT,IKmjChBs+B,EAAW,IAAKD,EAAU/f,YAActW,YAAYujB,EAAMtqB,QACvDiJ,EAAQ,EAAGA,EAAQqhB,EAAMtqB,OAAQiJ,IACtCo0B,EAASp0B,GAASqhB,EAAMrhB,GAE5B,IAAM,EAAa,EAAK6L,eAAeC,iBAAiBsoB,EAAU,GAAKD,EAAU,EAAI,IACrFvU,EAAM6F,sBAAsB7qB,EAAQwT,EAAc,EARlD,CASJ,C,SA5IiB,MAAAqd,EAAA,e,EAAJ,MAkJjB,IAFA,IAE0B,MAFLhyB,MAAMJ,KAAK85B,EAAsBtc,QAE5B,eAAc,CAAnC,IAAMyG,EAAW,KACZjP,EAAS8kB,EAAsBn+B,IAAIsoB,GAEzC,GAAKjP,EAML,IAFA,IAAMgmB,EAAkBzS,GAAwBtE,EAAajP,EAAO,GAAIpa,KAAK4X,eAAgB5X,KAAKgzB,aAAchzB,KAAK+yB,WAAYpH,EAAM/C,sBAEpH,MAAAxO,EAAA,eAAQ,CAAtB,IAAM6O,EAAI,KACX0C,EAAMsG,oBAAoBhJ,EAAMmX,EACpC,CACJ,CACJ,EAOc,YAAA7B,iBAAd,SAA+BhgB,EAAmB8hB,EAAmC1U,G,qHAEjF,YAAkBrrB,KADd+pB,EAAYrqB,KAAK2zB,SAAS5yB,IAAIwd,KAEzB8hB,EAAmBC,SAASjW,IAC7BgW,EAAmBp7B,KAAKolB,GAE5B,KAGS,GAAMrqB,KAAKugC,iBAAiBhiB,EAAaoN,I,QAAhDxS,EAAO,YAGTkR,EAAYrqB,KAAKmzB,OAAOrwB,OACxB9C,KAAKmzB,OAAOluB,KAAKkU,GACjBnZ,KAAK2zB,SAAS/d,IAAI2I,EAAa8L,GAC/BsB,EAAMyF,iBAAiB7S,GACvB8hB,EAAmBp7B,KAAKolB,GAGlBtE,EAAmC,CACrCjb,KAAM,qBACN4b,SAAU,GACVjO,SAAU,IAERuN,EAAmC,GAEpChmB,KAAKi0B,cAAc/L,gBAAgBplB,SACpC4hB,GAAemC,qDACXtI,EACAwH,EACAC,EACAhmB,KAAK2zB,SACL3zB,KAAKmzB,OACLnzB,KAAK4X,eACL5X,KAAKgzB,aACLhzB,KAAK+yB,WACL/yB,KAAKm+B,qBACLxS,EAAM/C,qBACN5oB,KAAKk0B,SAAS5N,uBAEd/H,EAAYiI,WAAW1jB,QACvB4hB,GAAeoB,uCACXvH,EACAwH,EACAC,EACAhmB,KAAK2zB,SACL3zB,KAAKmzB,OACLnzB,KAAK4X,eACL5X,KAAKgzB,aACLhzB,KAAK+yB,WACL/yB,KAAKm+B,qBACLxS,EAAM/C,qBACN5oB,KAAKk0B,SAAS5N,wBAKtBP,EAAqBW,SAAS5jB,QAAUijB,EAAqBtN,SAAS3V,QACtE9C,KAAK8yB,YAAY7tB,KAAK8gB,GAE1BC,EAAmBvD,SAAQ,SAAC+d,GACpBA,EAAkB9Z,SAAS5jB,QAAU09B,EAAkB/nB,SAAS3V,QAChE,EAAKgwB,YAAY7tB,KAAKu7B,EAE9B,KAIEC,EAAWtnB,EAAO,GAAKknB,E,IACE,EAAA9hB,EAAYE,c,wBAAZ,YAApBwgB,EAAgB,KAEvB,GAAMj/B,KAAKu+B,iBAAiBU,EAAkBwB,EAAU9U,KAFJ,M,OAEpD,S,wBAF2B,I,oBAK3BxS,GAAQsnB,EAAS39B,SACjBqW,EAAKsnB,SAAWA,G,YAQV,YAAAF,iBAAd,SAA+BhiB,EAAmBoN,G,sHAC9C,OAAK3rB,KAAKo+B,kBAAkB7f,IAItBpF,EAAc,CAAC,EAEjBoF,EAAYzT,OACZqO,EAAKrO,KAAOyT,EAAYzT,MAIxByT,EAAY8V,WACNE,EAASv0B,KAAKk0B,SAASE,iBAAiB7V,EAAY8V,aAEtDlb,EAAKob,OAASA,GAIlBhW,aAAuB,EAAAlF,eACvBrZ,KAAK05B,uBAAuBvgB,EAAMoF,EAAaoN,EAAM/C,sBAEjDrK,aAAuB,EAAA7E,cACjBsP,EAAczK,aAAuB,EAAAmiB,cAAgBniB,EAAYoiB,WAAcpiB,GACrEqiB,WAAa5X,EAAY4X,UAAU99B,OAAS,GACxD,EAAAqW,EAAY,GAAMnZ,KAAK6gC,iBAAiB7X,EAAa2C,KADrD,MAFJ,OAHJ,OAjBO,CAAP,EAAO,M,OAuBC,EAAK1C,KAAO,S,iBAGZ1K,EAAY8d,eAGC/7B,KAFPo8B,EAAO18B,KAAK+zB,SAAShzB,IAAIwd,EAAY8d,kBAGF/7B,IAAjCN,KAAKg0B,cAAcjzB,IAAI27B,IACvB18B,KAAKg0B,cAAcpe,IAAI8mB,EAAM,IAGL,QAA5B,EAAA18B,KAAKg0B,cAAcjzB,IAAI27B,UAAK,SAAEz3B,KAAKkU,I,iBAMnD,GAAIoF,aAAuB,EAAAK,eACjBqd,EAAaj8B,KAAK6zB,YAAY9yB,IAAIwd,IAExB,CASZ,QAR6Cje,IAAzCN,KAAK8zB,gBAAgB/yB,IAAIk7B,IACzBj8B,KAAK8zB,gBAAgBle,IAAIqmB,EAAY,IAGzCj8B,KAAK+5B,yBAAyB5gB,EAAMoF,EAAaoN,EAAM/C,sBAI7B,QADpBpK,EAAoBD,EAAYG,SACJJ,EAAmBC,EAAaC,SAEtCle,KADlBwgC,EAAkB9gC,KAAK2zB,SAAS5yB,IAAIyd,IAKtC,OAHMX,EAAa7d,KAAKmzB,OAAO2N,GAC/BljB,EAAwBzE,EAAM0E,GACM,QAApC,EAAA7d,KAAK8zB,gBAAgB/yB,IAAIk7B,UAAW,SAAEh3B,KAAK4Y,GACpC,CAAP,EAAO,MAIqB,QAApC,EAAA7d,KAAK8zB,gBAAgB/yB,IAAIk7B,UAAW,SAAEh3B,KAAKkU,EAC/C,CAIkB,SAAMnZ,KAAKq1B,+BAA+B,kBAAmBlc,EAAMoF,EAAave,KAAK2zB,SAAUhI,EAAM/C,uB,OAC3H,OADsB,SAMf,CAAP,EAAOzP,IAJH,EAAA2F,OAAO7T,KAAK,6BAAsBsT,EAAYzT,OACvC,CAAP,EAAO,O,QAMP,YAAAi2B,eAAR,SACIpQ,EACAqQ,EACApQ,EACA/V,EACAhM,EACAsN,EACA8kB,EACAtV,EACAkK,GAEA,IAAIqL,EAAkBvQ,EAEtBkF,EAAU0E,KAAOre,EAAiBC,GAGlC,IAAM0U,EAAOoQ,IAAoB,EAAA7kB,SAAS+kB,iCLxpC3C,SAA4BhlB,GAC/B,OAAQA,GACJ,KAAK,EAAAC,SAASC,iBACd,KAAK,EAAAD,SAASE,sBACd,KAAK,EAAAF,SAASG,oBACV,OAAO,EAGf,OAAO,CACX,CK+oCqF6kB,CAAmBjlB,GAChG,GAAI0U,EAAM,CACN,GAAI1U,IAAa,EAAAC,SAASE,uBAAyBH,IAAa,EAAAC,SAASG,oBACrE,MAAM,IAAIpS,MAAM,mDAGpB0rB,EAAU0E,KAAOre,EAAiBC,GAElC,IAAMklB,EAAaL,EAAW,IAAIzgB,YAAY1F,GAAS,IAAIsF,YAAYtF,GAEvE,GAAI8V,EACA,IAAK,IAAIhuB,EAAI,EAAGA,EAAI,EAAIkY,EAAOlY,GAAK,EAChC0+B,EAAW1+B,GAAKguB,EAAQC,EAAQjuB,GAAKkM,EACrCwyB,EAAW1+B,EAAI,GAAKguB,EAAQC,EAAQjuB,EAAI,GAAKkM,EAC7CwyB,EAAW1+B,EAAI,GAAKguB,EAAQC,EAAQjuB,EAAI,GAAKkM,OAGjD,IAASlM,EAAI,EAAGA,EAAI,EAAIkY,EAAOlY,GAAK,EAChC0+B,EAAW1+B,GAAKA,EAChB0+B,EAAW1+B,EAAI,GAAKA,EAAI,EACxB0+B,EAAW1+B,EAAI,GAAKA,EAAI,EAIhCu+B,EAAkBG,CACtB,MAAO,GAAI1Q,GAAsB,IAAX9hB,EAAc,CAEhC,IADMwyB,EAAaL,EAAW,IAAIzgB,YAAY1F,GAAS,IAAIsF,YAAYtF,GAC9DlY,EAAI,EAAGA,EAAIkY,EAAOlY,IACvB0+B,EAAW1+B,GAAKguB,EAAQC,EAAQjuB,GAAKkM,EAGzCqyB,EAAkBG,CACtB,CAEA,GAAIH,EAAiB,CACjB,IAAInQ,EAAgBpF,EAAM+E,mBAAmBC,EAASC,EAAO/V,EAAOhM,EAAQgiB,GAC5E,QAAsBvwB,IAAlBywB,EAA6B,CAC7B,IAAMoO,ELthCf,SAAqCxO,EAAuBC,EAAe/V,EAAemmB,GAC7F,IAAIM,EAAmB3Q,EAMvB,OALc,IAAVC,GAAe/V,IAAU8V,EAAQ7tB,SACjCw+B,EAAmB97B,MAAM4Z,QAAQuR,GAAWA,EAAQlrB,MAAMmrB,EAAOA,EAAQ/V,GAAS8V,EAAQ4Q,SAAS3Q,EAAOA,EAAQ/V,IAIlHymB,aAA4BjhB,WACrB,IAAIE,YAAY+gB,EAAiB36B,OAAQ26B,EAAiBp6B,WAAYo6B,EAAiBx+B,QAG9F0C,MAAM4Z,QAAQkiB,GACPN,EAAW,IAAIzgB,YAAY+gB,GAAoB,IAAInhB,YAAYmhB,GAGnEA,CACX,CKsgC8BE,CAA4BN,EAAiBtQ,EAAO/V,EAAOmmB,GACnErpB,EAAa3X,KAAK4X,eAAeC,iBAAiBsnB,GAElDjc,EAAgB8d,EAAW,KAAqC,KACtEhhC,KAAK+yB,WAAW9tB,KAAKjF,KAAK4X,eAAeqL,eAAetL,EAAY,SAAqBuL,EAAerI,EAAO,IAC/GkW,EAAgB/wB,KAAK+yB,WAAWjwB,OAAS,EACzC6oB,EAAMmF,mBAAmBH,EAASC,EAAO/V,EAAOhM,EAAQgiB,EAAME,EAClE,CAEA8E,EAAUlF,QAAUI,CACxB,CACJ,EAEQ,YAAA0Q,oBAAR,SAA4BtnB,EAA4BhR,EAA2BynB,EAAe/V,EAAe8Q,EAAsBkK,GACnI,IAAM/a,EAAOX,EAAaY,UAE1B,GAAKG,EAA0BJ,MAI3BA,EAAK4mB,WAAW,OAAU1hC,KAAKk0B,SAASO,iBACnCtrB,GAAoBnJ,KAAKgM,qBAAqB2X,IAAIxa,IAD3D,CAMA,IAAI4nB,EAAgBpF,EAAM+F,kBAAkBvX,EAAcyW,EAAO/V,GAEjE,QAAsBva,IAAlBywB,EAA6B,CAE7B,IAAMhqB,EAAO4kB,EAAM8E,8BAA8B1vB,IAAIoZ,EAAavT,UAAYuT,EAAavT,QAAQ8c,UAC7FP,EAASrI,IAAS,EAAAK,aAAaC,aL1hC1C,SAAmBrU,EAAiBoT,EAA4ByW,EAAe/V,GAC1E,IAAA3T,EAA6CiT,EAAY,WAA7CE,EAAiCF,EAAY,WAAjChY,EAAqBgY,EAAY,KAA3BG,EAAeH,EAAY,WAC3D/C,EAAO+C,EAAa5M,UACpB+V,EAAM,IAAI9d,MAAc4R,GAAMuqB,KAAKjU,KACnCte,EAAM,IAAI5J,MAAc4R,GAAMuqB,MAAK,KAQzC,OAPA,IAAArC,sBAAqBv4B,EAAMG,EAAa0pB,EAAQvW,EAAYA,EAAYjD,EAAMjV,EAAM0Y,EAAQzD,EAAMkD,GAAY,SAAC0hB,GAC3G,IAAK,IAAIr5B,EAAI,EAAGA,EAAIyU,EAAMzU,IACtB2gB,EAAI3gB,GAAKoF,KAAKub,IAAIA,EAAI3gB,GAAIq5B,EAAOr5B,IACjCyM,EAAIzM,GAAKoF,KAAKqH,IAAIA,EAAIzM,GAAIq5B,EAAOr5B,GAEzC,IAEO,CAAE2gB,IAAG,EAAElU,IAAG,EACrB,CK6gCgEwyB,CAAU76B,EAAMoT,EAAcyW,EAAO/V,QAASva,EAG5FuhC,GACD/mB,IAAS,EAAAK,aAAaK,qBAAuBV,IAAS,EAAAK,aAAaM,2BAA6BtB,EAAahY,OAAS,EAAAgZ,aAAa6kB,MAElI8B,EAAmBD,EAAyB,EAAA1mB,aAAawkB,cAAgBxlB,EAAahY,KACtF4/B,EAAyBF,OAAyBvhC,EAAY6Z,EAAaG,WAC3E3C,EAAakqB,EAAyBlW,EAAM8F,sBAAsBtX,EAAavT,QAASuT,GAAiBwR,EAAM2F,oBAAoBnX,EAAavT,SAEhJM,EAAaiT,EAAajT,WAAa0pB,EAAQzW,EAAaE,WAClEra,KAAK+yB,WAAW9tB,KACZjF,KAAK4X,eAAeqL,eAChBtL,EL7zCb,SAAyBmD,EAAc8W,GAC1C,GAAI9W,GAAQ,EAAAK,aAAaI,UACrB,OAAOqW,EAAsB,OAAoB,OAGrD,OAAQ9W,GACJ,KAAK,EAAAK,aAAaC,aAClB,KAAK,EAAAD,aAAaE,WACd,MAAO,OACX,KAAK,EAAAF,aAAaG,YAClB,KAAK,EAAAH,aAAaK,oBAClB,KAAK,EAAAL,aAAaM,yBAClB,KAAK,EAAAN,aAAaO,oBAClB,KAAK,EAAAP,aAAaQ,yBACd,MAAO,OACX,KAAK,EAAAR,aAAaS,OAClB,KAAK,EAAAT,aAAaU,QAClB,KAAK,EAAAV,aAAaW,QAClB,KAAK,EAAAX,aAAaY,QAClB,KAAK,EAAAZ,aAAaa,QAClB,KAAK,EAAAb,aAAac,QACd,MAAO,OAGf,MAAM,IAAI9R,MAAM,uBAAgB2Q,GACpC,CKqyCoBknB,CAAgBlnB,EAAM6Q,EAAMiG,oBAAoBzX,IAChD2nB,EACAjnB,EACA3T,EACAic,EACA4e,IAGRhR,EAAgB/wB,KAAK+yB,WAAWjwB,OAAS,EACzC6oB,EAAMgG,kBAAkBxX,EAAcyW,EAAO/V,EAAOkW,EACxD,CAEA8E,EAAUjI,WL/yCX,SAA0B9S,GAC7B,OAAQA,GACJ,KAAK,EAAAK,aAAaC,aACd,MAAO,WACX,KAAK,EAAAD,aAAaE,WACd,MAAO,SACX,KAAK,EAAAF,aAAaG,YACd,MAAO,UACX,KAAK,EAAAH,aAAaI,UACd,MAAO,UACX,KAAK,EAAAJ,aAAaS,OACd,MAAO,aACX,KAAK,EAAAT,aAAaU,QACd,MAAO,aACX,KAAK,EAAAV,aAAaW,QACd,MAAO,aACX,KAAK,EAAAX,aAAaY,QACd,MAAO,aACX,KAAK,EAAAZ,aAAaa,QACd,MAAO,aACX,KAAK,EAAAb,aAAac,QACd,MAAO,aACX,KAAK,EAAAd,aAAaK,oBACd,MAAO,WACX,KAAK,EAAAL,aAAaM,yBACd,MAAO,WACX,KAAK,EAAAN,aAAaO,oBACd,MAAO,YACX,KAAK,EAAAP,aAAaQ,yBACd,MAAO,YAGf,MAAM,IAAIxR,MAAM,wBAAiB2Q,GACrC,CK8wC6BmnB,CAAiBnnB,IAASiW,CAjC/C,CAkCJ,EAEc,YAAAmR,qBAAd,SAAmC/4B,EAA2By1B,EAAiDuD,EAAkBtM,G,8GAEvGv1B,KADlB8hC,EAAgBpiC,KAAK4zB,aAAa7yB,IAAIoI,IACtC,OACMwB,EAASi0B,GAAiBh+B,OAAOgiB,KAAKgc,GAAezmB,MAAK,SAAC2C,GAAS,OAAAA,EAAK4mB,WAAW,KAAhB,KAC1Ev4B,EAAkBA,aAA2B,EAAAk5B,cAAgBl5B,EAAgBm5B,aAAaH,EAAQC,eAAkBj5B,aACrF,EAAAqM,gBACX,GAAMxV,KAAKszB,kBAAkBxe,uBAAuB3L,EAAiBwB,IADrF,O,cACAy3B,EAAgB,S,oBACTj5B,aAA2B,EAAAu2B,iBAClB,GAAM1/B,KAAKszB,kBAAkB5oB,4BAA4BvB,EAAiBwB,IADnF,M,cACPy3B,EAAgB,S,oBACTj5B,aAA2B,EAAA+H,gBAClB,GAAMlR,KAAKszB,kBAAkBhd,2BAA2BnN,EAAiBwB,IADlF,M,cACPy3B,EAAgB,S,aAGhB,OADA,EAAAtjB,OAAO7T,KAAK,gCAAyB9B,EAAgB2B,KAAI,uBAAe3B,EAAgBo5B,iBACxF,I,OAGJviC,KAAK4zB,aAAahe,IAAIzM,EAAiBi5B,G,wBAG3CvM,EAAUhrB,SAAWu3B,E,YAGX,YAAAvB,iBAAd,SAA+B7X,EAAmB2C,G,kKAE9C,QAAkBrrB,KADd0xB,EAAYrG,EAAMmG,QAAQ9I,IAE1B,MAAO,CAAP,EAAOgJ,G,GAGL/I,EAAc,CAAEuZ,WAAY,IAClCxQ,EAAYhyB,KAAKkzB,QAAQpwB,OACzB9C,KAAKkzB,QAAQjuB,KAAKgkB,GAClB0C,EAAMoG,QAAQ/I,EAAagJ,GAErBrB,EAAU3H,EAAYyZ,YAAc,KAAOzZ,EAAY0Z,aACvD9D,EAAoC,QAApB,EAAA5V,EAAYrP,gBAAQ,eAAEklB,mBACtC1M,EAAexG,EAAM0G,wBAAwBrJ,GAE7C2Z,EAAc3Z,aAAuB,EAAA4Z,UACrCC,EAAoB7Z,aAAuB,EAAA8Z,oBAE3ClC,EAAY5X,EAAY4X,YAC1BhC,GAAiBgC,GAAaA,EAAU99B,OAAS,GAAjD,Y,IACsB,EAAA89B,E,wBAAA,YAAXuB,EAAO,KACRtM,EAA4B,CAAEjI,WAAY,CAAC,GAE3CzkB,EAAkBg5B,EAAQY,eAAiB/iC,KAAKi0B,cAAc+O,gBAEhEH,GACMh4B,EAAsB,CACxBC,KAAM3B,EAAgB2B,MAGpBm4B,EAAmBja,EAEnBka,EAAa,EAAAp9B,OAAOE,QACpB0C,EAAwC,QAAhC,EAAyB,QAAzB,EAAAu6B,EAAiBp4B,gBAAQ,eAAEnC,aAAK,QAAI,KAC5CiI,EAAmD,QAA3C,EAAoC,QAApC,EAAAsyB,EAAiBE,2BAAmB,eAAExyB,aAAK,QAAIuyB,GAClD12B,kBAAkB02B,EAAY,EAAAt9B,UAAY8C,EAAQ,KACzDmC,EAASD,qBAAuB,CAC5B9B,gBAAiB,OAAI6H,EAAMlE,WAAW,GAAF,CAAE/D,IAAK,KAInD1I,KAAK4M,WAAW3H,KAAK4F,GACrBgrB,EAAUhrB,SAAW7K,KAAK4M,WAAW9J,OAAS,E,OAjB9C,OALuB,M,cAuBhB6/B,GAED93B,EAAsB,CACxBC,KAAM3B,EAAgB2B,SAGpBm4B,EAAmBja,GAEHrY,MAAMnE,kBAAkB,EAAA1G,OAAOE,QAAS,EAAAJ,UAAYq9B,EAAiBv6B,MAAQ,KAC/FmC,EAASD,qBAAuB,CAC5B9B,gBAAiB,OAAIm6B,EAAiBtyB,MAAMlE,WAAW,GAAF,CAAEw2B,EAAiBv6B,QAAK,KAIrF1I,KAAK4M,WAAW3H,KAAK4F,GACrBgrB,EAAUhrB,SAAW7K,KAAK4M,WAAW9J,OAAS,E,OAfvC,M,OAmBP,SAAM9C,KAAKkiC,qBAAqB/4B,EAAiBy1B,EAAeuD,EAAStM,I,OAAzE,S,iBAyBJ,IArBM1Z,EAAWwmB,GAAeE,EAAoB,EAAAzmB,SAASO,iBAAyD,QAArC,EAAAqM,EAAYoa,iCAAyB,QAAIj6B,EAAgBgT,SAEtI8kB,EAAkB93B,EAAgBk6B,yBAAyBra,GAC3D2C,EAAMqE,qBAAuBhH,EAAY3gB,WAAW+Q,uBAEpD6nB,EAAkBA,IAAoB,EAAA7kB,SAASknB,yBAA2B,EAAAlnB,SAAS+kB,gCAAkC,EAAA/kB,SAASknB,0BAGlItjC,KAAK+gC,eACDpQ,EACAA,GAAU,IAAA4S,kBAAiB5S,EAASwR,EAAQqB,WAAYrB,EAAQsB,WAAYtB,EAAQuB,eAAiBvB,EAAQwB,cAAgB,MAC7HhT,EAAUwR,EAAQsB,WAAatB,EAAQuB,cACvC/S,EAAUwR,EAAQqB,WAAarB,EAAQwB,eACtCxB,EAAQuB,cACTvnB,EACA8kB,EACAtV,EACAkK,GAIC,EAAL,EAA2B,EAAAj1B,OAAOo7B,OAAO4C,GAAd,eAAhBzkB,EAAY,KACnBna,KAAKyhC,oBAAoBtnB,EAAchR,EAAiBg5B,EAAQuB,cAAevB,EAAQwB,cAAehY,EAAOkK,GAGjH,GAAI1D,EAEA,IADA0D,EAAU+N,QAAU,GACf,EAAL,EAA8B,EAAAzR,EAAA,eAAnB0R,EAAe,KACtBhO,EAAU+N,QAAQ3+B,KAAK4+B,EAAgBjW,YAI/C3E,EAAKuZ,WAAWv9B,KAAK4wB,GACrB71B,KAAK41B,mCAAmCC,G,wBA/EtB,I,aAmF1B,GAAI1D,EAQA,IAPAlJ,EAAK6a,QAAU,GAEV7a,EAAKsL,SACNtL,EAAKsL,OAAS,CAAC,GAEnBtL,EAAKsL,OAAOwP,YAAc,GAErB,EAAL,EAA8B,EAAA5R,EAAA,eAAnB0R,EAAe,KACtB5a,EAAK6a,QAAQ7+B,KAAK4+B,EAAgBpa,WAClCR,EAAKsL,OAAOwP,YAAY9+B,KAAK4+B,EAAgB/4B,MAIrD,MAAO,CAAP,EAAOknB,G,QA3xCa,EAAAoD,gBAAkB,IAAI5vB,MACtB,EAAAkxB,oBAAgG,CAAC,EACjG,EAAAM,iBAA+C,CAAC,EA2xC5E,C,CAh1CA,GCzJA,2BAsCA,QA9BwB,EAAAgN,UAApB,SAA8Bp6B,EAAc0tB,EAAkBhF,G,yGACrDA,GAAYA,EAAQkC,6BAArB,MACA,GAAM5qB,EAAMq6B,kB,OAAZ,S,iBAIS,UADPC,EAAW,IAAI/O,GAAavrB,EAAO0oB,IACbwF,kBAAkBR,EAAStf,QAAQ,YAAa,M,OAG5E,OAHMjR,EAAO,SACbm9B,EAASvN,UAEF,CAAP,EAAO5vB,G,QAUS,EAAAo9B,SAApB,SAA6Bv6B,EAAc0tB,EAAkBhF,G,yGACpDA,GAAYA,EAAQkC,6BAArB,MACA,GAAM5qB,EAAMq6B,kB,OAAZ,S,iBAIS,UADPC,EAAW,IAAI/O,GAAavrB,EAAO0oB,IACbsG,iBAAiBtB,EAAStf,QAAQ,YAAa,M,OAG3E,OAHMjR,EAAO,SACbm9B,EAASvN,UAEF,CAAP,EAAO5vB,G,QAEf,EAtCA,GC1DMq9B,GAAO,0BAEb,SAASC,GAAuBC,EAA2BC,GAGvD,IAFA,IAAMC,EAAiB,IAAIt6B,aAA6B,EAAhBq6B,GAE/B5hC,EAAI,EAAGA,EAAI4hC,EAAe5hC,IAC/B6hC,EAAmB,EAAJ7hC,EAAQ,GAAK2hC,EAAgB,EAAJ3hC,EAAQ,GAChD6hC,EAAmB,EAAJ7hC,EAAQ,GAAK2hC,EAAgB,EAAJ3hC,EAAQ,GAChD6hC,EAAmB,EAAJ7hC,EAAQ,GAAK2hC,EAAgB,EAAJ3hC,EAAQ,GAEpD,OAAO6hC,CACX,CAMA,kBAmBI,WAAYN,GAjBI,KAAAp5B,KAAOs5B,GAGhB,KAAAjO,SAAU,EAGV,KAAAI,UAAW,EAKV,KAAAkO,sBAAuB,EAIvB,KAAAC,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CA+HJ,OA7HW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAYa,YAAAnP,oBAAb,SACID,EACAnc,EACAoF,EACA0H,EACA2C,EACAzC,G,qGAEO,SAAM,IAAI7iB,SAAQ,SAACC,G,QACtB,GAAI4V,GAAQoF,aAAuB,EAAAuI,MAC3BvI,EAAYomB,kBAAoB,EAAKv6B,UAAW,CAChD,EAAKs6B,UAAW,EAuBhB,IArBA,IAAME,EAAgB,EAAA9rB,QAAQG,OACxB4rB,EAAa,EAAA9rB,WAAWC,WACxB8rB,EAAU,EAAAhsB,QAAQkU,MAGlB5O,EAASG,EAAYwmB,+BAErBC,EAAM,EAAAvrB,WAAWX,QAAQ,GACzBmsB,EAAM,EAAAxrB,WAAWV,WAAW,GAC5BmsB,EAAM,EAAAzrB,WAAWX,QAAQ,GAE3BqsB,GAAiC,EACjCC,GAA8B,EAC9BC,GAA2B,EAGzBC,EAAoB,IAAIp7B,aAA6C,EAAhCqU,EAAYgnB,mBACjDC,EAAiB,IAAIt7B,aAA6C,EAAhCqU,EAAYgnB,mBAC9CE,EAAc,IAAIv7B,aAA6C,EAAhCqU,EAAYgnB,mBAE7C5iC,EAAI,EACQ,MAAAyb,EAAA,eAAJ,KACNC,UAAU6mB,EAAKD,EAAKD,GAElBpc,IACA3L,EAA6B+nB,GAC7B9nB,EAA6B+nB,IAIjCK,EAAkB1vB,IAAIovB,EAAIv4B,UAAe,EAAJ9J,GACrC6iC,EAAe5vB,IAAIqvB,EAAI5Y,YAAY5f,UAAe,EAAJ9J,GAC9C8iC,EAAY7vB,IAAIsvB,EAAIz4B,UAAe,EAAJ9J,GAG/BwiC,EAAiCA,IAAmCH,EAAIx4B,kBAAkBo4B,GAC1FQ,EAA8BA,IAAgCH,EAAIz4B,kBAAkBq4B,GACpFQ,EAA2BA,IAA6BH,EAAI14B,kBAAkBs4B,GAE9EniC,IAGJ,IAAMsV,EAAmC,CACrC2V,WAAY,CAAC,GAIbuX,IACAltB,EAAU2V,WAAwB,YAAI,EAAK8X,eAAeJ,EAAmB,OAAmB/mB,EAAYgnB,kBAAmBpf,IAG/Hif,IAEAntB,EAAU2V,WAAqB,SAAI,EAAK8X,eAAeF,EAAgB,OAAmBjnB,EAAYgnB,kBAAmBpf,IAGzHkf,IACAptB,EAAU2V,WAAkB,MAAI,EAAK8X,eAAeD,EAAa,OAAmBlnB,EAAYgnB,kBAAmBpf,IAEvH,IAAIme,EAA+D,QAAjD,EAA2C,QAA3C,EAAA/lB,EAAYonB,uCAA+B,eAAE5+B,YAAI,eAAE6+B,cACrE,GAAItB,EAAa,CACb,IAAMC,EAAgBhmB,EAAYgnB,kBAE9BhnB,EAAYugB,gBAAkBwF,EAAYxhC,SAA2B,EAAhByhC,GAChD,EAAKE,uBACN,EAAA3lB,OAAO7T,KAAK,8GACZ,EAAKw5B,sBAAuB,GAEhCH,EAAcD,GAAuBC,EAAaC,IAC3CD,EAAYxhC,SAA2B,EAAhByhC,IAC9BD,EAAcD,GAAuBC,EAAaC,IAElDD,EAAYxhC,SAA2B,EAAhByhC,IACvBtsB,EAAU2V,WAAqB,SAAI,EAAK8X,eAAepB,EAXtC,OAWiEC,EAAepe,GAEzG,CAGAhN,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EACtCoD,EAAKpD,WAAWquB,IAAQnsB,CAC5B,CAEJ1U,EAAQ4V,EACZ,K,OAxFA,MAAO,CAAP,EAAO,U,QA2FH,YAAAusB,eAAR,SAAuB/+B,EAAsBxE,EAAoB0Y,EAAesL,GAE5E,IAAM3C,EAAK2C,EAActO,iBAAiBlR,GAGpC0c,EAAW8C,EAAclD,eAAeO,EAAIrhB,EAAM,KAA6B0Y,GAErF,OADA7a,KAAKoK,UAAU2oB,WAAW9tB,KAAKoe,GACxBrjB,KAAKoK,UAAU2oB,WAAWjwB,OAAS,CAC9C,EACJ,EApJA,GAuJAqyB,GAAayB,kBAAkBwN,IAAM,SAACF,GAAa,WAAI2B,GAAwB3B,EAA5B,IC1KnD,IAAM,GAAO,6BAmBb,cA2BI,WAAYA,GAzBI,KAAAp5B,KAAO,GAMhB,KAAAyrB,UAAW,EAGV,KAAAuP,iBAAqC,IAAIvd,IAGzC,KAAAwd,eAAiC,IAAIxd,IAGrC,KAAAyd,gBAAmC,GAEnC,KAAAtB,UAAW,EASf1kC,KAAKm2B,QAAqD,UAA3C+N,EAAS5R,QAAQsC,uBAAqC,EAAAqR,aAAaC,gBACtF,CAqHJ,OA5HI,sBAAW,sBAAO,C,IAAlB,WACI,OAAOlmC,KAAK0kC,QAChB,E,gCAQO,YAAA/N,QAAP,WAAkB,EAGX,YAAAb,wBAAP,SAA+BD,EAA2B1P,EAA8BC,GAAxF,WACI,GAAKpmB,KAAKm2B,QAIV,GAAuB,IAAnBN,EAAU0E,MAA2D,IAAnB1E,EAAU0E,KAAhE,CAMA,IAAM4L,EAAsC,GACtCC,EAAkC,GAGpCzV,EAA+C,KACnD,QAA0BrwB,IAAtBu1B,EAAUlF,QAAuB,CACjC,IAAMtN,EAAW+C,EAAUyP,EAAUlF,SAC/BhZ,EAAawO,EAAc1C,cAAcJ,GAE/CsN,EAAUxK,EAAczC,QAAQ/L,GAAYlS,QAE5C0gC,EAAqBlhC,KAAK0S,GAC1ByuB,EAAmBnhC,KAAKoe,EAC5B,CAIA,IADA,IA/EuBgjB,EA+EjBzY,EAAoC,GACN,MAAAhtB,OAAOse,QAAQ2W,EAAUjI,YAAzB,eAAsC,CAA/D,WAAC,EAAI,KAINxW,GAHAiM,EAAW+C,EADU,MAErBzO,EAAawO,EAAc1C,cAAcJ,GAElCrI,EAAwBqI,EAASlhB,OACxC4E,GAAO,IAAAu/B,mBACTngB,EAAczC,QAAQ/L,GACtBP,EACAiM,EAASH,cACTG,EAASnc,YAAc,EACvByQ,EAAW0C,aAAc,IAAAksB,mBAAkBljB,EAASH,eAAiB9L,EACrEiM,EAASxI,OACT,GAGJ+S,EAAW3oB,KAAK,CAAE6V,KAAM,EAAM0rB,WA/FXH,EA+F4C,EA9FtD,aAAbA,EACO,WACa,WAAbA,EACA,SACAA,EAAS3E,WAAW,SACpB,QACA2E,EAAS3E,WAAW,YACpB,YAEJ,WAqFuEtqB,KAAM4D,EAAwBqI,EAASlhB,MAAO4E,KAAMA,IAE1Ho/B,EAAqBlhC,KAAK0S,GAC1ByuB,EAAmBnhC,KAAKoe,EAC5B,CAGA,IAAMiP,EAAgC,CAClCmU,OAAQ5Q,EAAU+N,QAAU,2BAA6B,6BAGvD8C,EAAU,EAAAT,aAAaU,QAAQC,aAAahZ,EAAY+C,EAAS2B,GAElEvuB,MAAK,SAAC8iC,GACH,GAAKA,EAAL,CAKA,IAAMC,EAAsC,CACxCnvB,YAAa,EACbiW,WAAYiZ,EAAYE,cAEtBpvB,EAAawO,EAActO,iBAAiBgvB,EAAY9/B,MAC9Dof,EAAcrO,cAAcgvB,EAAWnvB,GAEvC,IAAyB,UAAAwuB,EAAA,eAAsB,CAA1C,IAAM,EAAU,KACjB,EAAKL,iBAAiB75B,IAAI,EAC9B,CACA,IAAuB,UAAAm6B,EAAA,eAAoB,CAAtC,IAAM/iB,EAAQ,KACf,EAAK0iB,eAAe95B,IAAIoX,EAC5B,CAEAwS,EAAU9f,aAAV8f,EAAU9f,WAAe,CAAC,GAC1B8f,EAAU9f,WAAW,IAAQ+wB,CAjB7B,MAFI,EAAAhoB,OAAO3U,MAAM,uCAoBrB,IAEC68B,OAAM,SAACC,GACJ,EAAAnoB,OAAO3U,MAAM,wCAA0C88B,EAC3D,IAEJjnC,KAAKgmC,gBAAgB/gC,KAAKyhC,GAE1B1mC,KAAK0kC,UAAW,CA9EhB,MAFI,EAAA5lB,OAAO7T,KAAK,uCAAyC4qB,EAAU0E,KAAO,IAiF9E,EAGa,YAAAvE,uBAAb,SAAoC7P,G,qGAChC,OAAKnmB,KAAKm2B,QAIV,GAAM7yB,QAAQ4I,IAAIlM,KAAKgmC,kBAHnB,I,cAGJ,SAGAhmC,KAAK8lC,iBAAiBrjB,SAAQ,SAAC9K,GACRwO,EAAcpD,4BAA4BpL,GACd6H,OAAM,SAACR,GAClD,OAAO,EAAK+mB,eAAepiB,IAAI3E,EACnC,KAEImH,EAAc5C,iBAAiB5L,EAEvC,IAEA3X,KAAK8lC,iBAAiBoB,QACtBlnC,KAAK+lC,eAAemB,Q,YAE5B,EAlJA,GAoJA/R,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIiD,GAA2BjD,EAA/B,ICtKnD,IAAM,GAAO,sBACPkD,GAAmD,CACrDt8B,KAAM,GACN6F,MAAO,CAAC,EAAG,EAAG,GACd02B,UAAW,EACXC,MAAOh2B,OAAOsJ,WAEZ2sB,GAA8D,CAChEC,eAAgB,EAChBC,eAAgB1/B,KAAK2/B,GAAK,GAExBC,GAAiB,EAAA7uB,QAAQ8uB,WAM/B,cAkBI,WAAY1D,GAhBI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAWdv2B,KAAKoK,UAAY85B,CACrB,CA6HJ,OA1HW,YAAAvN,QAAP,WACK32B,KAAK6nC,QAAkB,IAC5B,EAGA,sBAAW,sBAAO,C,IAAlB,WACI,QAAS7nC,KAAK6nC,OAClB,E,gCAGO,YAAApR,YAAP,WACIz2B,KAAKoK,UAAUqoB,MAAM1c,WAAY,IAAQ/V,KAAK6nC,OAClD,EAUa,YAAAtS,oBAAb,SAAiCD,EAAiBnc,EAAaoF,EAAmB0H,EAA4B2C,G,qGACnG,SAAM,IAAItlB,SAAQ,SAACC,GACtB,GAAMgb,aAAuB,EAAAuF,MAA7B,CAKA,IAAMgkB,EACFvpB,EAAYwpB,aAAe,EAAAjkB,MAAMkkB,uBAC3B,QACAzpB,EAAYwpB,aAAe,EAAAjkB,MAAMmkB,6BAC/B,cACA1pB,EAAYwpB,aAAe,EAAAjkB,MAAMokB,sBAC/B,OACA,KACd,KAAKJ,GAAevpB,aAAuB,EAAA4pB,aAGvC,OAFA,EAAArpB,OAAO7T,KAAK,UAAGqqB,EAAO,mBAAW/W,EAAYzT,KAAI,gCAAwB,UACzEvH,EAAQ4V,GASZ,GALIoF,EAAY6pB,cAAgB,EAAAtkB,MAAMukB,cAClC,EAAAvpB,OAAO7T,KAAK,UAAGqqB,EAAO,+BAAuB/W,EAAYzT,KAAI,+BAAuB,GAAI,qBAIvFyT,EAAYwO,SAASub,eAAe,EAAG,EAAG,GAAI,CAC/C,IAAMtqB,EAAc,EAAAvE,WAAWX,QAAQ,GAAG8gB,SAASrb,EAAYwO,UAC3DnE,GACA3L,EAA6Be,GAEjC7E,EAAK6E,YAAcA,EAAYvR,SACnC,CAIA,GAAkB,UAAdq7B,EAAiD,CACjD,IAAMS,EAAYhqB,EAAYgqB,UAAUC,eAAe,EAAA/uB,WAAWX,QAAQ,IACtE8P,GACA3L,EAA6BsrB,GAGjC,IAAME,EAA0B,EAAA1vB,WAAW2vB,qBAAqBf,GAAgBY,EAAW,EAAA9uB,WAAWV,WAAW,IAC5G,EAAAA,WAAW4vB,WAAWF,KACvBtvB,EAAKuE,SAAW+qB,EAAwBh8B,UAEhD,CAEA,IAAMm8B,EAAkC,CACpCzmC,KAAM2lC,EACNh9B,KAAMyT,EAAYzT,KAClB6F,MAAO4N,EAAY/W,QAAQiF,UAC3B46B,UAAW9oB,EAAY8oB,UACvBC,MAAO/oB,EAAY+oB,OAKvB,GAHAvoB,EAAkB6pB,EAAOxB,IAGP,SAAdU,EAAgD,CAChD,IAAMe,EAAmBtqB,EACzBqqB,EAAME,KAAO,CACTtB,eAAgBqB,EAAiBE,WAAa,EAC9CtB,eAAgBoB,EAAiBG,MAAQ,GAE7CjqB,EAAkB6pB,EAAME,KAAMvB,GAClC,CAEA,EAAKM,UAAL,EAAKA,QAAY,CACboB,OAAQ,KAEZ,EAAKpB,QAAQoB,OAAOhkC,KAAK2jC,GAEzB,IAAMM,EAAoD,CACtDN,MAAO,EAAKf,QAAQoB,OAAOnmC,OAAS,GAKlC0b,EAAoBD,EAAYG,OAEtC,GAAIF,GAAqBF,EAAmBC,EAAaC,GAAoB,CACzE,IAAMsiB,EAAkB7a,EAAQllB,IAAIyd,GACpC,GAAIsiB,EAAiB,CAEjB,IAAMjjB,EAAa,EAAKzT,UAAU+oB,OAAO2N,GAOzC,OANAljB,EAAwBzE,EAAM0E,GAC9BA,EAAW9H,aAAX8H,EAAW9H,WAAe,CAAC,GAC3B8H,EAAW9H,WAAW,IAAQmzB,OAG9B3lC,EAAQ,KAEZ,CACJ,CAEA4V,EAAKpD,aAALoD,EAAKpD,WAAe,CAAC,GACrBoD,EAAKpD,WAAW,IAAQmzB,EACxB3lC,EAAQ4V,EA5FR,MAFI5V,EAAQ4V,EA+FhB,K,OAjGA,MAAO,CAAP,EAAO,U,QAmGf,EAjJA,GAmJAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIiF,GAAoBjF,EAAxB,ICrKnD,IAAM,GAAO,kBACP,GAA+C,CACjDp5B,KAAM,GACN6F,MAAO,CAAC,EAAG,EAAG,GACd02B,UAAW,EACXjwB,KAAM,GAEJgyB,GAA0D,CAC5DC,OAAQ,GAEN,GAAiB,EAAAvwB,QAAQ8uB,WAM/B,cAkBI,WAAY1D,GAhBI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAWdv2B,KAAKoK,UAAY85B,CACrB,CAmHJ,OAhHW,YAAAvN,QAAP,WACK32B,KAAK6nC,QAAkB,IAC5B,EAGA,sBAAW,sBAAO,C,IAAlB,WACI,QAAS7nC,KAAK6nC,OAClB,E,gCAGO,YAAApR,YAAP,WACIz2B,KAAKoK,UAAUqoB,MAAM1c,WAAY,IAAQ/V,KAAK6nC,OAClD,EAUa,YAAAtS,oBAAb,SAAiCD,EAAiBnc,EAAaoF,EAAmB0H,EAA4B2C,G,qGACnG,SAAM,IAAItlB,SAAQ,SAACC,GACtB,GAAMgb,aAAuB,EAAAuF,MAA7B,CAKA,IAAMgkB,EAAYvpB,EAAYwpB,aAAe,EAAAjkB,MAAMwlB,2BAA6B,OAA+B,KAC/G,IAAKxB,EAGD,OAFA,EAAAhpB,OAAO7T,KAAK,UAAGqqB,EAAO,mBAAW/W,EAAYzT,KAAI,gCAAwB,UACzEvH,EAAQ4V,GAIZ,IAAMowB,EAAYhrB,EAOlB,GALIgrB,EAAUnB,cAAgB,EAAAtkB,MAAMukB,cAChC,EAAAvpB,OAAO7T,KAAK,UAAGqqB,EAAO,+BAAuB/W,EAAYzT,KAAI,+BAAuB,GAAI,qBAIvFy+B,EAAUxc,SAASub,eAAe,EAAG,EAAG,GAAI,CAC7C,IAAMtqB,EAAc,EAAAvE,WAAWX,QAAQ,GAAG8gB,SAAS2P,EAAUxc,UACzDnE,GACA3L,EAA6Be,GAEjC7E,EAAK6E,YAAcA,EAAYvR,SACnC,CAIA,IAAM87B,EAAY,EAAAzvB,QAAQ0wB,UACtB5gB,GACA3L,EAA6BsrB,GAGjC,IAAME,EAA0B,EAAA1vB,WAAW2vB,qBAAqB,GAAgBH,EAAW,EAAA9uB,WAAWV,WAAW,IAC5G,EAAAA,WAAW4vB,WAAWF,KACvBtvB,EAAKuE,SAAW+qB,EAAwBh8B,WAG5C,IAAMm8B,EAA8B,CAChCzmC,KAAM2lC,EACNh9B,KAAMy+B,EAAUz+B,KAChB6F,MAAO44B,EAAU/hC,QAAQiF,UACzB46B,UAAWkC,EAAUlC,UACrBjwB,KAAMmyB,EAAU5/B,OAChB8/B,KAAM,CACFJ,OAAQE,EAAU7/B,MAAQ6/B,EAAU5/B,SAG5CoV,EAAkB6pB,EAAO,IAErBA,EAAMa,MACN1qB,EAAkB6pB,EAAMa,KAAML,IAGlC,EAAKvB,UAAL,EAAKA,QAAY,CACboB,OAAQ,KAEZ,EAAKpB,QAAQoB,OAAOhkC,KAAK2jC,GAEzB,IAAMM,EAAgD,CAClDN,MAAO,EAAKf,QAAQoB,OAAOnmC,OAAS,GAKlC0b,EAAoBD,EAAYG,OAEtC,GAAIF,GAAqBF,EAAmBirB,EAAW/qB,GAAoB,CACvE,IAAMsiB,EAAkB7a,EAAQllB,IAAIyd,GACpC,GAAIsiB,EAAiB,CAEjB,IAAMjjB,EAAa,EAAKzT,UAAU+oB,OAAO2N,GAOzC,OANAljB,EAAwBzE,EAAM0E,GAC9BA,EAAW9H,aAAX8H,EAAW9H,WAAe,CAAC,GAC3B8H,EAAW9H,WAAW,IAAQmzB,OAG9B3lC,EAAQ,KAEZ,CACJ,CAEA4V,EAAKpD,aAALoD,EAAKpD,WAAe,CAAC,GACrBoD,EAAKpD,WAAW,IAAQmzB,EACxB3lC,EAAQ4V,EAlFR,MAFI5V,EAAQ4V,EAqFhB,K,OAvFA,MAAO,CAAP,EAAO,U,QAyFf,EAvIA,GAyIAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIwF,GAAgBxF,EAApB,IC1JnD,IAAM,GAAO,2BA6Bb,SAAeyF,GAA8BxgC,G,oGAOzC,OANMS,EAAQT,EAAgBd,WAExBuhC,EAA8CzgC,EAAgB0gC,mCAC9DC,EAAiB3gC,EAAgB4gC,uBAGjCH,GAAwBE,EAIvB,IAAM,IAAAt4B,oBACT,qBACA,IAAAC,yBACIq4B,GAAiB,IAAAp4B,oBAAmBo4B,EAAgB,IAAK,IAAAn4B,qBAAoB,GAC7Em4B,GAAiB,IAAAp4B,oBAAmBo4B,EAAgB,IAAK,IAAAn4B,qBAAoB,GAC7Ei4B,GAAuB,IAAAl4B,oBAAmBk4B,EAAsB,IAAK,IAAAj4B,qBAAoB,IAE7F/H,IAVO,CAAP,EAAO,M,OAGX,MAAO,CAAP,EAAO,U,OAeX,kBAgBI,WAAYs6B,GAdI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAEX,KAAAsF,kBAAuD,CAAC,EAG5DhqC,KAAKoK,UAAY85B,CACrB,CAuIJ,OArIW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,2GAChF8gC,EAAoC,GACtC9gC,aAA2B,EAAAqM,gBACvBrM,EAAgB+gC,WAAWC,YAAchhC,EAAgB+gC,WAAWE,QAChEjhC,EAAgB+gC,WAAWn9B,SAC3Bk9B,EAAmBhlC,KAAKkE,EAAgB+gC,WAAWn9B,SAEhD,CAAP,EAAOk9B,I,MALX,M,cAOO9gC,aAA2B,EAAA+H,iBAC9B/H,EAAgBkhC,4BAA8B,GACxCC,EAhFtB,SAA2BnhC,GACvB,IAAMygC,EAA8CzgC,EAAgB0gC,mCAC9DC,EAAiB3gC,EAAgB4gC,uBACjCQ,EAAaX,GAAwBA,EAAqBpjC,qBAAuBojC,EAAsBpjC,qBAAsBiE,SAAW,aACxI+/B,EAAYV,GAAkBA,EAAetjC,qBAAuBsjC,EAAgBtjC,qBAAsBiE,SAAW,YAC3H,MAAO,UAAG8/B,EAAU,YAAIC,EAC5B,CA0E8BC,CAAkBthC,GAC5BnJ,KAAKgqC,kBAAkBM,IACvBL,EAAmBhlC,KAAKjF,KAAKgqC,kBAAkBM,I,OAD/C,OAHD,M,OAMsB,SAAMX,GAA8BxgC,I,QAAnDuhC,EAAe,YAEjBT,EAAmBhlC,KAAKylC,GACxB1qC,KAAKgqC,kBAAkBM,GAASI,G,iBAGxC,MAAO,CAAP,EAAOT,G,OAIf,MAAO,CAAC,EAAD,I,QAIJ,YAAAzU,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,G,MApHaonC,EAAuBT,EACtDU,EACAC,EACAC,EAkHE,GAAI3hC,aAA2B,EAAAqM,gBAAiB,CAC5C,IAAKrM,EAAgB+gC,WAAWC,WAAahhC,EAAgB+gC,WAAWE,OAEpE,YADA7mC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAMg1B,EAAwB,EAAK3gC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB+gC,WAAWn9B,SAQhE,QANnCi+B,EAA0C,CAC5CC,mBAAoB9hC,EAAgB+gC,WAAW7C,UAC/C6D,mBAAoB/hC,EAAgB+gC,WAAWlB,MAC/CmC,kBAAmBJ,QAAAA,OAAyBzqC,IAG7B6qC,mBACf,EAAK/gC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQi1B,CAC5B,MAAO,GAAI7hC,aAA2B,EAAA+H,iBAC9B/H,EAAgBkhC,4BAA8B,EAAG,CACjD,EAAK3F,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAMtC,IAAIhF,EAA0C5H,EAAgByN,yBAC1DzN,EAAgBiiC,wCAChBr6B,EAAmB5H,EAAgBwN,sBAEvC,IAAM00B,EAAqB,EAAKrB,kBAAkB7gC,EAAgBmiC,IAIlE,IAAKv6B,IAAqBs6B,EAAoB,CAE1C,IAAIE,EAAmBpiC,EAAgBuN,kBACnC80B,EAAwBriC,EAAgBkhC,4BAC5C,IAAKlhC,EAAgBsiC,wBAAyB,CAC1C,IAAMC,GAnKOf,EAmKqCxhC,EAAgBuN,kBAhKpFo0B,GAAc,GAHwCZ,EAmKiD/gC,EAAgBkhC,+BAjKvHQ,GADAD,EAAYD,EAAgBA,GACH5iC,KAAKC,KAAK,GAAO,GAAO,EAAIkiC,IAAe,EAAIA,MAKvE,CAAEqB,iBAHgBxjC,KAAKC,KAAK8iC,GAGRU,sBAFGzjC,KAAKub,IAAIvb,KAAKC,MAAM6iC,EAAaD,GAAa7iC,KAAKqH,IAAI,EAAMw7B,EAAW,OAAU,KA+JxFW,EAAmBG,EAAUH,iBAC7BC,EAAwBE,EAAUF,qBACtC,CACIryB,EAAKvO,uBACLuO,EAAKvO,qBAAqB5B,gBAAkBuiC,GAEhD,IAAM,EAA0C,CAC5CN,mBAAoBO,EACpBN,mBAAoB/hC,EAAgBwiC,qBAAiC,GAAV5jC,KAAK2/B,GAChEyD,uBAAmB7qC,GAGvB,OADA6Y,EAAKpD,WAAW,IAAQ,EACjBxS,EAAQ4V,EACnB,CAEA,IAAMyyB,EAAyBP,EAAqB,EAAKjhC,UAAUkpB,kBAAkB9oB,eAAe6gC,GAAsB,KAEpHL,EAA0C,CAC5CC,mBAAoB9hC,EAAgBkhC,4BACpCa,mBAAoB/hC,EAAgBwiC,qBACpCR,kBAAmBS,QAAkDtrC,EACrEyV,WAAY,CAAC,GAGZ5M,EAAgBsiC,0BAEjBtyB,EAAKpD,WAAmC,sBAAI,CAAC,GAC7C,IAAK3L,UAAUqoB,OAAM6D,iBAAc,EAAdA,eAAmB,KACsC,IAA1E,EAAKlsB,UAAUqoB,MAAM6D,eAAelE,QAAQ,0BAC5C,EAAKhoB,UAAUqoB,MAAM6D,eAAerxB,KAAK,0BAIjD,EAAKmF,UAAU4B,qBAAqBC,IAAI9C,GAExCgQ,EAAKpD,WAAW,IAAQi1B,CAC5B,CAEJznC,EAAQ4V,EACZ,GACJ,EACJ,EAzJA,GA2JAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI2H,GAAyB3H,EAA7B,IC/MnD,IAAM,GAAO,0BAwBb,SAAe4H,GAAqC3iC,G,oGAKhD,OAJMS,EAAQT,EAAgBd,WACxB0jC,EAAqC5iC,EAAgB6iC,kBACrDC,EAA8C9iC,EAAgB8iC,qBAE9DF,GAAeE,EAIL,IAAM,IAAAz6B,oBAClB,eACA,IAAAC,yBACIs6B,GAAc,IAAAr6B,oBAAmBq6B,EAAa,IAAK,IAAAp6B,qBAAoB,GAEvEs6B,GAAuB,IAAAv6B,oBAAmBu6B,EAAsB9iC,EAAgB+iC,kCAAoC,EAAI,IAAK,IAAAv6B,qBAAoB,IAErJ/H,IAVO,CAAP,EAAO,M,OAaX,MAAO,CAAP,EAVgB,SAUDpD,sB,OASnB,SAAS2lC,GAAkB5lC,EAAkC6lC,GACzD,IAAMC,EAAc,IAAI,EAAA5+B,QAAQ2+B,EAActhC,KAAMshC,EAAc/jC,YAYlE,OAXAgkC,EAAYC,SAAW/lC,EACvB8lC,EAAYx3B,iBAAmBu3B,EAAcv3B,iBACzCu3B,aAAyB,EAAA3+B,UACzB4+B,EAAYE,QAAUH,EAAcG,QACpCF,EAAYG,QAAUJ,EAAcI,QACpCH,EAAYI,OAASL,EAAcK,OACnCJ,EAAYK,OAASN,EAAcM,OACnCL,EAAYM,KAAOP,EAAcO,MAErCN,EAAY/5B,MAAQ85B,EAAc95B,MAClC+5B,EAAY75B,MAAQ45B,EAAc55B,MAC3B65B,CACX,CAMA,kBAcI,WAAYnI,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EASX,KAAAkI,mBAAkD,CAAC,EAKnD,KAAAC,2BAA8D,CAAC,EAXnE7sC,KAAKoK,UAAY85B,CACrB,CA2MJ,OA/LW,YAAAvN,QAAP,WACI,IAAkB,UAAA/1B,OAAOgiB,KAAK5iB,KAAK4sC,oBAAjB,eAAsC,CAAnD,IAAMlsC,EAAG,KACMV,KAAK4sC,mBAAmBlsC,GAChCi2B,SACZ,CACA32B,KAAK4sC,mBAAqB,CAAC,EAC3B,IAAkB,UAAAhsC,OAAOgiB,KAAK5iB,KAAK6sC,4BAAjB,eAAPnsC,EAAG,KACcV,KAAK6sC,2BAA2BnsC,GACxCi2B,UAEpB32B,KAAK6sC,2BAA6B,CAAC,CACvC,EAGA,sBAAW,sBAAO,C,IAAlB,WACI,OAAO7sC,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,6GAChF8gC,EAAoC,GACtC9gC,aAA2B,EAAAqM,gBACvBrM,EAAgB2jC,UAAU3C,WACtBhhC,EAAgB2jC,UAAU//B,SAC1Bk9B,EAAmBhlC,KAAKkE,EAAgB2jC,UAAU//B,UAEjD5D,EAAgB2jC,UAAUC,6BAA+B5jC,EAAgB2jC,UAAUE,kBACpF/C,EAAmBhlC,KAAKkE,EAAgB2jC,UAAUE,kBAElD7jC,EAAgB2jC,UAAUthC,aAC1By+B,EAAmBhlC,KAAKkE,EAAgB2jC,UAAUthC,aAE/C,CAAP,EAAOy+B,I,MAXX,M,cAaO9gC,aAA2B,EAAA+H,iBAC9B/H,EAAgB8jC,WAAa,GAGzBC,GAAiB,EACjB/jC,EAAgB6iC,kBAGX7iC,EAAgB8iC,qBAGjB9iC,EAAgB+iC,mCAChB/iC,EAAgB6iC,kBAAkBxlC,uBAAyB2C,EAAgB8iC,qBAAqBzlC,sBAEhGyjC,EAAmBhlC,KAAKkE,EAAgB6iC,mBACxC/B,EAAmBhlC,KAAKkE,EAAgB8iC,uBAExCiB,GAAiB,EARjBjD,EAAmBhlC,KAAKkE,EAAgB6iC,mBAUrC7iC,EAAgB8iC,uBACnB9iC,EAAgB+iC,kCAChBjC,EAAmBhlC,KAAKkE,EAAgB8iC,sBAExCiB,GAAiB,GAGrBA,GAKM5C,EA3J1B,SAA0BnhC,GACtB,IAAM4iC,EAAqC5iC,EAAgB6iC,kBACrDmB,EAASpB,GAAeA,EAAYvlC,qBAAuBulC,EAAavlC,qBAAsBiE,SAAW,SACzGwhC,EAA8C9iC,EAAgB8iC,qBAC9Dj6B,EAAci6B,GAAwBA,EAAqBzlC,qBAAuBylC,EAAsBzlC,qBAAsBiE,SAAW,cAC/I,MAAO,UAAG0iC,EAAM,YAAIn7B,EACxB,CAqJkCo7B,CAAiBjkC,GAC1BnJ,KAAK6sC,2BAA2BvC,GAAjC,MACwB,GAAMwB,GAAqC3iC,KAPvE,OA1BD,M,QAiCW5C,EAAkB,YAEpBvG,KAAK6sC,2BAA2BvC,GAAS/jC,G,iBAG7CvG,KAAK6sC,2BAA2BvC,KAC5BnhC,EAAgB6iC,oBAChBhsC,KAAK4sC,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,UAAY0hC,GAClEnsC,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB6iC,mBAEpB/B,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,YAElFtB,EAAgB8iC,uBAChBjsC,KAAK4sC,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,UAAY0hC,GACrEnsC,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB8iC,sBAEpBhC,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,a,iBASjG,OAJItB,EAAgBkkC,2BAChBpD,EAAmBhlC,KAAKkE,EAAgBkkC,2BAGrC,CAAP,EAAOpD,G,OAIf,MAAO,CAAC,EAAD,I,QAIJ,YAAAzU,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,GAAI4F,aAA2B,EAAAqM,gBAAiB,CAC5C,IAAKrM,EAAgB2jC,UAAU3C,UAE3B,YADA5mC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IACIu3B,EADEC,EAAuB,EAAKnjC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAU//B,SAGnGugC,EADAnkC,EAAgB2jC,UAAUC,4BACM,EAAK3iC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAU//B,SAE1E,EAAK3C,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAUE,kBAG1G7jC,EAAgB2jC,UAAUU,eAC1B,EAAAnrC,MAAM4I,KAAK,2EAAoE9B,EAAgB2B,OAG/F3B,EAAgB2jC,UAAUW,0BAC1B,EAAAprC,MAAM4I,KAAK,mFAA4E9B,EAAgB2B,OAG3G,IAAM4iC,EAA6B,EAAKtjC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAUthC,aAUtE,QARjCmiC,EAAwC,CAC1CC,gBAAiBzkC,EAAgB2jC,UAAUzF,UAC3CwG,iBAAkBN,QAAAA,OAAwBjtC,EAC1CwtC,yBAA0B3kC,EAAgB2jC,UAAUlkC,UACpDmlC,0BAA2BT,QAAAA,OAAiChtC,EAC5D0tC,uBAAwBN,QAAAA,OAA8BptC,IAGxCutC,kBAAyE,OAA5CF,EAAcI,2BAAkF,OAA5CJ,EAAcI,2BAC7G,EAAK3jC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQ43B,CAC5B,MAAO,GAAIxkC,aAA2B,EAAA+H,gBAAiB,CACnD,GAAkC,GAA9B/H,EAAgB8jC,WAEhB,YADA1pC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAIi2B,EAA2C,KAC3CiC,OAAe,EACf9kC,EAAgB6iC,oBAChBA,EAAoB,EAAKY,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,UAC9EwjC,EAAkB,EAAK7jC,UAAUkpB,kBAAkB9oB,eAAewhC,IAGtE,IAaM2B,EAbF1B,EAA8C,KAC9CiC,OAAwB,EACxB/kC,EAAgB8iC,uBAChBA,EAAuB,EAAKW,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,UACpFyjC,EAA2B,EAAK9jC,UAAUkpB,kBAAkB9oB,eAAeyhC,IAG3E9iC,EAAgBglC,kBAChB,EAAA9rC,MAAM4I,KAAK,2EAAoE9B,EAAgB2B,OAG7F4iC,EAA6B,EAAKtjC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBkkC,2BAU5D,QARjCM,EAAwC,CAC1CC,gBAAiBzkC,EAAgB8jC,WACjCY,iBAAkBI,QAAAA,OAAmB3tC,EACrCwtC,yBAA0B3kC,EAAgBilC,cAC1CL,0BAA2BG,QAAAA,OAA4B5tC,EACvD0tC,uBAAwBN,QAAAA,OAA8BptC,IAGxCutC,kBAAyE,OAA5CF,EAAcI,2BAAkF,OAA5CJ,EAAcI,2BAC7G,EAAK3jC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQ43B,CAC5B,CACApqC,EAAQ4V,EACZ,GACJ,EACJ,EA3NA,GA6NAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAImK,GAAwBnK,EAA5B,ICvSnD,IAAM,GAAO,qBAoBb,SAAS,GAAkB/6B,GACvB,IAAMygC,EAA8CzgC,EAAgBmlC,+BAC9DxE,EAAiB3gC,EAAgBolC,2BACjChE,EAAaX,GAAwBA,EAAqBpjC,qBAAuBojC,EAAsBpjC,qBAAsBiE,SAAW,aACxI+/B,EAAYV,GAAkBA,EAAetjC,qBAAuBsjC,EAAgBtjC,qBAAsBiE,SAAW,YAC3H,MAAO,UAAG8/B,EAAU,YAAIC,EAC5B,CAuBA,SAAe,GAA8BrhC,G,oGAOzC,OANMS,EAAQT,EAAgBd,WAExBuhC,EAA8CzgC,EAAgBmlC,+BAC9DxE,EAAiB3gC,EAAgBolC,2BAGjC3E,GAAwBE,EAIvB,IAAM,IAAAt4B,oBACT,qBACA,IAAAC,yBACIq4B,GAAiB,IAAAp4B,oBAAmBo4B,EAAgB,IAAK,IAAAn4B,qBAAoB,GAC7Em4B,GAAiB,IAAAp4B,oBAAmBo4B,EAAgB,IAAK,IAAAn4B,qBAAoB,GAC7Ei4B,GAAuB,IAAAl4B,oBAAmBk4B,EAAsB,IAAK,IAAAj4B,qBAAoB,IAE7F/H,IAVO,CAAP,EAAO,M,OAGX,MAAO,CAAP,EAAO,U,OAkBX,SAAe,GAAqCT,G,oGAKhD,OAJMS,EAAQT,EAAgBd,WACxB0jC,EAAqC5iC,EAAgB6iC,kBACrDC,EAA8C9iC,EAAgB8iC,qBAE9DF,GAAeE,EAIL,IAAM,IAAAz6B,oBAClB,eACA,IAAAC,yBACIs6B,GAAc,IAAAr6B,oBAAmBq6B,EAAa,IAAK,IAAAp6B,qBAAoB,GAEvEs6B,GAAuB,IAAAv6B,oBAAmBu6B,EAAsB9iC,EAAgB+iC,kCAAoC,EAAI,IAAK,IAAAv6B,qBAAoB,IAErJ/H,IAVO,CAAP,EAAO,M,OAaX,MAAO,CAAP,EAVgB,SAUDpD,sB,OASnB,SAAS,GAAkBD,EAAkC6lC,GACzD,IAAMC,EAAc,IAAI,EAAA5+B,QAAQ2+B,EAActhC,KAAMshC,EAAc/jC,YAYlE,OAXAgkC,EAAYC,SAAW/lC,EACvB8lC,EAAYx3B,iBAAmBu3B,EAAcv3B,iBACzCu3B,aAAyB,EAAA3+B,UACzB4+B,EAAYE,QAAUH,EAAcG,QACpCF,EAAYG,QAAUJ,EAAcI,QACpCH,EAAYI,OAASL,EAAcK,OACnCJ,EAAYK,OAASN,EAAcM,OACnCL,EAAYM,KAAOP,EAAcO,MAErCN,EAAY/5B,MAAQ85B,EAAc95B,MAClC+5B,EAAY75B,MAAQ45B,EAAc55B,MAC3B65B,CACX,CAMA,kBAcI,WAAYnI,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EASX,KAAAkI,mBAAkD,CAAC,EAKnD,KAAAC,2BAA8D,CAAC,EAXnE7sC,KAAKoK,UAAY85B,CACrB,CAiSJ,OArRW,YAAAvN,QAAP,WACI,IAAkB,UAAA/1B,OAAOgiB,KAAK5iB,KAAK4sC,oBAAjB,eAAsC,CAAnD,IAAMlsC,EAAG,KACMV,KAAK4sC,mBAAmBlsC,GAChCi2B,SACZ,CACA32B,KAAK4sC,mBAAqB,CAAC,EAC3B,IAAkB,UAAAhsC,OAAOgiB,KAAK5iB,KAAK6sC,4BAAjB,eAAPnsC,EAAG,KACcV,KAAK6sC,2BAA2BnsC,GACxCi2B,UAEpB32B,KAAK6sC,2BAA6B,CAAC,CACvC,EAGA,sBAAW,sBAAO,C,IAAlB,WACI,OAAO7sC,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,+GAChF8gC,EAAoC,GACtC9gC,aAA2B,EAAAqM,gBACvBrM,EAAgB2jC,UAAU3C,WACtBhhC,EAAgB2jC,UAAU//B,SAC1Bk9B,EAAmBhlC,KAAKkE,EAAgB2jC,UAAU//B,UAEjD5D,EAAgB2jC,UAAUC,6BAA+B5jC,EAAgB2jC,UAAUE,kBACpF/C,EAAmBhlC,KAAKkE,EAAgB2jC,UAAUE,kBAElD7jC,EAAgB2jC,UAAUthC,aAC1By+B,EAAmBhlC,KAAKkE,EAAgB2jC,UAAUthC,aAElDrC,EAAgB2jC,UAAU0B,aAC1BvE,EAAmBhlC,KAAKkE,EAAgB2jC,UAAU0B,aAE/C,CAAP,EAAOvE,I,MAdX,M,cAgBO9gC,aAA2B,EAAA+H,iBAC9B/H,EAAgB8jC,WAAa,GAGzBC,GAAiB,EACjB/jC,EAAgB6iC,kBAGX7iC,EAAgB8iC,qBAGjB9iC,EAAgB+iC,mCAChB/iC,EAAgB6iC,kBAAkBxlC,uBAAyB2C,EAAgB8iC,qBAAqBzlC,sBAEhGyjC,EAAmBhlC,KAAKkE,EAAgB6iC,mBACxC/B,EAAmBhlC,KAAKkE,EAAgB8iC,uBAExCiB,GAAiB,EARjBjD,EAAmBhlC,KAAKkE,EAAgB6iC,mBAUrC7iC,EAAgB8iC,uBACnB9iC,EAAgB+iC,kCAChBjC,EAAmBhlC,KAAKkE,EAAgB8iC,sBAExCiB,GAAiB,GAGrBA,GAKM5C,EA1L1B,SAA0BnhC,GACtB,IAAM4iC,EAAqC5iC,EAAgB6iC,kBACrDmB,EAASpB,GAAeA,EAAYvlC,qBAAuBulC,EAAavlC,qBAAsBiE,SAAW,SACzGwhC,EAA8C9iC,EAAgB8iC,qBAC9Dj6B,EAAci6B,GAAwBA,EAAqBzlC,qBAAuBylC,EAAsBzlC,qBAAsBiE,SAAW,cAC/I,MAAO,UAAG0iC,EAAM,YAAIn7B,EACxB,CAoLkC,CAAiB7I,GAC1BnJ,KAAK6sC,2BAA2BvC,GAAjC,MACwB,GAAM,GAAqCnhC,KAPvE,OA1BD,M,QAiCW5C,EAAkB,YAEpBvG,KAAK6sC,2BAA2BvC,GAAS/jC,G,iBAG7CvG,KAAK6sC,2BAA2BvC,KAC5BnhC,EAAgB6iC,oBAChBhsC,KAAK4sC,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,UAAY,GAClEzK,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB6iC,mBAEpB/B,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,YAElFtB,EAAgB8iC,uBAChBjsC,KAAK4sC,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,UAAY,GACrEzK,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB8iC,sBAEpBhC,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,a,wBAK7FtB,EAAgBkkC,2BAChBpD,EAAmBhlC,KAAKkE,EAAgBkkC,2BAGxClkC,EAAgBglC,kBAChBlE,EAAmBhlC,KAAKkE,EAAgBglC,kBAExChlC,EAAgBslC,wBAA0B,GACpCnE,EAAQ,GAAkBnhC,GAC5BnJ,KAAK4sC,mBAAmBtC,IACxBL,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBtC,I,OADhD,OAFJ,M,OAKyB,SAAM,GAA8BnhC,I,QAAnDuhC,EAAe,YAEjBT,EAAmBhlC,KAAKylC,GACxB1qC,KAAK4sC,mBAAmBtC,GAASI,G,wBAK7C,MAAO,CAAP,EAAOT,G,OAIf,MAAO,CAAC,EAAD,I,QAIJ,YAAAzU,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,G,MAhRaonC,EAAuBT,EACtDU,EACAC,EACAC,EA8QE,GAAI3hC,aAA2B,EAAAqM,gBAAiB,CAC5C,IAAKrM,EAAgB2jC,UAAU3C,UAE3B,YADA5mC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IACI24B,EADET,EAAkB,EAAK7jC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAU//B,SAG9F2hC,EADAvlC,EAAgB2jC,UAAUC,4BACC,EAAK3iC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAU//B,SAE1E,EAAK3C,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAUE,kBAGzG,IAAI2B,OAAoB,EACpBxlC,EAAgB2jC,UAAUU,gBAC1BmB,EAAuB,EAAKvkC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAU0B,cAGrG,IAAMI,EAAwB,EAAKxkC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB2jC,UAAUthC,aAClGqjC,EAAkB1lC,EAAgB2jC,UAAUgC,kBAarB,QAXvBC,EAA8B,CAChCC,WAAY7lC,EAAgB2jC,UAAUzF,UACtC0E,YAAakC,QAAAA,OAAmB3tC,EAChC2uC,oBAAqB9lC,EAAgB2jC,UAAUlkC,UAC/CqjC,qBAAsByC,QAAAA,OAA4BpuC,EAClD4uC,kBAAmBN,QAAAA,OAAyBtuC,EAC5C6uC,gBAAiBhmC,EAAgB2jC,UAAUsC,UAAU3iC,UACrD0hC,iBAAkBQ,QAAAA,OAAwBruC,EAC1CuuC,QAAqB,MAAZA,EAAkBA,OAAUvuC,IAG5ByrC,aAA0D,OAAlCgD,EAAS9C,sBAAmE,OAAlC8C,EAAS9C,sBAA+D,OAA9B8C,EAASZ,kBAC9H,EAAK/jC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQg5B,CAC5B,MAAO,GAAI5lC,aAA2B,EAAA+H,gBAAiB,CACnD,GAAkC,GAA9B/H,EAAgB8jC,WAEhB,YADA1pC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAIi2B,EAA2C,KAC3CiC,OAAe,EACf9kC,EAAgB6iC,oBAEZA,EADA,EAAKY,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,UACtC,EAAKmiC,mBAAmBzjC,EAAgB6iC,kBAAkBvhC,UAE1DtB,EAAgB6iC,kBAExCiC,EAAkB,EAAK7jC,UAAUkpB,kBAAkB9oB,eAAewhC,IAGtE,IAAIC,EAA8C,KAC9CiC,OAAwB,EACxB/kC,EAAgB8iC,uBAEZA,EADA,EAAKW,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,UACtC,EAAKmiC,mBAAmBzjC,EAAgB8iC,qBAAqBxhC,UAE7DtB,EAAgB8iC,qBAE3CiC,EAA2B,EAAK9jC,UAAUkpB,kBAAkB9oB,eAAeyhC,IAGzE2C,EAAwB,EAAKxkC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBkkC,2BACxFsB,EAAuB,EAAKvkC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBglC,kBACvFU,EAAkB1lC,EAAgB0lC,QAFxC,IAmDME,EAhDAM,EAAsBlmC,EAAgBmmC,cAMtCv+B,EAA0C5H,EAAgB8iC,qBAC1D3B,EAAQ,GAAkBnhC,GAC1BkiC,EAAqB,EAAKuB,mBAAmBtC,GAC/CiF,EAAyB,EACzBC,EAAyB,EACzBC,OAAwBnvC,EAC5B,GAAI6I,EAAgBslC,wBAA0B,EAAK,CAG/C,GAAK19B,GAAqBs6B,EAenB,CACH,IAAMO,EAAyBP,EAAqB,EAAKjhC,UAAUkpB,kBAAkB9oB,eAAe6gC,GAAsB,KAE1HkE,EAAyBpmC,EAAgBslC,wBACzCe,EAAyBrmC,EAAgBumC,yBACzCD,EAAwB7D,QAAkDtrC,CAC9E,KArB8C,CAE1C,IAAIirC,EAAmBpiC,EAAgBilC,cACnC5C,EAAwBriC,EAAgBslC,wBAC5C,IAAKtlC,EAAgBsiC,wBAAyB,CAC1C,IAAMC,GAlXOf,EAkXqCxhC,EAAgBilC,cA/WpFtD,GAAc,GAHwCZ,EAkX6C/gC,EAAgBslC,2BAhXnH5D,GADAD,EAAYD,EAAgBA,GACH5iC,KAAKC,KAAK,GAAO,GAAO,EAAIkiC,IAAe,EAAIA,MAKvE,CAAEqB,iBAHgBxjC,KAAKC,KAAK8iC,GAGRU,sBAFGzjC,KAAKub,IAAIvb,KAAKC,MAAM6iC,EAAaD,GAAa7iC,KAAKqH,IAAI,EAAMw7B,EAAW,OAAU,KA8WxFW,EAAmBG,EAAUH,iBAC7BC,EAAwBE,EAAUF,qBACtC,CACIryB,EAAKvO,uBACLuO,EAAKvO,qBAAqB5B,gBAAkBuiC,GAEhDgE,EAAyB/D,EACzBgE,EAAyBrmC,EAAgBumC,yBAAqC,GAAV3nC,KAAK2/B,GACzE+H,OAAwBnvC,CAC5B,CAQK6I,EAAgBsiC,0BAEjBtyB,EAAKpD,WAAmC,sBAAI,CAAC,GAC7C,IAAK3L,UAAUqoB,OAAM6D,iBAAc,EAAdA,eAAmB,KACsC,IAA1E,EAAKlsB,UAAUqoB,MAAM6D,eAAelE,QAAQ,0BAC5C,EAAKhoB,UAAUqoB,MAAM6D,eAAerxB,KAAK,yBAGrD,CAkB6B,QAhBvB8pC,EAA8B,CAChCC,WAAY7lC,EAAgB8jC,WAC5BlB,YAAakC,QAAAA,OAAmB3tC,EAChC2uC,oBAAqB9lC,EAAgBilC,cACrCnC,qBAAsBiC,QAAAA,OAA4B5tC,EAClD4uC,kBAAmBN,QAAAA,OAAyBtuC,EAC5C6uC,gBAAiBhmC,EAAgBwmC,UAAUljC,UAC3C0hC,iBAAkBQ,QAAAA,OAAwBruC,EAC1CuuC,QAAqB,MAAZA,EAAkBA,OAAUvuC,EACrC+uC,oBAA6C,IAAxBA,EAA8BA,OAAsB/uC,EACzEkvC,uBAAwBA,EACxBD,uBAAwBA,EACxBE,sBAAuBA,IAId1D,aACyB,OAAlCgD,EAAS9C,sBACyB,OAAlC8C,EAAS9C,sBAC0B,OAAnC8C,EAASU,uBACqB,OAA9BV,EAASZ,kBAET,EAAK/jC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQg5B,CAC5B,CACAxrC,EAAQ4V,EACZ,GACJ,EACJ,EAjTA,GAmTAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI0L,GAAmB1L,EAAvB,ICpbnD,IAAM,GAAO,qCAMb,SAAS2L,GAAgCva,EAAiBnsB,GACtD,IAAM2mC,EAAO3mC,EAAgB4mC,WACzBhjC,EAAU,KASd,OANI+iC,EAAKE,6BACLjjC,EAAU+iC,EAAKE,6BACRF,EAAKG,kBAAoBH,EAAKI,8BACrCnjC,EAAU+iC,EAAKG,kBAGfljC,IAAY+iC,EAAKK,sBACjB,EAAArxB,OAAO7T,KAAK,UAAGqqB,EAAO,8GAAsGnsB,EAAgB2B,MAAQ,GAC7I,MAGJiC,CACX,CAOA,kBAcI,WAAYm3B,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CA2FJ,OAzFW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,2EAGtF,OAFM8gC,EAAoC,GAEtC9gC,aAA2B,EAAAinC,aAAepwC,KAAKqwC,oBAAoBlnC,KAC7D6mC,EAA+BH,GAAgCva,EAASnsB,KAE1E8gC,EAAmBhlC,KAAK+qC,GAExB7mC,EAAgB4mC,WAAWO,0BAC3BrG,EAAmBhlC,KAAKkE,EAAgB4mC,WAAWO,0BAEhD,CAAP,EAAOrG,IAGJ,CAAP,EAAOA,E,QAGH,YAAAoG,oBAAR,SAA4B/S,GAExB,GAAIA,EAAIiT,MACJ,OAAO,EAEX,IAAMT,EAAOxS,EAAIyS,WACjB,QAAKD,EAAKU,wBAKLlT,EAAIiT,QACJT,EAAKW,6BACNX,EAAKK,sBAC4B,IAAjCL,EAAKY,yBACqB,IAA1BZ,EAAKa,kBACqB,IAA1Bb,EAAKc,gBAEb,EAUO,YAAApb,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,G,QAChB,GAAI4F,aAA2B,EAAAinC,aAAe,EAAKC,oBAAoBlnC,GAAkB,CACrF,EAAKu7B,UAAW,EAEhB,IAAMoL,EAAO3mC,EAAgB4mC,WACvBC,EAA+BH,GAAgCva,EAASnsB,GAExE0nC,EAA0D,GAA9Bf,EAAKgB,2BAA6BxwC,EAAYwvC,EAAKgB,sBAC/EC,EAA0G,QAA7E,IAAK3mC,UAAUkpB,kBAAkB9oB,eAAewlC,UAA6B,aAAI1vC,EAC9G0wC,GAAkClB,EAAKmB,mBAAqBnB,EAAKmB,kBAAkBC,aAAa,EAAK,EAAK,QAAO5wC,EAAYwvC,EAAKmB,kBAAkBxkC,UACpJ0kC,EAAgH,QAA9E,IAAK/mC,UAAUkpB,kBAAkB9oB,eAAeslC,EAAKQ,iCAAyB,aAAIhwC,EAEpH8wC,EAA4D,CAC9DP,0BAAyB,EACzBE,2BAA0B,EAC1BC,+BAA8B,EAC9BG,gCAA+B,IAG/BJ,GAA8BI,IAC9B,EAAK/mC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EACtCoD,EAAKpD,WAAW,IAAQq7B,CAC5B,CACA7tC,EAAQ4V,EACZ,GACJ,EACJ,EA3GA,GA6GAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAImN,GAAmCnN,EAAvC,IC9InD,IAAM,GAAO,2BAOb,cAaI,aAXgB,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,CAGJ,CAgDnB,OA7CW,YAAA/N,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEQ,YAAA2L,oBAAR,SAA4B/S,GAExB,GAAIA,EAAIiT,MACJ,OAAO,EAEX,IAAMT,EAAOxS,EAAIyS,WAEjB,SAAKD,EAAKwB,sBAAwBxB,EAAKyB,oBAI3C,EAUO,YAAA/b,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,GAAI4F,aAA2B,EAAAinC,aAAe,EAAKC,oBAAoBlnC,GAAkB,CACrF,EAAKu7B,UAAW,EAEhB,IAGM8M,EAA0C,CAC5CC,WAJStoC,EAAgB4mC,WACL0B,YAKxBt4B,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EACtCoD,EAAKpD,WAAW,IAAQy7B,CAC5B,CACAjuC,EAAQ4V,EACZ,GACJ,EACJ,EA7DA,GA+DAgc,GAAayB,kBAAkB,IAAM,WAAM,WAAI8a,EAAJ,ICtE3C,IAAM,GAAO,kCAMb,2BAEoB,KAAA5mC,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,CA4CvB,QAzCW,YAAA/N,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAlP,wBAAb,SAAqCF,EAAiBnc,EAAiBhQ,G,qGAC5D,SAAM,IAAI7F,SAAQ,SAACC,GACtB,KAAM4F,aAA2B,EAAAinC,aAC7B,OAAO7sC,EAAQ4V,GAGnB,IAAM5M,EAAgBpD,EAAgBoD,cAAc/D,MAAMW,EAAgBwoC,mBACpEC,EAAuB7pC,KAAKqH,IAAG,MAARrH,KAAYwE,EAAcE,WAEvD,GAAImlC,EAAuB,EAAG,CAE1Bz4B,EAAKvN,eAAiBW,EAAc/D,MAAM,EAAIopC,GAAsBnlC,UAEpE,EAAKi4B,UAAW,EAChB,IAAMmN,EAAsD,CACxDC,iBAAkBF,GAEtBz4B,EAAKpD,aAALoD,EAAKpD,WAAe,CAAC,GACrBoD,EAAKpD,WAAW,IAAQ87B,CAC5B,MAEI14B,EAAKvN,eAAiBW,EAAcE,UAGxC,OAAOlJ,EAAQ4V,EACnB,K,OAxBA,MAAO,CAAP,EAAO,U,QA0Bf,EAtDA,GAwDAgc,GAAayB,kBAAkB,IAAM,WAAM,WAAImb,EAAJ,IC9D3C,IAAM,GAAO,oBAMb,cAYI,aAVgB,KAAAjnC,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,CAEJ,CAwCnB,OArCW,YAAA/N,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEQ,YAAA2L,oBAAR,SAA4B/S,GAExB,OAAIA,EAAIiT,OAGwBjwC,MAAzBg9B,EAAIwR,mBAA2D,KAAzBxR,EAAIwR,iBACrD,EAUO,YAAAtZ,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,GAAI4F,aAA2B,EAAAinC,aAAe,EAAKC,oBAAoBlnC,GAAkB,CACrF,EAAKu7B,UAAW,EAEhB,IAAMsN,EAA4B,CAC9BC,IAAK9oC,EAAgB2lC,mBAEzB31B,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EACtCoD,EAAKpD,WAAW,IAAQi8B,CAC5B,CACAzuC,EAAQ4V,EACZ,GACJ,EACJ,EApDA,GAuDAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIgO,EAAJ,IC3DnD,IAAM,GAAO,4BAMb,cAcI,WAAYhO,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CAkGJ,OAhGW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,yEAEtF,GADM8gC,EAAoC,GACtC9gC,aAA2B,EAAAqM,iBAC3B,GAAIrM,EAAgBgpC,YAAYhI,UAO5B,OANIhhC,EAAgBgpC,YAAYplC,SAC5Bk9B,EAAmBhlC,KAAKkE,EAAgBgpC,YAAYplC,SAEpD5D,EAAgBgpC,YAAYlC,kBAAoB9mC,EAAgBgpC,YAAYlC,mBAAqB9mC,EAAgBgpC,YAAYplC,SAC7Hk9B,EAAmBhlC,KAAKkE,EAAgBgpC,YAAYlC,kBAEjD,CAAP,EAAOhG,QAER,GAAI9gC,aAA2B,EAAA+H,iBAC9B/H,EAAgBipC,eAAiB,EAOjC,OANIjpC,EAAgBkpC,uBAChBpI,EAAmBhlC,KAAKkE,EAAgBkpC,uBAExClpC,EAAgBmpC,0BAA4BnpC,EAAgBmpC,2BAA6BnpC,EAAgBkpC,uBACzGpI,EAAmBhlC,KAAKkE,EAAgBmpC,0BAErC,CAAP,EAAOrI,GAGf,MAAO,CAAC,EAAD,G,QAIJ,YAAAzU,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,GAAI4F,aAA2B,EAAAqM,gBAAiB,CAC5C,IAAKrM,EAAgBgpC,YAAYhI,UAE7B,YADA5mC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAMw8B,EAAyB,EAAKnoC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBgpC,YAAYplC,SACrGylC,EAAkC,EAAKpoC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBgpC,YAAYlC,kBAYzE,QAVrCwC,EAA4C,CAC9CC,kBAAmBvpC,EAAgBgpC,YAAY9K,UAC/CsL,eAAgBxpC,EAAgBgpC,YAAYrD,kBAC5C8D,4BAA6BzpC,EAAgBgpC,YAAYxB,iBACzDkC,4BAA6B1pC,EAAgBgpC,YAAYvB,iBAEzDkC,mBAAoBP,QAAAA,OAA0BjyC,EAC9CyyC,4BAA6BP,QAAAA,OAAmClyC,IAGhDwyC,oBAA+E,OAAhDL,EAAgBM,6BAC/D,EAAK3oC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQ08B,CAC5B,MAAO,GAAItpC,aAA2B,EAAA+H,gBAAiB,CACnD,GAAI/H,EAAgBipC,gBAAkB,EAElC,YADA7uC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAGM08B,EAHAO,EAA4B,EAAK5oC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBkpC,uBAC5FY,EAA+B,EAAK7oC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBmpC,0BAY1D,QAVrCG,EAA4C,CAC9CC,kBAAmBvpC,EAAgBipC,eACnCO,eAAgBxpC,EAAgB+pC,YAChCN,4BAAoE,IAAvCzpC,EAAgBgqC,qBAC7CN,4BAAiE,IAApC1pC,EAAgBiqC,kBAE7CN,mBAAoBE,QAAAA,OAA6B1yC,EACjDyyC,4BAA6BE,QAAAA,OAAgC3yC,IAG7CwyC,oBAA+E,OAAhDL,EAAgBM,6BAC/D,EAAK3oC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQ08B,CAC5B,CACAlvC,EAAQ4V,EACZ,GACJ,EACJ,EAlHA,GAoHAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAImP,GAA0BnP,EAA9B,IC3HnD,IAAM,GAAO,sBAMb,cAcI,WAAYA,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,EAKf1kC,KAAKoK,UAAY85B,CACrB,CAwDJ,OAtDW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAuDJ,EAAiBnc,EAAiBhQ,G,mEACrF,OAAIA,aAA2B,EAAAinC,aACvBjnC,EAAgBmqC,MAAMnJ,WAAahhC,EAAgBmqC,MAAMvmC,QAClD,CAAC,EAAD,CAAC5D,EAAgBmqC,MAAMvmC,UAI/B,CAAC,EAAD,G,QAGE,YAAAyoB,wBAAb,SAAqCF,EAAiBnc,EAAiBhQ,G,qGAC5D,SAAM,IAAI7F,SAAQ,SAACC,G,YACtB,GAAI4F,aAA2B,EAAAinC,YAAa,CACxC,IAAKjnC,EAAgBmqC,MAAMnJ,UAEvB,YADA5mC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEO,MAAnBvrB,EAAKpD,aACLoD,EAAKpD,WAAa,CAAC,GAEvB,IAAMw9B,EAAgC,CAClCC,iBAAkBrqC,EAAgBmqC,MAAM3iC,MAAMlE,UAC9CgnC,qBAAqD,QAA/B,EAAAtqC,EAAgBmqC,MAAM1qC,iBAAS,QAAI,GAGzB,OAAhC2qC,EAAUG,mBAAkE,OAApCH,EAAUI,uBAClD,EAAKvpC,UAAU4B,qBAAqBC,IAAI9C,GAGxCA,EAAgBmqC,MAAMvmC,UACtBwmC,EAAUG,kBAAkG,QAA9E,IAAKtpC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBmqC,MAAMvmC,gBAAQ,aAAIzM,GAGhH6I,EAAgBmqC,MAAMtG,mBAAqB7jC,EAAgBmqC,MAAMvG,4BACjEwG,EAAUI,sBAA+G,QAAvF,IAAKvpC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBmqC,MAAMtG,yBAAiB,aAAI1sC,EACtH6I,EAAgBmqC,MAAMvmC,SAAW5D,EAAgBmqC,MAAMvG,8BAC9DwG,EAAUI,sBAAsG,QAA9E,IAAKvpC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBmqC,MAAMvmC,gBAAQ,aAAIzM,GAGxH6Y,EAAKpD,WAAW,IAAQw9B,CAC5B,CACAhwC,EAAQ4V,EACZ,K,OAlCA,MAAO,CAAP,EAAO,U,QAoCf,EAxEA,GA0EAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI0P,GAAoB1P,EAAxB,IC5EnD,IAAM,GAAO,qBAwBb,SAAe2P,GAAgC1qC,G,oGAK3C,OAJMS,EAAQT,EAAgBd,WACxByrC,EAA0C3qC,EAAgB2qC,iBAC1DC,EAA8C5qC,EAAgB4qC,qBAE9DD,GAAoBC,EAIV,IAAM,IAAAviC,oBAClB,eACA,IAAAC,yBACIqiC,GAAmB,IAAApiC,oBAAmBoiC,EAAkB,IAAK,IAAAniC,qBAAoB,GACjFmiC,GAAmB,IAAApiC,oBAAmBoiC,EAAkB,IAAK,IAAAniC,qBAAoB,GACjFmiC,GAAmB,IAAApiC,oBAAmBoiC,EAAkB,IAAK,IAAAniC,qBAAoB,GAEjFoiC,GAAuB,IAAAriC,oBAAmBqiC,EAAsB5qC,EAAgB6qC,kCAAoC,EAAI,IAAK,IAAAriC,qBAAoB,IAErJ/H,IAZO,CAAP,EAAO,M,OAeX,MAAO,CAAP,EAZgB,SAYDpD,sB,OASnB,SAAS,GAAkBD,EAAkC6lC,GACzD,IAAMC,EAAc,IAAI,EAAA5+B,QAAQ2+B,EAActhC,KAAMshC,EAAc/jC,YAYlE,OAXAgkC,EAAYC,SAAW/lC,EACvB8lC,EAAYx3B,iBAAmBu3B,EAAcv3B,iBACzCu3B,aAAyB,EAAA3+B,UACzB4+B,EAAYE,QAAUH,EAAcG,QACpCF,EAAYG,QAAUJ,EAAcI,QACpCH,EAAYI,OAASL,EAAcK,OACnCJ,EAAYK,OAASN,EAAcM,OACnCL,EAAYM,KAAOP,EAAcO,MAErCN,EAAY/5B,MAAQ85B,EAAc95B,MAClC+5B,EAAY75B,MAAQ45B,EAAc55B,MAC3B65B,CACX,CAMA,kBAcI,WAAYnI,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,EAWX,KAAAkI,mBAAkD,CAAC,EAKnD,KAAAC,2BAA8D,CAAC,EAXnE7sC,KAAKoK,UAAY85B,CACrB,CAoIJ,OAxHW,YAAAvN,QAAP,WACI,IAAkB,UAAA/1B,OAAOgiB,KAAK5iB,KAAK4sC,oBAAjB,eAAsC,CAAnD,IAAMlsC,EAAG,KACMV,KAAK4sC,mBAAmBlsC,GAChCi2B,SACZ,CACA32B,KAAK4sC,mBAAqB,CAAC,EAC3B,IAAkB,UAAAhsC,OAAOgiB,KAAK5iB,KAAK6sC,4BAAjB,eAAPnsC,EAAG,KACcV,KAAK6sC,2BAA2BnsC,GACxCi2B,UAEpB32B,KAAK6sC,2BAA6B,CAAC,CACvC,EAGA,sBAAW,sBAAO,C,IAAlB,WACI,OAAO7sC,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAuDJ,EAAiBnc,EAAiBhQ,G,6GACjFA,aAA2B,EAAA+H,iBACrB+4B,EAAoC,GACtC9gC,EAAgB8qC,WAAa,GACzB9qC,EAAgB+qC,mBAChBjK,EAAmBhlC,KAAKkE,EAAgB+qC,mBAExCC,GAAwB,EACxBhrC,EAAgB4qC,uBACZ5qC,EAAgB6qC,kCAChB/J,EAAmBhlC,KAAKkE,EAAgB4qC,sBAExCI,GAAwB,GAG5BhrC,EAAgB2qC,mBAAqBK,GACrClK,EAAmBhlC,KAAKkE,EAAgB2qC,kBAExCK,GACM7J,EAlI1B,SAA+BnhC,GAC3B,IAAM2qC,EAA0C3qC,EAAgB2qC,iBAC1DM,EAAcN,GAAoBA,EAAiBttC,qBAAuBstC,EAAkBttC,qBAAsBiE,SAAW,cAC7HspC,EAA8C5qC,EAAgB4qC,qBAC9DM,EAAkBN,GAAwBA,EAAqBvtC,qBAAuButC,EAAsBvtC,qBAAsBiE,SAAW,kBACnJ,MAAO,oBAAa2pC,EAAW,0BAAkBC,EACrD,CA4HkCC,CAAsBnrC,GAC/BnJ,KAAK6sC,2BAA2BvC,GAAjC,MAC8B,GAAMuJ,GAAgC1qC,KAHxE,OAfJ,OAFJ,M,QAoBkBorC,EAAwB,YAE1Bv0C,KAAK6sC,2BAA2BvC,GAASiK,G,iBAG7Cv0C,KAAK6sC,2BAA2BvC,KAC5BnhC,EAAgB2qC,mBAChB9zC,KAAK4sC,mBAAmBzjC,EAAgB2qC,iBAAiBrpC,UAAY,GACjEzK,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB2qC,kBAEpB7J,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB2qC,iBAAiBrpC,YAEjFtB,EAAgB4qC,uBAChB/zC,KAAK4sC,mBAAmBzjC,EAAgB4qC,qBAAqBtpC,UAAY,GACrEzK,KAAK6sC,2BAA2BvC,GAChCnhC,EAAgB4qC,sBAEpB9J,EAAmBhlC,KAAKjF,KAAK4sC,mBAAmBzjC,EAAgB4qC,qBAAqBtpC,a,iBAKrG,MAAO,CAAP,EAAOw/B,G,OAGX,MAAO,CAAC,EAAD,I,QAGE,YAAAzU,wBAAb,SAAqCF,EAAiBnc,EAAiBhQ,G,qGAC5D,SAAM,IAAI7F,SAAQ,SAACC,G,UACtB,GAAI4F,aAA2B,EAAA+H,gBAAiB,CAC5C,GAAkC,GAA9B/H,EAAgB8qC,WAEhB,YADA1wC,EAAQ4V,GAIZ,EAAKurB,UAAW,EAEO,MAAnBvrB,EAAKpD,aACLoD,EAAKpD,WAAa,CAAC,GAEvB,IAAMy+B,EAA8B,CAChCC,WAAYtrC,EAAgB8qC,WAC5BS,gBAAiBvrC,EAAgBwrC,UAAUloC,UAC3CmoC,oBAAqBzrC,EAAgB0rC,eAGrC1rC,EAAgB+qC,oBAChBM,EAASM,YAAgG,QAAlF,IAAK1qC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB+qC,0BAAkB,aAAI5zC,GAGjH,IAAIwzC,EAA0C,KAC1C3qC,EAAgB2qC,mBAEZA,EADA,EAAKlH,mBAAmBzjC,EAAgB2qC,iBAAiBrpC,UACtC,EAAKmiC,mBAAmBzjC,EAAgB2qC,iBAAiBrpC,UAEzDtB,EAAgB2qC,iBAEvCU,EAASV,iBAAoF,QAAjE,IAAK1pC,UAAUkpB,kBAAkB9oB,eAAespC,UAAiB,aAAIxzC,GAGrG,IAAIyzC,EAA8C,KAC9C5qC,EAAgB4qC,uBAEZA,EADA,EAAKnH,mBAAmBzjC,EAAgB4qC,qBAAqBtpC,UACtC,EAAKmiC,mBAAmBzjC,EAAgB4qC,qBAAqBtpC,UAE7DtB,EAAgB4qC,qBAE3CS,EAAST,qBAA4F,QAArE,IAAK3pC,UAAUkpB,kBAAkB9oB,eAAeupC,UAAqB,aAAIzzC,GAG3E,OAA9Bk0C,EAASV,kBAA+D,OAAlCU,EAAST,sBAC/C,EAAK3pC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQy+B,CAC5B,CACAjxC,EAAQ4V,EACZ,K,OAjDA,MAAO,CAAP,EAAO,U,QAmDf,EApJA,GAsJAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI6Q,GAAmB7Q,EAAvB,ICnOnD,IAAM,GAAO,yBAMb,cAcI,WAAYA,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CA6HJ,OA1HW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,yEAGtF,OAFM8gC,EAAoC,GAEtC9gC,aAA2B,EAAAinC,aACvBpwC,KAAKqwC,oBAAoBlnC,IACrBA,EAAgB6rC,4BAChB/K,EAAmBhlC,KAAKkE,EAAgB6rC,4BAExC7rC,EAAgB8rC,oBAChBhL,EAAmBhlC,KAAKkE,EAAgB8rC,oBAErC,CAAP,EAAOhL,IAIR,CAAP,EAAOA,E,QAGH,YAAAoG,oBAAR,SAA4B/S,GAExB,OAAIA,EAAIiT,QAIqBjwC,MAAxBg9B,EAAI4X,kBAAyD,GAAxB5X,EAAI4X,kBACT50C,MAAhCg9B,EAAI6X,2BAA0C7X,EAAI6X,yBAAyBjE,aAAa,EAAK,EAAK,IACnGlxC,KAAKo1C,sBAAsB9X,GAEnC,EAEQ,YAAA8X,sBAAR,SAA8B9X,GAC1B,OAAyC,MAAlCA,EAAI0X,4BAAgE,MAA1B1X,EAAI2X,kBACzD,EAUO,YAAAzf,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,G,cAChB,GAAI4F,aAA2B,EAAAinC,aAAe,EAAKC,oBAAoBlnC,GAAkB,CACrF,EAAKu7B,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAMi/B,EAAwH,QAA3F,IAAK5qC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB6rC,mCAA2B,aAAI10C,EAC5H20C,EAAwG,QAAnF,IAAK7qC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgB8rC,2BAAmB,aAAI30C,EAM5G+0C,EAAsC,CACxCC,eANyD,GAApCnsC,EAAgB+rC,sBAA0B50C,EAAY6I,EAAgB+rC,iBAO3FK,gBAAiBP,EACjBQ,oBAP6BrsC,EAAgBgsC,yBAAyBjE,aAAa,EAAK,EAAK,QAC3F5wC,EACA6I,EAAgBgsC,yBAAyB1oC,UAM3CgpC,qBAAsBR,GAGtB,EAAKG,sBAAsBjsC,IAC3B,EAAKiB,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQs/B,CAC5B,MAAO,GAAIlsC,aAA2B,EAAA+H,gBAAiB,CACnDiI,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAM2/B,EAA8G,QAAtF,IAAKtrC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBusC,8BAAsB,aAAIp1C,EAClHm1C,EAA4G,QAArF,IAAKrrC,UAAUkpB,kBAAkB9oB,eAAerB,EAAgBssC,6BAAqB,aAAIn1C,EAChHq1C,EAAmD,GAAlCxsC,EAAgBwsC,oBAAwBr1C,EAAY6I,EAAgBwsC,eACrF5mC,EAAgB5F,EAAgB4F,cAAcmiC,aAAa,EAAK,EAAK,QAAO5wC,EAAY6I,EAAgB4F,cAActC,UAE5H,IAAKgpC,IAAyBC,QAA4Cp1C,IAAnBq1C,QAAkDr1C,IAAlByO,EACnF,OAAOxL,EAAQ4V,GAEnB,EAAKurB,UAAW,GAMV2Q,EAAsC,CACxCC,eAAgBK,EAChBJ,gBAAiBG,EACjBF,oBAAqBzmC,EACrB0mC,qBAAsBA,EACtB1/B,WAAY,CAAC,IAGJA,WAA+C,kCAZE,CAC1D6/B,0BAA0B,IAY9B,IAAKxrC,UAAUqoB,OAAM6D,iBAAc,EAAdA,eAAmB,KACkD,IAAtF,EAAKlsB,UAAUqoB,MAAM6D,eAAelE,QAAQ,sCAC5C,EAAKhoB,UAAUqoB,MAAM6D,eAAerxB,KAAK,sCAGzCywC,GAAyBD,IACzB,EAAKrrC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQs/B,CAC5B,CACA9xC,EAAQ4V,EACZ,GACJ,EACJ,EA7IA,GA+IAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI2R,GAAuB3R,EAA3B,ICrJnD,IAAM,GAAO,6BAMb,cAcI,WAAYA,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CAoFJ,OAjFW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,yEAGtF,OAFM8gC,EAAoC,GAEtC9gC,aAA2B,EAAAinC,aACvBpwC,KAAKqwC,oBAAoBlnC,IACrBA,EAAgB4mC,WAAWE,kBAC3BhG,EAAmBhlC,KAAKkE,EAAgB4mC,WAAWE,kBAEhD,CAAP,EAAOhG,IAIR,CAAP,EAAOA,E,QAGH,YAAAoG,oBAAR,SAA4B/S,GAExB,GAAIA,EAAIiT,MACJ,OAAO,EAEX,IAAMT,EAAOxS,EAAIyS,WACjB,OAAQD,EAAKwB,qBAAmDhxC,MAA5BwvC,EAAKgG,qBAAgE,GAA5BhG,EAAKgG,qBAA6B91C,KAAKo1C,sBAAsB9X,EAC9I,EAEQ,YAAA8X,sBAAR,SAA8B9X,GAC1B,OAAoD,MAA7CA,EAAIyS,WAAWgG,0BAC1B,EASa,YAAAvgB,wBAAb,SAAsCF,EAAiBnc,EAAiBhQ,G,6GAChEA,aAA2B,EAAAinC,aAAepwC,KAAKqwC,oBAAoBlnC,IACnEnJ,KAAK0kC,UAAW,EAEVqL,EAAa5mC,EAAgB4mC,WAC7BiG,EAAwD,IAAnCjG,EAAW+F,yBAA4Bx1C,EAAYyvC,EAAW+F,oBAEnFG,EAAwC,CAC1CD,mBAAoBA,GAGpBh2C,KAAKo1C,sBAAsBjsC,IAC3BnJ,KAAKoK,UAAU4B,qBAAqBC,IAAI9C,GAGxC4mC,EAAWgG,2BACPhG,EAAWI,qBACiB,GAAMnwC,KAAKoK,UAAUkpB,kBAAkBjoB,mBAAmB0kC,EAAWgG,6BADjG,MADJ,OAdJ,M,cAgBcG,EAAsB,YAExBD,EAAWC,oBAAsBA,G,aAGrC,EAAAp3B,OAAO7T,KAAK,UAAGqqB,EAAO,0G,iBAI9Bnc,EAAKpD,aAALoD,EAAKpD,WAAe,CAAC,GACrBoD,EAAKpD,WAAW,IAAQkgC,E,iBAG5B,MAAO,CAAP,EAAO98B,G,QAEf,EApGA,GAsGAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIiS,GAA2BjS,EAA/B,IC7GnD,IAAM,GAAO,sBAMb,cAYI,aAVgB,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,CAEJ,CAiCnB,OA9BI,sBAAW,sBAAO,C,IAAlB,WACI,OAAO1kC,KAAK0kC,QAChB,E,gCAEO,YAAA/N,QAAP,WAAkB,EAGX,YAAAnB,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,IAAI6yC,GAAgB,EAEhBjtC,aAA2B,EAAAinC,YAC3BgG,EAAgBjtC,EAAgBonC,MACzBpnC,aAA2B,EAAAu2B,mBAClC0W,EAAgBjtC,EAAgBktC,iBAGhCD,IACA,EAAK1R,UAAW,EAEO,MAAnBvrB,EAAKpD,aACLoD,EAAKpD,WAAa,CAAC,GAGvBoD,EAAKpD,WAAW,IAAQ,CAAC,GAG7BxS,EAAQ4V,EACZ,GACJ,EACJ,EA7CA,GA+CAgc,GAAayB,kBAAkB,IAAM,WAAM,WAAI0f,EAAJ,ICpD3C,IAAM,GAAO,uBAMb,cAcI,WAAYpS,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CAyFJ,OAvFW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCASa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,yEAGtF,OAFM8gC,EAAoC,GAEtC9gC,aAA2B,EAAAinC,aACvBpwC,KAAKqwC,oBAAoBlnC,IACrBA,EAAgB4mC,WAAWE,kBAC3BhG,EAAmBhlC,KAAKkE,EAAgB4mC,WAAWE,kBAEhD,CAAP,EAAOhG,IAIR,CAAP,EAAOA,E,QAGH,YAAAoG,oBAAR,SAA4B/S,GAExB,GAAIA,EAAIiT,MACJ,OAAO,EAEX,IAAMT,EAAOxS,EAAIyS,WAEjB,SAAKD,EAAKwB,sBAAwBxB,EAAKU,yBAITlwC,MAAzBwvC,EAAKc,kBAA0D,GAAzBd,EAAKc,kBACftwC,MAA5BwvC,EAAKyG,qBAAoCzG,EAAKyG,qBAAuBjlC,OAAOklC,mBAC1Dl2C,MAAlBwvC,EAAKV,WAA0BU,EAAKV,WAAa,EAAAtpC,OAAOE,SACzDhG,KAAKo1C,sBAAsB9X,GAEnC,EAEQ,YAAA8X,sBAAR,SAA8B9X,GAC1B,OAA0C,MAAnCA,EAAIyS,WAAWE,gBAC1B,EAUO,YAAAza,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,G,MAChB,GAAI4F,aAA2B,EAAAinC,aAAe,EAAKC,oBAAoBlnC,GAAkB,CACrF,EAAKu7B,UAAW,EAEhB,IAAMoL,EAAO3mC,EAAgB4mC,WAMvBkG,EAAkC,CACpCQ,gBAN6C,GAAzB3G,EAAKc,sBAAwBtwC,EAAYwvC,EAAKc,iBAOlEX,iBAN2F,QAAtE,IAAK7lC,UAAUkpB,kBAAkB9oB,eAAeslC,EAAKG,yBAAiB,aAAI3vC,EAO/Fo2C,oBANwB5G,EAAKyG,qBAAuBjlC,OAAOklC,uBAAoBl2C,EAAYwvC,EAAKyG,oBAOhGI,iBANqB7G,EAAKV,UAAU8B,aAAa,EAAK,EAAK,QAAO5wC,EAAYwvC,EAAKV,UAAU3iC,WAS7F,EAAK2oC,sBAAsBjsC,IAC3B,EAAKiB,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EACtCoD,EAAKpD,WAAW,IAAQkgC,CAC5B,CACA1yC,EAAQ4V,EACZ,GACJ,EACJ,EAzGA,GA2GAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAI0S,GAAqB1S,EAAzB,IChHnD,IAAM,GAAO,kCAMb,cAcI,WAAYA,GAZI,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAIV,KAAAmO,UAAW,EAGf1kC,KAAKoK,UAAY85B,CACrB,CAmEJ,OAjEW,YAAAvN,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEa,YAAAhP,0CAAb,SAAwDJ,EAAiBnc,EAAiBhQ,G,yEAEtF,GADM8gC,EAAoC,GACtC9gC,aAA2B,EAAAqM,iBAC3B,GAAIrM,EAAgB0tC,sBAIhB,OAHI1tC,EAAgB2tC,8BAChB7M,EAAmBhlC,KAAKkE,EAAgB2tC,8BAErC,CAAP,EAAO7M,QAER,GAAI9gC,aAA2B,EAAA+H,iBAC9B/H,EAAgB4tC,qBAIhB,OAHI5tC,EAAgB6tC,6BAChB/M,EAAmBhlC,KAAKkE,EAAgB6tC,6BAErC,CAAP,EAAO/M,GAIf,MAAO,CAAC,EAAD,G,QAIJ,YAAAzU,wBAAP,SAAgCF,EAAiBnc,EAAiBhQ,GAAlE,WACI,OAAO,IAAI7F,SAAQ,SAACC,GAChB,IAAI0zC,EAA2C,KAC3CC,EAAiD,KAQrD,GAPI/tC,aAA2B,EAAAqM,iBAC3ByhC,EAAyB9tC,EAAgB0tC,sBACzCK,EAA0B/tC,EAAgB2tC,8BACnC3tC,aAA2B,EAAA+H,kBAClC+lC,EAAyB9tC,EAAgB4tC,qBACzCG,EAA0B/tC,EAAgB6tC,6BAEzCC,EAAL,CAKA,EAAKvS,UAAW,EAEhBvrB,EAAKpD,WAAaoD,EAAKpD,YAAc,CAAC,EAEtC,IAAMohC,EAA8B,EAAK/sC,UAAUkpB,kBAAkB9oB,eAAe0sC,GAE9EE,EAAsD,CACxDH,uBAAwBA,EACxBC,wBAAyBC,QAAAA,OAA+B72C,GAGP,OAAjD82C,EAAqBF,yBACrB,EAAK9sC,UAAU4B,qBAAqBC,IAAI9C,GAG5CgQ,EAAKpD,WAAW,IAAQqhC,EAExB7zC,EAAQ4V,EAnBR,MAFI5V,EAAQ4V,EAsBhB,GACJ,EACJ,EAnFA,GAqFAgc,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAImT,GAAgCnT,EAApC,IC9FnD,IAAM,GAAO,wBAqBb,cAaI,aAXgB,KAAAp5B,KAAO,GAGhB,KAAAqrB,SAAU,EAGV,KAAAI,UAAW,EAGV,KAAAmO,UAAW,CAEJ,CAwEnB,OAtEW,YAAA/N,QAAP,WAAkB,EAGlB,sBAAW,sBAAO,C,IAAlB,WACI,OAAO32B,KAAK0kC,QAChB,E,gCAEO,YAAA/O,kBAAP,SAA0BL,EAAiBhqB,EAA2BhF,GAUlE,GATcA,EAAe+B,YAEzB,EAAAhG,MAAM4I,KAAK,UAAGqqB,EAAO,wDAAgDhvB,EAAewE,KAAI,MAOhE,IAAxBxE,EAAegxC,MAAsC,IAAxBhxC,EAAeixC,OAC5C,EAAAl1C,MAAM4I,KAAK,UAAGqqB,EAAO,qBAAahvB,EAAewE,KAAI,gEAGd,IAAnCxE,EAAekxC,iBAA4D,IAAnClxC,EAAemxC,iBAJ/D,CASA,IAAMC,EAAyC,CAAC,EAC5CC,GAAsB,EAY1B,GAV+B,IAA3BrxC,EAAeimC,SAA4C,IAA3BjmC,EAAekmC,UAC/CkL,EAAiB7oC,OAAS,CAACvI,EAAeimC,QAASjmC,EAAekmC,SAClEmL,GAAsB,GAGI,IAA1BrxC,EAAemmC,QAA0C,IAA1BnmC,EAAeomC,SAC9CgL,EAAiBlvC,MAAQ,CAAClC,EAAemmC,OAAQnmC,EAAeomC,QAChEiL,GAAsB,GAGE,IAAxBrxC,EAAeqmC,KAAY,CAC3B,GAAuC,IAAnCrmC,EAAekxC,iBAA4D,IAAnClxC,EAAemxC,gBAAuB,CAE9E,GAAInxC,EAAesxC,kCAAoCtxC,EAAemmC,SAAWnmC,EAAeomC,OAI5F,YAHA,EAAArqC,MAAM4I,KACF,UAAGqqB,EAAO,qBAAahvB,EAAewE,KAAI,qHAA6G,GAAI,MAInK,EAAAzI,MAAM4I,KAAK,UAAGqqB,EAAO,qBAAahvB,EAAewE,KAAI,2FAAmF,GAAI,MAC5I4sC,EAAiB7oC,OA/EjC,SAAuCvI,GAC3B,IAAAimC,EAA6EjmC,EAAc,QAAlFkmC,EAAoElmC,EAAc,QAAzEkxC,EAA2DlxC,EAAc,gBAAxDmxC,EAA0CnxC,EAAc,gBAAvCmmC,EAAyBnmC,EAAc,OAA/BomC,EAAiBpmC,EAAc,OAAvBqmC,EAASrmC,EAAc,KAC7FuxC,EAAW9vC,KAAK+vC,IAAInL,GACpBoL,EAAWhwC,KAAKiwC,IAAIrL,GACpBsL,EAAwBT,EAAkB/K,EAC1CyL,EAAwBT,EAAkB/K,EAGhD,MAAO,CAACH,GAFO0L,GAAyB,EAAIJ,GAAYK,EAAwBH,GAEtDvL,GADX0L,GAAyB,EAAIL,GAAYI,EAAwBF,GAEpF,CAsE0CI,CAA8B7xC,EAC5D,CACAoxC,EAAiBh6B,UAAYpX,EAAeqmC,KAC5CgL,GAAsB,CAC1B,CAEwC,IAApCrxC,EAAeuO,mBACf6iC,EAAiB5hC,SAAWxP,EAAeuO,iBAC3C8iC,GAAsB,GAGrBA,IAIL33C,KAAK0kC,UAAW,EACXp5B,EAAYyK,aACbzK,EAAYyK,WAAa,CAAC,GAE9BzK,EAAYyK,WAAW,IAAQ2hC,EA5C/B,CA6CJ,EACJ,EArFA,GAuFAviB,GAAayB,kBAAkB,IAAM,WAAM,WAAIwhB,EAAJ,IC3G3C,IAAM,GAAO,qBAMb,cAeI,WAAYlU,GAdI,KAAAp5B,KAAO,GAEhB,KAAAqrB,SAAU,EAEV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,EASf1kC,KAAKoK,UAAY85B,CACrB,CAyBJ,OAjCI,sBAAW,sBAAO,C,IAAlB,WACI,OAAOlkC,KAAK0kC,QAChB,E,gCAQO,YAAA/N,QAAP,WAAkB,EAEX,YAAAhB,kBAAP,SAAyBvxB,EAAWkH,GAChC,IAAMyB,EAAU/M,KAAKoK,UAAUqK,UAAUnJ,EAAYS,OAC/C4I,EAAa5H,EAAQtG,OAC3B,QAAmBnG,IAAfqU,EAAJ,CAIA,IAAM+C,EAAQ1X,KAAKoK,UAAUoN,QAAQ7C,GAEd,gBADA+C,EAAMtR,WAAY,IAAAhE,aAAYsV,EAAMU,QAK3DrL,EAAQtG,YAASnG,EACjByM,EAAQgJ,aAARhJ,EAAQgJ,WAAe,CAAC,GACxBhJ,EAAQgJ,WAAW,IAAQ,CACvBtP,OAAQkO,GAGZ3U,KAAK0kC,UAAW,EAdhB,CAeJ,EACJ,EA1CA,GA4CAvP,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAImU,GAAmBnU,EAAvB,IClDnD,IAAM,GAAO,mBAMb,cAeI,WAAYA,GAdI,KAAAp5B,KAAO,GAEhB,KAAAqrB,SAAU,EAEV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,EASf1kC,KAAKoK,UAAY85B,CACrB,CAyBJ,OAjCI,sBAAW,sBAAO,C,IAAlB,WACI,OAAOlkC,KAAK0kC,QAChB,E,gCAQO,YAAA/N,QAAP,WAAkB,EAEX,YAAAhB,kBAAP,SAAyBvxB,EAAWkH,GAChC,IAAMyB,EAAU/M,KAAKoK,UAAUqK,UAAUnJ,EAAYS,OAC/C4I,EAAa5H,EAAQtG,OAC3B,QAAmBnG,IAAfqU,EAAJ,CAIA,IAAM+C,EAAQ1X,KAAKoK,UAAUoN,QAAQ7C,GAEd,gBADA+C,EAAMtR,WAAY,IAAAhE,aAAYsV,EAAMU,QAK3DrL,EAAQtG,YAASnG,EACjByM,EAAQgJ,aAARhJ,EAAQgJ,WAAe,CAAC,GACxBhJ,EAAQgJ,WAAW,IAAQ,CACvBtP,OAAQkO,GAGZ3U,KAAK0kC,UAAW,EAdhB,CAeJ,EACJ,EA1CA,GA4CAvP,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIoU,GAAiBpU,EAArB,IClDnD,IAAM,GAAO,mBAOb,cAeI,WAAYA,GAdI,KAAAp5B,KAAO,GAEhB,KAAAqrB,SAAU,EAEV,KAAAI,UAAW,EAEV,KAAAmO,UAAW,EASf1kC,KAAKoK,UAAY85B,CACrB,CAyBJ,OAjCI,sBAAW,sBAAO,C,IAAlB,WACI,OAAOlkC,KAAK0kC,QAChB,E,gCAQO,YAAA/N,QAAP,WAAkB,EAEX,YAAAhB,kBAAP,SAAyBvxB,EAAWkH,GAChC,IAAMyB,EAAU/M,KAAKoK,UAAUqK,UAAUnJ,EAAYS,OAC/C4I,EAAa5H,EAAQtG,OAC3B,QAAmBnG,IAAfqU,EAAJ,CAIA,IAAM+C,EAAQ1X,KAAKoK,UAAUoN,QAAQ7C,GAEd,gBADA+C,EAAMtR,WAAY,IAAAhE,aAAYsV,EAAMU,QAK3DrL,EAAQtG,YAASnG,EACjByM,EAAQgJ,aAARhJ,EAAQgJ,WAAe,CAAC,GACxBhJ,EAAQgJ,WAAW,IAAQ,CACvBtP,OAAQkO,GAGZ3U,KAAK0kC,UAAW,EAdhB,CAeJ,EACJ,EA1CA,GA4CAvP,GAAayB,kBAAkB,IAAM,SAACsN,GAAa,WAAIqU,GAAiBrU,EAArB,IC/CnD,IAAMsU,QAAiC,IAAX,EAAAx3C,EAAyB,EAAAA,EAA2B,oBAAXI,OAAyBA,YAASd,EACvG,QAA4B,IAAjBk4C,GAA8B,CAC/BA,GAAcC,QAAgBD,GAAcC,SAAW,CAAC,EAC9D,IAAM,GAAgBD,GAAcC,QACpC,GAAQC,MAAQ,GAAQA,OAAS,CAAC,EAClC,GAAQA,MAAMC,SAAW,GAAQD,MAAMC,UAAY,CAAC,EACpD,GAAQD,MAAMC,SAASC,WAAa,GAAQF,MAAMC,SAASC,YAAc,CAAC,EAE1E,IAAMh2B,GAAO,GACb,IAAK,IAAMliB,MAAO,EACd,GAAQA,IAAa,EAAWA,IAChCkiB,GAAK3d,KAAKvE,IAEd,IAAK,IAAMA,MAAO,EACd,GAAQA,IAAa,EAAOA,IAC5BkiB,GAAK3d,KAAKvE,IAEd,IAAK,IAAMA,MAAO,EACd,GAAQA,IAAa,EAAaA,IAClCkiB,GAAK3d,KAAKvE,IAGd,IAAK,IAAMA,MAAO,EACd,GAAQg4C,MAAMC,SAASC,WAAWl4C,IAAa,EAAYA,IAC3DkiB,GAAK3d,KAAKvE,IAGd,IAAK,IAAMA,MAAO,EAEVkiB,GAAKwP,QAAQ1xB,KAAQ,IAIzB,GAAQg4C,MAAMC,SAASj4C,IAAa,EAAOA,IAEnD,CC5CA,W","sources":["webpack://SERIALIZERS/webpack/universalModuleDefinition","webpack://SERIALIZERS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://SERIALIZERS/webpack/bootstrap","webpack://SERIALIZERS/webpack/runtime/define property getters","webpack://SERIALIZERS/webpack/runtime/global","webpack://SERIALIZERS/webpack/runtime/hasOwnProperty shorthand","webpack://SERIALIZERS/webpack/runtime/make namespace object","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/glTFFileExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFData.ts","webpack://SERIALIZERS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/exportUtils.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/dataWriter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/bufferManager.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMorphTargetsUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_lights_area.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_coat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_fuzz.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_basisu.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_texture_webp.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_texture_avif.ts","webpack://SERIALIZERS/../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts","webpack://SERIALIZERS/./src/glTF2.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-serializers\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-serializers\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"SERIALIZERS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtension = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for extending the exporter\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtension {\r\n /**\r\n * The name of this extension\r\n */\r\n readonly name: string;\r\n /**\r\n * Defines whether this extension is enabled\r\n */\r\n enabled: boolean;\r\n\r\n /**\r\n * Defines whether this extension is required\r\n */\r\n required: boolean;\r\n}\r\n","import { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Class for holding and downloading glTF file data\r\n */\r\nexport class GLTFData {\r\n /**\r\n * Object which contains the file name as the key and its data as the value\r\n */\r\n public readonly files: { [fileName: string]: string | Blob } = {};\r\n\r\n /**\r\n * @deprecated Use files instead\r\n */\r\n public get glTFFiles() {\r\n return this.files;\r\n }\r\n\r\n /**\r\n * Downloads the glTF data as files based on their names and data\r\n */\r\n public downloadFiles(): void {\r\n for (const key in this.files) {\r\n const value = this.files[key];\r\n const blob = new Blob([value], { type: GetMimeType(key) });\r\n Tools.Download(blob, key);\r\n }\r\n }\r\n}\r\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\r\n/* eslint-disable github/no-then */\r\n/* eslint-disable babylonjs/available */\r\n\r\nimport type { ITextureInfo, IMaterial, IMaterialPbrMetallicRoughness, IMaterialOcclusionTextureInfo, ISampler, IImage } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType, MaterialAlphaMode, TextureMagFilter, TextureMinFilter, TextureWrapMode } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { DeepImmutable, Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { GetTextureDataAsync, TextureTools } from \"core/Misc/textureTools\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\nimport type { Scene } from \"core/scene\";\r\n\r\nimport type { GLTFExporter } from \"./glTFExporter\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EncodeImageAsync } from \"core/Misc/dumpTools\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { SpecularPowerToRoughness } from \"core/Helpers/materialConversionHelper\";\r\nimport { InternalTextureSource } from \"core/Materials/Textures/internalTexture\";\r\nimport { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\n\r\nconst Epsilon = 1e-6;\r\nconst DielectricSpecular = new Color3(0.04, 0.04, 0.04) as DeepImmutable<Color3>;\r\nconst MaxSpecularPower = 1024;\r\nconst White = Color3.White() as DeepImmutable<Color3>;\r\nconst Black = Color3.BlackReadOnly;\r\n\r\n/**\r\n * Interface for storing specular glossiness factors\r\n * @internal\r\n */\r\ninterface IPBRSpecularGlossiness {\r\n /**\r\n * Represents the linear diffuse factors of the material\r\n */\r\n diffuseColor: Color3;\r\n specularColor: Color3;\r\n glossiness: number;\r\n}\r\n\r\ninterface IPBRMetallicRoughness {\r\n baseColor: Color3;\r\n metallic: Nullable<number>;\r\n roughness: Nullable<number>;\r\n metallicRoughnessTextureData?: Nullable<Blob>;\r\n baseColorTextureData?: Nullable<Blob>;\r\n}\r\n\r\nfunction GetFileExtensionFromMimeType(mimeType: ImageMimeType): string {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n return \".jpg\";\r\n case ImageMimeType.PNG:\r\n return \".png\";\r\n case ImageMimeType.WEBP:\r\n return \".webp\";\r\n case ImageMimeType.AVIF:\r\n return \".avif\";\r\n case ImageMimeType.KTX2:\r\n return \".ktx2\";\r\n }\r\n}\r\n\r\n/**\r\n * @param mimeType the MIME type requested by the user\r\n * @returns true if the given mime type is compatible with glTF\r\n */\r\nfunction IsSupportedMimeType(mimeType?: string): mimeType is ImageMimeType {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n case ImageMimeType.PNG:\r\n case ImageMimeType.WEBP:\r\n case ImageMimeType.AVIF:\r\n case ImageMimeType.KTX2:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Gets cached image from a texture, if available.\r\n * @param babylonTexture texture to check for cached image\r\n * @returns image data if found and directly usable; null otherwise\r\n */\r\nasync function GetCachedImageAsync(babylonTexture: BaseTexture): Promise<Nullable<Blob>> {\r\n const internalTexture = babylonTexture.getInternalTexture();\r\n if (!internalTexture || internalTexture.source !== InternalTextureSource.Url) {\r\n return null;\r\n }\r\n if (internalTexture.invertY) {\r\n return null;\r\n }\r\n\r\n const buffer = internalTexture._buffer;\r\n\r\n let data;\r\n let mimeType = (babylonTexture as Texture).mimeType;\r\n\r\n if (!buffer) {\r\n data = await Tools.LoadFileAsync(internalTexture.url);\r\n mimeType = GetMimeType(internalTexture.url) || mimeType;\r\n } else if (ArrayBuffer.isView(buffer)) {\r\n data = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\r\n } else if (buffer instanceof ArrayBuffer) {\r\n data = buffer;\r\n } else if (buffer instanceof Blob) {\r\n data = await buffer.arrayBuffer();\r\n mimeType = buffer.type || mimeType;\r\n } else if (typeof buffer === \"string\") {\r\n data = await Tools.LoadFileAsync(buffer);\r\n mimeType = GetMimeType(buffer) || mimeType;\r\n } else if (typeof HTMLImageElement !== \"undefined\" && buffer instanceof HTMLImageElement) {\r\n data = await Tools.LoadFileAsync(buffer.src);\r\n mimeType = GetMimeType(buffer.src) || mimeType;\r\n }\r\n\r\n if (data && IsSupportedMimeType(mimeType)) {\r\n return new Blob([data], { type: mimeType });\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Computes the metallic factor from specular glossiness values.\r\n * @param diffuse diffused value\r\n * @param specular specular value\r\n * @param oneMinusSpecularStrength one minus the specular strength\r\n * @returns metallic value\r\n * @internal\r\n */\r\nexport function _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number {\r\n if (specular < DielectricSpecular.r) {\r\n return 0;\r\n }\r\n\r\n const a = DielectricSpecular.r;\r\n const b = (diffuse * oneMinusSpecularStrength) / (1.0 - DielectricSpecular.r) + specular - 2.0 * DielectricSpecular.r;\r\n const c = DielectricSpecular.r - specular;\r\n const d = b * b - 4.0 * a * c;\r\n return Scalar.Clamp((-b + Math.sqrt(d)) / (2.0 * a), 0, 1);\r\n}\r\n\r\n/**\r\n * Computes the metallic/roughness factors from a Standard Material.\r\n * @internal\r\n */\r\nexport function _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness {\r\n const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);\r\n const opacity = babylonStandardMaterial.alpha;\r\n const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, MaxSpecularPower);\r\n\r\n const roughness = SpecularPowerToRoughness(specularPower);\r\n\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {\r\n baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],\r\n metallicFactor: 0,\r\n roughnessFactor: roughness,\r\n };\r\n\r\n return glTFPbrMetallicRoughness;\r\n}\r\n\r\n/**\r\n * Sets the glTF alpha mode to a glTF material from the Babylon Material\r\n * @param glTFMaterial glTF material\r\n * @param babylonMaterial Babylon material\r\n */\r\nfunction SetAlphaMode(glTFMaterial: IMaterial, babylonMaterial: Material & { alphaCutOff?: number }): void {\r\n if (babylonMaterial.needAlphaBlending()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.BLEND;\r\n } else if (babylonMaterial.needAlphaTesting()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.MASK;\r\n glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;\r\n }\r\n}\r\n\r\nfunction CreateWhiteTexture(width: number, height: number, scene: Scene): Texture {\r\n const data = new Uint8Array(width * height * 4);\r\n\r\n for (let i = 0; i < data.length; i = i + 4) {\r\n data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;\r\n }\r\n\r\n const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);\r\n\r\n return rawTexture;\r\n}\r\n\r\nfunction ConvertPixelArrayToFloat32(pixels: ArrayBufferView): Float32Array {\r\n if (pixels instanceof Uint8Array) {\r\n const length = pixels.length;\r\n const buffer = new Float32Array(pixels.length);\r\n for (let i = 0; i < length; ++i) {\r\n buffer[i] = pixels[i] / 255;\r\n }\r\n return buffer;\r\n } else if (pixels instanceof Float32Array) {\r\n return pixels;\r\n } else {\r\n throw new Error(\"Unsupported pixel format!\");\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods for working with glTF material conversion properties.\r\n * @internal\r\n */\r\nexport class GLTFMaterialExporter {\r\n // Mapping to store textures\r\n private _textureMap = new Map<number, ITextureInfo>();\r\n\r\n // Mapping of internal textures to images to avoid exporting duplicate images\r\n private _internalTextureToImage: { [uniqueId: number]: { [mimeType: string]: Promise<number> } } = {};\r\n\r\n constructor(private readonly _exporter: GLTFExporter) {}\r\n\r\n public getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo> {\r\n return babylonTexture ? (this._textureMap.get(babylonTexture.uniqueId) ?? null) : null;\r\n }\r\n\r\n public async exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, hasUVs: boolean): Promise<number> {\r\n const pbrMetallicRoughness = _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);\r\n\r\n const material: IMaterial = { name: babylonStandardMaterial.name };\r\n if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {\r\n if (!babylonStandardMaterial.twoSidedLighting) {\r\n Tools.Warn(babylonStandardMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n material.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const diffuseTexture = babylonStandardMaterial.diffuseTexture;\r\n if (diffuseTexture) {\r\n promises.push(\r\n this.exportTextureAsync(diffuseTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n pbrMetallicRoughness.baseColorTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const bumpTexture = babylonStandardMaterial.bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.normalTexture = textureInfo;\r\n if (bumpTexture.level !== 1) {\r\n material.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonStandardMaterial.emissiveTexture;\r\n if (emissiveTexture) {\r\n material.emissiveFactor = [1.0, 1.0, 1.0];\r\n\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.emissiveTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonStandardMaterial.ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: textureInfo.index,\r\n };\r\n material.occlusionTexture = occlusionTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonStandardMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {\r\n if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {\r\n material.alphaMode = MaterialAlphaMode.BLEND;\r\n } else {\r\n Tools.Warn(babylonStandardMaterial.name + \": glTF 2.0 does not support alpha mode: \" + babylonStandardMaterial.alphaMode.toString());\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.emissiveColor && !babylonStandardMaterial.emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();\r\n }\r\n\r\n material.pbrMetallicRoughness = pbrMetallicRoughness;\r\n SetAlphaMode(material, babylonStandardMaterial);\r\n\r\n await this._finishMaterialAsync(material, babylonStandardMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(material);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _finishMaterialAsync(glTFMaterial: IMaterial, babylonMaterial: Material): Promise<void> {\r\n const textures = await this._exporter._extensionsPostExportMaterialAdditionalTexturesAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n\r\n const promises: Array<Promise<Nullable<ITextureInfo>>> = [];\r\n\r\n for (const texture of textures) {\r\n promises.push(this.exportTextureAsync(texture));\r\n }\r\n\r\n await Promise.all(promises);\r\n\r\n await this._exporter._extensionsPostExportMaterialAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n }\r\n\r\n /**\r\n * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null\r\n * @param texture1 first texture to resize\r\n * @param texture2 second texture to resize\r\n * @param scene babylonjs scene\r\n * @returns resized textures or null\r\n */\r\n private _resizeTexturesToSameDimensions(texture1: Nullable<BaseTexture>, texture2: Nullable<BaseTexture>, scene: Scene): { texture1: BaseTexture; texture2: BaseTexture } {\r\n const texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };\r\n const texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };\r\n let resizedTexture1: BaseTexture;\r\n let resizedTexture2: BaseTexture;\r\n\r\n if (texture1Size.width < texture2Size.width) {\r\n if (texture1 && texture1 instanceof Texture) {\r\n resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);\r\n } else {\r\n resizedTexture1 = CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);\r\n }\r\n resizedTexture2 = texture2!;\r\n } else if (texture1Size.width > texture2Size.width) {\r\n if (texture2 && texture2 instanceof Texture) {\r\n resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);\r\n } else {\r\n resizedTexture2 = CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);\r\n }\r\n resizedTexture1 = texture1!;\r\n } else {\r\n resizedTexture1 = texture1!;\r\n resizedTexture2 = texture2!;\r\n }\r\n\r\n return {\r\n texture1: resizedTexture1!,\r\n texture2: resizedTexture2!,\r\n };\r\n }\r\n\r\n /**\r\n * Convert Specular Glossiness Textures to Metallic Roughness\r\n * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness\r\n * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js\r\n * @param diffuseTexture texture used to store diffuse information\r\n * @param specularGlossinessTexture texture used to store specular and glossiness information\r\n * @param factors specular glossiness material factors\r\n * @returns pbr metallic roughness interface or null\r\n */\r\n private async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(\r\n diffuseTexture: Nullable<BaseTexture>,\r\n specularGlossinessTexture: Nullable<BaseTexture>,\r\n factors: IPBRSpecularGlossiness\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises = new Array<Promise<void>>();\r\n if (!(diffuseTexture || specularGlossinessTexture)) {\r\n return await Promise.reject(\"diffuse and specular glossiness textures are not defined!\");\r\n }\r\n\r\n const scene: Nullable<Scene> = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null;\r\n if (scene) {\r\n const resizedTextures = this._resizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);\r\n\r\n const diffuseSize = resizedTextures.texture1?.getSize();\r\n\r\n let diffuseBuffer: Float32Array;\r\n let specularGlossinessBuffer: Float32Array;\r\n\r\n const width = diffuseSize.width;\r\n const height = diffuseSize.height;\r\n\r\n const diffusePixels = await resizedTextures.texture1.readPixels();\r\n const specularPixels = await resizedTextures.texture2.readPixels();\r\n\r\n if (diffusePixels) {\r\n diffuseBuffer = ConvertPixelArrayToFloat32(diffusePixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from diffuse texture!\");\r\n }\r\n if (specularPixels) {\r\n specularGlossinessBuffer = ConvertPixelArrayToFloat32(specularPixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from specular glossiness texture!\");\r\n }\r\n\r\n const byteLength = specularGlossinessBuffer.byteLength;\r\n\r\n const metallicRoughnessBuffer = new Uint8Array(byteLength);\r\n const baseColorBuffer = new Uint8Array(byteLength);\r\n\r\n const strideSize = 4;\r\n const maxBaseColor = new Color3(0, 0, 0);\r\n let maxMetallic = 0;\r\n let maxRoughness = 0;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const offset = (width * h + w) * strideSize;\r\n\r\n const diffuseColor = new Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.diffuseColor);\r\n const specularColor = new Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.specularColor);\r\n const glossiness = specularGlossinessBuffer[offset + 3] * factors.glossiness;\r\n\r\n const specularGlossiness: IPBRSpecularGlossiness = {\r\n diffuseColor: diffuseColor,\r\n specularColor: specularColor,\r\n glossiness: glossiness,\r\n };\r\n\r\n const metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);\r\n maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);\r\n maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);\r\n maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);\r\n maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic!);\r\n maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness!);\r\n\r\n baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;\r\n baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;\r\n baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;\r\n baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;\r\n\r\n metallicRoughnessBuffer[offset] = 0;\r\n metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness! * 255;\r\n metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic! * 255;\r\n metallicRoughnessBuffer[offset + 3] = 255;\r\n }\r\n }\r\n\r\n // Retrieves the metallic roughness factors from the maximum texture values.\r\n const metallicRoughnessFactors: IPBRMetallicRoughness = {\r\n baseColor: maxBaseColor,\r\n metallic: maxMetallic,\r\n roughness: maxRoughness,\r\n };\r\n\r\n let writeOutMetallicRoughnessTexture = false;\r\n let writeOutBaseColorTexture = false;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const destinationOffset = (width * h + w) * strideSize;\r\n\r\n baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > Epsilon ? metallicRoughnessFactors.baseColor.r : 1;\r\n baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > Epsilon ? metallicRoughnessFactors.baseColor.g : 1;\r\n baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > Epsilon ? metallicRoughnessFactors.baseColor.b : 1;\r\n\r\n const linearBaseColorPixel = Color3.FromInts(\r\n baseColorBuffer[destinationOffset],\r\n baseColorBuffer[destinationOffset + 1],\r\n baseColorBuffer[destinationOffset + 2]\r\n );\r\n const sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions);\r\n baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;\r\n baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;\r\n baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;\r\n\r\n if (!sRGBBaseColorPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutBaseColorTexture = true;\r\n }\r\n\r\n metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness! > Epsilon ? metallicRoughnessFactors.roughness! : 1;\r\n metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic! > Epsilon ? metallicRoughnessFactors.metallic! : 1;\r\n\r\n const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);\r\n\r\n if (!metallicRoughnessPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutMetallicRoughnessTexture = true;\r\n }\r\n }\r\n }\r\n\r\n if (writeOutMetallicRoughnessTexture) {\r\n promises.push(\r\n EncodeImageAsync(metallicRoughnessBuffer, width, height).then((data) => {\r\n metallicRoughnessFactors.metallicRoughnessTextureData = data;\r\n })\r\n );\r\n }\r\n if (writeOutBaseColorTexture) {\r\n promises.push(\r\n EncodeImageAsync(baseColorBuffer, width, height).then((data) => {\r\n metallicRoughnessFactors.baseColorTextureData = data;\r\n })\r\n );\r\n }\r\n\r\n return await Promise.all(promises).then(() => {\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return await Promise.reject(\"_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!\");\r\n }\r\n }\r\n\r\n /**\r\n * Converts specular glossiness material properties to metallic roughness\r\n * @param specularGlossiness interface with specular glossiness material properties\r\n * @returns interface with metallic roughness material properties\r\n */\r\n private _convertSpecularGlossinessToMetallicRoughness(specularGlossiness: IPBRSpecularGlossiness): IPBRMetallicRoughness {\r\n const diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor);\r\n const specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor);\r\n const oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor);\r\n const metallic = _SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);\r\n const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - DielectricSpecular.r) / Math.max(1 - metallic, Epsilon));\r\n const baseColorFromSpecular = specularGlossiness.specularColor.subtract(DielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, Epsilon));\r\n let baseColor = Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);\r\n baseColor = baseColor.clampToRef(0, 1, baseColor);\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: 1 - specularGlossiness.glossiness,\r\n };\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n /**\r\n * Calculates the surface reflectance, independent of lighting conditions\r\n * @param color Color source to calculate brightness from\r\n * @returns number representing the perceived brightness, or zero if color is undefined\r\n */\r\n private _getPerceivedBrightness(color: Color3): number {\r\n return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);\r\n }\r\n\r\n /**\r\n * Returns the maximum color component value\r\n * @param color\r\n * @returns maximum color component value, or zero if color is null or undefined\r\n */\r\n private _getMaxComponent(color: Color3): number {\r\n return Math.max(color.r, Math.max(color.g, color.b));\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors\r\n * @param baseColor Base color of the material\r\n * @param metallic Metallic factor of the material\r\n * @param roughness Roughness factor of the material\r\n * @param albedoTexture Albedo texture of the material\r\n * @param metallicTexture Metallic texture of the material\r\n * @param roughnessTexture Roughness texture of the material\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n baseColor: Color3,\r\n metallic: Nullable<number>,\r\n roughness: Nullable<number>,\r\n albedoTexture: Nullable<BaseTexture>,\r\n metallicTexture: Nullable<BaseTexture>,\r\n roughnessTexture: Nullable<BaseTexture>,\r\n babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises: Promise<void>[] = [];\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: roughness,\r\n };\r\n\r\n if (hasUVs) {\r\n if (babylonPBRMaterial instanceof OpenPBRMaterial) {\r\n if (babylonPBRMaterial.geometryOpacityTexture) {\r\n // Merge baseColor and opacity\r\n const albedoId = albedoTexture && albedoTexture.getInternalTexture() ? albedoTexture.getInternalTexture()!.uniqueId : 0;\r\n const opacityId =\r\n babylonPBRMaterial.geometryOpacityTexture && babylonPBRMaterial.geometryOpacityTexture.getInternalTexture()\r\n ? babylonPBRMaterial.geometryOpacityTexture.getInternalTexture()!.uniqueId\r\n : 0;\r\n const mergedId = Number(`${albedoId}${opacityId}`);\r\n const glTFTexture = this._textureMap.get(mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n } else {\r\n promises.push(\r\n MergeTexturesAsync(\r\n \"baseColorOpacityTexture\",\r\n CreateRGBAConfiguration(\r\n albedoTexture ? CreateTextureInput(albedoTexture, 0) : CreateConstantInput(1.0),\r\n albedoTexture ? CreateTextureInput(albedoTexture, 1) : CreateConstantInput(1.0),\r\n albedoTexture ? CreateTextureInput(albedoTexture, 2) : CreateConstantInput(1.0),\r\n CreateTextureInput(babylonPBRMaterial.geometryOpacityTexture, 0)\r\n ),\r\n babylonPBRMaterial.getScene()\r\n ).then(async (mergedTexture) => {\r\n const glTFTexture = await this.exportTextureAsync(mergedTexture, mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n } else {\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(albedoTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n if (babylonPBRMaterial._useMetallicFromMetallicTextureBlue && metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n } else if (roughnessTexture || metallicTexture) {\r\n const metallicId = metallicTexture && metallicTexture.getInternalTexture() ? metallicTexture.getInternalTexture()!.uniqueId : 0;\r\n const roughnessId = roughnessTexture && roughnessTexture.getInternalTexture() ? roughnessTexture.getInternalTexture()!.uniqueId : 0;\r\n const mergedId = Number(`${metallicId}${roughnessId}`);\r\n const glTFTexture = this._textureMap.get(mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n } else {\r\n promises.push(\r\n MergeTexturesAsync(\r\n \"MetalRoughTexture\",\r\n CreateRGBAConfiguration(\r\n babylonPBRMaterial.ambientOcclusionTexture ? CreateTextureInput(babylonPBRMaterial.ambientOcclusionTexture, 0) : CreateConstantInput(1.0),\r\n roughnessTexture ? CreateTextureInput(roughnessTexture, 0) : CreateConstantInput(1.0),\r\n metallicTexture ? CreateTextureInput(metallicTexture, 0) : CreateConstantInput(1.0)\r\n ),\r\n babylonPBRMaterial.getScene()\r\n ).then(async (mergedTexture) => {\r\n const glTFTexture = await this.exportTextureAsync(mergedTexture, mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n } else {\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(albedoTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n if (metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n private _getTextureSampler(texture: Nullable<BaseTexture>): ISampler {\r\n const sampler: ISampler = {};\r\n if (!texture || !(texture instanceof Texture)) {\r\n return sampler;\r\n }\r\n\r\n const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);\r\n if (wrapS !== TextureWrapMode.REPEAT) {\r\n sampler.wrapS = wrapS;\r\n }\r\n\r\n const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);\r\n if (wrapT !== TextureWrapMode.REPEAT) {\r\n sampler.wrapT = wrapT;\r\n }\r\n\r\n switch (texture.samplingMode) {\r\n case Texture.LINEAR_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n }\r\n\r\n return sampler;\r\n }\r\n\r\n private _getGLTFTextureWrapMode(wrapMode: number): TextureWrapMode {\r\n switch (wrapMode) {\r\n case Texture.WRAP_ADDRESSMODE: {\r\n return TextureWrapMode.REPEAT;\r\n }\r\n case Texture.CLAMP_ADDRESSMODE: {\r\n return TextureWrapMode.CLAMP_TO_EDGE;\r\n }\r\n case Texture.MIRROR_ADDRESSMODE: {\r\n return TextureWrapMode.MIRRORED_REPEAT;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Texture Wrap Mode ${wrapMode}!`);\r\n return TextureWrapMode.REPEAT;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertSpecGlossFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n pbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const specGloss: IPBRSpecularGlossiness = {\r\n diffuseColor: babylonPBRMaterial._albedoColor,\r\n specularColor: babylonPBRMaterial._reflectivityColor,\r\n glossiness: babylonPBRMaterial._microSurface,\r\n };\r\n\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;\r\n const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;\r\n if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {\r\n return await Promise.reject(\"_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported\");\r\n }\r\n\r\n if ((albedoTexture || reflectivityTexture) && hasUVs) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n\r\n const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);\r\n const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss);\r\n\r\n const textures = this._exporter._textures;\r\n\r\n if (metallicRoughnessFactors.baseColorTextureData) {\r\n const imageIndex = await this._exportImageAsync(`baseColor${textures.length}`, metallicRoughnessFactors.baseColorTextureData);\r\n pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);\r\n }\r\n\r\n if (metallicRoughnessFactors.metallicRoughnessTextureData) {\r\n const imageIndex = await this._exportImageAsync(`metallicRoughness${textures.length}`, metallicRoughnessFactors.metallicRoughnessTextureData);\r\n pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);\r\n }\r\n\r\n return metallicRoughnessFactors;\r\n } else {\r\n return this._convertSpecularGlossinessToMetallicRoughness(specGloss);\r\n }\r\n }\r\n\r\n public async exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonPBRMaterial.name,\r\n };\r\n\r\n const useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();\r\n\r\n if (useMetallicRoughness) {\r\n const albedoColor = babylonPBRMaterial._albedoColor;\r\n const alpha = babylonPBRMaterial.alpha;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n }\r\n\r\n const metallicRoughness = useMetallicRoughness\r\n ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial._albedoColor,\r\n babylonPBRMaterial._metallic,\r\n babylonPBRMaterial._roughness,\r\n babylonPBRMaterial._albedoTexture,\r\n babylonPBRMaterial._metallicTexture,\r\n babylonPBRMaterial._metallicTexture,\r\n babylonPBRMaterial,\r\n glTFPbrMetallicRoughness,\r\n hasUVs\r\n )\r\n : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _setMetallicRoughnessPbrMaterialAsync(\r\n metallicRoughness: IPBRMetallicRoughness,\r\n babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,\r\n glTFMaterial: IMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<void> {\r\n SetAlphaMode(glTFMaterial, babylonPBRMaterial);\r\n\r\n if (!metallicRoughness.baseColor.equalsWithEpsilon(White, Epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, Epsilon)) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];\r\n }\r\n\r\n if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {\r\n glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;\r\n }\r\n if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {\r\n glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;\r\n }\r\n\r\n if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {\r\n if (!babylonPBRMaterial._twoSidedLighting) {\r\n Tools.Warn(babylonPBRMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n glTFMaterial.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const bumpTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._bumpTexture : babylonPBRMaterial.geometryNormalTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.normalTexture = glTFTexture;\r\n if (bumpTexture.level !== 1) {\r\n glTFMaterial.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._ambientTexture : babylonPBRMaterial.ambientOcclusionTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n new Promise<Nullable<ITextureInfo>>(async (resolve) => {\r\n if (babylonPBRMaterial instanceof OpenPBRMaterial && glTFPbrMetallicRoughness.metallicRoughnessTexture) {\r\n // The metallicRoughnessTexture already contains the ambient occlusion data in its red channel, we don't need to export it again\r\n // However, we still need to set the texture info on the material.\r\n const samplerIndex = this._exportTextureSampler(ambientTexture);\r\n const imageIndex = this._exporter._textures[glTFPbrMetallicRoughness.metallicRoughnessTexture.index].source!;\r\n const textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, ambientTexture.coordinatesIndex);\r\n this._textureMap.set(ambientTexture.uniqueId, textureInfo);\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, ambientTexture);\r\n return resolve(textureInfo);\r\n } else {\r\n return resolve(await this.exportTextureAsync(ambientTexture));\r\n }\r\n }).then(async (glTFTexture) => {\r\n if (glTFTexture) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: glTFTexture.index,\r\n texCoord: glTFTexture.texCoord,\r\n extensions: glTFTexture.extensions,\r\n };\r\n\r\n glTFMaterial.occlusionTexture = occlusionTexture;\r\n if (babylonPBRMaterial instanceof PBRBaseMaterial) {\r\n occlusionTexture.strength = babylonPBRMaterial._ambientTextureStrength;\r\n } else {\r\n occlusionTexture.strength = babylonPBRMaterial.ambientOcclusionTexture!.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveTexture : babylonPBRMaterial.emissionColorTexture;\r\n if (emissiveTexture) {\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.emissiveTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n const emissiveColor = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveColor : babylonPBRMaterial.emissionColor;\r\n if (!emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n glTFMaterial.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n }\r\n\r\n public async exportOpenPBRMaterialAsync(babylonOpenPBRMaterial: OpenPBRMaterial, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonOpenPBRMaterial.name,\r\n };\r\n\r\n const albedoColor = babylonOpenPBRMaterial.baseColor;\r\n const alpha = babylonOpenPBRMaterial.geometryOpacity;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n\r\n const metallicRoughness = await this._convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonOpenPBRMaterial.baseColor,\r\n babylonOpenPBRMaterial.baseMetalness,\r\n babylonOpenPBRMaterial.specularRoughness,\r\n babylonOpenPBRMaterial.baseColorTexture,\r\n babylonOpenPBRMaterial.baseMetalnessTexture,\r\n babylonOpenPBRMaterial.specularRoughnessTexture,\r\n babylonOpenPBRMaterial,\r\n glTFPbrMetallicRoughness,\r\n hasUVs\r\n );\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonOpenPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonOpenPBRMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n public async exportTextureAsync(babylonTexture: BaseTexture, overrideId: Nullable<number> = null): Promise<Nullable<ITextureInfo>> {\r\n let textureInfo = this._textureMap.get(overrideId ?? babylonTexture.uniqueId);\r\n if (textureInfo) {\r\n return textureInfo;\r\n }\r\n\r\n const samplerIndex = this._exportTextureSampler(babylonTexture);\r\n const imageIndex = await this._exportTextureImageAsync(babylonTexture);\r\n\r\n textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, babylonTexture.coordinatesIndex);\r\n this._textureMap.set(overrideId ?? babylonTexture.uniqueId, textureInfo);\r\n\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, babylonTexture);\r\n return textureInfo;\r\n }\r\n\r\n private async _exportTextureImageAsync(babylonTexture: BaseTexture): Promise<number> {\r\n const requestedMimeType = (babylonTexture as Texture).mimeType ?? \"none\";\r\n // TODO: Add an official way for users to export using a different mime type\r\n // than the one they loaded with (which is denoted by Texture.mimeType)\r\n\r\n const internalTextureToImage = this._internalTextureToImage;\r\n const internalTextureUniqueId = babylonTexture.getInternalTexture()!.uniqueId;\r\n internalTextureToImage[internalTextureUniqueId] = internalTextureToImage[internalTextureUniqueId] || {};\r\n let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][requestedMimeType];\r\n\r\n if (imageIndexPromise === undefined) {\r\n imageIndexPromise = (async () => {\r\n // Try to get the image from memory first, if applicable\r\n const cache = await GetCachedImageAsync(babylonTexture);\r\n if (cache && (requestedMimeType === \"none\" || cache.type === requestedMimeType)) {\r\n return await this._exportImageAsync(babylonTexture.name, cache);\r\n }\r\n\r\n // Preserve texture mime type if defined\r\n let mimeType = ImageMimeType.PNG;\r\n if (requestedMimeType !== \"none\") {\r\n if (IsSupportedMimeType(requestedMimeType)) {\r\n mimeType = requestedMimeType;\r\n } else {\r\n mimeType = ImageMimeType.PNG;\r\n Tools.Warn(`Unsupported media type: ${requestedMimeType}. Exporting texture as PNG.`);\r\n }\r\n }\r\n\r\n const size = babylonTexture.getSize();\r\n const pixels = await GetTextureDataAsync(babylonTexture);\r\n const imageData = await EncodeImageAsync(pixels, size.width, size.height, mimeType);\r\n\r\n return await this._exportImageAsync(babylonTexture.name, imageData);\r\n })();\r\n\r\n internalTextureToImage[internalTextureUniqueId][requestedMimeType] = imageIndexPromise;\r\n }\r\n\r\n return await imageIndexPromise;\r\n }\r\n\r\n private async _exportImageAsync(name: string, imageData: Blob): Promise<number> {\r\n const images = this._exporter._images;\r\n\r\n let image: IImage;\r\n if (this._exporter._shouldUseGlb) {\r\n image = {\r\n name: name,\r\n mimeType: imageData.type as ImageMimeType,\r\n bufferView: undefined, // Will be updated later by BufferManager\r\n };\r\n const data = await imageData.arrayBuffer();\r\n const bufferView = this._exporter._bufferManager.createBufferView(new Uint8Array(data));\r\n this._exporter._bufferManager.setBufferView(image, bufferView);\r\n } else {\r\n // Build a unique URI\r\n const baseName = name.replace(/\\.\\/|\\/|\\.\\\\|\\\\/g, \"_\");\r\n const extension = GetFileExtensionFromMimeType(imageData.type as ImageMimeType);\r\n let fileName = baseName + extension;\r\n if (images.some((image) => image.uri === fileName)) {\r\n fileName = `${baseName}_${Tools.RandomId()}${extension}`;\r\n }\r\n\r\n image = {\r\n name: name,\r\n uri: fileName,\r\n };\r\n this._exporter._imageData[fileName] = imageData; // Save image data to be written to file later\r\n }\r\n\r\n images.push(image);\r\n\r\n return images.length - 1;\r\n }\r\n\r\n private _exportTextureInfo(imageIndex: number, samplerIndex: number, coordinatesIndex?: number): ITextureInfo {\r\n const textures = this._exporter._textures;\r\n let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);\r\n if (textureIndex === -1) {\r\n textureIndex = textures.length;\r\n textures.push({\r\n source: imageIndex,\r\n sampler: samplerIndex,\r\n });\r\n }\r\n\r\n const textureInfo: ITextureInfo = { index: textureIndex };\r\n if (coordinatesIndex) {\r\n textureInfo.texCoord = coordinatesIndex;\r\n }\r\n return textureInfo;\r\n }\r\n\r\n private _exportTextureSampler(texture: Nullable<BaseTexture>): number {\r\n const sampler = this._getTextureSampler(texture);\r\n\r\n // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler\r\n const samplers = this._exporter._samplers;\r\n const samplerIndex = samplers.findIndex(\r\n (s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT\r\n );\r\n if (samplerIndex !== -1) {\r\n return samplerIndex;\r\n }\r\n\r\n samplers.push(sampler);\r\n return samplers.length - 1;\r\n }\r\n}\r\n","import { Matrix, Quaternion, TmpVectors, Vector3 } from \"core/Maths/math.vector\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { Node } from \"core/node\";\r\n\r\n/**\r\n * Matrix that converts handedness on the X-axis. Used to convert from LH to RH and vice versa.\r\n * @internal\r\n */\r\nexport const ConvertHandednessMatrix = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());\r\n\r\n/**\r\n * Checks if a node is a \"noop\" transform node, usually inserted by the glTF loader to correct handedness.\r\n * @internal\r\n */\r\nexport function IsNoopNode(node: Node, useRightHandedSystem: boolean): boolean {\r\n if (!(node instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Transform\r\n if (useRightHandedSystem) {\r\n const matrix = node.getWorldMatrix();\r\n if (!matrix.equalsWithEpsilon(Matrix.IdentityReadOnly, Epsilon)) {\r\n return false;\r\n }\r\n } else {\r\n const matrix = node.getWorldMatrix().multiplyToRef(ConvertHandednessMatrix, TmpVectors.Matrix[0]);\r\n if (!matrix.equalsWithEpsilon(Matrix.IdentityReadOnly, Epsilon)) {\r\n return false;\r\n }\r\n }\r\n\r\n // Geometry\r\n if (node instanceof AbstractMesh && node.geometry) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { INode } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, DataArray, IndicesArray, DeepImmutable } from \"core/types\";\r\nimport type { Vector4 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, TmpVectors, Matrix, Vector3 } from \"core/Maths/math.vector\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\nimport type { Node } from \"core/node\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { TargetCamera } from \"core/Cameras/targetCamera\";\r\nimport type { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { ConvertHandednessMatrix } from \"../../exportUtils\";\r\nimport type { AreaLight } from \"core/Lights/areaLight\";\r\n\r\n// Default values for comparison.\r\nexport const DefaultTranslation = Vector3.ZeroReadOnly;\r\nexport const DefaultRotation = Quaternion.Identity() as DeepImmutable<Quaternion>;\r\nexport const DefaultScale = Vector3.OneReadOnly;\r\nconst DefaultLoaderCameraParentScaleLh = new Vector3(-1, 1, 1) as DeepImmutable<Vector3>;\r\n\r\n/**\r\n * Get the information necessary for enumerating a vertex buffer.\r\n * @param vertexBuffer the vertex buffer to enumerate\r\n * @param meshes the meshes that use the vertex buffer\r\n * @returns the information necessary to enumerate the vertex buffer\r\n */\r\nexport function GetVertexBufferInfo(vertexBuffer: VertexBuffer, meshes: AbstractMesh[]) {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const componentCount = vertexBuffer.getSize();\r\n const totalVertices = meshes.reduce((max, current) => {\r\n return current.getTotalVertices() > max ? current.getTotalVertices() : max;\r\n }, -Number.MAX_VALUE); // Get the max total vertices count, to ensure we capture the full range of vertex data used by the meshes.\r\n const count = totalVertices * componentCount;\r\n const kind = vertexBuffer.getKind();\r\n\r\n return { byteOffset, byteStride, componentCount, type, count, normalized, totalVertices, kind };\r\n}\r\n\r\nexport function GetAccessorElementCount(accessorType: AccessorType): number {\r\n switch (accessorType) {\r\n case AccessorType.MAT2:\r\n return 4;\r\n case AccessorType.MAT3:\r\n return 9;\r\n case AccessorType.MAT4:\r\n return 16;\r\n case AccessorType.SCALAR:\r\n return 1;\r\n case AccessorType.VEC2:\r\n return 2;\r\n case AccessorType.VEC3:\r\n return 3;\r\n case AccessorType.VEC4:\r\n return 4;\r\n }\r\n}\r\n\r\nexport function FloatsNeed16BitInteger(floatArray: FloatArray): boolean {\r\n return floatArray.some((value) => value >= 256);\r\n}\r\n\r\nexport function IsStandardVertexAttribute(type: string): boolean {\r\n switch (type) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.ColorKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function GetAccessorType(kind: string, hasVertexColorAlpha: boolean): AccessorType {\r\n if (kind == VertexBuffer.ColorKind) {\r\n return hasVertexColorAlpha ? AccessorType.VEC4 : AccessorType.VEC3;\r\n }\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n return AccessorType.VEC3;\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return AccessorType.VEC4;\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return AccessorType.VEC2;\r\n }\r\n\r\n throw new Error(`Unknown kind ${kind}`);\r\n}\r\n\r\nexport function GetAttributeType(kind: string): string {\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n return \"POSITION\";\r\n case VertexBuffer.NormalKind:\r\n return \"NORMAL\";\r\n case VertexBuffer.TangentKind:\r\n return \"TANGENT\";\r\n case VertexBuffer.ColorKind:\r\n return \"COLOR_0\";\r\n case VertexBuffer.UVKind:\r\n return \"TEXCOORD_0\";\r\n case VertexBuffer.UV2Kind:\r\n return \"TEXCOORD_1\";\r\n case VertexBuffer.UV3Kind:\r\n return \"TEXCOORD_2\";\r\n case VertexBuffer.UV4Kind:\r\n return \"TEXCOORD_3\";\r\n case VertexBuffer.UV5Kind:\r\n return \"TEXCOORD_4\";\r\n case VertexBuffer.UV6Kind:\r\n return \"TEXCOORD_5\";\r\n case VertexBuffer.MatricesIndicesKind:\r\n return \"JOINTS_0\";\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n return \"JOINTS_1\";\r\n case VertexBuffer.MatricesWeightsKind:\r\n return \"WEIGHTS_0\";\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return \"WEIGHTS_1\";\r\n }\r\n\r\n throw new Error(`Unknown kind: ${kind}`);\r\n}\r\n\r\nexport function GetPrimitiveMode(fillMode: number): MeshPrimitiveMode {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n return MeshPrimitiveMode.TRIANGLES;\r\n case Material.TriangleStripDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_STRIP;\r\n case Material.TriangleFanDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_FAN;\r\n case Material.PointListDrawMode:\r\n case Material.PointFillMode:\r\n return MeshPrimitiveMode.POINTS;\r\n case Material.LineLoopDrawMode:\r\n return MeshPrimitiveMode.LINE_LOOP;\r\n case Material.LineListDrawMode:\r\n return MeshPrimitiveMode.LINES;\r\n case Material.LineStripDrawMode:\r\n return MeshPrimitiveMode.LINE_STRIP;\r\n }\r\n\r\n throw new Error(`Unknown fill mode: ${fillMode}`);\r\n}\r\n\r\nexport function IsTriangleFillMode(fillMode: number): boolean {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n case Material.TriangleStripDrawMode:\r\n case Material.TriangleFanDrawMode:\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function NormalizeTangent(tangent: Vector4 | Vector3) {\r\n const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);\r\n if (length > 0) {\r\n tangent.x /= length;\r\n tangent.y /= length;\r\n tangent.z /= length;\r\n }\r\n}\r\n\r\nexport function ConvertToRightHandedPosition(value: Vector3): Vector3 {\r\n value.x *= -1;\r\n return value;\r\n}\r\n\r\n/** @internal */\r\nexport function ConvertToRightHandedTransformMatrix(matrix: Matrix): Matrix {\r\n ConvertHandednessMatrix.invertToRef(TmpVectors.Matrix[0]).multiplyToRef(matrix, matrix).multiplyToRef(ConvertHandednessMatrix, matrix);\r\n return matrix;\r\n}\r\n\r\n/**\r\n * Converts, in-place, a left-handed quaternion to a right-handed quaternion via a change of basis.\r\n * @param value the unit quaternion to convert\r\n * @returns the converted quaternion\r\n */\r\nexport function ConvertToRightHandedRotation(value: Quaternion): Quaternion {\r\n /**\r\n * This is the simplified version of the following equation:\r\n * q' = to_quaternion(M * to_matrix(q) * M^-1)\r\n * where M is the conversion matrix `convertHandednessMatrix`,\r\n * q is the input quaternion, and q' is the converted quaternion.\r\n * Reference: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf\r\n */\r\n if (value.x * value.x + value.y * value.y > 0.5) {\r\n const absX = Math.abs(value.x);\r\n const absY = Math.abs(value.y);\r\n if (absX > absY) {\r\n const sign = Math.sign(value.x);\r\n value.x = absX;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w *= sign;\r\n } else {\r\n const sign = Math.sign(value.y);\r\n value.x *= -sign;\r\n value.y = absY;\r\n value.z *= sign;\r\n value.w *= -sign;\r\n }\r\n } else {\r\n const absZ = Math.abs(value.z);\r\n const absW = Math.abs(value.w);\r\n if (absZ > absW) {\r\n const sign = Math.sign(value.z);\r\n value.x *= -sign;\r\n value.y *= sign;\r\n value.z = absZ;\r\n value.w *= -sign;\r\n } else {\r\n const sign = Math.sign(value.w);\r\n value.x *= sign;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w = absW;\r\n }\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Pre-multiplies a 180-degree Y rotation to the quaternion, in order to match glTF's flipped forward direction for cameras.\r\n * @param rotation Target camera rotation.\r\n */\r\nexport function Rotate180Y(rotation: Quaternion): void {\r\n // Simplified from: rotation * (0, 1, 0, 0).\r\n rotation.copyFromFloats(-rotation.z, rotation.w, rotation.x, -rotation.y);\r\n}\r\n\r\n/**\r\n * Collapses GLTF parent and node into a single node, ignoring scaling.\r\n * This is useful for removing nodes that were added by the GLTF importer.\r\n * @param node Original GLTF node (Light or Camera).\r\n * @param parentNode Target parent node.\r\n */\r\nexport function CollapseChildIntoParent(node: INode, parentNode: INode): void {\r\n const parentTranslation = Vector3.FromArrayToRef(parentNode.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n const parentRotation = Quaternion.FromArrayToRef(parentNode.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n const parentMatrix = Matrix.ComposeToRef(DefaultScale, parentRotation, parentTranslation, TmpVectors.Matrix[0]);\r\n\r\n const translation = Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, TmpVectors.Vector3[2]);\r\n const rotation = Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n const matrix = Matrix.ComposeToRef(DefaultScale, rotation, translation, TmpVectors.Matrix[1]);\r\n\r\n parentMatrix.multiplyToRef(matrix, matrix);\r\n matrix.decompose(undefined, parentRotation, parentTranslation);\r\n\r\n if (parentTranslation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete parentNode.translation;\r\n } else {\r\n parentNode.translation = parentTranslation.asArray();\r\n }\r\n\r\n if (parentRotation.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n delete parentNode.rotation;\r\n } else {\r\n parentNode.rotation = parentRotation.asArray();\r\n }\r\n\r\n if (parentNode.scale) {\r\n delete parentNode.scale;\r\n }\r\n}\r\n\r\n/**\r\n * Checks whether a camera or light node is candidate for collapsing with its parent node.\r\n * This is useful for roundtrips, as the glTF Importer parents a new node to\r\n * lights and cameras to store their original transformation information.\r\n * @param babylonNode Babylon light or camera node.\r\n * @param parentBabylonNode Target Babylon parent node.\r\n * @returns True if the two nodes can be merged, false otherwise.\r\n */\r\nexport function IsChildCollapsible(babylonNode: ShadowLight | TargetCamera | AreaLight, parentBabylonNode: Node): boolean {\r\n if (!(parentBabylonNode instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Verify child is the only descendant\r\n const isOnlyDescendant = parentBabylonNode.getChildren().length === 1 && babylonNode.getChildren().length === 0 && babylonNode.parent === parentBabylonNode;\r\n if (!isOnlyDescendant) {\r\n return false;\r\n }\r\n\r\n // Verify parent has the expected scaling, determined by the node type and scene's coordinate system.\r\n const scene = babylonNode.getScene();\r\n const expectedScale = babylonNode instanceof TargetCamera && !scene.useRightHandedSystem ? DefaultLoaderCameraParentScaleLh : DefaultScale;\r\n\r\n if (!parentBabylonNode.scaling.equalsWithEpsilon(expectedScale, Epsilon)) {\r\n Logger.Warn(`Cannot collapse node ${babylonNode.name} into parent node ${parentBabylonNode.name} with modified scaling.`);\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Converts an IndicesArray into either a Uint32Array or Uint16Array.\r\n * If the `start` and `count` parameters specify a subset of the array, a new view is created.\r\n * If the input is a number[], the data is copied into a new buffer.\r\n * @param indices input array to be converted\r\n * @param start starting index\r\n * @param count number of indices\r\n * @param is32Bits whether the output should be Uint32Array (true) or Uint16Array (false) when indices is an `Array`\r\n * @returns a Uint32Array or Uint16Array\r\n * @internal\r\n */\r\nexport function IndicesArrayToTypedSubarray(indices: IndicesArray, start: number, count: number, is32Bits: boolean): Uint32Array | Uint16Array {\r\n let processedIndices = indices;\r\n if (start !== 0 || count !== indices.length) {\r\n processedIndices = Array.isArray(indices) ? indices.slice(start, start + count) : indices.subarray(start, start + count);\r\n }\r\n\r\n // If Int32Array, cast the indices (which should all be positive) to Uint32Array\r\n if (processedIndices instanceof Int32Array) {\r\n return new Uint32Array(processedIndices.buffer, processedIndices.byteOffset, processedIndices.length);\r\n }\r\n\r\n if (Array.isArray(processedIndices)) {\r\n return is32Bits ? new Uint32Array(processedIndices) : new Uint16Array(processedIndices);\r\n }\r\n\r\n return processedIndices;\r\n}\r\n\r\nexport function DataArrayToUint8Array(data: DataArray): Uint8Array {\r\n if (data instanceof Array) {\r\n const floatData = new Float32Array(data);\r\n return new Uint8Array(floatData.buffer, floatData.byteOffset, floatData.byteLength);\r\n }\r\n\r\n return ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);\r\n}\r\n\r\nexport function GetMinMax(data: DataArray, vertexBuffer: VertexBuffer, start: number, count: number): { min: number[]; max: number[] } {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const size = vertexBuffer.getSize();\r\n const min = new Array<number>(size).fill(Infinity);\r\n const max = new Array<number>(size).fill(-Infinity);\r\n EnumerateFloatValues(data, byteOffset + start * byteStride, byteStride, size, type, count * size, normalized, (values) => {\r\n for (let i = 0; i < size; i++) {\r\n min[i] = Math.min(min[i], values[i]);\r\n max[i] = Math.max(max[i], values[i]);\r\n }\r\n });\r\n\r\n return { min, max };\r\n}\r\n\r\n/**\r\n * Removes, in-place, object properties which have the same value as the default value.\r\n * Useful for avoiding unnecessary properties in the glTF JSON.\r\n * @param object the object to omit default values from\r\n * @param defaultValues a partial object with default values\r\n * @returns object with default values omitted\r\n */\r\nexport function OmitDefaultValues<T extends object>(object: T, defaultValues: Partial<T>): T {\r\n for (const [key, value] of Object.entries(object)) {\r\n const defaultValue = defaultValues[key as keyof T];\r\n if ((Array.isArray(value) && Array.isArray(defaultValue) && AreArraysEqual(value, defaultValue)) || value === defaultValue) {\r\n delete object[key as keyof T];\r\n }\r\n }\r\n return object;\r\n}\r\n\r\nfunction AreArraysEqual(array1: unknown[], array2: unknown[]): boolean {\r\n return array1.length === array2.length && array1.every((val, i) => val === array2[i]);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\nimport type { TypedArray } from \"core/types\";\r\n\r\nconst TypedArrayToWriteMethod = new Map<Function, (dataView: DataView, byteOffset: number, value: number) => void>([\r\n [Int8Array, (d, b, v) => d.setInt8(b, v)],\r\n [Uint8Array, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Uint8ClampedArray, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Int16Array, (dv, bo, v) => dv.setInt16(bo, v, true)],\r\n [Uint16Array, (dv, bo, v) => dv.setUint16(bo, v, true)],\r\n [Int32Array, (dv, bo, v) => dv.setInt32(bo, v, true)],\r\n [Uint32Array, (dv, bo, v) => dv.setUint32(bo, v, true)],\r\n [Float32Array, (dv, bo, v) => dv.setFloat32(bo, v, true)],\r\n [Float64Array, (dv, bo, v) => dv.setFloat64(bo, v, true)],\r\n]);\r\n\r\n/** @internal */\r\nexport class DataWriter {\r\n private _data: Uint8Array;\r\n private _dataView: DataView;\r\n private _byteOffset: number;\r\n\r\n public writeTypedArray(value: Exclude<TypedArray, BigInt64Array | BigUint64Array>): void {\r\n this._checkGrowBuffer(value.byteLength);\r\n const setMethod = TypedArrayToWriteMethod.get(value.constructor)!;\r\n for (let i = 0; i < value.length; i++) {\r\n setMethod(this._dataView, this._byteOffset, value[i]);\r\n this._byteOffset += value.BYTES_PER_ELEMENT;\r\n }\r\n }\r\n\r\n public constructor(byteLength: number) {\r\n this._data = new Uint8Array(byteLength);\r\n this._dataView = new DataView(this._data.buffer);\r\n this._byteOffset = 0;\r\n }\r\n\r\n public get byteOffset(): number {\r\n return this._byteOffset;\r\n }\r\n\r\n public getOutputData(): Uint8Array {\r\n return new Uint8Array(this._data.buffer, 0, this._byteOffset);\r\n }\r\n\r\n public writeUInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setUint8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setInt8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt16(entry: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setInt16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeUInt16(value: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setUint16(this._byteOffset, value, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeInt32(entry: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setInt32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeUInt32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setUint32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setFloat32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat64(value: number): void {\r\n this._checkGrowBuffer(8);\r\n this._dataView.setFloat64(this._byteOffset, value, true);\r\n this._byteOffset += 8;\r\n }\r\n\r\n private _checkGrowBuffer(byteLength: number): void {\r\n const newByteLength = this.byteOffset + byteLength;\r\n if (newByteLength > this._data.byteLength) {\r\n const newData = new Uint8Array(newByteLength * 2);\r\n newData.set(this._data);\r\n this._data = newData;\r\n this._dataView = new DataView(this._data.buffer);\r\n }\r\n }\r\n}\r\n","import type { TypedArray } from \"core/types\";\nimport type { AccessorComponentType, AccessorType, IAccessor, IBufferView } from \"babylonjs-gltf2interface\";\nimport { DataWriter } from \"./dataWriter\";\n\ntype TypedArrayForglTF = Exclude<TypedArray, Float64Array | BigInt64Array | BigUint64Array>;\n\ninterface IPropertyWithBufferView {\n bufferView?: number;\n}\n\nfunction GetHighestByteAlignment(byteLength: number): number {\n if (byteLength % 4 === 0) {\n return 4;\n }\n if (byteLength % 2 === 0) {\n return 2;\n }\n return 1;\n}\n\n/**\n * Utility class to centralize the management of binary data, bufferViews, and the objects that reference them.\n * @internal\n */\nexport class BufferManager {\n /**\n * Maps a bufferView to its data\n */\n private _bufferViewToData: Map<IBufferView, TypedArrayForglTF> = new Map<IBufferView, TypedArrayForglTF>();\n\n /**\n * Maps a bufferView to glTF objects that reference it via a \"bufferView\" property (e.g. accessors, images)\n */\n private _bufferViewToProperties: Map<IBufferView, IPropertyWithBufferView[]> = new Map<IBufferView, IPropertyWithBufferView[]>();\n\n /**\n * Maps an accessor to its bufferView\n */\n private _accessorToBufferView: Map<IAccessor, IBufferView> = new Map<IAccessor, IBufferView>();\n\n /**\n * Generates a binary buffer from the stored bufferViews. Also populates the bufferViews list.\n * @param bufferViews The list of bufferViews to be populated while writing the binary\n * @returns The binary buffer\n */\n public generateBinary(bufferViews: IBufferView[]): Uint8Array {\n // Construct a DataWriter with the total byte length to prevent resizing\n let totalByteLength = 0;\n this._bufferViewToData.forEach((data) => {\n totalByteLength += data.byteLength;\n });\n const dataWriter = new DataWriter(totalByteLength);\n\n // Order the bufferViews in descending order of their alignment requirements\n const orderedBufferViews = Array.from(this._bufferViewToData.keys()).sort((a, b) => GetHighestByteAlignment(b.byteLength) - GetHighestByteAlignment(a.byteLength));\n\n // Fill in the bufferViews list and missing bufferView index references while writing the binary\n for (const bufferView of orderedBufferViews) {\n bufferView.byteOffset = dataWriter.byteOffset;\n bufferViews.push(bufferView);\n\n const bufferViewIndex = bufferViews.length - 1;\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n object.bufferView = bufferViewIndex;\n }\n\n dataWriter.writeTypedArray(this._bufferViewToData.get(bufferView)!);\n\n this._bufferViewToData.delete(bufferView); // Try to free up memory ASAP\n }\n\n return dataWriter.getOutputData();\n }\n\n /**\n * Creates a buffer view based on the supplied arguments\n * @param data a TypedArray to create the bufferView for\n * @param byteStride byte distance between consecutive elements\n * @returns bufferView for glTF\n */\n public createBufferView(data: TypedArrayForglTF, byteStride?: number): IBufferView {\n const bufferView: IBufferView = {\n buffer: 0,\n byteOffset: undefined, // byteOffset will be set later, when we write the binary and decide bufferView ordering\n byteLength: data.byteLength,\n byteStride: byteStride,\n };\n this._bufferViewToData.set(bufferView, data);\n return bufferView;\n }\n\n /**\n * Creates an accessor based on the supplied arguments and assigns it to the bufferView\n * @param bufferView The glTF bufferView referenced by this accessor\n * @param type The type of the accessor\n * @param componentType The datatype of components in the attribute\n * @param count The number of attributes referenced by this accessor\n * @param byteOffset The offset relative to the start of the bufferView in bytes\n * @param minMax Minimum and maximum value of each component in this attribute\n * @param normalized Specifies whether integer data values are normalized before usage\n * @returns accessor for glTF\n */\n public createAccessor(\n bufferView: IBufferView,\n type: AccessorType,\n componentType: AccessorComponentType,\n count: number,\n byteOffset?: number,\n minMax?: { min: number[]; max: number[] },\n normalized?: boolean\n ): IAccessor {\n this._verifyBufferView(bufferView);\n const accessor: IAccessor = {\n bufferView: undefined, // bufferView will be set to a real index later, once we write the binary and decide bufferView ordering\n componentType: componentType,\n count: count,\n type: type,\n min: minMax?.min,\n max: minMax?.max,\n normalized: normalized,\n byteOffset: byteOffset,\n };\n this.setBufferView(accessor, bufferView);\n this._accessorToBufferView.set(accessor, bufferView);\n return accessor;\n }\n\n /**\n * Assigns a bufferView to a glTF object that references it\n * @param object The glTF object\n * @param bufferView The bufferView to assign\n */\n public setBufferView(object: IPropertyWithBufferView, bufferView: IBufferView) {\n this._verifyBufferView(bufferView);\n const properties = this.getPropertiesWithBufferView(bufferView);\n properties.push(object);\n }\n\n /**\n * Removes buffer view from the binary data, as well as from all its known references\n * @param bufferView the bufferView to remove\n */\n public removeBufferView(bufferView: IBufferView): void {\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n if (object.bufferView !== undefined) {\n delete object.bufferView;\n }\n }\n\n this._bufferViewToData.delete(bufferView);\n this._bufferViewToProperties.delete(bufferView);\n this._accessorToBufferView.forEach((bv, accessor) => {\n if (bv === bufferView) {\n // Additionally, remove byteOffset from accessor referencing this bufferView\n if (accessor.byteOffset !== undefined) {\n delete accessor.byteOffset;\n }\n this._accessorToBufferView.delete(accessor);\n }\n });\n }\n\n public getBufferView(accessor: IAccessor): IBufferView {\n const bufferView = this._accessorToBufferView.get(accessor);\n this._verifyBufferView(bufferView);\n return bufferView!;\n }\n\n public getPropertiesWithBufferView(bufferView: IBufferView): IPropertyWithBufferView[] {\n this._verifyBufferView(bufferView);\n this._bufferViewToProperties.set(bufferView, this._bufferViewToProperties.get(bufferView) ?? []);\n return this._bufferViewToProperties.get(bufferView)!;\n }\n\n public getData(bufferView: IBufferView): TypedArrayForglTF {\n this._verifyBufferView(bufferView);\n return this._bufferViewToData.get(bufferView)!;\n }\n\n private _verifyBufferView(bufferView?: IBufferView): void {\n if (bufferView === undefined || !this._bufferViewToData.has(bufferView)) {\n throw new Error(`BufferView ${bufferView} not found in BufferManager.`);\n }\n }\n}\n","import type { IAnimation, INode, IBufferView, IAccessor, IAnimationSampler, IAnimationChannel } from \"babylonjs-gltf2interface\";\r\nimport { AnimationSamplerInterpolation, AnimationChannelTargetPath, AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Animation } from \"core/Animations/animation\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\n\r\nimport type { IAnimationKey } from \"core/Animations/animationKey\";\r\nimport { AnimationKeyInterpolation } from \"core/Animations/animationKey\";\r\n\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\nimport { GetAccessorElementCount, ConvertToRightHandedPosition, Rotate180Y, ConvertToRightHandedRotation } from \"./glTFUtilities\";\r\n\r\n/**\r\n * @internal\r\n * Interface to store animation data.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationData {\r\n /**\r\n * Keyframe data.\r\n */\r\n inputs: number[];\r\n /**\r\n * Value data.\r\n */\r\n outputs: number[][];\r\n /**\r\n * Animation interpolation data.\r\n */\r\n samplerInterpolation: AnimationSamplerInterpolation;\r\n /**\r\n * Minimum keyframe value.\r\n */\r\n inputsMin: number;\r\n /**\r\n * Maximum keyframe value.\r\n */\r\n inputsMax: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationInfo {\r\n /**\r\n * The target channel for the animation\r\n */\r\n animationChannelTargetPath: AnimationChannelTargetPath;\r\n /**\r\n * The glTF accessor type for the data.\r\n */\r\n dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;\r\n /**\r\n * Specifies if quaternions should be used.\r\n */\r\n useQuaternion: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Enum for handling in tangent and out tangent.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nenum _TangentType {\r\n /**\r\n * Specifies that input tangents are used.\r\n */\r\n INTANGENT,\r\n /**\r\n * Specifies that output tangents are used.\r\n */\r\n OUTTANGENT,\r\n}\r\n\r\n/**\r\n * @internal\r\n * Utility class for generating glTF animation data from BabylonJS.\r\n */\r\nexport class _GLTFAnimation {\r\n /**\r\n * Determine if a node is transformable - ie has properties it should be part of animation of transformation.\r\n * @param babylonNode the node to test\r\n * @returns true if can be animated, false otherwise. False if the parameter is null or undefined.\r\n */\r\n private static _IsTransformable(babylonNode: Node): boolean {\r\n return babylonNode && (babylonNode instanceof TransformNode || babylonNode instanceof Camera || babylonNode instanceof Light);\r\n }\r\n\r\n /**\r\n * @ignore\r\n *\r\n * Creates glTF channel animation from BabylonJS animation.\r\n * @param babylonTransformNode - BabylonJS mesh.\r\n * @param animation - animation.\r\n * @param animationChannelTargetPath - The target animation channel.\r\n * @param useQuaternion - Specifies if quaternions are used.\r\n * @returns nullable IAnimationData\r\n */\r\n public static _CreateNodeAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean,\r\n animationSampleRate: number\r\n ): Nullable<_IAnimationData> {\r\n if (this._IsTransformable(babylonTransformNode)) {\r\n const inputs: number[] = [];\r\n const outputs: number[][] = [];\r\n const keyFrames = animation.getKeys();\r\n const minMaxKeyFrames = _GLTFAnimation._CalculateMinMaxKeyFrames(keyFrames);\r\n const interpolationOrBake = _GLTFAnimation._DeduceInterpolation(keyFrames, animationChannelTargetPath, useQuaternion);\r\n\r\n const interpolation = interpolationOrBake.interpolationType;\r\n const shouldBakeAnimation = interpolationOrBake.shouldBakeAnimation;\r\n\r\n if (shouldBakeAnimation) {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n } else {\r\n if (interpolation === AnimationSamplerInterpolation.LINEAR || interpolation === AnimationSamplerInterpolation.STEP) {\r\n _GLTFAnimation._CreateLinearOrStepAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n _GLTFAnimation._CreateCubicSplineAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n }\r\n }\r\n\r\n if (inputs.length && outputs.length) {\r\n const result: _IAnimationData = {\r\n inputs: inputs,\r\n outputs: outputs,\r\n samplerInterpolation: interpolation,\r\n inputsMin: shouldBakeAnimation ? minMaxKeyFrames.min : Tools.FloatRound(minMaxKeyFrames.min / animation.framePerSecond),\r\n inputsMax: shouldBakeAnimation ? minMaxKeyFrames.max : Tools.FloatRound(minMaxKeyFrames.max / animation.framePerSecond),\r\n };\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private static _DeduceAnimationInfo(animation: Animation): Nullable<_IAnimationInfo> {\r\n let animationChannelTargetPath: Nullable<AnimationChannelTargetPath> = null;\r\n let dataAccessorType = AccessorType.VEC3;\r\n let useQuaternion: boolean = false;\r\n const property = animation.targetProperty.split(\".\");\r\n switch (property[0]) {\r\n case \"scaling\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.SCALE;\r\n break;\r\n }\r\n case \"position\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.TRANSLATION;\r\n break;\r\n }\r\n case \"rotation\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"rotationQuaternion\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n useQuaternion = true;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"influence\": {\r\n dataAccessorType = AccessorType.SCALAR;\r\n animationChannelTargetPath = AnimationChannelTargetPath.WEIGHTS;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported animatable property ${property[0]}`);\r\n }\r\n }\r\n if (animationChannelTargetPath) {\r\n return { animationChannelTargetPath: animationChannelTargetPath, dataAccessorType: dataAccessorType, useQuaternion: useQuaternion };\r\n } else {\r\n Tools.Error(\"animation channel target path and data accessor type could be deduced\");\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create node animations from the transform node animations\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAnimationFromNodeAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (_GLTFAnimation._IsTransformable(babylonNode)) {\r\n if (babylonNode.animations) {\r\n for (const animation of babylonNode.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: animation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create individual morph animations from the mesh's morph target animation tracks\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonNode instanceof Mesh) {\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n if (morphTargetManager) {\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n const morphTarget = morphTargetManager.getTarget(i);\r\n for (const animation of morphTarget.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const combinedAnimation = new Animation(\r\n `${animation.name}`,\r\n \"influence\",\r\n animation.framePerSecond,\r\n animation.dataType,\r\n animation.loopMode,\r\n animation.enableBlending\r\n );\r\n const combinedAnimationKeys: IAnimationKey[] = [];\r\n const animationKeys = animation.getKeys();\r\n\r\n for (let j = 0; j < animationKeys.length; ++j) {\r\n const animationKey = animationKeys[j];\r\n for (let k = 0; k < morphTargetManager.numTargets; ++k) {\r\n if (k == i) {\r\n combinedAnimationKeys.push(animationKey);\r\n } else {\r\n combinedAnimationKeys.push({ frame: animationKey.frame, value: 0 });\r\n }\r\n }\r\n }\r\n combinedAnimation.setKeys(combinedAnimationKeys, true);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: combinedAnimation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n animation.name,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n combinedAnimation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded,\r\n morphTargetManager.numTargets\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Create node and morph animations from the animation groups\r\n * @param babylonScene\r\n * @param glTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene: Scene,\r\n glTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n leftHandedNodes: Set<Node>,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonScene.animationGroups) {\r\n const animationGroups = babylonScene.animationGroups;\r\n for (const animationGroup of animationGroups) {\r\n const morphAnimations: Map<Mesh, Map<MorphTarget, Animation>> = new Map();\r\n const sampleAnimations: Map<Mesh, Animation> = new Map();\r\n const morphAnimationMeshes: Set<Mesh> = new Set();\r\n const animationGroupFrameDiff = animationGroup.to - animationGroup.from;\r\n glTFAnimation = {\r\n name: animationGroup.name,\r\n channels: [],\r\n samplers: [],\r\n };\r\n for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n const targetAnimation = animationGroup.targetedAnimations[i];\r\n const target = targetAnimation.target;\r\n const animation = targetAnimation.animation;\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n\r\n const convertToRightHanded = leftHandedNodes.has(target);\r\n\r\n if (this._IsTransformable(target) || (target.length === 1 && this._IsTransformable(target[0]))) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonTransformNode = this._IsTransformable(target) ? target : this._IsTransformable(target[0]) ? target[0] : null;\r\n if (babylonTransformNode) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n glTFAnimation,\r\n babylonTransformNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n convertToRightHanded\r\n );\r\n }\r\n }\r\n } else if (target instanceof MorphTarget || (target.length === 1 && target[0] instanceof MorphTarget)) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonMorphTarget = target instanceof MorphTarget ? target : (target[0] as MorphTarget);\r\n if (babylonMorphTarget) {\r\n const babylonMorphTargetManager = babylonScene.morphTargetManagers.find((morphTargetManager) => {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n if (morphTargetManager.getTarget(j) === babylonMorphTarget) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n if (babylonMorphTargetManager) {\r\n const babylonMesh = babylonScene.meshes.find((mesh) => {\r\n return (mesh as Mesh).morphTargetManager === babylonMorphTargetManager;\r\n }) as Mesh;\r\n if (babylonMesh) {\r\n if (!morphAnimations.has(babylonMesh)) {\r\n morphAnimations.set(babylonMesh, new Map());\r\n }\r\n morphAnimations.get(babylonMesh)?.set(babylonMorphTarget, animation);\r\n morphAnimationMeshes.add(babylonMesh);\r\n sampleAnimations.set(babylonMesh, animation);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // this is the place for the KHR_animation_pointer.\r\n }\r\n }\r\n morphAnimationMeshes.forEach((mesh) => {\r\n const morphTargetManager = mesh.morphTargetManager!;\r\n let combinedAnimationGroup: Nullable<Animation> = null;\r\n const animationKeys: IAnimationKey[] = [];\r\n const sampleAnimation = sampleAnimations.get(mesh)!;\r\n const sampleAnimationKeys = sampleAnimation.getKeys();\r\n const numAnimationKeys = sampleAnimationKeys.length;\r\n /*\r\n Due to how glTF expects morph target animation data to be formatted, we need to rearrange the individual morph target animation tracks,\r\n such that we have a single animation, where a given keyframe input value has successive output values for each morph target belonging to the manager.\r\n See: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\r\n\r\n We do this via constructing a new Animation track, and interleaving the frames of each morph target animation track in the current Animation Group\r\n We reuse the Babylon Animation data structure for ease of handling export of cubic spline animation keys, and to reuse the\r\n existing _GLTFAnimation.AddAnimation codepath with minimal modification, however the constructed Babylon Animation is NOT intended for use in-engine.\r\n */\r\n for (let i = 0; i < numAnimationKeys; ++i) {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n const morphTarget = morphTargetManager.getTarget(j);\r\n const animationsByMorphTarget = morphAnimations.get(mesh);\r\n if (animationsByMorphTarget) {\r\n const morphTargetAnimation = animationsByMorphTarget.get(morphTarget);\r\n if (morphTargetAnimation) {\r\n if (!combinedAnimationGroup) {\r\n combinedAnimationGroup = new Animation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n \"influence\",\r\n morphTargetAnimation.framePerSecond,\r\n Animation.ANIMATIONTYPE_FLOAT,\r\n morphTargetAnimation.loopMode,\r\n morphTargetAnimation.enableBlending\r\n );\r\n }\r\n animationKeys.push(morphTargetAnimation.getKeys()[i]);\r\n } else {\r\n animationKeys.push({\r\n frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i,\r\n value: morphTarget.influence,\r\n inTangent: sampleAnimationKeys[0].inTangent ? 0 : undefined,\r\n outTangent: sampleAnimationKeys[0].outTangent ? 0 : undefined,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n combinedAnimationGroup!.setKeys(animationKeys, true);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup!);\r\n if (animationInfo) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n glTFAnimation,\r\n mesh,\r\n combinedAnimationGroup!,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n false,\r\n morphTargetManager?.numTargets\r\n );\r\n }\r\n });\r\n if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {\r\n glTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private static _AddAnimation(\r\n name: string,\r\n glTFAnimation: IAnimation,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n dataAccessorType: AccessorType,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n useQuaternion: boolean,\r\n animationSampleRate: number,\r\n convertToRightHanded: boolean,\r\n morphAnimationChannels?: number\r\n ) {\r\n const animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate);\r\n let bufferView: IBufferView;\r\n let accessor: IAccessor;\r\n let keyframeAccessorIndex: number;\r\n let dataAccessorIndex: number;\r\n let animationSampler: IAnimationSampler;\r\n let animationChannel: IAnimationChannel;\r\n\r\n if (animationData) {\r\n /*\r\n * Now that we have the glTF converted morph target animation data,\r\n * we can remove redundant input data so that we have n input frames,\r\n * and morphAnimationChannels * n output frames\r\n */\r\n if (morphAnimationChannels) {\r\n let index = 0;\r\n let currentInput: number = 0;\r\n const newInputs: number[] = [];\r\n while (animationData.inputs.length > 0) {\r\n currentInput = animationData.inputs.shift()!;\r\n if (index % morphAnimationChannels == 0) {\r\n newInputs.push(currentInput);\r\n }\r\n index++;\r\n }\r\n animationData.inputs = newInputs;\r\n }\r\n\r\n const nodeIndex = nodeMap.get(babylonTransformNode);\r\n\r\n // Create buffer view and accessor for key frames.\r\n const inputData = new Float32Array(animationData.inputs);\r\n bufferView = bufferManager.createBufferView(inputData);\r\n accessor = bufferManager.createAccessor(bufferView, AccessorType.SCALAR, AccessorComponentType.FLOAT, animationData.inputs.length, undefined, {\r\n min: [animationData.inputsMin],\r\n max: [animationData.inputsMax],\r\n });\r\n accessors.push(accessor);\r\n keyframeAccessorIndex = accessors.length - 1;\r\n\r\n // Perform conversions on keyed values while also building their buffer.\r\n const rotationQuaternion = new Quaternion();\r\n const eulerVec3 = new Vector3();\r\n const position = new Vector3();\r\n const isCamera = babylonTransformNode instanceof Camera;\r\n\r\n const elementCount = GetAccessorElementCount(dataAccessorType);\r\n const outputData = new Float32Array(animationData.outputs.length * elementCount);\r\n animationData.outputs.forEach(function (output: number[], index: number) {\r\n let outputToWrite: number[] = output;\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.TRANSLATION:\r\n if (convertToRightHanded) {\r\n Vector3.FromArrayToRef(output, 0, position);\r\n ConvertToRightHandedPosition(position);\r\n position.toArray(outputToWrite);\r\n }\r\n break;\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n if (isCamera) {\r\n Rotate180Y(rotationQuaternion);\r\n }\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n outputData.set(outputToWrite, index * elementCount);\r\n });\r\n\r\n // Create buffer view and accessor for keyed values.\r\n bufferView = bufferManager.createBufferView(outputData);\r\n accessor = bufferManager.createAccessor(bufferView, dataAccessorType, AccessorComponentType.FLOAT, animationData.outputs.length);\r\n accessors.push(accessor);\r\n dataAccessorIndex = accessors.length - 1;\r\n\r\n // create sampler\r\n animationSampler = {\r\n interpolation: animationData.samplerInterpolation,\r\n input: keyframeAccessorIndex,\r\n output: dataAccessorIndex,\r\n };\r\n glTFAnimation.samplers.push(animationSampler);\r\n\r\n // create channel\r\n animationChannel = {\r\n sampler: glTFAnimation.samplers.length - 1,\r\n target: {\r\n node: nodeIndex,\r\n path: animationChannelTargetPath,\r\n },\r\n };\r\n glTFAnimation.channels.push(animationChannel);\r\n }\r\n }\r\n\r\n /**\r\n * Create a baked animation\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation corresponding to the BabylonJS mesh\r\n * @param animationChannelTargetPath animation target channel\r\n * @param minFrame minimum animation frame\r\n * @param maxFrame maximum animation frame\r\n * @param fps frames per second of the animation\r\n * @param sampleRate\r\n * @param inputs input key frames of the animation\r\n * @param outputs output key frame data of the animation\r\n * @param minMaxFrames\r\n * @param minMaxFrames.min\r\n * @param minMaxFrames.max\r\n * @param useQuaternion specifies if quaternions should be used\r\n */\r\n private static _CreateBakedAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n minFrame: number,\r\n maxFrame: number,\r\n fps: number,\r\n sampleRate: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n minMaxFrames: { min: number; max: number },\r\n useQuaternion: boolean\r\n ) {\r\n let value: number | Vector3 | Quaternion;\r\n const quaternionCache: Quaternion = Quaternion.Identity();\r\n let previousTime: Nullable<number> = null;\r\n let time: number;\r\n let maxUsedFrame: Nullable<number> = null;\r\n let currKeyFrame: Nullable<IAnimationKey> = null;\r\n let nextKeyFrame: Nullable<IAnimationKey> = null;\r\n let prevKeyFrame: Nullable<IAnimationKey> = null;\r\n let endFrame: Nullable<number> = null;\r\n minMaxFrames.min = Tools.FloatRound(minFrame / fps);\r\n\r\n const keyFrames = animation.getKeys();\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n endFrame = null;\r\n currKeyFrame = keyFrames[i];\r\n\r\n if (i + 1 < length) {\r\n nextKeyFrame = keyFrames[i + 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(nextKeyFrame.value)) || currKeyFrame.value === nextKeyFrame.value) {\r\n if (i === 0) {\r\n // set the first frame to itself\r\n endFrame = currKeyFrame.frame;\r\n } else {\r\n continue;\r\n }\r\n } else {\r\n endFrame = nextKeyFrame.frame;\r\n }\r\n } else {\r\n // at the last key frame\r\n prevKeyFrame = keyFrames[i - 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(prevKeyFrame.value)) || currKeyFrame.value === prevKeyFrame.value) {\r\n continue;\r\n } else {\r\n endFrame = maxFrame;\r\n }\r\n }\r\n if (endFrame) {\r\n for (let f = currKeyFrame.frame; f <= endFrame; f += sampleRate) {\r\n time = Tools.FloatRound(f / fps);\r\n if (time === previousTime) {\r\n continue;\r\n }\r\n previousTime = time;\r\n maxUsedFrame = time;\r\n const state = {\r\n key: 0,\r\n repeatCount: 0,\r\n loopMode: animation.loopMode,\r\n };\r\n value = animation._interpolate(f, state);\r\n\r\n _GLTFAnimation._SetInterpolatedValue(babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion);\r\n }\r\n }\r\n }\r\n if (maxUsedFrame) {\r\n minMaxFrames.max = maxUsedFrame;\r\n }\r\n }\r\n\r\n private static _ConvertFactorToVector3OrQuaternion(\r\n factor: number,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): Vector3 | Quaternion {\r\n const basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(babylonTransformNode, animationChannelTargetPath, useQuaternion);\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n const property = animation.targetProperty.split(\".\");\r\n const componentName = property ? property[1] : \"\"; // x, y, z, or w component\r\n const value = useQuaternion ? Quaternion.FromArray(basePositionRotationOrScale).normalize() : Vector3.FromArray(basePositionRotationOrScale);\r\n\r\n switch (componentName) {\r\n case \"x\":\r\n case \"y\":\r\n case \"z\": {\r\n value[componentName] = factor;\r\n break;\r\n }\r\n case \"w\": {\r\n (value as Quaternion).w = factor;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`glTFAnimation: Unsupported component name \"${componentName}\"!`);\r\n }\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private static _SetInterpolatedValue(\r\n babylonTransformNode: Node,\r\n value: number | Vector3 | Quaternion,\r\n time: number,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n quaternionCache: Quaternion,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n let cacheValue: Vector3 | Quaternion | number;\r\n inputs.push(time);\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([value as number]);\r\n return;\r\n }\r\n\r\n if (animation.dataType === Animation.ANIMATIONTYPE_FLOAT) {\r\n value = this._ConvertFactorToVector3OrQuaternion(value as number, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion);\r\n }\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n quaternionCache = value as Quaternion;\r\n } else {\r\n cacheValue = value as Vector3;\r\n Quaternion.RotationYawPitchRollToRef(cacheValue.y, cacheValue.x, cacheValue.z, quaternionCache);\r\n }\r\n outputs.push(quaternionCache.asArray());\r\n } else {\r\n // scaling and position animation\r\n cacheValue = value as Vector3;\r\n outputs.push(cacheValue.asArray());\r\n }\r\n }\r\n\r\n /**\r\n * Creates linear animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateLinearOrStepAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n for (const keyFrame of animation.getKeys()) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n }\r\n }\r\n\r\n /**\r\n * Creates cubic spline animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateCubicSplineAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n animation.getKeys().forEach(function (keyFrame) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddSplineTangent(_TangentType.INTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n\r\n _GLTFAnimation._AddSplineTangent(_TangentType.OUTTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n });\r\n }\r\n\r\n private static _GetBasePositionRotationOrScale(babylonTransformNode: Node, animationChannelTargetPath: AnimationChannelTargetPath, useQuaternion: boolean) {\r\n let basePositionRotationOrScale: number[];\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n const q = (babylonTransformNode as TransformNode).rotationQuaternion;\r\n basePositionRotationOrScale = (q ?? Quaternion.Identity()).asArray();\r\n } else {\r\n const r: Vector3 = (babylonTransformNode as TransformNode).rotation;\r\n basePositionRotationOrScale = (r ?? Vector3.Zero()).asArray();\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n const p: Vector3 = (babylonTransformNode as TransformNode).position;\r\n basePositionRotationOrScale = (p ?? Vector3.Zero()).asArray();\r\n } else {\r\n // scale\r\n const s: Vector3 = (babylonTransformNode as TransformNode).scaling;\r\n basePositionRotationOrScale = (s ?? Vector3.One()).asArray();\r\n }\r\n return basePositionRotationOrScale;\r\n }\r\n\r\n /**\r\n * Adds a key frame value\r\n * @param keyFrame\r\n * @param animation\r\n * @param outputs\r\n * @param animationChannelTargetPath\r\n * @param babylonTransformNode\r\n * @param useQuaternion\r\n */\r\n private static _AddKeyframeValue(\r\n keyFrame: IAnimationKey,\r\n animation: Animation,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n babylonTransformNode: Node,\r\n useQuaternion: boolean\r\n ) {\r\n let newPositionRotationOrScale: Nullable<Vector3 | Quaternion | number>;\r\n const animationType = animation.dataType;\r\n if (animationType === Animation.ANIMATIONTYPE_VECTOR3) {\r\n let value = keyFrame.value.asArray();\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const array = Vector3.FromArray(value);\r\n const rotationQuaternion = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z);\r\n value = rotationQuaternion.asArray();\r\n }\r\n outputs.push(value); // scale vector.\r\n } else if (animationType === Animation.ANIMATIONTYPE_FLOAT) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([keyFrame.value]);\r\n } else {\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(\r\n keyFrame.value as number,\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n useQuaternion\r\n );\r\n if (newPositionRotationOrScale) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const posRotScale = useQuaternion\r\n ? (newPositionRotationOrScale as Quaternion)\r\n : Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();\r\n outputs.push(posRotScale.asArray());\r\n }\r\n outputs.push(newPositionRotationOrScale.asArray());\r\n }\r\n }\r\n } else if (animationType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n outputs.push((keyFrame.value as Quaternion).normalize().asArray());\r\n } else {\r\n Tools.Error(\"glTFAnimation: Unsupported key frame values for animation!\");\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Determine the interpolation based on the key frames\r\n * @param keyFrames\r\n * @param animationChannelTargetPath\r\n * @param useQuaternion\r\n */\r\n private static _DeduceInterpolation(\r\n keyFrames: IAnimationKey[],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): { interpolationType: AnimationSamplerInterpolation; shouldBakeAnimation: boolean } {\r\n let interpolationType: AnimationSamplerInterpolation | undefined;\r\n let shouldBakeAnimation = false;\r\n let key: IAnimationKey;\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION && !useQuaternion) {\r\n return { interpolationType: AnimationSamplerInterpolation.LINEAR, shouldBakeAnimation: true };\r\n }\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n key = keyFrames[i];\r\n if (key.inTangent || key.outTangent) {\r\n if (interpolationType) {\r\n if (interpolationType !== AnimationSamplerInterpolation.CUBICSPLINE) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.CUBICSPLINE;\r\n }\r\n } else {\r\n if (interpolationType) {\r\n if (\r\n interpolationType === AnimationSamplerInterpolation.CUBICSPLINE ||\r\n (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP && interpolationType !== AnimationSamplerInterpolation.STEP)\r\n ) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n if (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP) {\r\n interpolationType = AnimationSamplerInterpolation.STEP;\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n }\r\n }\r\n }\r\n if (!interpolationType) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n\r\n return { interpolationType: interpolationType, shouldBakeAnimation: shouldBakeAnimation };\r\n }\r\n\r\n /**\r\n * Adds an input tangent or output tangent to the output data\r\n * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion\r\n * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent)\r\n * @param outputs The animation data by keyframe\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param interpolation The interpolation type\r\n * @param keyFrame The key frame with the animation data\r\n * @param useQuaternion Specifies if quaternions are used\r\n */\r\n private static _AddSplineTangent(\r\n tangentType: _TangentType,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n interpolation: AnimationSamplerInterpolation,\r\n keyFrame: IAnimationKey,\r\n useQuaternion: boolean\r\n ) {\r\n let tangent: number[];\r\n const tangentValue: Vector3 | Quaternion | number = tangentType === _TangentType.INTANGENT ? keyFrame.inTangent : keyFrame.outTangent;\r\n if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (tangentValue) {\r\n if (useQuaternion) {\r\n tangent = (tangentValue as Quaternion).asArray();\r\n } else {\r\n const array = tangentValue as Vector3;\r\n tangent = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z).asArray();\r\n }\r\n } else {\r\n tangent = [0, 0, 0, 0];\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n if (tangentValue) {\r\n tangent = [tangentValue as number];\r\n } else {\r\n tangent = [0];\r\n }\r\n } else {\r\n if (tangentValue) {\r\n tangent = (tangentValue as Vector3).asArray();\r\n } else {\r\n tangent = [0, 0, 0];\r\n }\r\n }\r\n\r\n outputs.push(tangent);\r\n }\r\n }\r\n\r\n /**\r\n * Get the minimum and maximum key frames' frame values\r\n * @param keyFrames animation key frames\r\n * @returns the minimum and maximum key frame value\r\n */\r\n private static _CalculateMinMaxKeyFrames(keyFrames: IAnimationKey[]): { min: number; max: number } {\r\n let min: number = Infinity;\r\n let max: number = -Infinity;\r\n keyFrames.forEach(function (keyFrame) {\r\n min = Math.min(min, keyFrame.frame);\r\n max = Math.max(max, keyFrame.frame);\r\n });\r\n\r\n return { min: min, max: max };\r\n }\r\n}\r\n","import type { IBufferView, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType } from \"babylonjs-gltf2interface\";\r\nimport type { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\nimport { NormalizeTangent } from \"./glTFUtilities\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Interface to store morph target information.\r\n * @internal\r\n */\r\nexport interface IMorphTargetData {\r\n attributes: Record<string, number>;\r\n influence: number;\r\n name: string;\r\n}\r\n\r\nexport function BuildMorphTargetBuffers(\r\n morphTarget: MorphTarget,\r\n mesh: AbstractMesh,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHanded: boolean\r\n): IMorphTargetData {\r\n const result: IMorphTargetData = {\r\n attributes: {},\r\n influence: morphTarget.influence,\r\n name: morphTarget.name,\r\n };\r\n\r\n const geometry = mesh.geometry;\r\n if (!geometry) {\r\n Tools.Warn(\"Attempted to export morph target data from a mesh without geometry. This should not happen.\");\r\n return result;\r\n }\r\n\r\n const flipX = convertToRightHanded ? -1 : 1;\r\n const floatSize = 4;\r\n const difference = Vector3.Zero();\r\n let vertexStart = 0;\r\n let vertexCount = 0;\r\n\r\n if (morphTarget.hasPositions) {\r\n const morphPositions = morphTarget.getPositions()!;\r\n const originalPositions = geometry.getVerticesData(VertexBuffer.PositionKind); // Bypasses any instance data of mesh\r\n\r\n if (originalPositions) {\r\n const positionData = new Float32Array(originalPositions.length);\r\n const min = [Infinity, Infinity, Infinity];\r\n const max = [-Infinity, -Infinity, -Infinity];\r\n vertexCount = originalPositions.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalPosition = Vector3.FromArray(originalPositions, i * 3);\r\n const morphPosition = Vector3.FromArray(morphPositions, i * 3);\r\n morphPosition.subtractToRef(originalPosition, difference);\r\n difference.x *= flipX;\r\n\r\n min[0] = Math.min(min[0], difference.x);\r\n max[0] = Math.max(max[0], difference.x);\r\n\r\n min[1] = Math.min(min[1], difference.y);\r\n max[1] = Math.max(max[1], difference.y);\r\n\r\n min[2] = Math.min(min[2], difference.z);\r\n max[2] = Math.max(max[2], difference.z);\r\n\r\n positionData[i * 3] = difference.x;\r\n positionData[i * 3 + 1] = difference.y;\r\n positionData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(positionData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphPositions.length / 3, 0, { min, max });\r\n accessors.push(accessor);\r\n result.attributes[\"POSITION\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target positions for mesh ${mesh.name} were not exported. Mesh does not have position vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasNormals) {\r\n const morphNormals = morphTarget.getNormals()!;\r\n const originalNormals = geometry.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n if (originalNormals) {\r\n const normalData = new Float32Array(originalNormals.length);\r\n vertexCount = originalNormals.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalNormal = Vector3.FromArray(originalNormals, i * 3).normalize();\r\n const morphNormal = Vector3.FromArray(morphNormals, i * 3).normalize();\r\n morphNormal.subtractToRef(originalNormal, difference);\r\n\r\n normalData[i * 3] = difference.x * flipX;\r\n normalData[i * 3 + 1] = difference.y;\r\n normalData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(normalData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphNormals.length / 3, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"NORMAL\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target normals for mesh ${mesh.name} were not exported. Mesh does not have normals vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasTangents) {\r\n const morphTangents = morphTarget.getTangents()!;\r\n const originalTangents = geometry.getVerticesData(VertexBuffer.TangentKind);\r\n\r\n if (originalTangents) {\r\n vertexCount = originalTangents.length / 4;\r\n const tangentData = new Float32Array(vertexCount * 3);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n // Only read the x, y, z components and ignore w\r\n const originalTangent = Vector3.FromArray(originalTangents, i * 4);\r\n NormalizeTangent(originalTangent);\r\n\r\n // Morph target tangents omit the w component so it won't be present in the data\r\n const morphTangent = Vector3.FromArray(morphTangents, i * 3);\r\n NormalizeTangent(morphTangent);\r\n\r\n morphTangent.subtractToRef(originalTangent, difference);\r\n tangentData[i * 3] = difference.x * flipX;\r\n tangentData[i * 3 + 1] = difference.y;\r\n tangentData[i * 3 + 2] = difference.z;\r\n }\r\n const bufferView = bufferManager.createBufferView(tangentData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"TANGENT\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target tangents for mesh ${mesh.name} were not exported. Mesh does not have tangents vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasColors) {\r\n const morphColors = morphTarget.getColors()!;\r\n const originalColors = geometry.getVerticesData(VertexBuffer.ColorKind);\r\n const buffer = geometry.getVertexBuffer(VertexBuffer.ColorKind);\r\n\r\n if (originalColors && buffer) {\r\n const componentSize = buffer.getSize();\r\n\r\n vertexCount = originalColors.length / componentSize;\r\n const colorData = new Float32Array(vertexCount * componentSize);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n if (componentSize === 3) {\r\n const originalColor = Vector3.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector3.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference);\r\n colorData[i * 3] = difference.x;\r\n colorData[i * 3 + 1] = difference.y;\r\n colorData[i * 3 + 2] = difference.z;\r\n } else if (componentSize === 4) {\r\n const difference4 = new Vector4();\r\n const originalColor = Vector4.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector4.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference4);\r\n colorData[i * 4] = difference4.x;\r\n colorData[i * 4 + 1] = difference4.y;\r\n colorData[i * 4 + 2] = difference4.z;\r\n colorData[i * 4 + 3] = difference4.w;\r\n } else {\r\n Tools.Warn(`Unsupported number of components for color attribute: ${componentSize}`);\r\n }\r\n }\r\n const bufferView = bufferManager.createBufferView(colorData, floatSize * componentSize);\r\n const accessor = bufferManager.createAccessor(bufferView, componentSize === 3 ? AccessorType.VEC3 : AccessorType.VEC4, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"COLOR_0\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target colors for mesh ${mesh.name} were not exported. Mesh does not have colors vertex data`);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import type {\r\n IBufferView,\r\n IAccessor,\r\n INode,\r\n IScene,\r\n IMesh,\r\n IMaterial,\r\n ITexture,\r\n IImage,\r\n ISampler,\r\n IAnimation,\r\n IMeshPrimitive,\r\n IBuffer,\r\n IGLTF,\r\n ITextureInfo,\r\n ISkin,\r\n ICamera,\r\n} from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType, CameraType } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, IndicesArray, Nullable } from \"core/types\";\r\nimport { TmpVectors, Quaternion } from \"core/Maths/math.vector\";\r\nimport type { Matrix } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Buffer } from \"core/Buffers/buffer\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Node } from \"core/node\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { Engine } from \"core/Engines/engine\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\n\r\nimport type { IGLTFExporterExtensionV2 } from \"./glTFExporterExtension\";\r\nimport { GLTFMaterialExporter } from \"./glTFMaterialExporter\";\r\nimport type { IExportOptions } from \"./glTFSerializer\";\r\nimport { GLTFData } from \"./glTFData\";\r\nimport {\r\n ConvertToRightHandedPosition,\r\n ConvertToRightHandedRotation,\r\n DataArrayToUint8Array,\r\n GetAccessorType,\r\n GetAttributeType,\r\n GetMinMax,\r\n GetPrimitiveMode,\r\n IsTriangleFillMode,\r\n IsChildCollapsible,\r\n FloatsNeed16BitInteger,\r\n IsStandardVertexAttribute,\r\n IndicesArrayToTypedSubarray,\r\n GetVertexBufferInfo,\r\n CollapseChildIntoParent,\r\n Rotate180Y,\r\n DefaultTranslation,\r\n DefaultScale,\r\n DefaultRotation,\r\n ConvertToRightHandedTransformMatrix,\r\n} from \"./glTFUtilities\";\r\nimport { IsNoopNode } from \"../../exportUtils\";\r\nimport { BufferManager } from \"./bufferManager\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { EnumerateFloatValues, AreIndices32Bits } from \"core/Buffers/bufferUtils\";\r\nimport type { Bone, Skeleton } from \"core/Bones\";\r\nimport { _GLTFAnimation } from \"./glTFAnimation\";\r\nimport type { MorphTarget } from \"core/Morph\";\r\nimport { BuildMorphTargetBuffers } from \"./glTFMorphTargetsUtilities\";\r\nimport type { IMorphTargetData } from \"./glTFMorphTargetsUtilities\";\r\nimport { LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { GreasedLineBaseMesh } from \"core/Meshes/GreasedLine/greasedLineBaseMesh\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport { TargetCamera } from \"core/Cameras/targetCamera\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { DataWriter } from \"./dataWriter\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\n\r\nclass ExporterState {\r\n // Babylon indices array, start, count, offset, flip -> glTF accessor index\r\n private _indicesAccessorMap = new Map<Nullable<IndicesArray>, Map<number, Map<number, Map<number, Map<boolean, number>>>>>();\r\n\r\n // Babylon buffer -> glTF buffer view\r\n private _vertexBufferViewMap = new Map<Buffer, IBufferView>();\r\n\r\n // Babylon vertex buffer, start, count -> glTF accessor index\r\n private _vertexAccessorMap = new Map<VertexBuffer, Map<number, Map<number, number>>>();\r\n\r\n private _remappedBufferView = new Map<Buffer, Map<VertexBuffer, IBufferView>>();\r\n\r\n private _meshMorphTargetMap = new Map<AbstractMesh, IMorphTargetData[]>();\r\n\r\n private _vertexMapColorAlpha = new Map<VertexBuffer, boolean>();\r\n\r\n private _exportedNodes = new Set<Node>();\r\n\r\n // Babylon mesh -> glTF mesh index\r\n private _meshMap = new Map<AbstractMesh, number>();\r\n\r\n public constructor(convertToRightHanded: boolean, wasAddedByNoopNode: boolean) {\r\n this.convertToRightHanded = convertToRightHanded;\r\n this.wasAddedByNoopNode = wasAddedByNoopNode;\r\n }\r\n\r\n public readonly convertToRightHanded: boolean;\r\n\r\n public readonly wasAddedByNoopNode: boolean;\r\n\r\n // Only used when convertToRightHanded is true.\r\n public readonly convertedToRightHandedBuffers = new Map<Buffer, Uint8Array>();\r\n\r\n public getIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean): number | undefined {\r\n return this._indicesAccessorMap.get(indices)?.get(start)?.get(count)?.get(offset)?.get(flip);\r\n }\r\n\r\n public setIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean, accessorIndex: number): void {\r\n let map1 = this._indicesAccessorMap.get(indices);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, Map<number, Map<boolean, number>>>>();\r\n this._indicesAccessorMap.set(indices, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, Map<number, Map<boolean, number>>>();\r\n map1.set(start, map2);\r\n }\r\n\r\n let map3 = map2.get(count);\r\n if (!map3) {\r\n map3 = new Map<number, Map<boolean, number>>();\r\n map2.set(count, map3);\r\n }\r\n\r\n let map4 = map3.get(offset);\r\n if (!map4) {\r\n map4 = new Map<boolean, number>();\r\n map3.set(offset, map4);\r\n }\r\n\r\n map4.set(flip, accessorIndex);\r\n }\r\n\r\n public pushExportedNode(node: Node) {\r\n if (!this._exportedNodes.has(node)) {\r\n this._exportedNodes.add(node);\r\n }\r\n }\r\n\r\n public getNodesSet(): Set<Node> {\r\n return this._exportedNodes;\r\n }\r\n\r\n public getVertexBufferView(buffer: Buffer): IBufferView | undefined {\r\n return this._vertexBufferViewMap.get(buffer);\r\n }\r\n\r\n public setVertexBufferView(buffer: Buffer, bufferView: IBufferView): void {\r\n this._vertexBufferViewMap.set(buffer, bufferView);\r\n }\r\n\r\n public setRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer, bufferView: IBufferView) {\r\n this._remappedBufferView.set(buffer, new Map<VertexBuffer, IBufferView>());\r\n this._remappedBufferView.get(buffer)!.set(vertexBuffer, bufferView);\r\n }\r\n\r\n public getRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer): IBufferView | undefined {\r\n return this._remappedBufferView.get(buffer)?.get(vertexBuffer);\r\n }\r\n\r\n public getVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number): number | undefined {\r\n return this._vertexAccessorMap.get(vertexBuffer)?.get(start)?.get(count);\r\n }\r\n\r\n public setVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number, accessorIndex: number): void {\r\n let map1 = this._vertexAccessorMap.get(vertexBuffer);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, number>>();\r\n this._vertexAccessorMap.set(vertexBuffer, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, number>();\r\n map1.set(start, map2);\r\n }\r\n\r\n map2.set(count, accessorIndex);\r\n }\r\n\r\n public hasVertexColorAlpha(vertexBuffer: VertexBuffer): boolean {\r\n return this._vertexMapColorAlpha.get(vertexBuffer) || false;\r\n }\r\n\r\n public setHasVertexColorAlpha(vertexBuffer: VertexBuffer, hasAlpha: boolean) {\r\n return this._vertexMapColorAlpha.set(vertexBuffer, hasAlpha);\r\n }\r\n\r\n public getMesh(mesh: AbstractMesh): number | undefined {\r\n return this._meshMap.get(mesh);\r\n }\r\n\r\n public setMesh(mesh: AbstractMesh, meshIndex: number): void {\r\n this._meshMap.set(mesh, meshIndex);\r\n }\r\n\r\n public bindMorphDataToMesh(mesh: AbstractMesh, morphData: IMorphTargetData) {\r\n const morphTargets = this._meshMorphTargetMap.get(mesh) || [];\r\n this._meshMorphTargetMap.set(mesh, morphTargets);\r\n if (morphTargets.indexOf(morphData) === -1) {\r\n morphTargets.push(morphData);\r\n }\r\n }\r\n\r\n public getMorphTargetsFromMesh(mesh: AbstractMesh): IMorphTargetData[] | undefined {\r\n return this._meshMorphTargetMap.get(mesh);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class GLTFExporter {\r\n public readonly _glTF: IGLTF = {\r\n asset: { generator: `Babylon.js v${Engine.Version}`, version: \"2.0\" },\r\n };\r\n\r\n public readonly _animations: IAnimation[] = [];\r\n public readonly _accessors: IAccessor[] = [];\r\n public readonly _bufferViews: IBufferView[] = [];\r\n public readonly _cameras: ICamera[] = [];\r\n public readonly _images: IImage[] = [];\r\n public readonly _materials: IMaterial[] = [];\r\n public readonly _meshes: IMesh[] = [];\r\n public readonly _nodes: INode[] = [];\r\n public readonly _samplers: ISampler[] = [];\r\n public readonly _scenes: IScene[] = [];\r\n public readonly _skins: ISkin[] = [];\r\n public readonly _textures: ITexture[] = [];\r\n\r\n public readonly _babylonScene: Scene;\r\n public readonly _imageData: { [fileName: string]: Blob } = {};\r\n\r\n /**\r\n * Baked animation sample rate\r\n */\r\n private _animationSampleRate: number;\r\n\r\n private readonly _options: Required<IExportOptions>;\r\n\r\n public _shouldUseGlb: boolean = false;\r\n\r\n public readonly _materialExporter = new GLTFMaterialExporter(this);\r\n\r\n private readonly _extensions: { [name: string]: IGLTFExporterExtensionV2 } = {};\r\n\r\n public readonly _bufferManager = new BufferManager();\r\n\r\n private readonly _shouldExportNodeMap = new Map<Node, boolean>();\r\n\r\n // Babylon node -> glTF node index\r\n private readonly _nodeMap = new Map<Node, number>();\r\n\r\n // Babylon material -> glTF material index\r\n public readonly _materialMap = new Map<Material, number>();\r\n private readonly _camerasMap = new Map<Camera, ICamera>();\r\n private readonly _nodesCameraMap = new Map<ICamera, INode[]>();\r\n private readonly _skinMap = new Map<Skeleton, ISkin>();\r\n private readonly _nodesSkinMap = new Map<ISkin, INode[]>();\r\n\r\n // A material in this set requires UVs\r\n public readonly _materialNeedsUVsSet = new Set<Material>();\r\n\r\n private static readonly _ExtensionNames = new Array<string>();\r\n private static readonly _ExtensionFactories: { [name: string]: (exporter: GLTFExporter) => IGLTFExporterExtensionV2 } = {};\r\n private static readonly _ExtensionOrders: { [name: string]: number } = {};\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtension<T>(\r\n node: T,\r\n extensions: IGLTFExporterExtensionV2[],\r\n index: number,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined\r\n ): Promise<Nullable<T>> {\r\n if (index >= extensions.length) {\r\n return Promise.resolve(node);\r\n }\r\n\r\n const currentPromise = actionAsync(extensions[index], node);\r\n\r\n if (!currentPromise) {\r\n return this._ApplyExtension(node, extensions, index + 1, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line github/no-then\r\n return currentPromise.then(async (newNode) => (newNode ? await this._ApplyExtension(newNode, extensions, index + 1, actionAsync) : null));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtensions<T>(node: T, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {\r\n const extensions: IGLTFExporterExtensionV2[] = [];\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n extensions.push(this._extensions[name]);\r\n }\r\n\r\n return this._ApplyExtension(node, extensions, 0, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return this._ApplyExtensions(\r\n node,\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this._bufferManager)\r\n );\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportMaterialAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<Nullable<IMaterial>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));\r\n }\r\n\r\n /**\r\n * Get additional textures for a material\r\n * @param context The context when loading the asset\r\n * @param material The glTF material\r\n * @param babylonMaterial The Babylon.js material\r\n * @returns List of additional textures\r\n */\r\n public async _extensionsPostExportMaterialAdditionalTexturesAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const output: BaseTexture[] = [];\r\n\r\n await Promise.all(\r\n GLTFExporter._ExtensionNames.map(async (name) => {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMaterialAdditionalTexturesAsync) {\r\n const textures = await extension.postExportMaterialAdditionalTexturesAsync(context, material, babylonMaterial);\r\n output.push(...textures);\r\n }\r\n })\r\n );\r\n\r\n return output;\r\n }\r\n\r\n public _extensionsPostExportTextures(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportTexture) {\r\n extension.postExportTexture(context, textureInfo, babylonTexture);\r\n }\r\n }\r\n }\r\n\r\n public _extensionsPostExportMeshPrimitive(primitive: IMeshPrimitive): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMeshPrimitive) {\r\n extension.postExportMeshPrimitive(primitive, this._bufferManager, this._accessors);\r\n }\r\n }\r\n }\r\n\r\n public async _extensionsPreGenerateBinaryAsync(): Promise<void> {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.preGenerateBinaryAsync) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await extension.preGenerateBinaryAsync(this._bufferManager);\r\n }\r\n }\r\n }\r\n\r\n private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n if (extension.enabled) {\r\n action(extension);\r\n }\r\n }\r\n }\r\n\r\n private _extensionsOnExporting(): void {\r\n this._forEachExtensions((extension) => {\r\n if (extension.wasUsed) {\r\n this._glTF.extensionsUsed ||= [];\r\n if (this._glTF.extensionsUsed.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsUsed.push(extension.name);\r\n }\r\n\r\n if (extension.required) {\r\n this._glTF.extensionsRequired ||= [];\r\n if (this._glTF.extensionsRequired.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsRequired.push(extension.name);\r\n }\r\n }\r\n\r\n this._glTF.extensions ||= {};\r\n if (extension.onExporting) {\r\n extension.onExporting();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _loadExtensions(): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = GLTFExporter._ExtensionFactories[name](this);\r\n this._extensions[name] = extension;\r\n }\r\n }\r\n\r\n public constructor(babylonScene: Nullable<Scene> = EngineStore.LastCreatedScene, options?: IExportOptions) {\r\n if (!babylonScene) {\r\n throw new Error(\"No scene available to export\");\r\n }\r\n\r\n this._babylonScene = babylonScene;\r\n\r\n this._options = {\r\n shouldExportNode: () => true,\r\n shouldExportAnimation: () => true,\r\n metadataSelector: (metadata) => metadata?.gltf?.extras,\r\n animationSampleRate: 1 / 60,\r\n exportWithoutWaitingForScene: false,\r\n exportUnusedUVs: false,\r\n removeNoopRootNodes: true,\r\n includeCoordinateSystemConversionNodes: false,\r\n meshCompressionMethod: \"None\",\r\n ...options,\r\n };\r\n\r\n this._loadExtensions();\r\n }\r\n\r\n public dispose() {\r\n for (const key in this._extensions) {\r\n const extension = this._extensions[key];\r\n extension.dispose();\r\n }\r\n }\r\n\r\n public get options() {\r\n return this._options;\r\n }\r\n\r\n public static RegisterExtension(name: string, factory: (exporter: GLTFExporter) => IGLTFExporterExtensionV2, order: number = 100): void {\r\n if (GLTFExporter.UnregisterExtension(name)) {\r\n Tools.Warn(`Extension with the name ${name} already exists`);\r\n }\r\n\r\n GLTFExporter._ExtensionFactories[name] = factory;\r\n const extensionOrder = order ?? 0; // Use provided order or default to 0\r\n GLTFExporter._ExtensionOrders[name] = extensionOrder;\r\n\r\n // Find the correct position to insert the extension based on order\r\n let insertIndex = GLTFExporter._ExtensionNames.length;\r\n for (let i = 0; i < GLTFExporter._ExtensionNames.length; i++) {\r\n const existingName = GLTFExporter._ExtensionNames[i];\r\n const existingOrder = GLTFExporter._ExtensionOrders[existingName];\r\n\r\n // If the order is less, insert before.\r\n if (extensionOrder < existingOrder) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n GLTFExporter._ExtensionNames.splice(insertIndex, 0, name);\r\n }\r\n\r\n public static UnregisterExtension(name: string): boolean {\r\n if (!GLTFExporter._ExtensionFactories[name]) {\r\n return false;\r\n }\r\n delete GLTFExporter._ExtensionFactories[name];\r\n delete GLTFExporter._ExtensionOrders[name];\r\n\r\n const index = GLTFExporter._ExtensionNames.indexOf(name);\r\n if (index !== -1) {\r\n GLTFExporter._ExtensionNames.splice(index, 1);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _generateJSON(bufferByteLength: number, fileName?: string, prettyPrint?: boolean): string {\r\n const buffer: IBuffer = { byteLength: bufferByteLength };\r\n\r\n if (buffer.byteLength) {\r\n this._glTF.buffers = [buffer];\r\n }\r\n if (this._nodes && this._nodes.length) {\r\n this._glTF.nodes = this._nodes;\r\n }\r\n if (this._meshes && this._meshes.length) {\r\n this._glTF.meshes = this._meshes;\r\n }\r\n if (this._scenes && this._scenes.length) {\r\n this._glTF.scenes = this._scenes;\r\n this._glTF.scene = 0;\r\n }\r\n if (this._cameras && this._cameras.length) {\r\n this._glTF.cameras = this._cameras;\r\n }\r\n if (this._bufferViews && this._bufferViews.length) {\r\n this._glTF.bufferViews = this._bufferViews;\r\n }\r\n if (this._accessors && this._accessors.length) {\r\n this._glTF.accessors = this._accessors;\r\n }\r\n if (this._animations && this._animations.length) {\r\n this._glTF.animations = this._animations;\r\n }\r\n if (this._materials && this._materials.length) {\r\n this._glTF.materials = this._materials;\r\n }\r\n if (this._textures && this._textures.length) {\r\n this._glTF.textures = this._textures;\r\n }\r\n if (this._samplers && this._samplers.length) {\r\n this._glTF.samplers = this._samplers;\r\n }\r\n if (this._skins && this._skins.length) {\r\n this._glTF.skins = this._skins;\r\n }\r\n if (this._images && this._images.length) {\r\n this._glTF.images = this._images;\r\n }\r\n\r\n if (!this._shouldUseGlb) {\r\n buffer.uri = fileName + \".bin\";\r\n }\r\n\r\n return prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);\r\n }\r\n\r\n public async generateGLTFAsync(glTFPrefix: string): Promise<GLTFData> {\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength, glTFPrefix, true);\r\n\r\n const bin = new Blob([binaryBuffer], { type: \"application/octet-stream\" });\r\n\r\n const glTFFileName = glTFPrefix + \".gltf\";\r\n const glTFBinFile = glTFPrefix + \".bin\";\r\n\r\n const container = new GLTFData();\r\n\r\n container.files[glTFFileName] = jsonText;\r\n container.files[glTFBinFile] = bin;\r\n\r\n if (this._imageData) {\r\n for (const image in this._imageData) {\r\n container.files[image] = this._imageData[image];\r\n }\r\n }\r\n\r\n return container;\r\n }\r\n\r\n private async _generateBinaryAsync(): Promise<Uint8Array> {\r\n await this._exportSceneAsync();\r\n await this._extensionsPreGenerateBinaryAsync();\r\n return this._bufferManager.generateBinary(this._bufferViews);\r\n }\r\n\r\n /**\r\n * Pads the number to a multiple of 4\r\n * @param num number to pad\r\n * @returns padded number\r\n */\r\n private _getPadding(num: number): number {\r\n const remainder = num % 4;\r\n const padding = remainder === 0 ? remainder : 4 - remainder;\r\n\r\n return padding;\r\n }\r\n\r\n public async generateGLBAsync(glTFPrefix: string): Promise<GLTFData> {\r\n this._shouldUseGlb = true;\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength);\r\n\r\n const glbFileName = glTFPrefix + \".glb\";\r\n const headerLength = 12;\r\n const chunkLengthPrefix = 8;\r\n let jsonLength = jsonText.length;\r\n let encodedJsonText;\r\n // Make use of TextEncoder when available\r\n if (typeof TextEncoder !== \"undefined\") {\r\n const encoder = new TextEncoder();\r\n encodedJsonText = encoder.encode(jsonText);\r\n jsonLength = encodedJsonText.length;\r\n }\r\n const jsonPadding = this._getPadding(jsonLength);\r\n const binPadding = this._getPadding(binaryBuffer.byteLength);\r\n\r\n const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding;\r\n\r\n const dataWriter = new DataWriter(byteLength);\r\n\r\n // Header\r\n dataWriter.writeUInt32(0x46546c67); // \"glTF\"\r\n dataWriter.writeUInt32(2); // Version\r\n dataWriter.writeUInt32(byteLength); // Total bytes in file\r\n\r\n // JSON chunk length prefix\r\n dataWriter.writeUInt32(jsonLength + jsonPadding);\r\n dataWriter.writeUInt32(0x4e4f534a); // \"JSON\"\r\n\r\n // JSON chunk bytes\r\n if (encodedJsonText) {\r\n // If TextEncoder was available, we can simply copy the encoded array\r\n dataWriter.writeTypedArray(encodedJsonText);\r\n } else {\r\n const blankCharCode = \"_\".charCodeAt(0);\r\n for (let i = 0; i < jsonLength; ++i) {\r\n const charCode = jsonText.charCodeAt(i);\r\n // If the character doesn't fit into a single UTF-16 code unit, just put a blank character\r\n if (charCode != jsonText.codePointAt(i)) {\r\n dataWriter.writeUInt8(blankCharCode);\r\n } else {\r\n dataWriter.writeUInt8(charCode);\r\n }\r\n }\r\n }\r\n\r\n // JSON padding\r\n for (let i = 0; i < jsonPadding; ++i) {\r\n dataWriter.writeUInt8(0x20);\r\n }\r\n\r\n // Binary chunk length prefix\r\n dataWriter.writeUInt32(binaryBuffer.byteLength + binPadding);\r\n dataWriter.writeUInt32(0x004e4942); // \"BIN\"\r\n\r\n // Binary chunk bytes\r\n dataWriter.writeTypedArray(binaryBuffer);\r\n\r\n // Binary padding\r\n for (let i = 0; i < binPadding; ++i) {\r\n dataWriter.writeUInt8(0);\r\n }\r\n\r\n const container = new GLTFData();\r\n container.files[glbFileName] = new Blob([dataWriter.getOutputData()], { type: \"application/octet-stream\" });\r\n\r\n return container;\r\n }\r\n\r\n private _setNodeTransformation(node: INode, babylonTransformNode: TransformNode, convertToRightHanded: boolean): void {\r\n if (!babylonTransformNode.getPivotPoint().equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n Tools.Warn(\"Pivot points are not supported in the glTF serializer\");\r\n }\r\n\r\n if (!babylonTransformNode.position.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonTransformNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!babylonTransformNode.scaling.equalsWithEpsilon(DefaultScale, Epsilon)) {\r\n node.scale = babylonTransformNode.scaling.asArray();\r\n }\r\n\r\n const rotationQuaternion =\r\n babylonTransformNode.rotationQuaternion?.clone() ||\r\n Quaternion.FromEulerAngles(babylonTransformNode.rotation.x, babylonTransformNode.rotation.y, babylonTransformNode.rotation.z);\r\n\r\n if (!rotationQuaternion.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _setCameraTransformation(node: INode, babylonCamera: TargetCamera, convertToRightHanded: boolean): void {\r\n // Camera types store rotation differently (e.g., ArcRotateCamera uses alpha/beta, others use rotationQuaternion).\r\n // Extract the transform from the world matrix instead of handling each case separately.\r\n const translation = TmpVectors.Vector3[0];\r\n const rotationQuaternion = TmpVectors.Quaternion[0];\r\n const cameraWorldMatrix = babylonCamera.getWorldMatrix();\r\n\r\n if (babylonCamera.parent) {\r\n // Camera.getWorldMatrix returns global coordinates. GLTF node must use local coordinates. If camera has parent we need to use local translation/rotation.\r\n const parentInvWorldMatrix = babylonCamera.parent.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n const cameraLocal = cameraWorldMatrix.multiplyToRef(parentInvWorldMatrix, TmpVectors.Matrix[1]);\r\n cameraLocal.decompose(undefined, rotationQuaternion, translation);\r\n } else {\r\n cameraWorldMatrix.decompose(undefined, rotationQuaternion, translation);\r\n }\r\n\r\n if (!translation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n // Left-handed scenes have cameras that always face Z+ (opposite of glTF's Z-).\r\n // Use scene coordinate system rather than convertToRightHanded, since some\r\n // cameras may not need convertToRightHanded but still need correction to face Z-.\r\n if (!this._babylonScene.useRightHandedSystem) {\r\n Rotate180Y(rotationQuaternion);\r\n }\r\n\r\n if (!rotationQuaternion.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n node.rotation = rotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n // Export babylon cameras to glTF cameras\r\n private _listAvailableCameras(): void {\r\n for (const camera of this._babylonScene.cameras) {\r\n const glTFCamera: ICamera = {\r\n type: camera.mode === Camera.PERSPECTIVE_CAMERA ? CameraType.PERSPECTIVE : CameraType.ORTHOGRAPHIC,\r\n };\r\n\r\n if (camera.name) {\r\n glTFCamera.name = camera.name;\r\n }\r\n\r\n if (glTFCamera.type === CameraType.PERSPECTIVE) {\r\n glTFCamera.perspective = {\r\n aspectRatio: camera.getEngine().getAspectRatio(camera),\r\n yfov: camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera),\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n } else if (glTFCamera.type === CameraType.ORTHOGRAPHIC) {\r\n const halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;\r\n const halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;\r\n glTFCamera.orthographic = {\r\n xmag: halfWidth,\r\n ymag: halfHeight,\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n }\r\n this._camerasMap.set(camera, glTFCamera);\r\n }\r\n }\r\n\r\n // Cleanup unused cameras and assign index to nodes.\r\n private _exportAndAssignCameras(): void {\r\n const gltfCameras = Array.from(this._camerasMap.values());\r\n for (const gltfCamera of gltfCameras) {\r\n const usedNodes = this._nodesCameraMap.get(gltfCamera);\r\n if (usedNodes !== undefined) {\r\n this._cameras.push(gltfCamera);\r\n for (const node of usedNodes) {\r\n node.camera = this._cameras.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Collects all skins in a skins map so nodes can reference it during node parsing.\r\n private _listAvailableSkeletons(): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin: ISkin = { joints: [] };\r\n this._skinMap.set(skeleton, skin);\r\n }\r\n }\r\n\r\n private _exportAndAssignSkeletons(leftHandNodes: Set<Node>): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin = this._skinMap.get(skeleton);\r\n if (skin == undefined) {\r\n continue;\r\n }\r\n\r\n // The bones (joints) of a skeleton (skin) must be exported in the same order as they appear in vertex attributes,\r\n // which is indicated by getIndex and may not match a bone's index in skeleton.bones\r\n const boneIndexMap: { [index: number]: Bone } = {};\r\n let maxBoneIndex = -1;\r\n for (let i = 0; i < skeleton.bones.length; ++i) {\r\n const bone = skeleton.bones[i];\r\n const boneIndex = bone.getIndex() ?? i;\r\n if (boneIndex !== -1) {\r\n boneIndexMap[boneIndex] = bone;\r\n if (boneIndex > maxBoneIndex) {\r\n maxBoneIndex = boneIndex;\r\n }\r\n }\r\n }\r\n\r\n // Set joints indices to scene nodes.\r\n const inverseBindMatrices: Matrix[] = [];\r\n for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {\r\n const bone = boneIndexMap[boneIndex]; // Assumes no gaps in bone indices\r\n const transformNode = bone.getTransformNode();\r\n const nodeIndex = transformNode ? this._nodeMap.get(transformNode) : undefined;\r\n if (nodeIndex === undefined) {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported.\");\r\n continue; // The indices may be out-of-sync after this and break the skinning.\r\n }\r\n skin.joints.push(nodeIndex);\r\n\r\n const boneMatrix = bone.getAbsoluteInverseBindMatrix().clone();\r\n if (leftHandNodes.has(transformNode!)) {\r\n ConvertToRightHandedTransformMatrix(boneMatrix);\r\n }\r\n inverseBindMatrices.push(boneMatrix);\r\n }\r\n\r\n // Nodes that use this skin.\r\n const skinnedNodes = this._nodesSkinMap.get(skin);\r\n\r\n // Only export the skin if it has at least one joint and is used by a mesh.\r\n if (skin.joints.length > 0 && skinnedNodes !== undefined) {\r\n const inverseBindMatricesData = new Float32Array(inverseBindMatrices.length * 16); // Always a 4 x 4 matrix of 32 bit float\r\n inverseBindMatrices.forEach((mat: Matrix, index: number) => {\r\n inverseBindMatricesData.set(mat.m, index * 16);\r\n });\r\n\r\n const bufferView = this._bufferManager.createBufferView(inverseBindMatricesData);\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.MAT4, AccessorComponentType.FLOAT, inverseBindMatrices.length));\r\n skin.inverseBindMatrices = this._accessors.length - 1;\r\n\r\n this._skins.push(skin);\r\n const skinIndex = this._skins.length - 1;\r\n for (const skinnedNode of skinnedNodes) {\r\n skinnedNode.skin = skinIndex;\r\n }\r\n }\r\n }\r\n }\r\n\r\n private async _exportSceneAsync(): Promise<void> {\r\n const scene: IScene = { nodes: [] };\r\n\r\n // Scene metadata\r\n if (this._babylonScene.metadata) {\r\n const extras = this._options.metadataSelector(this._babylonScene.metadata);\r\n if (extras) {\r\n scene.extras = extras;\r\n }\r\n }\r\n\r\n // TODO:\r\n // deal with this from the loader:\r\n // babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;\r\n // babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem;\r\n\r\n const rootNodesRH = new Array<Node>();\r\n const rootNodesLH = new Array<Node>();\r\n const rootNoopNodesRH = new Array<Node>();\r\n\r\n for (const rootNode of this._babylonScene.rootNodes) {\r\n if (this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes && IsNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) {\r\n rootNoopNodesRH.push(...rootNode.getChildren());\r\n } else if (this._babylonScene.useRightHandedSystem) {\r\n rootNodesRH.push(rootNode);\r\n } else {\r\n rootNodesLH.push(rootNode);\r\n }\r\n }\r\n\r\n this._listAvailableCameras();\r\n this._listAvailableSkeletons();\r\n\r\n const stateLH = new ExporterState(true, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesLH, stateLH)));\r\n const stateRH = new ExporterState(false, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesRH, stateRH)));\r\n const noopRH = new ExporterState(false, true);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNoopNodesRH, noopRH)));\r\n\r\n if (scene.nodes.length) {\r\n this._scenes.push(scene);\r\n }\r\n\r\n this._exportAndAssignCameras();\r\n this._exportAndAssignSkeletons(stateLH.getNodesSet());\r\n\r\n if (this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(\r\n this._babylonScene,\r\n this._animations,\r\n this._nodeMap,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n stateLH.getNodesSet(),\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n private _shouldExportNode(babylonNode: Node): boolean {\r\n let result = this._shouldExportNodeMap.get(babylonNode);\r\n\r\n if (result === undefined) {\r\n result = this._options.shouldExportNode(babylonNode);\r\n this._shouldExportNodeMap.set(babylonNode, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async _exportNodesAsync(babylonRootNodes: Node[], state: ExporterState): Promise<number[]> {\r\n const nodes = new Array<number>();\r\n\r\n this._exportBuffers(babylonRootNodes, state);\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonNode, nodes, state);\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n private _collectBuffers(\r\n babylonNode: Node,\r\n bufferToVertexBuffersMap: Map<Buffer, VertexBuffer[]>,\r\n vertexBufferToMeshesMap: Map<VertexBuffer, AbstractMesh[]>,\r\n morphTargetsToMeshesMap: Map<MorphTarget, AbstractMesh[]>,\r\n state: ExporterState\r\n ): void {\r\n if (this._shouldExportNode(babylonNode) && babylonNode instanceof AbstractMesh && babylonNode.geometry) {\r\n const vertexBuffers = babylonNode.geometry.getVertexBuffers();\r\n if (vertexBuffers) {\r\n for (const kind in vertexBuffers) {\r\n if (!IsStandardVertexAttribute(kind)) {\r\n continue;\r\n }\r\n const vertexBuffer = vertexBuffers[kind];\r\n state.setHasVertexColorAlpha(vertexBuffer, babylonNode.hasVertexAlpha);\r\n const buffer = vertexBuffer._buffer;\r\n const vertexBufferArray = bufferToVertexBuffersMap.get(buffer) || [];\r\n bufferToVertexBuffersMap.set(buffer, vertexBufferArray);\r\n if (vertexBufferArray.indexOf(vertexBuffer) === -1) {\r\n vertexBufferArray.push(vertexBuffer);\r\n }\r\n\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer) || [];\r\n vertexBufferToMeshesMap.set(vertexBuffer, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n\r\n if (morphTargetManager) {\r\n for (let morphIndex = 0; morphIndex < morphTargetManager.numTargets; morphIndex++) {\r\n const morphTarget = morphTargetManager.getTarget(morphIndex);\r\n\r\n const meshes = morphTargetsToMeshesMap.get(morphTarget) || [];\r\n morphTargetsToMeshesMap.set(morphTarget, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n this._collectBuffers(babylonChildNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsToMeshesMap, state);\r\n }\r\n }\r\n\r\n private _exportBuffers(babylonRootNodes: Node[], state: ExporterState): void {\r\n const bufferToVertexBuffersMap = new Map<Buffer, VertexBuffer[]>();\r\n const vertexBufferToMeshesMap = new Map<VertexBuffer, AbstractMesh[]>();\r\n const morphTargetsMeshesMap = new Map<MorphTarget, AbstractMesh[]>();\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n this._collectBuffers(babylonNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsMeshesMap, state);\r\n }\r\n\r\n const buffers = Array.from(bufferToVertexBuffersMap.keys());\r\n\r\n for (const buffer of buffers) {\r\n const data = buffer.getData();\r\n if (!data) {\r\n throw new Error(\"Buffer data is not available\");\r\n }\r\n\r\n const vertexBuffers = bufferToVertexBuffersMap.get(buffer);\r\n\r\n if (!vertexBuffers) {\r\n continue;\r\n }\r\n\r\n const byteStride = vertexBuffers[0].byteStride;\r\n if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {\r\n throw new Error(\"Vertex buffers pointing to the same buffer must have the same byte stride\");\r\n }\r\n\r\n const bytes = DataArrayToUint8Array(data).slice();\r\n\r\n // Apply normalizations and color corrections to buffer data in-place.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n // Normalize normals and tangents.\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);\r\n if (length > 0) {\r\n const invLength = 1 / length;\r\n values[0] *= invLength;\r\n values[1] *= invLength;\r\n values[2] *= invLength;\r\n }\r\n });\r\n break;\r\n }\r\n // Convert StandardMaterial vertex colors from gamma to linear space.\r\n case VertexBuffer.ColorKind: {\r\n const stdMaterialCount = meshes.filter((mesh) => mesh.material instanceof StandardMaterial || mesh.material == null).length;\r\n if (stdMaterialCount == 0) {\r\n break; // Buffer not used by StandardMaterials, so no conversion needed.\r\n }\r\n // TODO: Implement this case.\r\n if (stdMaterialCount != meshes.length) {\r\n Logger.Warn(\"Not converting vertex color space, as buffer is shared by StandardMaterials and other material types. Results may look incorrect.\");\r\n break;\r\n }\r\n if (type == VertexBuffer.UNSIGNED_BYTE) {\r\n Logger.Warn(\"Converting uint8 vertex colors to linear space. Results may look incorrect.\");\r\n }\r\n\r\n const vertexData3 = new Color3();\r\n const vertexData4 = new Color4();\r\n const useExactSrgbConversions = this._babylonScene.getEngine().useExactSrgbConversions;\r\n\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n // Using separate Color3 and Color4 objects to ensure the right functions are called.\r\n if (values.length === 3) {\r\n vertexData3.fromArray(values, 0);\r\n vertexData3.toLinearSpaceToRef(vertexData3, useExactSrgbConversions);\r\n vertexData3.toArray(values, 0);\r\n } else {\r\n vertexData4.fromArray(values, 0);\r\n vertexData4.toLinearSpaceToRef(vertexData4, useExactSrgbConversions);\r\n vertexData4.toArray(values, 0);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Perform coordinate conversions, if needed, to buffer data in-place (only for positions, normals and tangents).\r\n if (state.convertToRightHanded) {\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n values[0] = -values[0];\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Save converted bytes for min/max computation.\r\n state.convertedToRightHandedBuffers.set(buffer, bytes);\r\n }\r\n\r\n // Create buffer view, but defer accessor creation for later. Instead, track it via ExporterState.\r\n const bufferView = this._bufferManager.createBufferView(bytes, byteStride);\r\n state.setVertexBufferView(buffer, bufferView);\r\n\r\n const floatMatricesIndices = new Map<VertexBuffer, FloatArray>();\r\n\r\n // If buffers are of type MatricesIndicesKind and have float values, we need to create a new buffer instead.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { kind, totalVertices } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n switch (kind) {\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n if (vertexBuffer.type == VertexBuffer.FLOAT) {\r\n const floatData = vertexBuffer.getFloatData(totalVertices);\r\n if (floatData !== null) {\r\n floatMatricesIndices.set(vertexBuffer, floatData);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (floatMatricesIndices.size !== 0) {\r\n Logger.Warn(\r\n `Joint indices conversion needed: some joint indices are stored as floats in Babylon but GLTF requires UNSIGNED BYTES. We will perform the conversion but this might lead to unused data in the buffer.`\r\n );\r\n }\r\n\r\n const floatArrayVertexBuffers = Array.from(floatMatricesIndices.keys());\r\n\r\n for (const vertexBuffer of floatArrayVertexBuffers) {\r\n const array = floatMatricesIndices.get(vertexBuffer);\r\n\r\n if (!array) {\r\n continue;\r\n }\r\n\r\n const is16Bit = FloatsNeed16BitInteger(array);\r\n const newArray = new (is16Bit ? Uint16Array : Uint8Array)(array.length);\r\n for (let index = 0; index < array.length; index++) {\r\n newArray[index] = array[index];\r\n }\r\n const bufferView = this._bufferManager.createBufferView(newArray, 4 * (is16Bit ? 2 : 1));\r\n state.setRemappedBufferView(buffer, vertexBuffer, bufferView);\r\n }\r\n }\r\n\r\n // Build morph targets buffers\r\n const morphTargets = Array.from(morphTargetsMeshesMap.keys());\r\n\r\n for (const morphTarget of morphTargets) {\r\n const meshes = morphTargetsMeshesMap.get(morphTarget);\r\n\r\n if (!meshes) {\r\n continue;\r\n }\r\n\r\n const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this._bufferManager, this._bufferViews, this._accessors, state.convertToRightHanded);\r\n\r\n for (const mesh of meshes) {\r\n state.bindMorphDataToMesh(mesh, glTFMorphTarget);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Processes a node to be exported to the glTF file\r\n * @returns A promise that resolves once the node has been exported\r\n * @internal\r\n */\r\n private async _exportNodeAsync(babylonNode: Node, parentNodeChildren: Array<number>, state: ExporterState): Promise<void> {\r\n let nodeIndex = this._nodeMap.get(babylonNode);\r\n if (nodeIndex !== undefined) {\r\n if (!parentNodeChildren.includes(nodeIndex)) {\r\n parentNodeChildren.push(nodeIndex);\r\n }\r\n return;\r\n }\r\n\r\n const node = await this._createNodeAsync(babylonNode, state);\r\n\r\n if (node) {\r\n nodeIndex = this._nodes.length;\r\n this._nodes.push(node);\r\n this._nodeMap.set(babylonNode, nodeIndex);\r\n state.pushExportedNode(babylonNode);\r\n parentNodeChildren.push(nodeIndex);\r\n\r\n // Process node's animations once the node has been added to nodeMap (TODO: This should be refactored)\r\n const runtimeGLTFAnimation: IAnimation = {\r\n name: \"runtime animations\",\r\n channels: [],\r\n samplers: [],\r\n };\r\n const idleGLTFAnimations: IAnimation[] = [];\r\n\r\n if (!this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n if (babylonNode.animations.length) {\r\n _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {\r\n this._animations.push(runtimeGLTFAnimation);\r\n }\r\n idleGLTFAnimations.forEach((idleGLTFAnimation) => {\r\n if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {\r\n this._animations.push(idleGLTFAnimation);\r\n }\r\n });\r\n }\r\n\r\n // Begin processing child nodes once parent has been added to the node list\r\n const children = node ? [] : parentNodeChildren;\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonChildNode, children, state);\r\n }\r\n\r\n if (node && children.length) {\r\n node.children = children;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a glTF node from a Babylon.js node. If skipped, returns null.\r\n * @internal\r\n */\r\n private async _createNodeAsync(babylonNode: Node, state: ExporterState): Promise<Nullable<INode>> {\r\n if (!this._shouldExportNode(babylonNode)) {\r\n return null;\r\n }\r\n\r\n const node: INode = {};\r\n\r\n if (babylonNode.name) {\r\n node.name = babylonNode.name;\r\n }\r\n\r\n // Node metadata\r\n if (babylonNode.metadata) {\r\n const extras = this._options.metadataSelector(babylonNode.metadata);\r\n if (extras) {\r\n node.extras = extras;\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TransformNode) {\r\n this._setNodeTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n if (babylonNode instanceof AbstractMesh) {\r\n const babylonMesh = babylonNode instanceof InstancedMesh ? babylonNode.sourceMesh : (babylonNode as Mesh);\r\n if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {\r\n node.mesh = await this._exportMeshAsync(babylonMesh, state);\r\n }\r\n\r\n if (babylonNode.skeleton) {\r\n const skin = this._skinMap.get(babylonNode.skeleton);\r\n\r\n if (skin !== undefined) {\r\n if (this._nodesSkinMap.get(skin) === undefined) {\r\n this._nodesSkinMap.set(skin, []);\r\n }\r\n\r\n this._nodesSkinMap.get(skin)?.push(node);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TargetCamera) {\r\n const gltfCamera = this._camerasMap.get(babylonNode);\r\n\r\n if (gltfCamera) {\r\n if (this._nodesCameraMap.get(gltfCamera) === undefined) {\r\n this._nodesCameraMap.set(gltfCamera, []);\r\n }\r\n\r\n this._setCameraTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n // If a parent node exists and can be collapsed, merge their transformations and mark the parent as the camera-containing node.\r\n const parentBabylonNode = babylonNode.parent;\r\n if (parentBabylonNode !== null && IsChildCollapsible(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = this._nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex !== undefined) {\r\n const parentNode = this._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n this._nodesCameraMap.get(gltfCamera)?.push(parentNode);\r\n return null; // Skip exporting the original child node\r\n }\r\n }\r\n\r\n this._nodesCameraMap.get(gltfCamera)?.push(node);\r\n }\r\n }\r\n\r\n // Apply extensions to the node. If this resolves to null, it means we should skip exporting this node\r\n const processedNode = await this._extensionsPostExportNodeAsync(\"exportNodeAsync\", node, babylonNode, this._nodeMap, state.convertToRightHanded);\r\n if (!processedNode) {\r\n Logger.Warn(`Not exporting node ${babylonNode.name}`);\r\n return null;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n private _exportIndices(\r\n indices: Nullable<IndicesArray>,\r\n is32Bits: boolean,\r\n start: number,\r\n count: number,\r\n offset: number,\r\n fillMode: number,\r\n sideOrientation: number,\r\n state: ExporterState,\r\n primitive: IMeshPrimitive\r\n ): void {\r\n let indicesToExport = indices;\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n // Flip indices if triangle winding order is not CCW, as glTF is always CCW.\r\n const flip = sideOrientation !== Material.CounterClockWiseSideOrientation && IsTriangleFillMode(fillMode);\r\n if (flip) {\r\n if (fillMode === Material.TriangleStripDrawMode || fillMode === Material.TriangleFanDrawMode) {\r\n throw new Error(\"Triangle strip/fan fill mode is not implemented\");\r\n }\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n\r\n if (indices) {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = indices[start + i] + offset;\r\n newIndices[i + 1] = indices[start + i + 2] + offset;\r\n newIndices[i + 2] = indices[start + i + 1] + offset;\r\n }\r\n } else {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = i;\r\n newIndices[i + 1] = i + 2;\r\n newIndices[i + 2] = i + 1;\r\n }\r\n }\r\n\r\n indicesToExport = newIndices;\r\n } else if (indices && offset !== 0) {\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n for (let i = 0; i < count; i++) {\r\n newIndices[i] = indices[start + i] + offset;\r\n }\r\n\r\n indicesToExport = newIndices;\r\n }\r\n\r\n if (indicesToExport) {\r\n let accessorIndex = state.getIndicesAccessor(indices, start, count, offset, flip);\r\n if (accessorIndex === undefined) {\r\n const bytes = IndicesArrayToTypedSubarray(indicesToExport, start, count, is32Bits);\r\n const bufferView = this._bufferManager.createBufferView(bytes);\r\n\r\n const componentType = is32Bits ? AccessorComponentType.UNSIGNED_INT : AccessorComponentType.UNSIGNED_SHORT;\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.SCALAR, componentType, count, 0));\r\n accessorIndex = this._accessors.length - 1;\r\n state.setIndicesAccessor(indices, start, count, offset, flip, accessorIndex);\r\n }\r\n\r\n primitive.indices = accessorIndex;\r\n }\r\n }\r\n\r\n private _exportVertexBuffer(vertexBuffer: VertexBuffer, babylonMaterial: Material, start: number, count: number, state: ExporterState, primitive: IMeshPrimitive): void {\r\n const kind = vertexBuffer.getKind();\r\n\r\n if (!IsStandardVertexAttribute(kind)) {\r\n return;\r\n }\r\n\r\n if (kind.startsWith(\"uv\") && !this._options.exportUnusedUVs) {\r\n if (!babylonMaterial || !this._materialNeedsUVsSet.has(babylonMaterial)) {\r\n return;\r\n }\r\n }\r\n\r\n let accessorIndex = state.getVertexAccessor(vertexBuffer, start, count);\r\n\r\n if (accessorIndex === undefined) {\r\n // Get min/max from converted or original data.\r\n const data = state.convertedToRightHandedBuffers.get(vertexBuffer._buffer) || vertexBuffer._buffer.getData()!;\r\n const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) : undefined;\r\n\r\n // For the remapped buffer views we created for float matrices indices, make sure to use their updated information.\r\n const isFloatMatricesIndices =\r\n (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) && vertexBuffer.type === VertexBuffer.FLOAT;\r\n\r\n const vertexBufferType = isFloatMatricesIndices ? VertexBuffer.UNSIGNED_BYTE : vertexBuffer.type;\r\n const vertexBufferNormalized = isFloatMatricesIndices ? undefined : vertexBuffer.normalized;\r\n const bufferView = isFloatMatricesIndices ? state.getRemappedBufferView(vertexBuffer._buffer, vertexBuffer)! : state.getVertexBufferView(vertexBuffer._buffer)!;\r\n\r\n const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;\r\n this._accessors.push(\r\n this._bufferManager.createAccessor(\r\n bufferView,\r\n GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)),\r\n vertexBufferType,\r\n count,\r\n byteOffset,\r\n minMax,\r\n vertexBufferNormalized // TODO: Find other places where this is needed.\r\n )\r\n );\r\n accessorIndex = this._accessors.length - 1;\r\n state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);\r\n }\r\n\r\n primitive.attributes[GetAttributeType(kind)] = accessorIndex;\r\n }\r\n\r\n private async _exportMaterialAsync(babylonMaterial: Material, vertexBuffers: { [kind: string]: VertexBuffer }, subMesh: SubMesh, primitive: IMeshPrimitive): Promise<void> {\r\n let materialIndex = this._materialMap.get(babylonMaterial);\r\n if (materialIndex === undefined) {\r\n const hasUVs = vertexBuffers && Object.keys(vertexBuffers).some((kind) => kind.startsWith(\"uv\"));\r\n babylonMaterial = babylonMaterial instanceof MultiMaterial ? babylonMaterial.subMaterials[subMesh.materialIndex]! : babylonMaterial;\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n materialIndex = await this._materialExporter.exportPBRMaterialAsync(babylonMaterial, hasUVs);\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n materialIndex = await this._materialExporter.exportStandardMaterialAsync(babylonMaterial, hasUVs);\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n materialIndex = await this._materialExporter.exportOpenPBRMaterialAsync(babylonMaterial, hasUVs);\r\n } else {\r\n Logger.Warn(`Unsupported material '${babylonMaterial.name}' with type ${babylonMaterial.getClassName()}`);\r\n return;\r\n }\r\n\r\n this._materialMap.set(babylonMaterial, materialIndex);\r\n }\r\n\r\n primitive.material = materialIndex;\r\n }\r\n\r\n private async _exportMeshAsync(babylonMesh: Mesh, state: ExporterState): Promise<number> {\r\n let meshIndex = state.getMesh(babylonMesh);\r\n if (meshIndex !== undefined) {\r\n return meshIndex;\r\n }\r\n\r\n const mesh: IMesh = { primitives: [] };\r\n meshIndex = this._meshes.length;\r\n this._meshes.push(mesh);\r\n state.setMesh(babylonMesh, meshIndex);\r\n\r\n const indices = babylonMesh.isUnIndexed ? null : babylonMesh.getIndices();\r\n const vertexBuffers = babylonMesh.geometry?.getVertexBuffers();\r\n const morphTargets = state.getMorphTargetsFromMesh(babylonMesh);\r\n\r\n const isLinesMesh = babylonMesh instanceof LinesMesh;\r\n const isGreasedLineMesh = babylonMesh instanceof GreasedLineBaseMesh;\r\n\r\n const subMeshes = babylonMesh.subMeshes;\r\n if (vertexBuffers && subMeshes && subMeshes.length > 0) {\r\n for (const subMesh of subMeshes) {\r\n const primitive: IMeshPrimitive = { attributes: {} };\r\n\r\n const babylonMaterial = subMesh.getMaterial() || this._babylonScene.defaultMaterial;\r\n\r\n if (isGreasedLineMesh) {\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n const colorWhite = Color3.White();\r\n const alpha = babylonLinesMesh.material?.alpha ?? 1;\r\n const color = babylonLinesMesh.greasedLineMaterial?.color ?? colorWhite;\r\n if (!color.equalsWithEpsilon(colorWhite, Epsilon) || alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...color.asArray(), alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else if (isLinesMesh) {\r\n // Special case for LinesMesh\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n if (!babylonLinesMesh.color.equalsWithEpsilon(Color3.White(), Epsilon) || babylonLinesMesh.alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...babylonLinesMesh.color.asArray(), babylonLinesMesh.alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else {\r\n // Material\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportMaterialAsync(babylonMaterial, vertexBuffers, subMesh, primitive);\r\n }\r\n\r\n // Index buffer\r\n const fillMode = isLinesMesh || isGreasedLineMesh ? Material.LineListDrawMode : (babylonMesh.overrideRenderingFillMode ?? babylonMaterial.fillMode);\r\n\r\n let sideOrientation = babylonMaterial._getEffectiveOrientation(babylonMesh);\r\n if (state.wasAddedByNoopNode && !babylonMesh.getScene().useRightHandedSystem) {\r\n // To properly remove a conversion node, we must also cancel out the implicit flip in its children's side orientations.\r\n sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\r\n }\r\n\r\n this._exportIndices(\r\n indices,\r\n indices ? AreIndices32Bits(indices, subMesh.indexCount, subMesh.indexStart, subMesh.verticesStart) : subMesh.verticesCount > 65535,\r\n indices ? subMesh.indexStart : subMesh.verticesStart,\r\n indices ? subMesh.indexCount : subMesh.verticesCount,\r\n -subMesh.verticesStart,\r\n fillMode,\r\n sideOrientation,\r\n state,\r\n primitive\r\n );\r\n\r\n // Vertex buffers\r\n for (const vertexBuffer of Object.values(vertexBuffers)) {\r\n this._exportVertexBuffer(vertexBuffer, babylonMaterial, subMesh.verticesStart, subMesh.verticesCount, state, primitive);\r\n }\r\n\r\n if (morphTargets) {\r\n primitive.targets = [];\r\n for (const gltfMorphTarget of morphTargets) {\r\n primitive.targets.push(gltfMorphTarget.attributes);\r\n }\r\n }\r\n\r\n mesh.primitives.push(primitive);\r\n this._extensionsPostExportMeshPrimitive(primitive);\r\n }\r\n }\r\n\r\n if (morphTargets) {\r\n mesh.weights = [];\r\n\r\n if (!mesh.extras) {\r\n mesh.extras = {};\r\n }\r\n mesh.extras.targetNames = [];\r\n\r\n for (const gltfMorphTarget of morphTargets) {\r\n mesh.weights.push(gltfMorphTarget.influence);\r\n mesh.extras.targetNames.push(gltfMorphTarget.name);\r\n }\r\n }\r\n\r\n return meshIndex;\r\n }\r\n}\r\n","import type { Node } from \"core/node\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Animation } from \"core/Animations/animation\";\r\nimport type { GLTFData } from \"./glTFData\";\r\nimport { GLTFExporter } from \"./glTFExporter\";\r\n\r\n/**\r\n * Mesh compression methods.\r\n */\r\nexport type MeshCompressionMethod = \"None\" | \"Draco\";\r\n\r\n/**\r\n * Holds a collection of exporter options and parameters\r\n */\r\nexport interface IExportOptions {\r\n /**\r\n * Function which indicates whether a babylon node should be exported or not\r\n * @param node source Babylon node. It is used to check whether it should be exported to glTF or not\r\n * @returns boolean, which indicates whether the node should be exported (true) or not (false)\r\n */\r\n shouldExportNode?(node: Node): boolean;\r\n\r\n /**\r\n * Function which indicates whether an animation on the scene should be exported or not\r\n * @param animation source animation\r\n * @returns boolean, which indicates whether the animation should be exported (true) or not (false)\r\n */\r\n shouldExportAnimation?(animation: Animation): boolean;\r\n\r\n /**\r\n * Function to extract the part of the scene or node's `metadata` that will populate the corresponding\r\n * glTF object's `extras` field. If not defined, `node.metadata.gltf.extras` will be used.\r\n * @param metadata source metadata to read from\r\n * @returns the data to store into the glTF extras field\r\n */\r\n metadataSelector?(metadata: any): any;\r\n\r\n /**\r\n * The sample rate to bake animation curves. Defaults to 1 / 60.\r\n */\r\n animationSampleRate?: number;\r\n\r\n /**\r\n * Begin serialization without waiting for the scene to be ready. Defaults to false.\r\n */\r\n exportWithoutWaitingForScene?: boolean;\r\n\r\n /**\r\n * Indicates if unused vertex uv attributes should be included in export. Defaults to false.\r\n */\r\n exportUnusedUVs?: boolean;\r\n\r\n /**\r\n * Remove no-op root nodes when possible. Defaults to true.\r\n */\r\n removeNoopRootNodes?: boolean;\r\n\r\n /**\r\n * Indicates if coordinate system swapping root nodes should be included in export. Defaults to false.\r\n * @deprecated Please use removeNoopRootNodes instead\r\n */\r\n includeCoordinateSystemConversionNodes?: boolean;\r\n\r\n /**\r\n * Indicates what compression method to apply to mesh data.\r\n */\r\n meshCompressionMethod?: MeshCompressionMethod;\r\n}\r\n\r\n/**\r\n * Class for generating glTF data from a Babylon scene.\r\n */\r\nexport class GLTF2Export {\r\n /**\r\n * Exports the scene to .gltf file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .gltf file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLTFAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLTFAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Exports the scene to .glb file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .glb file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLBAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLBAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n}\r\n","import type { INode, IEXTMeshGpuInstancing } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport type { BufferManager } from \"../bufferManager\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Node } from \"core/node\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { TmpVectors, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { ConvertToRightHandedPosition, ConvertToRightHandedRotation } from \"../glTFUtilities\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"EXT_mesh_gpu_instancing\";\r\n\r\nfunction ColorBufferToRGBAToRGB(colorBuffer: Float32Array, instanceCount: number) {\r\n const colorBufferRgb = new Float32Array(instanceCount * 3);\r\n\r\n for (let i = 0; i < instanceCount; i++) {\r\n colorBufferRgb[i * 3 + 0] = colorBuffer[i * 4 + 0];\r\n colorBufferRgb[i * 3 + 1] = colorBuffer[i * 4 + 1];\r\n colorBufferRgb[i * 3 + 2] = colorBuffer[i * 4 + 2];\r\n }\r\n return colorBufferRgb;\r\n}\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_mesh_gpu_instancing implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /**\r\n * Internal state to emit warning about instance color alpha once\r\n */\r\n private _instanceColorWarned = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After node is exported\r\n * @param context the GLTF context when loading the asset\r\n * @param node the node exported\r\n * @param babylonNode the corresponding babylon node\r\n * @param nodeMap map from babylon node id to node index\r\n * @param convertToRightHanded true if we need to convert data from left hand to right hand system.\r\n * @param bufferManager buffer manager\r\n * @returns nullable promise, resolves with the node\r\n */\r\n public async postExportNodeAsync(\r\n context: string,\r\n node: Nullable<INode>,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (node && babylonNode instanceof Mesh) {\r\n if (babylonNode.hasThinInstances && this._exporter) {\r\n this._wasUsed = true;\r\n\r\n const noTranslation = Vector3.Zero();\r\n const noRotation = Quaternion.Identity();\r\n const noScale = Vector3.One();\r\n\r\n // retrieve all the instance world matrix\r\n const matrix = babylonNode.thinInstanceGetWorldMatrices();\r\n\r\n const iwt = TmpVectors.Vector3[2];\r\n const iwr = TmpVectors.Quaternion[1];\r\n const iws = TmpVectors.Vector3[3];\r\n\r\n let hasAnyInstanceWorldTranslation = false;\r\n let hasAnyInstanceWorldRotation = false;\r\n let hasAnyInstanceWorldScale = false;\r\n\r\n // prepare temp buffers\r\n const translationBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n const rotationBuffer = new Float32Array(babylonNode.thinInstanceCount * 4);\r\n const scaleBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n\r\n let i = 0;\r\n for (const m of matrix) {\r\n m.decompose(iws, iwr, iwt);\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(iwt);\r\n ConvertToRightHandedRotation(iwr);\r\n }\r\n\r\n // fill the temp buffer\r\n translationBuffer.set(iwt.asArray(), i * 3);\r\n rotationBuffer.set(iwr.normalize().asArray(), i * 4); // ensure the quaternion is normalized\r\n scaleBuffer.set(iws.asArray(), i * 3);\r\n\r\n // this is where we decide if there is any transformation\r\n hasAnyInstanceWorldTranslation = hasAnyInstanceWorldTranslation || !iwt.equalsWithEpsilon(noTranslation);\r\n hasAnyInstanceWorldRotation = hasAnyInstanceWorldRotation || !iwr.equalsWithEpsilon(noRotation);\r\n hasAnyInstanceWorldScale = hasAnyInstanceWorldScale || !iws.equalsWithEpsilon(noScale);\r\n\r\n i++;\r\n }\r\n\r\n const extension: IEXTMeshGpuInstancing = {\r\n attributes: {},\r\n };\r\n\r\n // do we need to write TRANSLATION ?\r\n if (hasAnyInstanceWorldTranslation) {\r\n extension.attributes[\"TRANSLATION\"] = this._buildAccessor(translationBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write ROTATION ?\r\n if (hasAnyInstanceWorldRotation) {\r\n // we decided to stay on FLOAT for now see https://github.com/BabylonJS/Babylon.js/pull/12495\r\n extension.attributes[\"ROTATION\"] = this._buildAccessor(rotationBuffer, AccessorType.VEC4, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write SCALE ?\r\n if (hasAnyInstanceWorldScale) {\r\n extension.attributes[\"SCALE\"] = this._buildAccessor(scaleBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n let colorBuffer = babylonNode._userThinInstanceBuffersStorage?.data?.instanceColor;\r\n if (colorBuffer) {\r\n const instanceCount = babylonNode.thinInstanceCount;\r\n const accessorType = AccessorType.VEC3;\r\n if (babylonNode.hasVertexAlpha && colorBuffer.length === instanceCount * 4) {\r\n if (!this._instanceColorWarned) {\r\n Logger.Warn(\"EXT_mesh_gpu_instancing: Exporting instance colors as RGB, alpha channel of instance color is not exported\");\r\n this._instanceColorWarned = true;\r\n }\r\n colorBuffer = ColorBufferToRGBAToRGB(colorBuffer, instanceCount);\r\n } else if (colorBuffer.length === instanceCount * 4) {\r\n colorBuffer = ColorBufferToRGBAToRGB(colorBuffer, instanceCount);\r\n }\r\n if (colorBuffer.length === instanceCount * 3) {\r\n extension.attributes[\"_COLOR_0\"] = this._buildAccessor(colorBuffer, accessorType, instanceCount, bufferManager);\r\n }\r\n }\r\n\r\n /* eslint-enable @typescript-eslint/naming-convention*/\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = extension;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n\r\n private _buildAccessor(buffer: Float32Array, type: AccessorType, count: number, bufferManager: BufferManager): number {\r\n // build the buffer view\r\n const bv = bufferManager.createBufferView(buffer);\r\n\r\n // finally build the accessor\r\n const accessor = bufferManager.createAccessor(bv, type, AccessorComponentType.FLOAT, count);\r\n this._exporter._accessors.push(accessor);\r\n return this._exporter._accessors.length - 1;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_mesh_gpu_instancing(exporter));\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\nimport type { IAccessor, IBufferView, IKHRDracoMeshCompression, IMeshPrimitive } from \"babylonjs-gltf2interface\";\nimport type { BufferManager } from \"../bufferManager\";\nimport { DracoEncoder } from \"core/Meshes/Compression/dracoEncoder\";\nimport { GetTypedArrayData, GetTypeByteLength } from \"core/Buffers/bufferUtils\";\nimport { GetAccessorElementCount } from \"../glTFUtilities\";\nimport type { DracoAttributeName, IDracoAttributeData, IDracoEncoderOptions } from \"core/Meshes/Compression/dracoEncoder.types\";\nimport { Logger } from \"core/Misc/logger\";\nimport type { Nullable } from \"core/types\";\n\nconst NAME = \"KHR_draco_mesh_compression\";\n\nfunction GetDracoAttributeName(glTFName: string): DracoAttributeName {\n if (glTFName === \"POSITION\") {\n return \"POSITION\";\n } else if (glTFName === \"NORMAL\") {\n return \"NORMAL\";\n } else if (glTFName.startsWith(\"COLOR\")) {\n return \"COLOR\";\n } else if (glTFName.startsWith(\"TEXCOORD\")) {\n return \"TEX_COORD\";\n }\n return \"GENERIC\";\n}\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_draco_mesh_compression implements IGLTFExporterExtensionV2 {\n /** Name of this extension */\n public readonly name = NAME;\n\n /** Defines whether this extension is enabled */\n public enabled;\n\n /** KHR_draco_mesh_compression is required, as uncompressed fallback data is not yet implemented. */\n public required = true;\n\n /** BufferViews used for Draco data, which may be eligible for removal after Draco encoding */\n private _bufferViewsUsed: Set<IBufferView> = new Set();\n\n /** Accessors that were replaced with Draco data, which may be eligible for removal after Draco encoding */\n private _accessorsUsed: Set<IAccessor> = new Set();\n\n /** Promise pool for Draco encoding work */\n private _encodePromises: Promise<void>[] = [];\n\n private _wasUsed = false;\n\n /** @internal */\n public get wasUsed() {\n return this._wasUsed;\n }\n\n /** @internal */\n constructor(exporter: GLTFExporter) {\n this.enabled = exporter.options.meshCompressionMethod === \"Draco\" && DracoEncoder.DefaultAvailable;\n }\n\n /** @internal */\n public dispose() {}\n\n /** @internal */\n public postExportMeshPrimitive(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void {\n if (!this.enabled) {\n return;\n }\n\n if (primitive.mode !== MeshPrimitiveMode.TRIANGLES && primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP) {\n Logger.Warn(\"Cannot compress primitive with mode \" + primitive.mode + \".\");\n return;\n }\n\n // Collect bufferViews and accessors used by this primitive\n const primitiveBufferViews: IBufferView[] = [];\n const primitiveAccessors: IAccessor[] = [];\n\n // Prepare indices for Draco encoding\n let indices: Nullable<Uint32Array | Uint16Array> = null;\n if (primitive.indices !== undefined) {\n const accessor = accessors[primitive.indices];\n const bufferView = bufferManager.getBufferView(accessor);\n // Per exportIndices, indices must be either Uint16Array or Uint32Array\n indices = bufferManager.getData(bufferView).slice() as Uint32Array | Uint16Array;\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Prepare attributes for Draco encoding\n const attributes: IDracoAttributeData[] = [];\n for (const [name, accessorIndex] of Object.entries(primitive.attributes)) {\n const accessor = accessors[accessorIndex];\n const bufferView = bufferManager.getBufferView(accessor);\n\n const size = GetAccessorElementCount(accessor.type);\n const data = GetTypedArrayData(\n bufferManager.getData(bufferView),\n size,\n accessor.componentType,\n accessor.byteOffset || 0,\n bufferView.byteStride || GetTypeByteLength(accessor.componentType) * size,\n accessor.count,\n true\n );\n\n attributes.push({ kind: name, dracoName: GetDracoAttributeName(name), size: GetAccessorElementCount(accessor.type), data: data });\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Use sequential encoding to preserve vertex order for cases like morph targets\n const options: IDracoEncoderOptions = {\n method: primitive.targets ? \"MESH_SEQUENTIAL_ENCODING\" : \"MESH_EDGEBREAKER_ENCODING\",\n };\n\n const promise = DracoEncoder.Default._encodeAsync(attributes, indices, options)\n // eslint-disable-next-line github/no-then\n .then((encodedData) => {\n if (!encodedData) {\n Logger.Error(\"Draco encoding failed for primitive.\");\n return;\n }\n\n const dracoInfo: IKHRDracoMeshCompression = {\n bufferView: -1, // bufferView will be set to a real index later, when we write the binary and decide bufferView ordering\n attributes: encodedData.attributeIds,\n };\n const bufferView = bufferManager.createBufferView(encodedData.data);\n bufferManager.setBufferView(dracoInfo, bufferView);\n\n for (const bufferView of primitiveBufferViews) {\n this._bufferViewsUsed.add(bufferView);\n }\n for (const accessor of primitiveAccessors) {\n this._accessorsUsed.add(accessor);\n }\n\n primitive.extensions ||= {};\n primitive.extensions[NAME] = dracoInfo;\n })\n // eslint-disable-next-line github/no-then\n .catch((error) => {\n Logger.Error(\"Draco encoding failed for primitive: \" + error);\n });\n\n this._encodePromises.push(promise);\n\n this._wasUsed = true;\n }\n\n /** @internal */\n public async preGenerateBinaryAsync(bufferManager: BufferManager): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n await Promise.all(this._encodePromises);\n\n // Cull obsolete bufferViews that were replaced with Draco data\n this._bufferViewsUsed.forEach((bufferView) => {\n const references = bufferManager.getPropertiesWithBufferView(bufferView);\n const onlyUsedByEncodedPrimitives = references.every((object) => {\n return this._accessorsUsed.has(object as IAccessor); // has() can handle any object, but TS doesn't know that\n });\n if (onlyUsedByEncodedPrimitives) {\n bufferManager.removeBufferView(bufferView);\n }\n });\n\n this._bufferViewsUsed.clear();\n this._accessorsUsed.clear();\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_draco_mesh_compression(exporter));\n","import type { SpotLight } from \"core/Lights/spotLight\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport type { INode, IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from \"babylonjs-gltf2interface\";\r\nimport { KHRLightsPunctual_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"KHR_lights_punctual\";\r\nconst DEFAULTS: Omit<IKHRLightsPunctual_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n range: Number.MAX_VALUE,\r\n};\r\nconst SPOTDEFAULTS: NonNullable<IKHRLightsPunctual_Light[\"spot\"]> = {\r\n innerConeAngle: 0,\r\n outerConeAngle: Math.PI / 4.0,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_lights_punctual implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IKHRLightsPunctual;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof Light)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType =\r\n babylonNode.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT\r\n ? KHRLightsPunctual_LightType.POINT\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT\r\n ? KHRLightsPunctual_LightType.DIRECTIONAL\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT\r\n ? KHRLightsPunctual_LightType.SPOT\r\n : null;\r\n if (!lightType || !(babylonNode instanceof ShadowLight)) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n if (babylonNode.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!babylonNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Represent the Babylon light's direction as a quaternion\r\n // relative to glTF lights' forward direction, (0, 0, -1).\r\n if (lightType !== KHRLightsPunctual_LightType.POINT) {\r\n const direction = babylonNode.direction.normalizeToRef(TmpVectors.Vector3[0]);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n\r\n const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n const light: IKHRLightsPunctual_Light = {\r\n type: lightType,\r\n name: babylonNode.name,\r\n color: babylonNode.diffuse.asArray(),\r\n intensity: babylonNode.intensity,\r\n range: babylonNode.range,\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n // Separately handle the required 'spot' field for spot lights\r\n if (lightType === KHRLightsPunctual_LightType.SPOT) {\r\n const babylonSpotLight = babylonNode as SpotLight;\r\n light.spot = {\r\n innerConeAngle: babylonSpotLight.innerAngle / 2.0,\r\n outerConeAngle: babylonSpotLight.angle / 2.0,\r\n };\r\n OmitDefaultValues(light.spot, SPOTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IKHRLightsPunctual_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsChildCollapsible(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_lights_punctual(exporter));\r\n","import type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport type { INode, IEXTLightsArea_LightReference, IEXTLightsArea_Light, IEXTLightsArea } from \"babylonjs-gltf2interface\";\r\nimport { EXTLightsArea_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from \"../glTFUtilities\";\r\nimport type { RectAreaLight } from \"core/Lights/rectAreaLight\";\r\n\r\nconst NAME = \"EXT_lights_area\";\r\nconst DEFAULTS: Omit<IEXTLightsArea_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n size: 1,\r\n};\r\nconst RECTDEFAULTS: NonNullable<IEXTLightsArea_Light[\"rect\"]> = {\r\n aspect: 1,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/EXT_lights_area/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_lights_area implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IEXTLightsArea;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof Light)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType = babylonNode.getTypeID() == Light.LIGHTTYPEID_RECT_AREALIGHT ? EXTLightsArea_LightType.RECT : null;\r\n if (!lightType) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const areaLight = babylonNode as RectAreaLight;\r\n\r\n if (areaLight.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!areaLight.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(areaLight.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Represent the Babylon light's direction as a quaternion\r\n // relative to glTF lights' forward direction, (0, 0, -1).\r\n const direction = Vector3.Forward();\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n\r\n const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n\r\n const light: IEXTLightsArea_Light = {\r\n type: lightType,\r\n name: areaLight.name,\r\n color: areaLight.diffuse.asArray(),\r\n intensity: areaLight.intensity,\r\n size: areaLight.height,\r\n rect: {\r\n aspect: areaLight.width / areaLight.height,\r\n },\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n if (light.rect) {\r\n OmitDefaultValues(light.rect, RECTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IEXTLightsArea_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsChildCollapsible(areaLight, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_lights_area(exporter));\r\n","import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged anisotropy textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged anisotropy textures\r\n * @internal\r\n */\r\nfunction GetAnisoTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture!.getInternalTexture()!.uniqueId : \"NoStrength\";\r\n const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture!.getInternalTexture()!.uniqueId : \"NoTangent\";\r\n return `${strengthId}_${tangentId}`;\r\n}\r\n\r\n// In your postExportMaterialAsync method:\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<ProceduralTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n return await MergeTexturesAsync(\r\n \"AnisotropyTexture\",\r\n CreateRGBAConfiguration(\r\n tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel\r\n tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel\r\n anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel\r\n ),\r\n scene\r\n );\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n private _anisoTexturesMap: Record<string, ProceduralTexture> = {};\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n if (this._anisoTexturesMap[texId]) {\r\n additionalTextures.push(this._anisoTexturesMap[texId]);\r\n } else {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._anisoTexturesMap[texId] = anisoTexture;\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n let roughnessTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessTexture;\r\n if (babylonMaterial._useRoughnessFromMetallicTextureGreen) {\r\n roughnessTexture = babylonMaterial.baseMetalnessTexture;\r\n }\r\n const mergedAnisoTexture = this._anisoTexturesMap[babylonMaterial.id];\r\n\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.specularRoughness;\r\n let newAnisotropyStrength = babylonMaterial.specularRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.specularRoughness, babylonMaterial.specularRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: newAnisotropyStrength,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle + Math.PI * 0.5,\r\n anisotropyTexture: undefined,\r\n };\r\n node.extensions[NAME] = anisotropyInfo;\r\n return resolve(node);\r\n }\r\n\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.specularRoughnessAnisotropy,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle,\r\n anisotropyTexture: mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined,\r\n extensions: {},\r\n };\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n // Enable OpenPBR extension on this material.\r\n node.extensions![\"KHR_materials_openpbr\"] = {};\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"KHR_materials_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"KHR_materials_openpbr\");\r\n }\r\n }\r\n\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n","import type { IMaterial, IKHRMaterialsClearcoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_clearcoat\";\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetCoatTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatId = coatTexture && coatTexture.getInternalTexture() ? coatTexture!.getInternalTexture()!.uniqueId : \"NoCoat\";\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const roughnessId = coatRoughnessTexture && coatRoughnessTexture.getInternalTexture() ? coatRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoRoughness\";\r\n return `${coatId}_${roughnessId}`;\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedCoatInternalTextureAsync(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(coatTexture || coatRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"CoatTexture\",\r\n CreateRGBAConfiguration(\r\n coatTexture ? CreateTextureInput(coatTexture, 0) : CreateConstantInput(1.0), // coat weight from red channel\r\n // coat roughness goes in the green channel but may come from red or green channels in the source\r\n coatRoughnessTexture ? CreateTextureInput(coatRoughnessTexture, babylonMaterial._useCoatRoughnessFromGreenChannel ? 1 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight > 0) {\r\n // We will merge the coat_weight and coat_roughness textures, if needed.\r\n // However, we want to retain the original texture's transforms and sampling info.\r\n let coatNeedsMerge = false;\r\n if (babylonMaterial.coatWeightTexture) {\r\n // If we don't have a coat_roughness texture or if the coat_weight and coat_roughness\r\n // textures are already merged, export them as-is.\r\n if (!babylonMaterial.coatRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n } else if (\r\n babylonMaterial._useCoatRoughnessFromGreenChannel &&\r\n babylonMaterial.coatWeightTexture.getInternalTexture() === babylonMaterial.coatRoughnessTexture.getInternalTexture()\r\n ) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n } else if (babylonMaterial.coatRoughnessTexture) {\r\n if (babylonMaterial._useCoatRoughnessFromGreenChannel) {\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n }\r\n if (coatNeedsMerge) {\r\n // Merge the two textures together but retain the transforms for each.\r\n // We do this by caching the internal texture that is created during the merge,\r\n // and then creating temporary textures that use that internal texture but\r\n // have the original texture's transforms/sampling info.\r\n const texId = GetCoatTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const internalTexture = await CreateMergedCoatInternalTextureAsync(babylonMaterial);\r\n if (internalTexture) {\r\n this._cachedInternalTexturesMap[texId] = internalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.coatWeightTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatWeightTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n\r\n if (babylonMaterial.geometryCoatNormalTexture) {\r\n additionalTextures.push(babylonMaterial.geometryCoatNormalTexture);\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const clearCoatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let clearCoatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.remapF0OnInterfaceChange) {\r\n Tools.Warn(`Clear Color F0 remapping is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.clearCoat.intensity,\r\n clearcoatTexture: clearCoatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n let coatWeightTexture: Nullable<BaseTexture> = null;\r\n let coatTextureInfo;\r\n if (babylonMaterial.coatWeightTexture) {\r\n coatWeightTexture = this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId];\r\n coatTextureInfo = this._exporter._materialExporter.getTextureInfo(coatWeightTexture);\r\n }\r\n\r\n let coatRoughnessTexture: Nullable<BaseTexture> = null;\r\n let coatRoughnessTextureInfo;\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n coatRoughnessTexture = this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId];\r\n coatRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(coatRoughnessTexture);\r\n }\r\n\r\n if (babylonMaterial.coatColorTexture) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.geometryCoatNormalTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.coatWeight,\r\n clearcoatTexture: coatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.coatRoughness,\r\n clearcoatRoughnessTexture: coatRoughnessTextureInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_clearcoat(exporter));\r\n","import type { IMaterial, IKHRMaterialsCoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\n\r\nconst NAME = \"KHR_materials_coat\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged anisotropy textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged anisotropy textures\r\n * @internal\r\n */\r\nfunction GetAnisoTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryCoatTangentTexture;\r\n const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture!.getInternalTexture()!.uniqueId : \"NoStrength\";\r\n const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture!.getInternalTexture()!.uniqueId : \"NoTangent\";\r\n return `${strengthId}_${tangentId}`;\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetCoatTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatId = coatTexture && coatTexture.getInternalTexture() ? coatTexture!.getInternalTexture()!.uniqueId : \"NoCoat\";\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const roughnessId = coatRoughnessTexture && coatRoughnessTexture.getInternalTexture() ? coatRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoRoughness\";\r\n return `${coatId}_${roughnessId}`;\r\n}\r\n\r\n/**\r\n * Creates a new texture with the anisotropy data merged together for export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new texture with the merged anisotropy data\r\n * @internal\r\n */\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<BaseTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryCoatTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n return await MergeTexturesAsync(\r\n \"AnisotropyTexture\",\r\n CreateRGBAConfiguration(\r\n tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel\r\n tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel\r\n anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel\r\n ),\r\n scene\r\n );\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedCoatInternalTextureAsync(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(coatTexture || coatRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"CoatTexture\",\r\n CreateRGBAConfiguration(\r\n coatTexture ? CreateTextureInput(coatTexture, 0) : CreateConstantInput(1.0), // coat weight from red channel\r\n // coat roughness goes in the green channel but may come from red or green channels in the source\r\n coatRoughnessTexture ? CreateTextureInput(coatRoughnessTexture, babylonMaterial._useCoatRoughnessFromGreenChannel ? 1 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_coat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n if (babylonMaterial.clearCoat.tintTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.tintTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight > 0) {\r\n // We will merge the coat_weight and coat_roughness textures, if needed.\r\n // However, we want to retain the original texture's transforms and sampling info.\r\n let coatNeedsMerge = false;\r\n if (babylonMaterial.coatWeightTexture) {\r\n // If we don't have a coat_roughness texture or if the coat_weight and coat_roughness\r\n // textures are already merged, export them as-is.\r\n if (!babylonMaterial.coatRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n } else if (\r\n babylonMaterial._useCoatRoughnessFromGreenChannel &&\r\n babylonMaterial.coatWeightTexture.getInternalTexture() === babylonMaterial.coatRoughnessTexture.getInternalTexture()\r\n ) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n } else if (babylonMaterial.coatRoughnessTexture) {\r\n if (babylonMaterial._useCoatRoughnessFromGreenChannel) {\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n }\r\n if (coatNeedsMerge) {\r\n // Merge the two textures together but retain the transforms for each.\r\n // We do this by caching the internal texture that is created during the merge,\r\n // and then creating temporary textures that use that internal texture but\r\n // have the original texture's transforms/sampling info.\r\n const texId = GetCoatTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const internalTexture = await CreateMergedCoatInternalTextureAsync(babylonMaterial);\r\n if (internalTexture) {\r\n this._cachedInternalTexturesMap[texId] = internalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.coatWeightTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatWeightTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n\r\n if (babylonMaterial.geometryCoatNormalTexture) {\r\n additionalTextures.push(babylonMaterial.geometryCoatNormalTexture);\r\n }\r\n\r\n if (babylonMaterial.coatColorTexture) {\r\n additionalTextures.push(babylonMaterial.coatColorTexture);\r\n }\r\n if (babylonMaterial.coatRoughnessAnisotropy > 0) {\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n if (this._mergedTexturesMap[texId]) {\r\n additionalTextures.push(this._mergedTexturesMap[texId]);\r\n } else {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._mergedTexturesMap[texId] = anisoTexture;\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const coatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let coatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n coatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n coatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n let coatColorTextureInfo;\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n coatColorTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.tintTexture);\r\n }\r\n\r\n const coatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n const coatIor: number = babylonMaterial.clearCoat.indexOfRefraction;\r\n\r\n const coatInfo: IKHRMaterialsCoat = {\r\n coatFactor: babylonMaterial.clearCoat.intensity,\r\n coatTexture: coatTextureInfo ?? undefined,\r\n coatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n coatRoughnessTexture: coatTextureRoughnessInfo ?? undefined,\r\n coatNormalTexture: coatNormalTextureInfo ?? undefined,\r\n coatColorFactor: babylonMaterial.clearCoat.tintColor.asArray(),\r\n coatColorTexture: coatColorTextureInfo ?? undefined,\r\n coatIor: coatIor !== 1.5 ? coatIor : undefined,\r\n };\r\n\r\n if (coatInfo.coatTexture !== null || coatInfo.coatRoughnessTexture !== null || coatInfo.coatRoughnessTexture !== null || coatInfo.coatColorTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = coatInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n let coatWeightTexture: Nullable<BaseTexture> = null;\r\n let coatTextureInfo;\r\n if (babylonMaterial.coatWeightTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]) {\r\n coatWeightTexture = this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId];\r\n } else {\r\n coatWeightTexture = babylonMaterial.coatWeightTexture;\r\n }\r\n coatTextureInfo = this._exporter._materialExporter.getTextureInfo(coatWeightTexture);\r\n }\r\n\r\n let coatRoughnessTexture: Nullable<BaseTexture> = null;\r\n let coatRoughnessTextureInfo;\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]) {\r\n coatRoughnessTexture = this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId];\r\n } else {\r\n coatRoughnessTexture = babylonMaterial.coatRoughnessTexture;\r\n }\r\n coatRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(coatRoughnessTexture);\r\n }\r\n\r\n const coatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.geometryCoatNormalTexture);\r\n const coatColorTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.coatColorTexture);\r\n const coatIor: number = babylonMaterial.coatIor;\r\n const coatDarkeningFactor = babylonMaterial.coatDarkening;\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n const roughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n const mergedAnisoTexture = this._mergedTexturesMap[texId];\r\n let coatAnisotropyStrength = 0;\r\n let coatAnisotropyRotation = 0;\r\n let coatAnisotropyTexture = undefined;\r\n if (babylonMaterial.coatRoughnessAnisotropy > 0.0) {\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.coatRoughness;\r\n let newAnisotropyStrength = babylonMaterial.coatRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.coatRoughness, babylonMaterial.coatRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n coatAnisotropyStrength = newAnisotropyStrength;\r\n coatAnisotropyRotation = babylonMaterial.geometryCoatTangentAngle + Math.PI * 0.5;\r\n coatAnisotropyTexture = undefined;\r\n } else {\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n coatAnisotropyStrength = babylonMaterial.coatRoughnessAnisotropy;\r\n coatAnisotropyRotation = babylonMaterial.geometryCoatTangentAngle;\r\n coatAnisotropyTexture = mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined;\r\n }\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n // Enable OpenPBR extension on this material.\r\n node.extensions![\"KHR_materials_openpbr\"] = {};\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"KHR_materials_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"KHR_materials_openpbr\");\r\n }\r\n }\r\n }\r\n\r\n const coatInfo: IKHRMaterialsCoat = {\r\n coatFactor: babylonMaterial.coatWeight,\r\n coatTexture: coatTextureInfo ?? undefined,\r\n coatRoughnessFactor: babylonMaterial.coatRoughness,\r\n coatRoughnessTexture: coatRoughnessTextureInfo ?? undefined,\r\n coatNormalTexture: coatNormalTextureInfo ?? undefined,\r\n coatColorFactor: babylonMaterial.coatColor.asArray(),\r\n coatColorTexture: coatColorTextureInfo ?? undefined,\r\n coatIor: coatIor !== 1.5 ? coatIor : undefined,\r\n coatDarkeningFactor: coatDarkeningFactor !== 1.0 ? coatDarkeningFactor : undefined,\r\n coatAnisotropyRotation: coatAnisotropyRotation,\r\n coatAnisotropyStrength: coatAnisotropyStrength,\r\n coatAnisotropyTexture: coatAnisotropyTexture,\r\n };\r\n\r\n if (\r\n coatInfo.coatTexture !== null ||\r\n coatInfo.coatRoughnessTexture !== null ||\r\n coatInfo.coatRoughnessTexture !== null ||\r\n coatInfo.coatAnisotropyTexture !== null ||\r\n coatInfo.coatColorTexture !== null\r\n ) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = coatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_coat(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_transmission\";\r\n\r\n/**\r\n * Get the appropriate translucency intensity texture for the material.\r\n * @internal\r\n */\r\nfunction GetTranslucencyIntensityTexture(context: string, babylonMaterial: PBRMaterial): Nullable<BaseTexture> {\r\n const subs = babylonMaterial.subSurface;\r\n let texture = null;\r\n\r\n // Check if translucency intensity texture is available or can be derived from thickness texture\r\n if (subs.translucencyIntensityTexture) {\r\n texture = subs.translucencyIntensityTexture;\r\n } else if (subs.thicknessTexture && subs.useMaskFromThicknessTexture) {\r\n texture = subs.thicknessTexture;\r\n }\r\n\r\n if (texture && !subs.useGltfStyleTextures) {\r\n Logger.Warn(`${context}: Translucency intensity texture is not supported when useGltfStyleTextures = false. Ignoring for: ${babylonMaterial.name}`, 1);\r\n return null;\r\n }\r\n\r\n return texture;\r\n}\r\n\r\n/**\r\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)\r\n * !!! Experimental Extension Subject to Changes !!!\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n if (translucencyIntensityTexture) {\r\n additionalTextures.push(translucencyIntensityTexture);\r\n }\r\n if (babylonMaterial.subSurface.translucencyColorTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.translucencyColorTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n if (!subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n\r\n return (\r\n !mat.unlit &&\r\n !subs.useAlbedoToTintTranslucency &&\r\n subs.useGltfStyleTextures &&\r\n subs.volumeIndexOfRefraction === 1 &&\r\n subs.minimumThickness === 0 &&\r\n subs.maximumThickness === 0\r\n );\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n\r\n const diffuseTransmissionFactor = subs.translucencyIntensity == 0 ? undefined : subs.translucencyIntensity;\r\n const diffuseTransmissionTexture = this._exporter._materialExporter.getTextureInfo(translucencyIntensityTexture) ?? undefined;\r\n const diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray();\r\n const diffuseTransmissionColorTexture = this._exporter._materialExporter.getTextureInfo(subs.translucencyColorTexture) ?? undefined;\r\n\r\n const diffuseTransmissionInfo: IKHRMaterialsDiffuseTransmission = {\r\n diffuseTransmissionFactor,\r\n diffuseTransmissionTexture,\r\n diffuseTransmissionColorFactor,\r\n diffuseTransmissionColorTexture,\r\n };\r\n\r\n if (diffuseTransmissionTexture || diffuseTransmissionColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = diffuseTransmissionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_transmission(exporter));\r\n","import type { IMaterial, IKHRMaterialsDispersion } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_dispersion\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md)\r\n * @experimental\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_dispersion implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Constructor */\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires refraction to be enabled.\r\n if (!subs.isRefractionEnabled && !subs.isDispersionEnabled) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const dispersion = subs.dispersion;\r\n\r\n const dispersionInfo: IKHRMaterialsDispersion = {\r\n dispersion: dispersion,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = dispersionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_dispersion());\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { IMaterial, IKHRMaterialsEmissiveStrength } from \"babylonjs-gltf2interface\";\r\n\r\nconst NAME = \"KHR_materials_emissive_strength\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_emissive_strength implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonMaterial instanceof PBRMaterial)) {\r\n return resolve(node);\r\n }\r\n\r\n const emissiveColor = babylonMaterial.emissiveColor.scale(babylonMaterial.emissiveIntensity);\r\n const tempEmissiveStrength = Math.max(...emissiveColor.asArray());\r\n\r\n if (tempEmissiveStrength > 1) {\r\n // If the strength is greater than 1, normalize the color and store the strength\r\n node.emissiveFactor = emissiveColor.scale(1 / tempEmissiveStrength).asArray();\r\n\r\n this._wasUsed = true;\r\n const emissiveStrengthInfo: IKHRMaterialsEmissiveStrength = {\r\n emissiveStrength: tempEmissiveStrength,\r\n };\r\n node.extensions ||= {};\r\n node.extensions[NAME] = emissiveStrengthInfo;\r\n } else {\r\n // Otherwise, just store the adjusted emissive color in emissiveFactor\r\n node.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n return resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_emissive_strength());\r\n","import type { IMaterial, IKHRMaterialsIor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_ior\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_ior implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value.\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const iorInfo: IKHRMaterialsIor = {\r\n ior: babylonMaterial.indexOfRefraction,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = iorInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior());\r\n","import type { IMaterial, IKHRMaterialsIridescence } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_iridescence\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_iridescence implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.iridescence.isEnabled) {\r\n if (babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.texture);\r\n }\r\n if (babylonMaterial.iridescence.thicknessTexture && babylonMaterial.iridescence.thicknessTexture !== babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.thinFilmWeight > 0) {\r\n if (babylonMaterial.thinFilmWeightTexture) {\r\n additionalTextures.push(babylonMaterial.thinFilmWeightTexture);\r\n }\r\n if (babylonMaterial.thinFilmThicknessTexture && babylonMaterial.thinFilmThicknessTexture !== babylonMaterial.thinFilmWeightTexture) {\r\n additionalTextures.push(babylonMaterial.thinFilmThicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.iridescence.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const iridescenceTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.texture);\r\n const iridescenceThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.thicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.iridescence.intensity,\r\n iridescenceIor: babylonMaterial.iridescence.indexOfRefraction,\r\n iridescenceThicknessMinimum: babylonMaterial.iridescence.minimumThickness,\r\n iridescenceThicknessMaximum: babylonMaterial.iridescence.maximumThickness,\r\n\r\n iridescenceTexture: iridescenceTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: iridescenceThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.thinFilmWeight <= 0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const thinFilmWeightTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.thinFilmWeightTexture);\r\n const thinFilmThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.thinFilmThicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.thinFilmWeight,\r\n iridescenceIor: babylonMaterial.thinFilmIor,\r\n iridescenceThicknessMinimum: babylonMaterial.thinFilmThicknessMin * 1000, // Convert to nanometers for glTF\r\n iridescenceThicknessMaximum: babylonMaterial.thinFilmThickness * 1000, // Convert to nanometers for glTF\r\n\r\n iridescenceTexture: thinFilmWeightTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: thinFilmThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_iridescence(exporter));\r\n","import type { IMaterial, IKHRMaterialsSheen } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_sheen\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_sheen implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (babylonMaterial.sheen.isEnabled && babylonMaterial.sheen.texture) {\r\n return [babylonMaterial.sheen.texture];\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (!babylonMaterial.sheen.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const sheenInfo: IKHRMaterialsSheen = {\r\n sheenColorFactor: babylonMaterial.sheen.color.asArray(),\r\n sheenRoughnessFactor: babylonMaterial.sheen.roughness ?? 0,\r\n };\r\n\r\n if (sheenInfo.sheenColorTexture !== null || sheenInfo.sheenRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (babylonMaterial.sheen.texture) {\r\n sheenInfo.sheenColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.textureRoughness) ?? undefined;\r\n } else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n node.extensions[NAME] = sheenInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_sheen(exporter));\r\n","import type { IMaterial, IKHRMaterialsFuzz } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nconst NAME = \"KHR_materials_fuzz\";\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetFuzzColorTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const fuzzColorTexture: Nullable<BaseTexture> = babylonMaterial.fuzzColorTexture;\r\n const fuzzColorId = fuzzColorTexture && fuzzColorTexture.getInternalTexture() ? fuzzColorTexture!.getInternalTexture()!.uniqueId : \"NoFuzzColor\";\r\n const fuzzRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.fuzzRoughnessTexture;\r\n const fuzzRoughnessId = fuzzRoughnessTexture && fuzzRoughnessTexture.getInternalTexture() ? fuzzRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoFuzzRoughness\";\r\n return `FuzzColor_${fuzzColorId}_FuzzRoughness_${fuzzRoughnessId}`;\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedFuzzInternalTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const fuzzColorTexture: Nullable<BaseTexture> = babylonMaterial.fuzzColorTexture;\r\n const fuzzRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.fuzzRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(fuzzColorTexture || fuzzRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"FuzzTexture\",\r\n CreateRGBAConfiguration(\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 0) : CreateConstantInput(1.0), // fuzz color from red channel\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 1) : CreateConstantInput(1.0), // fuzz color from green channel\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 2) : CreateConstantInput(1.0), // fuzz color from blue channel\r\n // fuzz roughness goes in the alpha channel but may come from red or alpha channels in the source\r\n fuzzRoughnessTexture ? CreateTextureInput(fuzzRoughnessTexture, babylonMaterial._useFuzzRoughnessFromTextureAlpha ? 3 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_fuzz implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n if (babylonMaterial instanceof OpenPBRMaterial) {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial.fuzzWeight > 0.0) {\r\n if (babylonMaterial.fuzzWeightTexture) {\r\n additionalTextures.push(babylonMaterial.fuzzWeightTexture);\r\n }\r\n let fuzzTexturesNeedMerge = false;\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n if (babylonMaterial._useFuzzRoughnessFromTextureAlpha) {\r\n additionalTextures.push(babylonMaterial.fuzzRoughnessTexture);\r\n } else {\r\n fuzzTexturesNeedMerge = true;\r\n }\r\n }\r\n if (babylonMaterial.fuzzColorTexture && !fuzzTexturesNeedMerge) {\r\n additionalTextures.push(babylonMaterial.fuzzColorTexture);\r\n }\r\n if (fuzzTexturesNeedMerge) {\r\n const texId = GetFuzzColorTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const mergedInternalTexture = await CreateMergedFuzzInternalTexture(babylonMaterial);\r\n if (mergedInternalTexture) {\r\n this._cachedInternalTexturesMap[texId] = mergedInternalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.fuzzColorTexture) {\r\n this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.fuzzColorTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.fuzzRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.fuzzWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const fuzzInfo: IKHRMaterialsFuzz = {\r\n fuzzFactor: babylonMaterial.fuzzWeight,\r\n fuzzColorFactor: babylonMaterial.fuzzColor.asArray(),\r\n fuzzRoughnessFactor: babylonMaterial.fuzzRoughness,\r\n };\r\n\r\n if (babylonMaterial.fuzzWeightTexture) {\r\n fuzzInfo.fuzzTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.fuzzWeightTexture) ?? undefined;\r\n }\r\n\r\n let fuzzColorTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial.fuzzColorTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId]) {\r\n fuzzColorTexture = this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId];\r\n } else {\r\n fuzzColorTexture = babylonMaterial.fuzzColorTexture;\r\n }\r\n fuzzInfo.fuzzColorTexture = this._exporter._materialExporter.getTextureInfo(fuzzColorTexture) ?? undefined;\r\n }\r\n\r\n let fuzzRoughnessTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId]) {\r\n fuzzRoughnessTexture = this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId];\r\n } else {\r\n fuzzRoughnessTexture = babylonMaterial.fuzzRoughnessTexture;\r\n }\r\n fuzzInfo.fuzzRoughnessTexture = this._exporter._materialExporter.getTextureInfo(fuzzRoughnessTexture) ?? undefined;\r\n }\r\n\r\n if (fuzzInfo.fuzzColorTexture !== null || fuzzInfo.fuzzRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = fuzzInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_fuzz(exporter));\r\n","import type { IMaterial, IKHRMaterialsSpecular, IEXTMaterialsSpecularEdgeColor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_specular\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_specular implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.metallicReflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.metallicReflectanceTexture);\r\n }\r\n if (babylonMaterial.reflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.reflectanceTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return (\r\n (mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) ||\r\n (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.metallicReflectanceTexture != null || mat.reflectanceTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const metallicReflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.metallicReflectanceTexture) ?? undefined;\r\n const reflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.reflectanceTexture) ?? undefined;\r\n const metallicF0Factor = babylonMaterial.metallicF0Factor == 1.0 ? undefined : babylonMaterial.metallicF0Factor;\r\n const metallicReflectanceColor = babylonMaterial.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)\r\n ? undefined\r\n : babylonMaterial.metallicReflectanceColor.asArray();\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: metallicF0Factor,\r\n specularTexture: metallicReflectanceTexture,\r\n specularColorFactor: metallicReflectanceColor,\r\n specularColorTexture: reflectanceTexture,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n node.extensions = node.extensions || {};\r\n\r\n const specularWeightTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.specularWeightTexture) ?? undefined;\r\n const specularColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.specularColorTexture) ?? undefined;\r\n const specularWeight = babylonMaterial.specularWeight == 1.0 ? undefined : babylonMaterial.specularWeight;\r\n const specularColor = babylonMaterial.specularColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : babylonMaterial.specularColor.asArray();\r\n\r\n if (!specularColorTexture && !specularWeightTexture && specularWeight === undefined && specularColor === undefined) {\r\n return resolve(node);\r\n }\r\n this._wasUsed = true;\r\n\r\n const specularEdgeColorInfo: IEXTMaterialsSpecularEdgeColor = {\r\n specularEdgeColorEnabled: true,\r\n };\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: specularWeight,\r\n specularTexture: specularWeightTexture,\r\n specularColorFactor: specularColor,\r\n specularColorTexture: specularColorTexture,\r\n extensions: {},\r\n };\r\n\r\n specularInfo.extensions![\"EXT_materials_specular_edge_color\"] = specularEdgeColorInfo;\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"EXT_materials_specular_edge_color\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"EXT_materials_specular_edge_color\");\r\n }\r\n\r\n if (specularWeightTexture || specularColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_specular(exporter));\r\n","import type { IMaterial, IKHRMaterialsTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"KHR_materials_transmission\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat);\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.refractionIntensityTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns true if successful\r\n */\r\n public async postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subSurface = babylonMaterial.subSurface;\r\n const transmissionFactor = subSurface.refractionIntensity === 0 ? undefined : subSurface.refractionIntensity;\r\n\r\n const volumeInfo: IKHRMaterialsTransmission = {\r\n transmissionFactor: transmissionFactor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (subSurface.refractionIntensityTexture) {\r\n if (subSurface.useGltfStyleTextures) {\r\n const transmissionTexture = await this._exporter._materialExporter.exportTextureAsync(subSurface.refractionIntensityTexture);\r\n if (transmissionTexture) {\r\n volumeInfo.transmissionTexture = transmissionTexture;\r\n }\r\n } else {\r\n Logger.Warn(`${context}: Exporting a subsurface refraction intensity texture without \\`useGltfStyleTextures\\` is not supported`);\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n\r\n return node;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter));\r\n","import type { IMaterial } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\n\r\nconst NAME = \"KHR_materials_unlit\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_unlit implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public dispose() {}\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let unlitMaterial = false;\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n unlitMaterial = babylonMaterial.unlit;\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n unlitMaterial = babylonMaterial.disableLighting;\r\n }\r\n\r\n if (unlitMaterial) {\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n\r\n node.extensions[NAME] = {};\r\n }\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_unlit());\r\n","import type { IMaterial, IKHRMaterialsVolume } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\n\r\nconst NAME = \"KHR_materials_volume\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_volume implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions.\r\n if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n return (\r\n (subs.maximumThickness != undefined && subs.maximumThickness != 0) ||\r\n (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) ||\r\n (subs.tintColor != undefined && subs.tintColor != Color3.White()) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.thicknessTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness;\r\n const thicknessTexture = this._exporter._materialExporter.getTextureInfo(subs.thicknessTexture) ?? undefined;\r\n const attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance;\r\n const attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray();\r\n\r\n const volumeInfo: IKHRMaterialsVolume = {\r\n thicknessFactor: thicknessFactor,\r\n thicknessTexture: thicknessTexture,\r\n attenuationDistance: attenuationDistance,\r\n attenuationColor: attenuationColor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseRoughness } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_roughness\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_roughness implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial._baseDiffuseRoughness) {\r\n if (babylonMaterial._baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial._baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.baseDiffuseRoughness) {\r\n if (babylonMaterial.baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let diffuseRoughnessFactor: Nullable<number> = null;\r\n let diffuseRoughnessTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n diffuseRoughnessFactor = babylonMaterial._baseDiffuseRoughness;\r\n diffuseRoughnessTexture = babylonMaterial._baseDiffuseRoughnessTexture;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n diffuseRoughnessFactor = babylonMaterial.baseDiffuseRoughness;\r\n diffuseRoughnessTexture = babylonMaterial.baseDiffuseRoughnessTexture;\r\n }\r\n if (!diffuseRoughnessFactor) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const diffuseRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(diffuseRoughnessTexture);\r\n\r\n const diffuseRoughnessInfo: IKHRMaterialsDiffuseRoughness = {\r\n diffuseRoughnessFactor: diffuseRoughnessFactor,\r\n diffuseRoughnessTexture: diffuseRoughnessTextureInfo ?? undefined,\r\n };\r\n\r\n if (diffuseRoughnessInfo.diffuseRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = diffuseRoughnessInfo;\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_roughness(exporter));\r\n","import type { ITextureInfo, IKHRTextureTransform } from \"babylonjs-gltf2interface\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\n\r\nconst NAME = \"KHR_texture_transform\";\r\n\r\n/**\r\n * Computes the adjusted offset for a rotation centered about the origin.\r\n * @internal\r\n */\r\nfunction AdjustOffsetForRotationCenter(babylonTexture: Texture): [number, number] {\r\n const { uOffset, vOffset, uRotationCenter, vRotationCenter, uScale, vScale, wAng } = babylonTexture;\r\n const cosAngle = Math.cos(wAng);\r\n const sinAngle = Math.sin(wAng);\r\n const scaledURotationCenter = uRotationCenter * uScale;\r\n const scaledVRotationCenter = vRotationCenter * vScale;\r\n const deltaU = scaledURotationCenter * (1 - cosAngle) + scaledVRotationCenter * sinAngle;\r\n const deltaV = scaledVRotationCenter * (1 - cosAngle) - scaledURotationCenter * sinAngle;\r\n return [uOffset + deltaU, vOffset + deltaV];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_texture_transform implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: Texture): void {\r\n const scene = babylonTexture.getScene();\r\n if (!scene) {\r\n Tools.Warn(`${context}: \"scene\" is not defined for Babylon texture ${babylonTexture.name}!`);\r\n }\r\n\r\n /*\r\n * The KHR_texture_transform schema only supports w rotation around the origin.\r\n * See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates.\r\n */\r\n if (babylonTexture.uAng !== 0 || babylonTexture.vAng !== 0) {\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with rotation in the u or v axis is not supported in glTF.`);\r\n // Usually, we'd always early return here if the texture uses an unsupported combination of transform properties,\r\n // but we're making an exception here to maintain backwards compatibility.\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n return;\r\n }\r\n }\r\n\r\n const textureTransform: IKHRTextureTransform = {};\r\n let transformIsRequired = false;\r\n\r\n if (babylonTexture.uOffset !== 0 || babylonTexture.vOffset !== 0) {\r\n textureTransform.offset = [babylonTexture.uOffset, babylonTexture.vOffset];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.uScale !== 1 || babylonTexture.vScale !== 1) {\r\n textureTransform.scale = [babylonTexture.uScale, babylonTexture.vScale];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.wAng !== 0) {\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n // See https://github.com/mrdoob/three.js/issues/15831 for more details.\r\n if (babylonTexture.homogeneousRotationInUVTransform && babylonTexture.uScale !== babylonTexture.vScale) {\r\n Tools.Warn(\r\n `${context}: Texture ${babylonTexture.name} with homogenousRotationInUVTransform, non-uniform scaling, and non-zero rotation cannot be exported with ${NAME}.`\r\n );\r\n return;\r\n }\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with non-origin rotation center will be exported using an adjusted offset with ${NAME}.`);\r\n textureTransform.offset = AdjustOffsetForRotationCenter(babylonTexture);\r\n }\r\n textureTransform.rotation = -babylonTexture.wAng;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.coordinatesIndex !== 0) {\r\n textureTransform.texCoord = babylonTexture.coordinatesIndex;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (!transformIsRequired) {\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n if (!textureInfo.extensions) {\r\n textureInfo.extensions = {};\r\n }\r\n textureInfo.extensions[NAME] = textureTransform;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_texture_transform());\r\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"KHR_texture_basisu\";\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_basisu/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_texture_basisu implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.KTX2) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_texture_basisu(exporter));\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"EXT_texture_webp\";\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_webp/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class EXT_texture_webp implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.WEBP) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_texture_webp(exporter));\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"EXT_texture_avif\";\n\n/**\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/blob/5cb7518cf9a1bfb8268320026961b21caf5a4aac/extensions/2.0/Vendor/EXT_texture_avif/README.md)\n * @experimental\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class EXT_texture_avif implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.AVIF) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_texture_avif(exporter));\n","/* eslint-disable @typescript-eslint/no-restricted-imports */\r\nimport * as Exporters from \"serializers/glTF/glTFFileExporter\";\r\nimport * as Datas from \"serializers/glTF/2.0/glTFData\";\r\nimport * as Serializers from \"serializers/glTF/2.0/glTFSerializer\";\r\nimport * as Extensions from \"serializers/glTF/2.0/Extensions/index\";\r\nimport * as GLTF2 from \"serializers/glTF/2.0/index\";\r\n\r\n/**\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nif (typeof globalObject !== \"undefined\") {\r\n (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};\r\n const BABYLON = (<any>globalObject).BABYLON;\r\n BABYLON.GLTF2 = BABYLON.GLTF2 || {};\r\n BABYLON.GLTF2.Exporter = BABYLON.GLTF2.Exporter || {};\r\n BABYLON.GLTF2.Exporter.Extensions = BABYLON.GLTF2.Exporter.Extensions || {};\r\n\r\n const keys = [];\r\n for (const key in Exporters) {\r\n BABYLON[key] = (<any>Exporters)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Datas) {\r\n BABYLON[key] = (<any>Datas)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Serializers) {\r\n BABYLON[key] = (<any>Serializers)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in Extensions) {\r\n BABYLON.GLTF2.Exporter.Extensions[key] = (<any>Extensions)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in GLTF2) {\r\n // Prevent Reassignment.\r\n if (keys.indexOf(key) > -1) {\r\n continue;\r\n }\r\n\r\n BABYLON.GLTF2.Exporter[key] = (<any>GLTF2)[key];\r\n }\r\n}\r\n\r\nexport * from \"serializers/glTF/glTFFileExporter\";\r\nexport * from \"serializers/glTF/2.0/index\";\r\n","import * as serializers from \"@lts/serializers/legacy/legacy-glTF2Serializer\";\r\nexport { serializers };\r\nexport default serializers;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","key","o","Object","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","__IGLTFExporterExtension","files","downloadFiles","blob","Blob","type","GetMimeType","Tools","Download","__assign","assign","t","s","i","n","arguments","length","p","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","rejected","result","done","then","__generator","body","f","y","_","label","sent","trys","ops","create","Iterator","verb","iterator","v","op","TypeError","pop","push","__spreadArray","to","from","pack","ar","l","Array","slice","concat","SuppressedError","Epsilon","DielectricSpecular","Color3","MaxSpecularPower","White","Black","BlackReadOnly","IsSupportedMimeType","mimeType","GetCachedImageAsync","babylonTexture","internalTexture","getInternalTexture","source","invertY","buffer","_buffer","LoadFileAsync","url","data","ArrayBuffer","isView","byteOffset","byteLength","arrayBuffer","HTMLImageElement","src","_SolveMetallic","diffuse","specular","oneMinusSpecularStrength","a","b","Scalar","Clamp","Math","sqrt","_ConvertToGLTFPBRMetallicRoughness","babylonStandardMaterial","diffuseColor","toLinearSpace","getScene","getEngine","useExactSrgbConversions","scale","opacity","alpha","specularPower","roughness","SpecularPowerToRoughness","baseColorFactor","metallicFactor","roughnessFactor","SetAlphaMode","glTFMaterial","babylonMaterial","needAlphaBlending","alphaMode","needAlphaTesting","alphaCutoff","alphaCutOff","CreateWhiteTexture","width","height","scene","Uint8Array","RawTexture","CreateRGBATexture","ConvertPixelArrayToFloat32","pixels","Float32Array","Error","_exporter","_textureMap","Map","_internalTextureToImage","getTextureInfo","uniqueId","exportStandardMaterialAsync","hasUVs","pbrMetallicRoughness","material","name","backFaceCulling","twoSidedLighting","Warn","doubleSided","promises","diffuseTexture","exportTextureAsync","textureInfo","baseColorTexture","bumpTexture","normalTexture","level","emissiveTexture","emissiveFactor","ambientTexture","occlusionTexture","index","_materialNeedsUVsSet","add","all","opacityTexture","Constants","ALPHA_COMBINE","toString","emissiveColor","equalsWithEpsilon","asArray","_finishMaterialAsync","materials","_materials","_extensionsPostExportMaterialAdditionalTexturesAsync","textures","texture","_extensionsPostExportMaterialAsync","_resizeTexturesToSameDimensions","texture1","texture2","resizedTexture1","resizedTexture2","texture1Size","getSize","texture2Size","Texture","TextureTools","CreateResizedCopy","_convertSpecularGlossinessTexturesToMetallicRoughnessAsync","specularGlossinessTexture","factors","resizedTextures","diffuseSize","diffuseBuffer","specularGlossinessBuffer","readPixels","diffusePixels","specularPixels","metallicRoughnessBuffer","baseColorBuffer","maxBaseColor","maxMetallic","maxRoughness","h","w","offset","multiply","specularColor","glossiness","specularGlossiness","metallicRoughness","_convertSpecularGlossinessToMetallicRoughness","max","baseColor","metallic","hasAlpha","writeOutMetallicRoughnessTexture","writeOutBaseColorTexture","destinationOffset","linearBaseColorPixel","FromInts","sRGBBaseColorPixel","toGammaSpace","EncodeImageAsync","metallicRoughnessTextureData","baseColorTextureData","diffusePerceivedBrightness","_getPerceivedBrightness","specularPerceivedBrightness","_getMaxComponent","baseColorFromDiffuse","baseColorFromSpecular","subtract","Lerp","clampToRef","color","_convertMetalRoughFactorsToMetallicRoughnessAsync","albedoTexture","metallicTexture","roughnessTexture","babylonPBRMaterial","glTFPbrMetallicRoughness","OpenPBRMaterial","geometryOpacityTexture","albedoId","opacityId","Number","glTFTexture","MergeTexturesAsync","CreateRGBAConfiguration","CreateTextureInput","CreateConstantInput","mergedTexture","_useMetallicFromMetallicTextureBlue","metallicRoughnessTexture","metallicId","roughnessId","ambientOcclusionTexture","_getTextureSampler","sampler","wrapS","_getGLTFTextureWrapMode","wrapU","wrapT","wrapV","samplingMode","LINEAR_LINEAR","magFilter","minFilter","LINEAR_NEAREST","NEAREST_LINEAR","NEAREST_LINEAR_MIPLINEAR","NEAREST_NEAREST","NEAREST_LINEAR_MIPNEAREST","LINEAR_NEAREST_MIPNEAREST","LINEAR_NEAREST_MIPLINEAR","NEAREST_NEAREST_MIPLINEAR","LINEAR_LINEAR_MIPLINEAR","LINEAR_LINEAR_MIPNEAREST","NEAREST_NEAREST_MIPNEAREST","wrapMode","WRAP_ADDRESSMODE","CLAMP_ADDRESSMODE","MIRROR_ADDRESSMODE","_convertSpecGlossFactorsToMetallicRoughnessAsync","specGloss","_albedoColor","_reflectivityColor","_microSurface","_albedoTexture","reflectivityTexture","_reflectivityTexture","useMicrosurfaceFromReflectivityMapAlpha","_useMicroSurfaceFromReflectivityMapAlpha","samplerIndex","_exportTextureSampler","metallicRoughnessFactors","_textures","_exportImageAsync","imageIndex","_exportTextureInfo","coordinatesIndex","exportPBRMaterialAsync","useMetallicRoughness","isMetallicWorkflow","albedoColor","_metallic","_roughness","_metallicTexture","_setMetallicRoughnessPbrMaterialAsync","WithinEpsilon","_twoSidedLighting","PBRBaseMaterial","_bumpTexture","geometryNormalTexture","_ambientTexture","set","_extensionsPostExportTextures","texCoord","extensions","strength","_ambientTextureStrength","_emissiveTexture","emissionColorTexture","_emissiveColor","emissionColor","exportOpenPBRMaterialAsync","babylonOpenPBRMaterial","geometryOpacity","baseMetalness","specularRoughness","baseMetalnessTexture","specularRoughnessTexture","overrideId","_exportTextureImageAsync","requestedMimeType","internalTextureToImage","internalTextureUniqueId","imageIndexPromise","cache","size","GetTextureDataAsync","imageData","images","_images","_shouldUseGlb","image","bufferView","_bufferManager","createBufferView","setBufferView","baseName","replace","extension","GetFileExtensionFromMimeType","some","uri","RandomId","_imageData","textureIndex","findIndex","samplers","_samplers","ConvertHandednessMatrix","Matrix","Compose","Vector3","Quaternion","Identity","Zero","IsNoopNode","node","useRightHandedSystem","TransformNode","getWorldMatrix","IdentityReadOnly","multiplyToRef","TmpVectors","AbstractMesh","geometry","DefaultTranslation","ZeroReadOnly","DefaultRotation","DefaultScale","OneReadOnly","DefaultLoaderCameraParentScaleLh","GetVertexBufferInfo","vertexBuffer","meshes","byteStride","normalized","componentCount","totalVertices","reduce","current","getTotalVertices","MAX_VALUE","count","kind","getKind","GetAccessorElementCount","accessorType","IsStandardVertexAttribute","VertexBuffer","PositionKind","NormalKind","TangentKind","ColorKind","MatricesIndicesKind","MatricesIndicesExtraKind","MatricesWeightsKind","MatricesWeightsExtraKind","UVKind","UV2Kind","UV3Kind","UV4Kind","UV5Kind","UV6Kind","GetPrimitiveMode","fillMode","Material","TriangleFillMode","TriangleStripDrawMode","TriangleFanDrawMode","PointListDrawMode","PointFillMode","LineLoopDrawMode","LineListDrawMode","LineStripDrawMode","NormalizeTangent","tangent","x","z","ConvertToRightHandedPosition","ConvertToRightHandedRotation","absX","abs","absY","sign","absZ","absW","Rotate180Y","rotation","copyFromFloats","CollapseChildIntoParent","parentNode","parentTranslation","FromArrayToRef","translation","parentRotation","parentMatrix","ComposeToRef","matrix","decompose","IsChildCollapsible","babylonNode","parentBabylonNode","getChildren","parent","expectedScale","TargetCamera","scaling","Logger","OmitDefaultValues","object","defaultValues","entries","defaultValue","isArray","AreArraysEqual","array1","array2","every","val","TypedArrayToWriteMethod","Int8Array","setInt8","dv","bo","setUint8","Uint8ClampedArray","Int16Array","setInt16","Uint16Array","setUint16","Int32Array","setInt32","Uint32Array","setUint32","setFloat32","Float64Array","setFloat64","_data","_dataView","DataView","_byteOffset","writeTypedArray","_checkGrowBuffer","setMethod","constructor","BYTES_PER_ELEMENT","getOutputData","writeUInt8","writeInt8","writeInt16","entry","writeUInt16","writeInt32","writeUInt32","writeFloat32","writeFloat64","newByteLength","newData","GetHighestByteAlignment","_TangentType","_bufferViewToData","_bufferViewToProperties","_accessorToBufferView","generateBinary","bufferViews","totalByteLength","forEach","dataWriter","DataWriter","keys","sort","bufferViewIndex","getPropertiesWithBufferView","delete","createAccessor","componentType","minMax","_verifyBufferView","accessor","min","removeBufferView","bv","getBufferView","getData","has","_IsTransformable","Camera","Light","_CreateNodeAnimation","babylonTransformNode","animation","animationChannelTargetPath","useQuaternion","animationSampleRate","inputs","outputs","keyFrames","getKeys","minMaxKeyFrames","_GLTFAnimation","_CalculateMinMaxKeyFrames","interpolationOrBake","_DeduceInterpolation","interpolation","interpolationType","shouldBakeAnimation","_CreateBakedAnimation","framePerSecond","_CreateLinearOrStepAnimation","_CreateCubicSplineAnimation","samplerInterpolation","inputsMin","FloatRound","inputsMax","_DeduceAnimationInfo","dataAccessorType","property","targetProperty","split","_CreateNodeAnimationFromNodeAnimations","runtimeGLTFAnimation","idleGLTFAnimations","nodeMap","nodes","bufferManager","accessors","useRightHanded","shouldExportAnimation","glTFAnimation","animations","animationInfo","channels","_AddAnimation","hasRunningRuntimeAnimations","_CreateMorphTargetAnimationFromMorphTargetAnimations","Mesh","morphTargetManager","numTargets","getTarget","combinedAnimation","Animation","dataType","loopMode","enableBlending","combinedAnimationKeys","animationKeys","j","animationKey","k","frame","setKeys","_CreateNodeAndMorphAnimationFromAnimationGroups","babylonScene","glTFAnimations","leftHandedNodes","animationGroups","animationGroup","morphAnimations","sampleAnimations","morphAnimationMeshes","Set","animationGroupFrameDiff","targetAnimation","targetedAnimations","target","convertToRightHanded","MorphTarget","morphTargetManagers","find","babylonMesh","mesh","combinedAnimationGroup","sampleAnimationKeys","numAnimationKeys","morphTarget","animationsByMorphTarget","morphTargetAnimation","ANIMATIONTYPE_FLOAT","influence","inTangent","outTangent","morphAnimationChannels","keyframeAccessorIndex","dataAccessorIndex","animationSampler","animationChannel","animationData","currentInput","newInputs","shift","nodeIndex","inputData","output","outputToWrite","toArray","FromEulerVectorToRef","input","path","minFrame","maxFrame","fps","sampleRate","minMaxFrames","time","quaternionCache","previousTime","maxUsedFrame","currKeyFrame","nextKeyFrame","prevKeyFrame","endFrame","equals","state","repeatCount","_interpolate","_SetInterpolatedValue","_ConvertFactorToVector3OrQuaternion","factor","basePositionRotationOrScale","_GetBasePositionRotationOrScale","componentName","FromArray","normalize","cacheValue","RotationYawPitchRollToRef","keyFrame","_AddKeyframeValue","_AddSplineTangent","INTANGENT","OUTTANGENT","q","rotationQuaternion","position","One","newPositionRotationOrScale","animationType","ANIMATIONTYPE_VECTOR3","array","RotationYawPitchRoll","posRotScale","ANIMATIONTYPE_QUATERNION","tangentType","tangentValue","Infinity","BuildMorphTargetBuffers","attributes","flipX","difference","vertexCount","hasPositions","morphPositions","getPositions","originalPositions","getVerticesData","positionData","originalPosition","subtractToRef","floatSize","hasNormals","morphNormals","getNormals","originalNormals","normalData","originalNormal","hasTangents","morphTangents","getTangents","originalTangents","tangentData","originalTangent","morphTangent","hasColors","morphColors","getColors","originalColors","getVertexBuffer","componentSize","colorData","originalColor","difference4","Vector4","wasAddedByNoopNode","_indicesAccessorMap","_vertexBufferViewMap","_vertexAccessorMap","_remappedBufferView","_meshMorphTargetMap","_vertexMapColorAlpha","_exportedNodes","_meshMap","convertedToRightHandedBuffers","getIndicesAccessor","indices","start","flip","setIndicesAccessor","accessorIndex","map1","map2","map3","map4","pushExportedNode","getNodesSet","getVertexBufferView","setVertexBufferView","setRemappedBufferView","getRemappedBufferView","getVertexAccessor","setVertexAccessor","hasVertexColorAlpha","setHasVertexColorAlpha","getMesh","setMesh","meshIndex","bindMorphDataToMesh","morphData","morphTargets","indexOf","getMorphTargetsFromMesh","options","EngineStore","LastCreatedScene","_glTF","asset","Engine","Version","version","_animations","_accessors","_bufferViews","_cameras","_meshes","_nodes","_scenes","_skins","_materialExporter","GLTFMaterialExporter","_extensions","BufferManager","_shouldExportNodeMap","_nodeMap","_materialMap","_camerasMap","_nodesCameraMap","_skinMap","_nodesSkinMap","_babylonScene","_options","shouldExportNode","metadataSelector","metadata","gltf","extras","exportWithoutWaitingForScene","exportUnusedUVs","removeNoopRootNodes","includeCoordinateSystemConversionNodes","meshCompressionMethod","_loadExtensions","_ApplyExtension","actionAsync","currentPromise","newNode","_ApplyExtensions","GLTFExporter","_ExtensionNames","_extensionsPostExportNodeAsync","context","postExportNodeAsync","postExportMaterialAsync","map","postExportMaterialAdditionalTexturesAsync","postExportTexture","_extensionsPostExportMeshPrimitive","primitive","postExportMeshPrimitive","_extensionsPreGenerateBinaryAsync","preGenerateBinaryAsync","_forEachExtensions","action","enabled","_extensionsOnExporting","wasUsed","extensionsUsed","required","extensionsRequired","onExporting","_ExtensionFactories","dispose","RegisterExtension","order","UnregisterExtension","extensionOrder","_ExtensionOrders","insertIndex","existingName","splice","_generateJSON","bufferByteLength","fileName","prettyPrint","buffers","scenes","cameras","skins","JSON","stringify","generateGLTFAsync","glTFPrefix","_generateBinaryAsync","binaryBuffer","jsonText","bin","glTFFileName","glTFBinFile","container","GLTFData","_exportSceneAsync","_getPadding","num","remainder","generateGLBAsync","glbFileName","jsonLength","TextEncoder","encoder","encodedJsonText","encode","jsonPadding","binPadding","headerLength","blankCharCode","charCodeAt","charCode","codePointAt","_setNodeTransformation","getPivotPoint","copyFrom","clone","FromEulerAngles","_setCameraTransformation","babylonCamera","cameraWorldMatrix","parentInvWorldMatrix","invertToRef","_listAvailableCameras","camera","glTFCamera","mode","PERSPECTIVE_CAMERA","perspective","aspectRatio","getAspectRatio","yfov","fovMode","FOVMODE_VERTICAL_FIXED","fov","znear","minZ","zfar","maxZ","halfWidth","orthoLeft","orthoRight","getRenderWidth","halfHeight","orthoBottom","orthoTop","getRenderHeight","orthographic","xmag","ymag","_exportAndAssignCameras","values","gltfCamera","usedNodes","_listAvailableSkeletons","skeletons","skeleton","bones","joints","_exportAndAssignSkeletons","leftHandNodes","skin","boneIndexMap","maxBoneIndex","bone","boneIndex","getIndex","inverseBindMatrices","transformNode","getTransformNode","boneMatrix","getAbsoluteInverseBindMatrix","skinnedNodes","mat","m","skinIndex","rootNodesRH","rootNodesLH","rootNoopNodesRH","rootNodes","rootNode","stateLH","ExporterState","_exportNodesAsync","stateRH","noopRH","_animationSampleRate","_shouldExportNode","babylonRootNodes","_exportBuffers","_exportNodeAsync","_collectBuffers","bufferToVertexBuffersMap","vertexBufferToMeshesMap","morphTargetsToMeshesMap","vertexBuffers","getVertexBuffers","hasVertexAlpha","vertexBufferArray","morphIndex","babylonChildNode","morphTargetsMeshesMap","bytes","floatData","DataArrayToUint8Array","EnumerateFloatValues","invLength","stdMaterialCount","filter","StandardMaterial","UNSIGNED_BYTE","Color4","fromArray","toLinearSpaceToRef","floatMatricesIndices","FLOAT","getFloatData","is16Bit","newArray","glTFMorphTarget","parentNodeChildren","includes","_createNodeAsync","idleGLTFAnimation","children","InstancedMesh","sourceMesh","subMeshes","_exportMeshAsync","parentNodeIndex","_exportIndices","is32Bits","sideOrientation","indicesToExport","CounterClockWiseSideOrientation","IsTriangleFillMode","newIndices","processedIndices","subarray","IndicesArrayToTypedSubarray","_exportVertexBuffer","startsWith","fill","GetMinMax","isFloatMatricesIndices","vertexBufferType","vertexBufferNormalized","GetAccessorType","GetAttributeType","_exportMaterialAsync","subMesh","materialIndex","MultiMaterial","subMaterials","getClassName","primitives","isUnIndexed","getIndices","isLinesMesh","LinesMesh","isGreasedLineMesh","GreasedLineBaseMesh","getMaterial","defaultMaterial","babylonLinesMesh","colorWhite","greasedLineMaterial","overrideRenderingFillMode","_getEffectiveOrientation","ClockWiseSideOrientation","AreIndices32Bits","indexCount","indexStart","verticesStart","verticesCount","targets","gltfMorphTarget","weights","targetNames","GLTFAsync","whenReadyAsync","exporter","GLBAsync","NAME","ColorBufferToRGBAToRGB","colorBuffer","instanceCount","colorBufferRgb","_instanceColorWarned","_wasUsed","hasThinInstances","noTranslation","noRotation","noScale","thinInstanceGetWorldMatrices","iwt","iwr","iws","hasAnyInstanceWorldTranslation","hasAnyInstanceWorldRotation","hasAnyInstanceWorldScale","translationBuffer","thinInstanceCount","rotationBuffer","scaleBuffer","_buildAccessor","_userThinInstanceBuffersStorage","instanceColor","EXT_mesh_gpu_instancing","_bufferViewsUsed","_accessorsUsed","_encodePromises","DracoEncoder","DefaultAvailable","primitiveBufferViews","primitiveAccessors","glTFName","GetTypedArrayData","GetTypeByteLength","dracoName","method","promise","Default","_encodeAsync","encodedData","dracoInfo","attributeIds","catch","error","clear","KHR_draco_mesh_compression","DEFAULTS","intensity","range","SPOTDEFAULTS","innerConeAngle","outerConeAngle","PI","LIGHTDIRECTION","Backward","_lights","lightType","getTypeID","LIGHTTYPEID_POINTLIGHT","LIGHTTYPEID_DIRECTIONALLIGHT","LIGHTTYPEID_SPOTLIGHT","ShadowLight","falloffType","FALLOFF_GLTF","equalsToFloats","direction","normalizeToRef","lightRotationQuaternion","FromUnitVectorsToRef","IsIdentity","light","babylonSpotLight","spot","innerAngle","angle","lights","lightReference","KHR_lights_punctual","RECTDEFAULTS","aspect","LIGHTTYPEID_RECT_AREALIGHT","areaLight","Forward","rect","EXT_lights_area","CreateMergedAnisotropyTexture","anisoStrengthTexture","specularRoughnessAnisotropyTexture","tangentTexture","geometryTangentTexture","_anisoTexturesMap","additionalTextures","anisotropy","isEnabled","legacy","specularRoughnessAnisotropy","texId","strengthId","tangentId","GetAnisoTextureId","anisoTexture","baseRoughness","baseAlpha","roughnessT","roughnessB","anisotropyTextureInfo","anisotropyInfo","anisotropyStrength","anisotropyRotation","anisotropyTexture","_useRoughnessFromMetallicTextureGreen","mergedAnisoTexture","id","newBaseRoughness","newAnisotropyStrength","_useGltfStyleAnisotropy","newParams","geometryTangentAngle","mergedAnisoTextureInfo","KHR_materials_anisotropy","CreateMergedCoatInternalTextureAsync","coatTexture","coatWeightTexture","coatRoughnessTexture","_useCoatRoughnessFromGreenChannel","CreateTempTexture","sourceTexture","tempTexture","_texture","uOffset","vOffset","uScale","vScale","wAng","_mergedTexturesMap","_cachedInternalTexturesMap","clearCoat","useRoughnessFromMainTexture","textureRoughness","coatWeight","coatNeedsMerge","coatId","GetCoatTextureId","geometryCoatNormalTexture","clearCoatTextureRoughnessInfo","clearCoatTextureInfo","isTintEnabled","remapF0OnInterfaceChange","clearCoatNormalTextureInfo","clearCoatInfo","clearcoatFactor","clearcoatTexture","clearcoatRoughnessFactor","clearcoatRoughnessTexture","clearcoatNormalTexture","coatTextureInfo","coatRoughnessTextureInfo","coatColorTexture","coatRoughness","KHR_materials_clearcoat","coatRoughnessAnisotropyTexture","geometryCoatTangentTexture","tintTexture","coatRoughnessAnisotropy","coatTextureRoughnessInfo","coatColorTextureInfo","coatNormalTextureInfo","coatIor","indexOfRefraction","coatInfo","coatFactor","coatRoughnessFactor","coatNormalTexture","coatColorFactor","tintColor","coatDarkeningFactor","coatDarkening","coatAnisotropyStrength","coatAnisotropyRotation","coatAnisotropyTexture","geometryCoatTangentAngle","coatColor","KHR_materials_coat","GetTranslucencyIntensityTexture","subs","subSurface","translucencyIntensityTexture","thicknessTexture","useMaskFromThicknessTexture","useGltfStyleTextures","PBRMaterial","_isExtensionEnabled","translucencyColorTexture","unlit","isTranslucencyEnabled","useAlbedoToTintTranslucency","volumeIndexOfRefraction","minimumThickness","maximumThickness","diffuseTransmissionFactor","translucencyIntensity","diffuseTransmissionTexture","diffuseTransmissionColorFactor","translucencyColor","equalsFloats","diffuseTransmissionColorTexture","diffuseTransmissionInfo","KHR_materials_diffuse_transmission","isRefractionEnabled","isDispersionEnabled","dispersionInfo","dispersion","KHR_materials_dispersion","emissiveIntensity","tempEmissiveStrength","emissiveStrengthInfo","emissiveStrength","KHR_materials_emissive_strength","iorInfo","ior","KHR_materials_ior","iridescence","thinFilmWeight","thinFilmWeightTexture","thinFilmThicknessTexture","iridescenceTextureInfo","iridescenceThicknessTextureInfo","iridescenceInfo","iridescenceFactor","iridescenceIor","iridescenceThicknessMinimum","iridescenceThicknessMaximum","iridescenceTexture","iridescenceThicknessTexture","thinFilmWeightTextureInfo","thinFilmThicknessTextureInfo","thinFilmIor","thinFilmThicknessMin","thinFilmThickness","KHR_materials_iridescence","sheen","sheenInfo","sheenColorFactor","sheenRoughnessFactor","sheenColorTexture","sheenRoughnessTexture","KHR_materials_sheen","CreateMergedFuzzInternalTexture","fuzzColorTexture","fuzzRoughnessTexture","_useFuzzRoughnessFromTextureAlpha","fuzzWeight","fuzzWeightTexture","fuzzTexturesNeedMerge","fuzzColorId","fuzzRoughnessId","GetFuzzColorTextureId","mergedInternalTexture","fuzzInfo","fuzzFactor","fuzzColorFactor","fuzzColor","fuzzRoughnessFactor","fuzzRoughness","fuzzTexture","KHR_materials_fuzz","metallicReflectanceTexture","reflectanceTexture","metallicF0Factor","metallicReflectanceColor","_hasTexturesExtension","specularInfo","specularFactor","specularTexture","specularColorFactor","specularColorTexture","specularWeightTexture","specularWeight","specularEdgeColorEnabled","KHR_materials_specular","refractionIntensity","refractionIntensityTexture","transmissionFactor","volumeInfo","transmissionTexture","KHR_materials_transmission","unlitMaterial","disableLighting","KHR_materials_unlit","tintColorAtDistance","POSITIVE_INFINITY","thicknessFactor","attenuationDistance","attenuationColor","KHR_materials_volume","_baseDiffuseRoughness","_baseDiffuseRoughnessTexture","baseDiffuseRoughness","baseDiffuseRoughnessTexture","diffuseRoughnessFactor","diffuseRoughnessTexture","diffuseRoughnessTextureInfo","diffuseRoughnessInfo","KHR_materials_diffuse_roughness","uAng","vAng","uRotationCenter","vRotationCenter","textureTransform","transformIsRequired","homogeneousRotationInUVTransform","cosAngle","cos","sinAngle","sin","scaledURotationCenter","scaledVRotationCenter","AdjustOffsetForRotationCenter","KHR_texture_transform","KHR_texture_basisu","EXT_texture_webp","EXT_texture_avif","globalObject","BABYLON","GLTF2","Exporter","Extensions"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"babylon.glTF2Serializer.min.js","mappings":"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","sources":["webpack://SERIALIZERS/webpack/universalModuleDefinition","webpack://SERIALIZERS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://SERIALIZERS/webpack/bootstrap","webpack://SERIALIZERS/webpack/runtime/define property getters","webpack://SERIALIZERS/webpack/runtime/global","webpack://SERIALIZERS/webpack/runtime/hasOwnProperty shorthand","webpack://SERIALIZERS/webpack/runtime/make namespace object","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/glTFFileExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFData.ts","webpack://SERIALIZERS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/exportUtils.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/dataWriter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/bufferManager.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMorphTargetsUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_lights_area.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_coat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_fuzz.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_basisu.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_texture_webp.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_texture_avif.ts","webpack://SERIALIZERS/../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts","webpack://SERIALIZERS/./src/glTF2.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-serializers\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-serializers\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"SERIALIZERS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtension = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for extending the exporter\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtension {\r\n /**\r\n * The name of this extension\r\n */\r\n readonly name: string;\r\n /**\r\n * Defines whether this extension is enabled\r\n */\r\n enabled: boolean;\r\n\r\n /**\r\n * Defines whether this extension is required\r\n */\r\n required: boolean;\r\n}\r\n","import { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Class for holding and downloading glTF file data\r\n */\r\nexport class GLTFData {\r\n /**\r\n * Object which contains the file name as the key and its data as the value\r\n */\r\n public readonly files: { [fileName: string]: string | Blob } = {};\r\n\r\n /**\r\n * @deprecated Use files instead\r\n */\r\n public get glTFFiles() {\r\n return this.files;\r\n }\r\n\r\n /**\r\n * Downloads the glTF data as files based on their names and data\r\n */\r\n public downloadFiles(): void {\r\n for (const key in this.files) {\r\n const value = this.files[key];\r\n const blob = new Blob([value], { type: GetMimeType(key) });\r\n Tools.Download(blob, key);\r\n }\r\n }\r\n}\r\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\r\n/* eslint-disable github/no-then */\r\n/* eslint-disable babylonjs/available */\r\n\r\nimport type { ITextureInfo, IMaterial, IMaterialPbrMetallicRoughness, IMaterialOcclusionTextureInfo, ISampler, IImage } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType, MaterialAlphaMode, TextureMagFilter, TextureMinFilter, TextureWrapMode } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { DeepImmutable, Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { GetTextureDataAsync, TextureTools } from \"core/Misc/textureTools\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\nimport type { Scene } from \"core/scene\";\r\n\r\nimport type { GLTFExporter } from \"./glTFExporter\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EncodeImageAsync } from \"core/Misc/dumpTools\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { SpecularPowerToRoughness } from \"core/Helpers/materialConversionHelper\";\r\nimport { InternalTextureSource } from \"core/Materials/Textures/internalTexture\";\r\nimport { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\n\r\nconst Epsilon = 1e-6;\r\nconst DielectricSpecular = new Color3(0.04, 0.04, 0.04) as DeepImmutable<Color3>;\r\nconst MaxSpecularPower = 1024;\r\nconst White = Color3.White() as DeepImmutable<Color3>;\r\nconst Black = Color3.BlackReadOnly;\r\n\r\n/**\r\n * Interface for storing specular glossiness factors\r\n * @internal\r\n */\r\ninterface IPBRSpecularGlossiness {\r\n /**\r\n * Represents the linear diffuse factors of the material\r\n */\r\n diffuseColor: Color3;\r\n specularColor: Color3;\r\n glossiness: number;\r\n}\r\n\r\ninterface IPBRMetallicRoughness {\r\n baseColor: Color3;\r\n metallic: Nullable<number>;\r\n roughness: Nullable<number>;\r\n metallicRoughnessTextureData?: Nullable<Blob>;\r\n baseColorTextureData?: Nullable<Blob>;\r\n}\r\n\r\nfunction GetFileExtensionFromMimeType(mimeType: ImageMimeType): string {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n return \".jpg\";\r\n case ImageMimeType.PNG:\r\n return \".png\";\r\n case ImageMimeType.WEBP:\r\n return \".webp\";\r\n case ImageMimeType.AVIF:\r\n return \".avif\";\r\n case ImageMimeType.KTX2:\r\n return \".ktx2\";\r\n }\r\n}\r\n\r\n/**\r\n * @param mimeType the MIME type requested by the user\r\n * @returns true if the given mime type is compatible with glTF\r\n */\r\nfunction IsSupportedMimeType(mimeType?: string): mimeType is ImageMimeType {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n case ImageMimeType.PNG:\r\n case ImageMimeType.WEBP:\r\n case ImageMimeType.AVIF:\r\n case ImageMimeType.KTX2:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Gets cached image from a texture, if available.\r\n * @param babylonTexture texture to check for cached image\r\n * @returns image data if found and directly usable; null otherwise\r\n */\r\nasync function GetCachedImageAsync(babylonTexture: BaseTexture): Promise<Nullable<Blob>> {\r\n const internalTexture = babylonTexture.getInternalTexture();\r\n if (!internalTexture || internalTexture.source !== InternalTextureSource.Url) {\r\n return null;\r\n }\r\n if (internalTexture.invertY) {\r\n return null;\r\n }\r\n\r\n const buffer = internalTexture._buffer;\r\n\r\n let data;\r\n let mimeType = (babylonTexture as Texture).mimeType;\r\n\r\n if (!buffer) {\r\n data = await Tools.LoadFileAsync(internalTexture.url);\r\n mimeType = GetMimeType(internalTexture.url) || mimeType;\r\n } else if (ArrayBuffer.isView(buffer)) {\r\n data = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\r\n } else if (buffer instanceof ArrayBuffer) {\r\n data = buffer;\r\n } else if (buffer instanceof Blob) {\r\n data = await buffer.arrayBuffer();\r\n mimeType = buffer.type || mimeType;\r\n } else if (typeof buffer === \"string\") {\r\n data = await Tools.LoadFileAsync(buffer);\r\n mimeType = GetMimeType(buffer) || mimeType;\r\n } else if (typeof HTMLImageElement !== \"undefined\" && buffer instanceof HTMLImageElement) {\r\n data = await Tools.LoadFileAsync(buffer.src);\r\n mimeType = GetMimeType(buffer.src) || mimeType;\r\n }\r\n\r\n if (data && IsSupportedMimeType(mimeType)) {\r\n return new Blob([data], { type: mimeType });\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Computes the metallic factor from specular glossiness values.\r\n * @param diffuse diffused value\r\n * @param specular specular value\r\n * @param oneMinusSpecularStrength one minus the specular strength\r\n * @returns metallic value\r\n * @internal\r\n */\r\nexport function _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number {\r\n if (specular < DielectricSpecular.r) {\r\n return 0;\r\n }\r\n\r\n const a = DielectricSpecular.r;\r\n const b = (diffuse * oneMinusSpecularStrength) / (1.0 - DielectricSpecular.r) + specular - 2.0 * DielectricSpecular.r;\r\n const c = DielectricSpecular.r - specular;\r\n const d = b * b - 4.0 * a * c;\r\n return Scalar.Clamp((-b + Math.sqrt(d)) / (2.0 * a), 0, 1);\r\n}\r\n\r\n/**\r\n * Computes the metallic/roughness factors from a Standard Material.\r\n * @internal\r\n */\r\nexport function _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness {\r\n const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);\r\n const opacity = babylonStandardMaterial.alpha;\r\n const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, MaxSpecularPower);\r\n\r\n const roughness = SpecularPowerToRoughness(specularPower);\r\n\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {\r\n baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],\r\n metallicFactor: 0,\r\n roughnessFactor: roughness,\r\n };\r\n\r\n return glTFPbrMetallicRoughness;\r\n}\r\n\r\n/**\r\n * Sets the glTF alpha mode to a glTF material from the Babylon Material\r\n * @param glTFMaterial glTF material\r\n * @param babylonMaterial Babylon material\r\n */\r\nfunction SetAlphaMode(glTFMaterial: IMaterial, babylonMaterial: Material & { alphaCutOff?: number }): void {\r\n if (babylonMaterial.needAlphaBlending()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.BLEND;\r\n } else if (babylonMaterial.needAlphaTesting()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.MASK;\r\n glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;\r\n }\r\n}\r\n\r\nfunction CreateWhiteTexture(width: number, height: number, scene: Scene): Texture {\r\n const data = new Uint8Array(width * height * 4);\r\n\r\n for (let i = 0; i < data.length; i = i + 4) {\r\n data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;\r\n }\r\n\r\n const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);\r\n\r\n return rawTexture;\r\n}\r\n\r\nfunction ConvertPixelArrayToFloat32(pixels: ArrayBufferView): Float32Array {\r\n if (pixels instanceof Uint8Array) {\r\n const length = pixels.length;\r\n const buffer = new Float32Array(pixels.length);\r\n for (let i = 0; i < length; ++i) {\r\n buffer[i] = pixels[i] / 255;\r\n }\r\n return buffer;\r\n } else if (pixels instanceof Float32Array) {\r\n return pixels;\r\n } else {\r\n throw new Error(\"Unsupported pixel format!\");\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods for working with glTF material conversion properties.\r\n * @internal\r\n */\r\nexport class GLTFMaterialExporter {\r\n // Mapping to store textures\r\n private _textureMap = new Map<number, ITextureInfo>();\r\n\r\n // Mapping of internal textures to images to avoid exporting duplicate images\r\n private _internalTextureToImage: { [uniqueId: number]: { [mimeType: string]: Promise<number> } } = {};\r\n\r\n constructor(private readonly _exporter: GLTFExporter) {}\r\n\r\n public getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo> {\r\n return babylonTexture ? (this._textureMap.get(babylonTexture.uniqueId) ?? null) : null;\r\n }\r\n\r\n public async exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, hasUVs: boolean): Promise<number> {\r\n const pbrMetallicRoughness = _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);\r\n\r\n const material: IMaterial = { name: babylonStandardMaterial.name };\r\n if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {\r\n if (!babylonStandardMaterial.twoSidedLighting) {\r\n Tools.Warn(babylonStandardMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n material.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const diffuseTexture = babylonStandardMaterial.diffuseTexture;\r\n if (diffuseTexture) {\r\n promises.push(\r\n this.exportTextureAsync(diffuseTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n pbrMetallicRoughness.baseColorTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const bumpTexture = babylonStandardMaterial.bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.normalTexture = textureInfo;\r\n if (bumpTexture.level !== 1) {\r\n material.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonStandardMaterial.emissiveTexture;\r\n if (emissiveTexture) {\r\n material.emissiveFactor = [1.0, 1.0, 1.0];\r\n\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.emissiveTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonStandardMaterial.ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture).then((textureInfo) => {\r\n if (textureInfo) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: textureInfo.index,\r\n };\r\n material.occlusionTexture = occlusionTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonStandardMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {\r\n if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {\r\n material.alphaMode = MaterialAlphaMode.BLEND;\r\n } else {\r\n Tools.Warn(babylonStandardMaterial.name + \": glTF 2.0 does not support alpha mode: \" + babylonStandardMaterial.alphaMode.toString());\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.emissiveColor && !babylonStandardMaterial.emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();\r\n }\r\n\r\n material.pbrMetallicRoughness = pbrMetallicRoughness;\r\n SetAlphaMode(material, babylonStandardMaterial);\r\n\r\n await this._finishMaterialAsync(material, babylonStandardMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(material);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _finishMaterialAsync(glTFMaterial: IMaterial, babylonMaterial: Material): Promise<void> {\r\n const textures = await this._exporter._extensionsPostExportMaterialAdditionalTexturesAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n\r\n const promises: Array<Promise<Nullable<ITextureInfo>>> = [];\r\n\r\n for (const texture of textures) {\r\n promises.push(this.exportTextureAsync(texture));\r\n }\r\n\r\n await Promise.all(promises);\r\n\r\n await this._exporter._extensionsPostExportMaterialAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n }\r\n\r\n /**\r\n * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null\r\n * @param texture1 first texture to resize\r\n * @param texture2 second texture to resize\r\n * @param scene babylonjs scene\r\n * @returns resized textures or null\r\n */\r\n private _resizeTexturesToSameDimensions(texture1: Nullable<BaseTexture>, texture2: Nullable<BaseTexture>, scene: Scene): { texture1: BaseTexture; texture2: BaseTexture } {\r\n const texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };\r\n const texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };\r\n let resizedTexture1: BaseTexture;\r\n let resizedTexture2: BaseTexture;\r\n\r\n if (texture1Size.width < texture2Size.width) {\r\n if (texture1 && texture1 instanceof Texture) {\r\n resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);\r\n } else {\r\n resizedTexture1 = CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);\r\n }\r\n resizedTexture2 = texture2!;\r\n } else if (texture1Size.width > texture2Size.width) {\r\n if (texture2 && texture2 instanceof Texture) {\r\n resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);\r\n } else {\r\n resizedTexture2 = CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);\r\n }\r\n resizedTexture1 = texture1!;\r\n } else {\r\n resizedTexture1 = texture1!;\r\n resizedTexture2 = texture2!;\r\n }\r\n\r\n return {\r\n texture1: resizedTexture1!,\r\n texture2: resizedTexture2!,\r\n };\r\n }\r\n\r\n /**\r\n * Convert Specular Glossiness Textures to Metallic Roughness\r\n * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness\r\n * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js\r\n * @param diffuseTexture texture used to store diffuse information\r\n * @param specularGlossinessTexture texture used to store specular and glossiness information\r\n * @param factors specular glossiness material factors\r\n * @returns pbr metallic roughness interface or null\r\n */\r\n private async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(\r\n diffuseTexture: Nullable<BaseTexture>,\r\n specularGlossinessTexture: Nullable<BaseTexture>,\r\n factors: IPBRSpecularGlossiness\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises = new Array<Promise<void>>();\r\n if (!(diffuseTexture || specularGlossinessTexture)) {\r\n return await Promise.reject(\"diffuse and specular glossiness textures are not defined!\");\r\n }\r\n\r\n const scene: Nullable<Scene> = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null;\r\n if (scene) {\r\n const resizedTextures = this._resizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);\r\n\r\n const diffuseSize = resizedTextures.texture1?.getSize();\r\n\r\n let diffuseBuffer: Float32Array;\r\n let specularGlossinessBuffer: Float32Array;\r\n\r\n const width = diffuseSize.width;\r\n const height = diffuseSize.height;\r\n\r\n const diffusePixels = await resizedTextures.texture1.readPixels();\r\n const specularPixels = await resizedTextures.texture2.readPixels();\r\n\r\n if (diffusePixels) {\r\n diffuseBuffer = ConvertPixelArrayToFloat32(diffusePixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from diffuse texture!\");\r\n }\r\n if (specularPixels) {\r\n specularGlossinessBuffer = ConvertPixelArrayToFloat32(specularPixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from specular glossiness texture!\");\r\n }\r\n\r\n const byteLength = specularGlossinessBuffer.byteLength;\r\n\r\n const metallicRoughnessBuffer = new Uint8Array(byteLength);\r\n const baseColorBuffer = new Uint8Array(byteLength);\r\n\r\n const strideSize = 4;\r\n const maxBaseColor = new Color3(0, 0, 0);\r\n let maxMetallic = 0;\r\n let maxRoughness = 0;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const offset = (width * h + w) * strideSize;\r\n\r\n const diffuseColor = new Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.diffuseColor);\r\n const specularColor = new Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.specularColor);\r\n const glossiness = specularGlossinessBuffer[offset + 3] * factors.glossiness;\r\n\r\n const specularGlossiness: IPBRSpecularGlossiness = {\r\n diffuseColor: diffuseColor,\r\n specularColor: specularColor,\r\n glossiness: glossiness,\r\n };\r\n\r\n const metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);\r\n maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);\r\n maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);\r\n maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);\r\n maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic!);\r\n maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness!);\r\n\r\n baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;\r\n baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;\r\n baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;\r\n baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;\r\n\r\n metallicRoughnessBuffer[offset] = 0;\r\n metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness! * 255;\r\n metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic! * 255;\r\n metallicRoughnessBuffer[offset + 3] = 255;\r\n }\r\n }\r\n\r\n // Retrieves the metallic roughness factors from the maximum texture values.\r\n const metallicRoughnessFactors: IPBRMetallicRoughness = {\r\n baseColor: maxBaseColor,\r\n metallic: maxMetallic,\r\n roughness: maxRoughness,\r\n };\r\n\r\n let writeOutMetallicRoughnessTexture = false;\r\n let writeOutBaseColorTexture = false;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const destinationOffset = (width * h + w) * strideSize;\r\n\r\n baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > Epsilon ? metallicRoughnessFactors.baseColor.r : 1;\r\n baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > Epsilon ? metallicRoughnessFactors.baseColor.g : 1;\r\n baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > Epsilon ? metallicRoughnessFactors.baseColor.b : 1;\r\n\r\n const linearBaseColorPixel = Color3.FromInts(\r\n baseColorBuffer[destinationOffset],\r\n baseColorBuffer[destinationOffset + 1],\r\n baseColorBuffer[destinationOffset + 2]\r\n );\r\n const sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions);\r\n baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;\r\n baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;\r\n baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;\r\n\r\n if (!sRGBBaseColorPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutBaseColorTexture = true;\r\n }\r\n\r\n metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness! > Epsilon ? metallicRoughnessFactors.roughness! : 1;\r\n metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic! > Epsilon ? metallicRoughnessFactors.metallic! : 1;\r\n\r\n const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);\r\n\r\n if (!metallicRoughnessPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutMetallicRoughnessTexture = true;\r\n }\r\n }\r\n }\r\n\r\n if (writeOutMetallicRoughnessTexture) {\r\n promises.push(\r\n EncodeImageAsync(metallicRoughnessBuffer, width, height).then((data) => {\r\n metallicRoughnessFactors.metallicRoughnessTextureData = data;\r\n })\r\n );\r\n }\r\n if (writeOutBaseColorTexture) {\r\n promises.push(\r\n EncodeImageAsync(baseColorBuffer, width, height).then((data) => {\r\n metallicRoughnessFactors.baseColorTextureData = data;\r\n })\r\n );\r\n }\r\n\r\n return await Promise.all(promises).then(() => {\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return await Promise.reject(\"_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!\");\r\n }\r\n }\r\n\r\n /**\r\n * Converts specular glossiness material properties to metallic roughness\r\n * @param specularGlossiness interface with specular glossiness material properties\r\n * @returns interface with metallic roughness material properties\r\n */\r\n private _convertSpecularGlossinessToMetallicRoughness(specularGlossiness: IPBRSpecularGlossiness): IPBRMetallicRoughness {\r\n const diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor);\r\n const specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor);\r\n const oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor);\r\n const metallic = _SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);\r\n const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - DielectricSpecular.r) / Math.max(1 - metallic, Epsilon));\r\n const baseColorFromSpecular = specularGlossiness.specularColor.subtract(DielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, Epsilon));\r\n let baseColor = Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);\r\n baseColor = baseColor.clampToRef(0, 1, baseColor);\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: 1 - specularGlossiness.glossiness,\r\n };\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n /**\r\n * Calculates the surface reflectance, independent of lighting conditions\r\n * @param color Color source to calculate brightness from\r\n * @returns number representing the perceived brightness, or zero if color is undefined\r\n */\r\n private _getPerceivedBrightness(color: Color3): number {\r\n return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);\r\n }\r\n\r\n /**\r\n * Returns the maximum color component value\r\n * @param color\r\n * @returns maximum color component value, or zero if color is null or undefined\r\n */\r\n private _getMaxComponent(color: Color3): number {\r\n return Math.max(color.r, Math.max(color.g, color.b));\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors\r\n * @param baseColor Base color of the material\r\n * @param metallic Metallic factor of the material\r\n * @param roughness Roughness factor of the material\r\n * @param albedoTexture Albedo texture of the material\r\n * @param metallicTexture Metallic texture of the material\r\n * @param roughnessTexture Roughness texture of the material\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n baseColor: Color3,\r\n metallic: Nullable<number>,\r\n roughness: Nullable<number>,\r\n albedoTexture: Nullable<BaseTexture>,\r\n metallicTexture: Nullable<BaseTexture>,\r\n roughnessTexture: Nullable<BaseTexture>,\r\n babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises: Promise<void>[] = [];\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: roughness,\r\n };\r\n\r\n if (hasUVs) {\r\n if (babylonPBRMaterial instanceof OpenPBRMaterial) {\r\n if (babylonPBRMaterial.geometryOpacityTexture) {\r\n // Merge baseColor and opacity\r\n const albedoId = albedoTexture && albedoTexture.getInternalTexture() ? albedoTexture.getInternalTexture()!.uniqueId : 0;\r\n const opacityId =\r\n babylonPBRMaterial.geometryOpacityTexture && babylonPBRMaterial.geometryOpacityTexture.getInternalTexture()\r\n ? babylonPBRMaterial.geometryOpacityTexture.getInternalTexture()!.uniqueId\r\n : 0;\r\n const mergedId = Number(`${albedoId}${opacityId}`);\r\n const glTFTexture = this._textureMap.get(mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n } else {\r\n promises.push(\r\n MergeTexturesAsync(\r\n \"baseColorOpacityTexture\",\r\n CreateRGBAConfiguration(\r\n albedoTexture ? CreateTextureInput(albedoTexture, 0) : CreateConstantInput(1.0),\r\n albedoTexture ? CreateTextureInput(albedoTexture, 1) : CreateConstantInput(1.0),\r\n albedoTexture ? CreateTextureInput(albedoTexture, 2) : CreateConstantInput(1.0),\r\n CreateTextureInput(babylonPBRMaterial.geometryOpacityTexture, 0)\r\n ),\r\n babylonPBRMaterial.getScene()\r\n ).then(async (mergedTexture) => {\r\n const glTFTexture = await this.exportTextureAsync(mergedTexture, mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n } else {\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(albedoTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n if (babylonPBRMaterial._useMetallicFromMetallicTextureBlue && metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n } else if (roughnessTexture || metallicTexture) {\r\n const metallicId = metallicTexture && metallicTexture.getInternalTexture() ? metallicTexture.getInternalTexture()!.uniqueId : 0;\r\n const roughnessId = roughnessTexture && roughnessTexture.getInternalTexture() ? roughnessTexture.getInternalTexture()!.uniqueId : 0;\r\n const mergedId = Number(`${metallicId}${roughnessId}`);\r\n const glTFTexture = this._textureMap.get(mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n } else {\r\n promises.push(\r\n MergeTexturesAsync(\r\n \"MetalRoughTexture\",\r\n CreateRGBAConfiguration(\r\n babylonPBRMaterial.ambientOcclusionTexture ? CreateTextureInput(babylonPBRMaterial.ambientOcclusionTexture, 0) : CreateConstantInput(1.0),\r\n roughnessTexture ? CreateTextureInput(roughnessTexture, 0) : CreateConstantInput(1.0),\r\n metallicTexture ? CreateTextureInput(metallicTexture, 0) : CreateConstantInput(1.0)\r\n ),\r\n babylonPBRMaterial.getScene()\r\n ).then(async (mergedTexture) => {\r\n const glTFTexture = await this.exportTextureAsync(mergedTexture, mergedId);\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n } else {\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(albedoTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n if (metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n private _getTextureSampler(texture: Nullable<BaseTexture>): ISampler {\r\n const sampler: ISampler = {};\r\n if (!texture || !(texture instanceof Texture)) {\r\n return sampler;\r\n }\r\n\r\n const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);\r\n if (wrapS !== TextureWrapMode.REPEAT) {\r\n sampler.wrapS = wrapS;\r\n }\r\n\r\n const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);\r\n if (wrapT !== TextureWrapMode.REPEAT) {\r\n sampler.wrapT = wrapT;\r\n }\r\n\r\n switch (texture.samplingMode) {\r\n case Texture.LINEAR_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n }\r\n\r\n return sampler;\r\n }\r\n\r\n private _getGLTFTextureWrapMode(wrapMode: number): TextureWrapMode {\r\n switch (wrapMode) {\r\n case Texture.WRAP_ADDRESSMODE: {\r\n return TextureWrapMode.REPEAT;\r\n }\r\n case Texture.CLAMP_ADDRESSMODE: {\r\n return TextureWrapMode.CLAMP_TO_EDGE;\r\n }\r\n case Texture.MIRROR_ADDRESSMODE: {\r\n return TextureWrapMode.MIRRORED_REPEAT;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Texture Wrap Mode ${wrapMode}!`);\r\n return TextureWrapMode.REPEAT;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertSpecGlossFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n pbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const specGloss: IPBRSpecularGlossiness = {\r\n diffuseColor: babylonPBRMaterial._albedoColor,\r\n specularColor: babylonPBRMaterial._reflectivityColor,\r\n glossiness: babylonPBRMaterial._microSurface,\r\n };\r\n\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;\r\n const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;\r\n if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {\r\n return await Promise.reject(\"_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported\");\r\n }\r\n\r\n if ((albedoTexture || reflectivityTexture) && hasUVs) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n\r\n const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);\r\n const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss);\r\n\r\n const textures = this._exporter._textures;\r\n\r\n if (metallicRoughnessFactors.baseColorTextureData) {\r\n const imageIndex = await this._exportImageAsync(`baseColor${textures.length}`, metallicRoughnessFactors.baseColorTextureData);\r\n pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);\r\n }\r\n\r\n if (metallicRoughnessFactors.metallicRoughnessTextureData) {\r\n const imageIndex = await this._exportImageAsync(`metallicRoughness${textures.length}`, metallicRoughnessFactors.metallicRoughnessTextureData);\r\n pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);\r\n }\r\n\r\n return metallicRoughnessFactors;\r\n } else {\r\n return this._convertSpecularGlossinessToMetallicRoughness(specGloss);\r\n }\r\n }\r\n\r\n public async exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonPBRMaterial.name,\r\n };\r\n\r\n const useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();\r\n\r\n if (useMetallicRoughness) {\r\n const albedoColor = babylonPBRMaterial._albedoColor;\r\n const alpha = babylonPBRMaterial.alpha;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n }\r\n\r\n const metallicRoughness = useMetallicRoughness\r\n ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial._albedoColor,\r\n babylonPBRMaterial._metallic,\r\n babylonPBRMaterial._roughness,\r\n babylonPBRMaterial._albedoTexture,\r\n babylonPBRMaterial._metallicTexture,\r\n babylonPBRMaterial._metallicTexture,\r\n babylonPBRMaterial,\r\n glTFPbrMetallicRoughness,\r\n hasUVs\r\n )\r\n : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _setMetallicRoughnessPbrMaterialAsync(\r\n metallicRoughness: IPBRMetallicRoughness,\r\n babylonPBRMaterial: PBRBaseMaterial | OpenPBRMaterial,\r\n glTFMaterial: IMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<void> {\r\n SetAlphaMode(glTFMaterial, babylonPBRMaterial);\r\n\r\n if (!metallicRoughness.baseColor.equalsWithEpsilon(White, Epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, Epsilon)) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];\r\n }\r\n\r\n if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {\r\n glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;\r\n }\r\n if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {\r\n glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;\r\n }\r\n\r\n if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {\r\n if (!babylonPBRMaterial._twoSidedLighting) {\r\n Tools.Warn(babylonPBRMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n glTFMaterial.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const bumpTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._bumpTexture : babylonPBRMaterial.geometryNormalTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.normalTexture = glTFTexture;\r\n if (bumpTexture.level !== 1) {\r\n glTFMaterial.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._ambientTexture : babylonPBRMaterial.ambientOcclusionTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n new Promise<Nullable<ITextureInfo>>(async (resolve) => {\r\n if (babylonPBRMaterial instanceof OpenPBRMaterial && glTFPbrMetallicRoughness.metallicRoughnessTexture) {\r\n // The metallicRoughnessTexture already contains the ambient occlusion data in its red channel, we don't need to export it again\r\n // However, we still need to set the texture info on the material.\r\n const samplerIndex = this._exportTextureSampler(ambientTexture);\r\n const imageIndex = this._exporter._textures[glTFPbrMetallicRoughness.metallicRoughnessTexture.index].source!;\r\n const textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, ambientTexture.coordinatesIndex);\r\n this._textureMap.set(ambientTexture.uniqueId, textureInfo);\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, ambientTexture);\r\n return resolve(textureInfo);\r\n } else {\r\n return resolve(await this.exportTextureAsync(ambientTexture));\r\n }\r\n }).then(async (glTFTexture) => {\r\n if (glTFTexture) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: glTFTexture.index,\r\n texCoord: glTFTexture.texCoord,\r\n extensions: glTFTexture.extensions,\r\n };\r\n\r\n glTFMaterial.occlusionTexture = occlusionTexture;\r\n if (babylonPBRMaterial instanceof PBRBaseMaterial) {\r\n occlusionTexture.strength = babylonPBRMaterial._ambientTextureStrength;\r\n } else {\r\n occlusionTexture.strength = babylonPBRMaterial.ambientOcclusionTexture!.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveTexture : babylonPBRMaterial.emissionColorTexture;\r\n if (emissiveTexture) {\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.emissiveTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n const emissiveColor = babylonPBRMaterial instanceof PBRBaseMaterial ? babylonPBRMaterial._emissiveColor : babylonPBRMaterial.emissionColor;\r\n if (!emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n glTFMaterial.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n }\r\n\r\n public async exportOpenPBRMaterialAsync(babylonOpenPBRMaterial: OpenPBRMaterial, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonOpenPBRMaterial.name,\r\n };\r\n\r\n const albedoColor = babylonOpenPBRMaterial.baseColor;\r\n const alpha = babylonOpenPBRMaterial.geometryOpacity;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n\r\n const metallicRoughness = await this._convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonOpenPBRMaterial.baseColor,\r\n babylonOpenPBRMaterial.baseMetalness,\r\n babylonOpenPBRMaterial.specularRoughness,\r\n babylonOpenPBRMaterial.baseColorTexture,\r\n babylonOpenPBRMaterial.baseMetalnessTexture,\r\n babylonOpenPBRMaterial.specularRoughnessTexture,\r\n babylonOpenPBRMaterial,\r\n glTFPbrMetallicRoughness,\r\n hasUVs\r\n );\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonOpenPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonOpenPBRMaterial);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n public async exportTextureAsync(babylonTexture: BaseTexture, overrideId: Nullable<number> = null): Promise<Nullable<ITextureInfo>> {\r\n let textureInfo = this._textureMap.get(overrideId ?? babylonTexture.uniqueId);\r\n if (textureInfo) {\r\n return textureInfo;\r\n }\r\n\r\n const samplerIndex = this._exportTextureSampler(babylonTexture);\r\n const imageIndex = await this._exportTextureImageAsync(babylonTexture);\r\n\r\n textureInfo = this._exportTextureInfo(imageIndex, samplerIndex, babylonTexture.coordinatesIndex);\r\n this._textureMap.set(overrideId ?? babylonTexture.uniqueId, textureInfo);\r\n\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, babylonTexture);\r\n return textureInfo;\r\n }\r\n\r\n private async _exportTextureImageAsync(babylonTexture: BaseTexture): Promise<number> {\r\n const requestedMimeType = (babylonTexture as Texture).mimeType ?? \"none\";\r\n // TODO: Add an official way for users to export using a different mime type\r\n // than the one they loaded with (which is denoted by Texture.mimeType)\r\n\r\n const internalTextureToImage = this._internalTextureToImage;\r\n const internalTextureUniqueId = babylonTexture.getInternalTexture()!.uniqueId;\r\n internalTextureToImage[internalTextureUniqueId] = internalTextureToImage[internalTextureUniqueId] || {};\r\n let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][requestedMimeType];\r\n\r\n if (imageIndexPromise === undefined) {\r\n imageIndexPromise = (async () => {\r\n // Try to get the image from memory first, if applicable\r\n const cache = await GetCachedImageAsync(babylonTexture);\r\n if (cache && (requestedMimeType === \"none\" || cache.type === requestedMimeType)) {\r\n return await this._exportImageAsync(babylonTexture.name, cache);\r\n }\r\n\r\n // Preserve texture mime type if defined\r\n let mimeType = ImageMimeType.PNG;\r\n if (requestedMimeType !== \"none\") {\r\n if (IsSupportedMimeType(requestedMimeType)) {\r\n mimeType = requestedMimeType;\r\n } else {\r\n mimeType = ImageMimeType.PNG;\r\n Tools.Warn(`Unsupported media type: ${requestedMimeType}. Exporting texture as PNG.`);\r\n }\r\n }\r\n\r\n const size = babylonTexture.getSize();\r\n const pixels = await GetTextureDataAsync(babylonTexture);\r\n const imageData = await EncodeImageAsync(pixels, size.width, size.height, mimeType);\r\n\r\n return await this._exportImageAsync(babylonTexture.name, imageData);\r\n })();\r\n\r\n internalTextureToImage[internalTextureUniqueId][requestedMimeType] = imageIndexPromise;\r\n }\r\n\r\n return await imageIndexPromise;\r\n }\r\n\r\n private async _exportImageAsync(name: string, imageData: Blob): Promise<number> {\r\n const images = this._exporter._images;\r\n\r\n let image: IImage;\r\n if (this._exporter._shouldUseGlb) {\r\n image = {\r\n name: name,\r\n mimeType: imageData.type as ImageMimeType,\r\n bufferView: undefined, // Will be updated later by BufferManager\r\n };\r\n const data = await imageData.arrayBuffer();\r\n const bufferView = this._exporter._bufferManager.createBufferView(new Uint8Array(data));\r\n this._exporter._bufferManager.setBufferView(image, bufferView);\r\n } else {\r\n // Build a unique URI\r\n const baseName = name.replace(/\\.\\/|\\/|\\.\\\\|\\\\/g, \"_\");\r\n const extension = GetFileExtensionFromMimeType(imageData.type as ImageMimeType);\r\n let fileName = baseName + extension;\r\n if (images.some((image) => image.uri === fileName)) {\r\n fileName = `${baseName}_${Tools.RandomId()}${extension}`;\r\n }\r\n\r\n image = {\r\n name: name,\r\n uri: fileName,\r\n };\r\n this._exporter._imageData[fileName] = imageData; // Save image data to be written to file later\r\n }\r\n\r\n images.push(image);\r\n\r\n return images.length - 1;\r\n }\r\n\r\n private _exportTextureInfo(imageIndex: number, samplerIndex: number, coordinatesIndex?: number): ITextureInfo {\r\n const textures = this._exporter._textures;\r\n let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);\r\n if (textureIndex === -1) {\r\n textureIndex = textures.length;\r\n textures.push({\r\n source: imageIndex,\r\n sampler: samplerIndex,\r\n });\r\n }\r\n\r\n const textureInfo: ITextureInfo = { index: textureIndex };\r\n if (coordinatesIndex) {\r\n textureInfo.texCoord = coordinatesIndex;\r\n }\r\n return textureInfo;\r\n }\r\n\r\n private _exportTextureSampler(texture: Nullable<BaseTexture>): number {\r\n const sampler = this._getTextureSampler(texture);\r\n\r\n // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler\r\n const samplers = this._exporter._samplers;\r\n const samplerIndex = samplers.findIndex(\r\n (s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT\r\n );\r\n if (samplerIndex !== -1) {\r\n return samplerIndex;\r\n }\r\n\r\n samplers.push(sampler);\r\n return samplers.length - 1;\r\n }\r\n}\r\n","import { Matrix, Quaternion, TmpVectors, Vector3 } from \"core/Maths/math.vector\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { Node } from \"core/node\";\r\n\r\n/**\r\n * Matrix that converts handedness on the X-axis. Used to convert from LH to RH and vice versa.\r\n * @internal\r\n */\r\nexport const ConvertHandednessMatrix = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());\r\n\r\n/**\r\n * Checks if a node is a \"noop\" transform node, usually inserted by the glTF loader to correct handedness.\r\n * @internal\r\n */\r\nexport function IsNoopNode(node: Node, useRightHandedSystem: boolean): boolean {\r\n if (!(node instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Transform\r\n if (useRightHandedSystem) {\r\n const matrix = node.getWorldMatrix();\r\n if (!matrix.equalsWithEpsilon(Matrix.IdentityReadOnly, Epsilon)) {\r\n return false;\r\n }\r\n } else {\r\n const matrix = node.getWorldMatrix().multiplyToRef(ConvertHandednessMatrix, TmpVectors.Matrix[0]);\r\n if (!matrix.equalsWithEpsilon(Matrix.IdentityReadOnly, Epsilon)) {\r\n return false;\r\n }\r\n }\r\n\r\n // Geometry\r\n if (node instanceof AbstractMesh && node.geometry) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\nimport type { INode } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, DataArray, IndicesArray, DeepImmutable } from \"core/types\";\r\nimport type { Vector4 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, TmpVectors, Matrix, Vector3 } from \"core/Maths/math.vector\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\nimport type { Node } from \"core/node\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { TargetCamera } from \"core/Cameras/targetCamera\";\r\nimport type { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { ConvertHandednessMatrix } from \"../../exportUtils\";\r\nimport type { AreaLight } from \"core/Lights/areaLight\";\r\n\r\n// Default values for comparison.\r\nexport const DefaultTranslation = Vector3.ZeroReadOnly;\r\nexport const DefaultRotation = Quaternion.Identity() as DeepImmutable<Quaternion>;\r\nexport const DefaultScale = Vector3.OneReadOnly;\r\nconst DefaultLoaderCameraParentScaleLh = new Vector3(-1, 1, 1) as DeepImmutable<Vector3>;\r\n\r\n/**\r\n * Get the information necessary for enumerating a vertex buffer.\r\n * @param vertexBuffer the vertex buffer to enumerate\r\n * @param meshes the meshes that use the vertex buffer\r\n * @returns the information necessary to enumerate the vertex buffer\r\n */\r\nexport function GetVertexBufferInfo(vertexBuffer: VertexBuffer, meshes: AbstractMesh[]) {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const componentCount = vertexBuffer.getSize();\r\n const totalVertices = meshes.reduce((max, current) => {\r\n return current.getTotalVertices() > max ? current.getTotalVertices() : max;\r\n }, -Number.MAX_VALUE); // Get the max total vertices count, to ensure we capture the full range of vertex data used by the meshes.\r\n const count = totalVertices * componentCount;\r\n const kind = vertexBuffer.getKind();\r\n\r\n return { byteOffset, byteStride, componentCount, type, count, normalized, totalVertices, kind };\r\n}\r\n\r\nexport function GetAccessorElementCount(accessorType: AccessorType): number {\r\n switch (accessorType) {\r\n case AccessorType.MAT2:\r\n return 4;\r\n case AccessorType.MAT3:\r\n return 9;\r\n case AccessorType.MAT4:\r\n return 16;\r\n case AccessorType.SCALAR:\r\n return 1;\r\n case AccessorType.VEC2:\r\n return 2;\r\n case AccessorType.VEC3:\r\n return 3;\r\n case AccessorType.VEC4:\r\n return 4;\r\n }\r\n}\r\n\r\nexport function FloatsNeed16BitInteger(floatArray: FloatArray): boolean {\r\n return floatArray.some((value) => value >= 256);\r\n}\r\n\r\nexport function IsStandardVertexAttribute(type: string): boolean {\r\n switch (type) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.ColorKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function GetAccessorType(kind: string, hasVertexColorAlpha: boolean): AccessorType {\r\n if (kind == VertexBuffer.ColorKind) {\r\n return hasVertexColorAlpha ? AccessorType.VEC4 : AccessorType.VEC3;\r\n }\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n return AccessorType.VEC3;\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return AccessorType.VEC4;\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return AccessorType.VEC2;\r\n }\r\n\r\n throw new Error(`Unknown kind ${kind}`);\r\n}\r\n\r\nexport function GetAttributeType(kind: string): string {\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n return \"POSITION\";\r\n case VertexBuffer.NormalKind:\r\n return \"NORMAL\";\r\n case VertexBuffer.TangentKind:\r\n return \"TANGENT\";\r\n case VertexBuffer.ColorKind:\r\n return \"COLOR_0\";\r\n case VertexBuffer.UVKind:\r\n return \"TEXCOORD_0\";\r\n case VertexBuffer.UV2Kind:\r\n return \"TEXCOORD_1\";\r\n case VertexBuffer.UV3Kind:\r\n return \"TEXCOORD_2\";\r\n case VertexBuffer.UV4Kind:\r\n return \"TEXCOORD_3\";\r\n case VertexBuffer.UV5Kind:\r\n return \"TEXCOORD_4\";\r\n case VertexBuffer.UV6Kind:\r\n return \"TEXCOORD_5\";\r\n case VertexBuffer.MatricesIndicesKind:\r\n return \"JOINTS_0\";\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n return \"JOINTS_1\";\r\n case VertexBuffer.MatricesWeightsKind:\r\n return \"WEIGHTS_0\";\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return \"WEIGHTS_1\";\r\n }\r\n\r\n throw new Error(`Unknown kind: ${kind}`);\r\n}\r\n\r\nexport function GetPrimitiveMode(fillMode: number): MeshPrimitiveMode {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n return MeshPrimitiveMode.TRIANGLES;\r\n case Material.TriangleStripDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_STRIP;\r\n case Material.TriangleFanDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_FAN;\r\n case Material.PointListDrawMode:\r\n case Material.PointFillMode:\r\n return MeshPrimitiveMode.POINTS;\r\n case Material.LineLoopDrawMode:\r\n return MeshPrimitiveMode.LINE_LOOP;\r\n case Material.LineListDrawMode:\r\n return MeshPrimitiveMode.LINES;\r\n case Material.LineStripDrawMode:\r\n return MeshPrimitiveMode.LINE_STRIP;\r\n }\r\n\r\n throw new Error(`Unknown fill mode: ${fillMode}`);\r\n}\r\n\r\nexport function IsTriangleFillMode(fillMode: number): boolean {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n case Material.TriangleStripDrawMode:\r\n case Material.TriangleFanDrawMode:\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function NormalizeTangent(tangent: Vector4 | Vector3) {\r\n const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);\r\n if (length > 0) {\r\n tangent.x /= length;\r\n tangent.y /= length;\r\n tangent.z /= length;\r\n }\r\n}\r\n\r\nexport function ConvertToRightHandedPosition(value: Vector3): Vector3 {\r\n value.x *= -1;\r\n return value;\r\n}\r\n\r\n/** @internal */\r\nexport function ConvertToRightHandedTransformMatrix(matrix: Matrix): Matrix {\r\n ConvertHandednessMatrix.invertToRef(TmpVectors.Matrix[0]).multiplyToRef(matrix, matrix).multiplyToRef(ConvertHandednessMatrix, matrix);\r\n return matrix;\r\n}\r\n\r\n/**\r\n * Converts, in-place, a left-handed quaternion to a right-handed quaternion via a change of basis.\r\n * @param value the unit quaternion to convert\r\n * @returns the converted quaternion\r\n */\r\nexport function ConvertToRightHandedRotation(value: Quaternion): Quaternion {\r\n /**\r\n * This is the simplified version of the following equation:\r\n * q' = to_quaternion(M * to_matrix(q) * M^-1)\r\n * where M is the conversion matrix `convertHandednessMatrix`,\r\n * q is the input quaternion, and q' is the converted quaternion.\r\n * Reference: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf\r\n */\r\n if (value.x * value.x + value.y * value.y > 0.5) {\r\n const absX = Math.abs(value.x);\r\n const absY = Math.abs(value.y);\r\n if (absX > absY) {\r\n const sign = Math.sign(value.x);\r\n value.x = absX;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w *= sign;\r\n } else {\r\n const sign = Math.sign(value.y);\r\n value.x *= -sign;\r\n value.y = absY;\r\n value.z *= sign;\r\n value.w *= -sign;\r\n }\r\n } else {\r\n const absZ = Math.abs(value.z);\r\n const absW = Math.abs(value.w);\r\n if (absZ > absW) {\r\n const sign = Math.sign(value.z);\r\n value.x *= -sign;\r\n value.y *= sign;\r\n value.z = absZ;\r\n value.w *= -sign;\r\n } else {\r\n const sign = Math.sign(value.w);\r\n value.x *= sign;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w = absW;\r\n }\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Pre-multiplies a 180-degree Y rotation to the quaternion, in order to match glTF's flipped forward direction for cameras.\r\n * @param rotation Target camera rotation.\r\n */\r\nexport function Rotate180Y(rotation: Quaternion): void {\r\n // Simplified from: rotation * (0, 1, 0, 0).\r\n rotation.copyFromFloats(-rotation.z, rotation.w, rotation.x, -rotation.y);\r\n}\r\n\r\n/**\r\n * Collapses GLTF parent and node into a single node, ignoring scaling.\r\n * This is useful for removing nodes that were added by the GLTF importer.\r\n * @param node Original GLTF node (Light or Camera).\r\n * @param parentNode Target parent node.\r\n */\r\nexport function CollapseChildIntoParent(node: INode, parentNode: INode): void {\r\n const parentTranslation = Vector3.FromArrayToRef(parentNode.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n const parentRotation = Quaternion.FromArrayToRef(parentNode.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n const parentMatrix = Matrix.ComposeToRef(DefaultScale, parentRotation, parentTranslation, TmpVectors.Matrix[0]);\r\n\r\n const translation = Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, TmpVectors.Vector3[2]);\r\n const rotation = Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n const matrix = Matrix.ComposeToRef(DefaultScale, rotation, translation, TmpVectors.Matrix[1]);\r\n\r\n parentMatrix.multiplyToRef(matrix, matrix);\r\n matrix.decompose(undefined, parentRotation, parentTranslation);\r\n\r\n if (parentTranslation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete parentNode.translation;\r\n } else {\r\n parentNode.translation = parentTranslation.asArray();\r\n }\r\n\r\n if (parentRotation.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n delete parentNode.rotation;\r\n } else {\r\n parentNode.rotation = parentRotation.asArray();\r\n }\r\n\r\n if (parentNode.scale) {\r\n delete parentNode.scale;\r\n }\r\n}\r\n\r\n/**\r\n * Checks whether a camera or light node is candidate for collapsing with its parent node.\r\n * This is useful for roundtrips, as the glTF Importer parents a new node to\r\n * lights and cameras to store their original transformation information.\r\n * @param babylonNode Babylon light or camera node.\r\n * @param parentBabylonNode Target Babylon parent node.\r\n * @returns True if the two nodes can be merged, false otherwise.\r\n */\r\nexport function IsChildCollapsible(babylonNode: ShadowLight | TargetCamera | AreaLight, parentBabylonNode: Node): boolean {\r\n if (!(parentBabylonNode instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Verify child is the only descendant\r\n const isOnlyDescendant = parentBabylonNode.getChildren().length === 1 && babylonNode.getChildren().length === 0 && babylonNode.parent === parentBabylonNode;\r\n if (!isOnlyDescendant) {\r\n return false;\r\n }\r\n\r\n // Verify parent has the expected scaling, determined by the node type and scene's coordinate system.\r\n const scene = babylonNode.getScene();\r\n const expectedScale = babylonNode instanceof TargetCamera && !scene.useRightHandedSystem ? DefaultLoaderCameraParentScaleLh : DefaultScale;\r\n\r\n if (!parentBabylonNode.scaling.equalsWithEpsilon(expectedScale, Epsilon)) {\r\n Logger.Warn(`Cannot collapse node ${babylonNode.name} into parent node ${parentBabylonNode.name} with modified scaling.`);\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Converts an IndicesArray into either a Uint32Array or Uint16Array.\r\n * If the `start` and `count` parameters specify a subset of the array, a new view is created.\r\n * If the input is a number[], the data is copied into a new buffer.\r\n * @param indices input array to be converted\r\n * @param start starting index\r\n * @param count number of indices\r\n * @param is32Bits whether the output should be Uint32Array (true) or Uint16Array (false) when indices is an `Array`\r\n * @returns a Uint32Array or Uint16Array\r\n * @internal\r\n */\r\nexport function IndicesArrayToTypedSubarray(indices: IndicesArray, start: number, count: number, is32Bits: boolean): Uint32Array | Uint16Array {\r\n let processedIndices = indices;\r\n if (start !== 0 || count !== indices.length) {\r\n processedIndices = Array.isArray(indices) ? indices.slice(start, start + count) : indices.subarray(start, start + count);\r\n }\r\n\r\n // If Int32Array, cast the indices (which should all be positive) to Uint32Array\r\n if (processedIndices instanceof Int32Array) {\r\n return new Uint32Array(processedIndices.buffer, processedIndices.byteOffset, processedIndices.length);\r\n }\r\n\r\n if (Array.isArray(processedIndices)) {\r\n return is32Bits ? new Uint32Array(processedIndices) : new Uint16Array(processedIndices);\r\n }\r\n\r\n return processedIndices;\r\n}\r\n\r\nexport function DataArrayToUint8Array(data: DataArray): Uint8Array {\r\n if (data instanceof Array) {\r\n const floatData = new Float32Array(data);\r\n return new Uint8Array(floatData.buffer, floatData.byteOffset, floatData.byteLength);\r\n }\r\n\r\n return ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);\r\n}\r\n\r\nexport function GetMinMax(data: DataArray, vertexBuffer: VertexBuffer, start: number, count: number): { min: number[]; max: number[] } {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const size = vertexBuffer.getSize();\r\n const min = new Array<number>(size).fill(Infinity);\r\n const max = new Array<number>(size).fill(-Infinity);\r\n EnumerateFloatValues(data, byteOffset + start * byteStride, byteStride, size, type, count * size, normalized, (values) => {\r\n for (let i = 0; i < size; i++) {\r\n min[i] = Math.min(min[i], values[i]);\r\n max[i] = Math.max(max[i], values[i]);\r\n }\r\n });\r\n\r\n return { min, max };\r\n}\r\n\r\n/**\r\n * Removes, in-place, object properties which have the same value as the default value.\r\n * Useful for avoiding unnecessary properties in the glTF JSON.\r\n * @param object the object to omit default values from\r\n * @param defaultValues a partial object with default values\r\n * @returns object with default values omitted\r\n */\r\nexport function OmitDefaultValues<T extends object>(object: T, defaultValues: Partial<T>): T {\r\n for (const [key, value] of Object.entries(object)) {\r\n const defaultValue = defaultValues[key as keyof T];\r\n if ((Array.isArray(value) && Array.isArray(defaultValue) && AreArraysEqual(value, defaultValue)) || value === defaultValue) {\r\n delete object[key as keyof T];\r\n }\r\n }\r\n return object;\r\n}\r\n\r\nfunction AreArraysEqual(array1: unknown[], array2: unknown[]): boolean {\r\n return array1.length === array2.length && array1.every((val, i) => val === array2[i]);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\nimport type { TypedArray } from \"core/types\";\r\n\r\nconst TypedArrayToWriteMethod = new Map<Function, (dataView: DataView, byteOffset: number, value: number) => void>([\r\n [Int8Array, (d, b, v) => d.setInt8(b, v)],\r\n [Uint8Array, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Uint8ClampedArray, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Int16Array, (dv, bo, v) => dv.setInt16(bo, v, true)],\r\n [Uint16Array, (dv, bo, v) => dv.setUint16(bo, v, true)],\r\n [Int32Array, (dv, bo, v) => dv.setInt32(bo, v, true)],\r\n [Uint32Array, (dv, bo, v) => dv.setUint32(bo, v, true)],\r\n [Float32Array, (dv, bo, v) => dv.setFloat32(bo, v, true)],\r\n [Float64Array, (dv, bo, v) => dv.setFloat64(bo, v, true)],\r\n]);\r\n\r\n/** @internal */\r\nexport class DataWriter {\r\n private _data: Uint8Array;\r\n private _dataView: DataView;\r\n private _byteOffset: number;\r\n\r\n public writeTypedArray(value: Exclude<TypedArray, BigInt64Array | BigUint64Array>): void {\r\n this._checkGrowBuffer(value.byteLength);\r\n const setMethod = TypedArrayToWriteMethod.get(value.constructor)!;\r\n for (let i = 0; i < value.length; i++) {\r\n setMethod(this._dataView, this._byteOffset, value[i]);\r\n this._byteOffset += value.BYTES_PER_ELEMENT;\r\n }\r\n }\r\n\r\n public constructor(byteLength: number) {\r\n this._data = new Uint8Array(byteLength);\r\n this._dataView = new DataView(this._data.buffer);\r\n this._byteOffset = 0;\r\n }\r\n\r\n public get byteOffset(): number {\r\n return this._byteOffset;\r\n }\r\n\r\n public getOutputData(): Uint8Array {\r\n return new Uint8Array(this._data.buffer, 0, this._byteOffset);\r\n }\r\n\r\n public writeUInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setUint8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setInt8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt16(entry: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setInt16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeUInt16(value: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setUint16(this._byteOffset, value, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeInt32(entry: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setInt32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeUInt32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setUint32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setFloat32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat64(value: number): void {\r\n this._checkGrowBuffer(8);\r\n this._dataView.setFloat64(this._byteOffset, value, true);\r\n this._byteOffset += 8;\r\n }\r\n\r\n private _checkGrowBuffer(byteLength: number): void {\r\n const newByteLength = this.byteOffset + byteLength;\r\n if (newByteLength > this._data.byteLength) {\r\n const newData = new Uint8Array(newByteLength * 2);\r\n newData.set(this._data);\r\n this._data = newData;\r\n this._dataView = new DataView(this._data.buffer);\r\n }\r\n }\r\n}\r\n","import type { TypedArray } from \"core/types\";\nimport type { AccessorComponentType, AccessorType, IAccessor, IBufferView } from \"babylonjs-gltf2interface\";\nimport { DataWriter } from \"./dataWriter\";\n\ntype TypedArrayForglTF = Exclude<TypedArray, Float64Array | BigInt64Array | BigUint64Array>;\n\ninterface IPropertyWithBufferView {\n bufferView?: number;\n}\n\nfunction GetHighestByteAlignment(byteLength: number): number {\n if (byteLength % 4 === 0) {\n return 4;\n }\n if (byteLength % 2 === 0) {\n return 2;\n }\n return 1;\n}\n\n/**\n * Utility class to centralize the management of binary data, bufferViews, and the objects that reference them.\n * @internal\n */\nexport class BufferManager {\n /**\n * Maps a bufferView to its data\n */\n private _bufferViewToData: Map<IBufferView, TypedArrayForglTF> = new Map<IBufferView, TypedArrayForglTF>();\n\n /**\n * Maps a bufferView to glTF objects that reference it via a \"bufferView\" property (e.g. accessors, images)\n */\n private _bufferViewToProperties: Map<IBufferView, IPropertyWithBufferView[]> = new Map<IBufferView, IPropertyWithBufferView[]>();\n\n /**\n * Maps an accessor to its bufferView\n */\n private _accessorToBufferView: Map<IAccessor, IBufferView> = new Map<IAccessor, IBufferView>();\n\n /**\n * Generates a binary buffer from the stored bufferViews. Also populates the bufferViews list.\n * @param bufferViews The list of bufferViews to be populated while writing the binary\n * @returns The binary buffer\n */\n public generateBinary(bufferViews: IBufferView[]): Uint8Array {\n // Construct a DataWriter with the total byte length to prevent resizing\n let totalByteLength = 0;\n this._bufferViewToData.forEach((data) => {\n totalByteLength += data.byteLength;\n });\n const dataWriter = new DataWriter(totalByteLength);\n\n // Order the bufferViews in descending order of their alignment requirements\n const orderedBufferViews = Array.from(this._bufferViewToData.keys()).sort((a, b) => GetHighestByteAlignment(b.byteLength) - GetHighestByteAlignment(a.byteLength));\n\n // Fill in the bufferViews list and missing bufferView index references while writing the binary\n for (const bufferView of orderedBufferViews) {\n bufferView.byteOffset = dataWriter.byteOffset;\n bufferViews.push(bufferView);\n\n const bufferViewIndex = bufferViews.length - 1;\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n object.bufferView = bufferViewIndex;\n }\n\n dataWriter.writeTypedArray(this._bufferViewToData.get(bufferView)!);\n\n this._bufferViewToData.delete(bufferView); // Try to free up memory ASAP\n }\n\n return dataWriter.getOutputData();\n }\n\n /**\n * Creates a buffer view based on the supplied arguments\n * @param data a TypedArray to create the bufferView for\n * @param byteStride byte distance between consecutive elements\n * @returns bufferView for glTF\n */\n public createBufferView(data: TypedArrayForglTF, byteStride?: number): IBufferView {\n const bufferView: IBufferView = {\n buffer: 0,\n byteOffset: undefined, // byteOffset will be set later, when we write the binary and decide bufferView ordering\n byteLength: data.byteLength,\n byteStride: byteStride,\n };\n this._bufferViewToData.set(bufferView, data);\n return bufferView;\n }\n\n /**\n * Creates an accessor based on the supplied arguments and assigns it to the bufferView\n * @param bufferView The glTF bufferView referenced by this accessor\n * @param type The type of the accessor\n * @param componentType The datatype of components in the attribute\n * @param count The number of attributes referenced by this accessor\n * @param byteOffset The offset relative to the start of the bufferView in bytes\n * @param minMax Minimum and maximum value of each component in this attribute\n * @param normalized Specifies whether integer data values are normalized before usage\n * @returns accessor for glTF\n */\n public createAccessor(\n bufferView: IBufferView,\n type: AccessorType,\n componentType: AccessorComponentType,\n count: number,\n byteOffset?: number,\n minMax?: { min: number[]; max: number[] },\n normalized?: boolean\n ): IAccessor {\n this._verifyBufferView(bufferView);\n const accessor: IAccessor = {\n bufferView: undefined, // bufferView will be set to a real index later, once we write the binary and decide bufferView ordering\n componentType: componentType,\n count: count,\n type: type,\n min: minMax?.min,\n max: minMax?.max,\n normalized: normalized,\n byteOffset: byteOffset,\n };\n this.setBufferView(accessor, bufferView);\n this._accessorToBufferView.set(accessor, bufferView);\n return accessor;\n }\n\n /**\n * Assigns a bufferView to a glTF object that references it\n * @param object The glTF object\n * @param bufferView The bufferView to assign\n */\n public setBufferView(object: IPropertyWithBufferView, bufferView: IBufferView) {\n this._verifyBufferView(bufferView);\n const properties = this.getPropertiesWithBufferView(bufferView);\n properties.push(object);\n }\n\n /**\n * Removes buffer view from the binary data, as well as from all its known references\n * @param bufferView the bufferView to remove\n */\n public removeBufferView(bufferView: IBufferView): void {\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n if (object.bufferView !== undefined) {\n delete object.bufferView;\n }\n }\n\n this._bufferViewToData.delete(bufferView);\n this._bufferViewToProperties.delete(bufferView);\n this._accessorToBufferView.forEach((bv, accessor) => {\n if (bv === bufferView) {\n // Additionally, remove byteOffset from accessor referencing this bufferView\n if (accessor.byteOffset !== undefined) {\n delete accessor.byteOffset;\n }\n this._accessorToBufferView.delete(accessor);\n }\n });\n }\n\n public getBufferView(accessor: IAccessor): IBufferView {\n const bufferView = this._accessorToBufferView.get(accessor);\n this._verifyBufferView(bufferView);\n return bufferView!;\n }\n\n public getPropertiesWithBufferView(bufferView: IBufferView): IPropertyWithBufferView[] {\n this._verifyBufferView(bufferView);\n this._bufferViewToProperties.set(bufferView, this._bufferViewToProperties.get(bufferView) ?? []);\n return this._bufferViewToProperties.get(bufferView)!;\n }\n\n public getData(bufferView: IBufferView): TypedArrayForglTF {\n this._verifyBufferView(bufferView);\n return this._bufferViewToData.get(bufferView)!;\n }\n\n private _verifyBufferView(bufferView?: IBufferView): void {\n if (bufferView === undefined || !this._bufferViewToData.has(bufferView)) {\n throw new Error(`BufferView ${bufferView} not found in BufferManager.`);\n }\n }\n}\n","import type { IAnimation, INode, IBufferView, IAccessor, IAnimationSampler, IAnimationChannel } from \"babylonjs-gltf2interface\";\r\nimport { AnimationSamplerInterpolation, AnimationChannelTargetPath, AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Animation } from \"core/Animations/animation\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\n\r\nimport type { IAnimationKey } from \"core/Animations/animationKey\";\r\nimport { AnimationKeyInterpolation } from \"core/Animations/animationKey\";\r\n\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\nimport { GetAccessorElementCount, ConvertToRightHandedPosition, Rotate180Y, ConvertToRightHandedRotation } from \"./glTFUtilities\";\r\n\r\n/**\r\n * @internal\r\n * Interface to store animation data.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationData {\r\n /**\r\n * Keyframe data.\r\n */\r\n inputs: number[];\r\n /**\r\n * Value data.\r\n */\r\n outputs: number[][];\r\n /**\r\n * Animation interpolation data.\r\n */\r\n samplerInterpolation: AnimationSamplerInterpolation;\r\n /**\r\n * Minimum keyframe value.\r\n */\r\n inputsMin: number;\r\n /**\r\n * Maximum keyframe value.\r\n */\r\n inputsMax: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationInfo {\r\n /**\r\n * The target channel for the animation\r\n */\r\n animationChannelTargetPath: AnimationChannelTargetPath;\r\n /**\r\n * The glTF accessor type for the data.\r\n */\r\n dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;\r\n /**\r\n * Specifies if quaternions should be used.\r\n */\r\n useQuaternion: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Enum for handling in tangent and out tangent.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nenum _TangentType {\r\n /**\r\n * Specifies that input tangents are used.\r\n */\r\n INTANGENT,\r\n /**\r\n * Specifies that output tangents are used.\r\n */\r\n OUTTANGENT,\r\n}\r\n\r\n/**\r\n * @internal\r\n * Utility class for generating glTF animation data from BabylonJS.\r\n */\r\nexport class _GLTFAnimation {\r\n /**\r\n * Determine if a node is transformable - ie has properties it should be part of animation of transformation.\r\n * @param babylonNode the node to test\r\n * @returns true if can be animated, false otherwise. False if the parameter is null or undefined.\r\n */\r\n private static _IsTransformable(babylonNode: Node): boolean {\r\n return babylonNode && (babylonNode instanceof TransformNode || babylonNode instanceof Camera || babylonNode instanceof Light);\r\n }\r\n\r\n /**\r\n * @ignore\r\n *\r\n * Creates glTF channel animation from BabylonJS animation.\r\n * @param babylonTransformNode - BabylonJS mesh.\r\n * @param animation - animation.\r\n * @param animationChannelTargetPath - The target animation channel.\r\n * @param useQuaternion - Specifies if quaternions are used.\r\n * @returns nullable IAnimationData\r\n */\r\n public static _CreateNodeAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean,\r\n animationSampleRate: number\r\n ): Nullable<_IAnimationData> {\r\n if (this._IsTransformable(babylonTransformNode)) {\r\n const inputs: number[] = [];\r\n const outputs: number[][] = [];\r\n const keyFrames = animation.getKeys();\r\n const minMaxKeyFrames = _GLTFAnimation._CalculateMinMaxKeyFrames(keyFrames);\r\n const interpolationOrBake = _GLTFAnimation._DeduceInterpolation(keyFrames, animationChannelTargetPath, useQuaternion);\r\n\r\n const interpolation = interpolationOrBake.interpolationType;\r\n const shouldBakeAnimation = interpolationOrBake.shouldBakeAnimation;\r\n\r\n if (shouldBakeAnimation) {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n } else {\r\n if (interpolation === AnimationSamplerInterpolation.LINEAR || interpolation === AnimationSamplerInterpolation.STEP) {\r\n _GLTFAnimation._CreateLinearOrStepAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n _GLTFAnimation._CreateCubicSplineAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n }\r\n }\r\n\r\n if (inputs.length && outputs.length) {\r\n const result: _IAnimationData = {\r\n inputs: inputs,\r\n outputs: outputs,\r\n samplerInterpolation: interpolation,\r\n inputsMin: shouldBakeAnimation ? minMaxKeyFrames.min : Tools.FloatRound(minMaxKeyFrames.min / animation.framePerSecond),\r\n inputsMax: shouldBakeAnimation ? minMaxKeyFrames.max : Tools.FloatRound(minMaxKeyFrames.max / animation.framePerSecond),\r\n };\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private static _DeduceAnimationInfo(animation: Animation): Nullable<_IAnimationInfo> {\r\n let animationChannelTargetPath: Nullable<AnimationChannelTargetPath> = null;\r\n let dataAccessorType = AccessorType.VEC3;\r\n let useQuaternion: boolean = false;\r\n const property = animation.targetProperty.split(\".\");\r\n switch (property[0]) {\r\n case \"scaling\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.SCALE;\r\n break;\r\n }\r\n case \"position\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.TRANSLATION;\r\n break;\r\n }\r\n case \"rotation\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"rotationQuaternion\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n useQuaternion = true;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"influence\": {\r\n dataAccessorType = AccessorType.SCALAR;\r\n animationChannelTargetPath = AnimationChannelTargetPath.WEIGHTS;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported animatable property ${property[0]}`);\r\n }\r\n }\r\n if (animationChannelTargetPath) {\r\n return { animationChannelTargetPath: animationChannelTargetPath, dataAccessorType: dataAccessorType, useQuaternion: useQuaternion };\r\n } else {\r\n Tools.Error(\"animation channel target path and data accessor type could be deduced\");\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create node animations from the transform node animations\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAnimationFromNodeAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (_GLTFAnimation._IsTransformable(babylonNode)) {\r\n if (babylonNode.animations) {\r\n for (const animation of babylonNode.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: animation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create individual morph animations from the mesh's morph target animation tracks\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonNode instanceof Mesh) {\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n if (morphTargetManager) {\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n const morphTarget = morphTargetManager.getTarget(i);\r\n for (const animation of morphTarget.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const combinedAnimation = new Animation(\r\n `${animation.name}`,\r\n \"influence\",\r\n animation.framePerSecond,\r\n animation.dataType,\r\n animation.loopMode,\r\n animation.enableBlending\r\n );\r\n const combinedAnimationKeys: IAnimationKey[] = [];\r\n const animationKeys = animation.getKeys();\r\n\r\n for (let j = 0; j < animationKeys.length; ++j) {\r\n const animationKey = animationKeys[j];\r\n for (let k = 0; k < morphTargetManager.numTargets; ++k) {\r\n if (k == i) {\r\n combinedAnimationKeys.push(animationKey);\r\n } else {\r\n combinedAnimationKeys.push({ frame: animationKey.frame, value: 0 });\r\n }\r\n }\r\n }\r\n combinedAnimation.setKeys(combinedAnimationKeys, true);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: combinedAnimation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n animation.name,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n combinedAnimation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded,\r\n morphTargetManager.numTargets\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Create node and morph animations from the animation groups\r\n * @param babylonScene\r\n * @param glTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene: Scene,\r\n glTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n leftHandedNodes: Set<Node>,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonScene.animationGroups) {\r\n const animationGroups = babylonScene.animationGroups;\r\n for (const animationGroup of animationGroups) {\r\n const morphAnimations: Map<Mesh, Map<MorphTarget, Animation>> = new Map();\r\n const sampleAnimations: Map<Mesh, Animation> = new Map();\r\n const morphAnimationMeshes: Set<Mesh> = new Set();\r\n const animationGroupFrameDiff = animationGroup.to - animationGroup.from;\r\n glTFAnimation = {\r\n name: animationGroup.name,\r\n channels: [],\r\n samplers: [],\r\n };\r\n for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n const targetAnimation = animationGroup.targetedAnimations[i];\r\n const target = targetAnimation.target;\r\n const animation = targetAnimation.animation;\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n\r\n const convertToRightHanded = leftHandedNodes.has(target);\r\n\r\n if (this._IsTransformable(target) || (target.length === 1 && this._IsTransformable(target[0]))) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonTransformNode = this._IsTransformable(target) ? target : this._IsTransformable(target[0]) ? target[0] : null;\r\n if (babylonTransformNode) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n glTFAnimation,\r\n babylonTransformNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n convertToRightHanded\r\n );\r\n }\r\n }\r\n } else if (target instanceof MorphTarget || (target.length === 1 && target[0] instanceof MorphTarget)) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonMorphTarget = target instanceof MorphTarget ? target : (target[0] as MorphTarget);\r\n if (babylonMorphTarget) {\r\n const babylonMorphTargetManager = babylonScene.morphTargetManagers.find((morphTargetManager) => {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n if (morphTargetManager.getTarget(j) === babylonMorphTarget) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n if (babylonMorphTargetManager) {\r\n const babylonMesh = babylonScene.meshes.find((mesh) => {\r\n return (mesh as Mesh).morphTargetManager === babylonMorphTargetManager;\r\n }) as Mesh;\r\n if (babylonMesh) {\r\n if (!morphAnimations.has(babylonMesh)) {\r\n morphAnimations.set(babylonMesh, new Map());\r\n }\r\n morphAnimations.get(babylonMesh)?.set(babylonMorphTarget, animation);\r\n morphAnimationMeshes.add(babylonMesh);\r\n sampleAnimations.set(babylonMesh, animation);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // this is the place for the KHR_animation_pointer.\r\n }\r\n }\r\n morphAnimationMeshes.forEach((mesh) => {\r\n const morphTargetManager = mesh.morphTargetManager!;\r\n let combinedAnimationGroup: Nullable<Animation> = null;\r\n const animationKeys: IAnimationKey[] = [];\r\n const sampleAnimation = sampleAnimations.get(mesh)!;\r\n const sampleAnimationKeys = sampleAnimation.getKeys();\r\n const numAnimationKeys = sampleAnimationKeys.length;\r\n /*\r\n Due to how glTF expects morph target animation data to be formatted, we need to rearrange the individual morph target animation tracks,\r\n such that we have a single animation, where a given keyframe input value has successive output values for each morph target belonging to the manager.\r\n See: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\r\n\r\n We do this via constructing a new Animation track, and interleaving the frames of each morph target animation track in the current Animation Group\r\n We reuse the Babylon Animation data structure for ease of handling export of cubic spline animation keys, and to reuse the\r\n existing _GLTFAnimation.AddAnimation codepath with minimal modification, however the constructed Babylon Animation is NOT intended for use in-engine.\r\n */\r\n for (let i = 0; i < numAnimationKeys; ++i) {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n const morphTarget = morphTargetManager.getTarget(j);\r\n const animationsByMorphTarget = morphAnimations.get(mesh);\r\n if (animationsByMorphTarget) {\r\n const morphTargetAnimation = animationsByMorphTarget.get(morphTarget);\r\n if (morphTargetAnimation) {\r\n if (!combinedAnimationGroup) {\r\n combinedAnimationGroup = new Animation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n \"influence\",\r\n morphTargetAnimation.framePerSecond,\r\n Animation.ANIMATIONTYPE_FLOAT,\r\n morphTargetAnimation.loopMode,\r\n morphTargetAnimation.enableBlending\r\n );\r\n }\r\n animationKeys.push(morphTargetAnimation.getKeys()[i]);\r\n } else {\r\n animationKeys.push({\r\n frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i,\r\n value: morphTarget.influence,\r\n inTangent: sampleAnimationKeys[0].inTangent ? 0 : undefined,\r\n outTangent: sampleAnimationKeys[0].outTangent ? 0 : undefined,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n combinedAnimationGroup!.setKeys(animationKeys, true);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup!);\r\n if (animationInfo) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n glTFAnimation,\r\n mesh,\r\n combinedAnimationGroup!,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n false,\r\n morphTargetManager?.numTargets\r\n );\r\n }\r\n });\r\n if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {\r\n glTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private static _AddAnimation(\r\n name: string,\r\n glTFAnimation: IAnimation,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n dataAccessorType: AccessorType,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n useQuaternion: boolean,\r\n animationSampleRate: number,\r\n convertToRightHanded: boolean,\r\n morphAnimationChannels?: number\r\n ) {\r\n const animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate);\r\n let bufferView: IBufferView;\r\n let accessor: IAccessor;\r\n let keyframeAccessorIndex: number;\r\n let dataAccessorIndex: number;\r\n let animationSampler: IAnimationSampler;\r\n let animationChannel: IAnimationChannel;\r\n\r\n if (animationData) {\r\n /*\r\n * Now that we have the glTF converted morph target animation data,\r\n * we can remove redundant input data so that we have n input frames,\r\n * and morphAnimationChannels * n output frames\r\n */\r\n if (morphAnimationChannels) {\r\n let index = 0;\r\n let currentInput: number = 0;\r\n const newInputs: number[] = [];\r\n while (animationData.inputs.length > 0) {\r\n currentInput = animationData.inputs.shift()!;\r\n if (index % morphAnimationChannels == 0) {\r\n newInputs.push(currentInput);\r\n }\r\n index++;\r\n }\r\n animationData.inputs = newInputs;\r\n }\r\n\r\n const nodeIndex = nodeMap.get(babylonTransformNode);\r\n\r\n // Create buffer view and accessor for key frames.\r\n const inputData = new Float32Array(animationData.inputs);\r\n bufferView = bufferManager.createBufferView(inputData);\r\n accessor = bufferManager.createAccessor(bufferView, AccessorType.SCALAR, AccessorComponentType.FLOAT, animationData.inputs.length, undefined, {\r\n min: [animationData.inputsMin],\r\n max: [animationData.inputsMax],\r\n });\r\n accessors.push(accessor);\r\n keyframeAccessorIndex = accessors.length - 1;\r\n\r\n // Perform conversions on keyed values while also building their buffer.\r\n const rotationQuaternion = new Quaternion();\r\n const eulerVec3 = new Vector3();\r\n const position = new Vector3();\r\n const isCamera = babylonTransformNode instanceof Camera;\r\n\r\n const elementCount = GetAccessorElementCount(dataAccessorType);\r\n const outputData = new Float32Array(animationData.outputs.length * elementCount);\r\n animationData.outputs.forEach(function (output: number[], index: number) {\r\n let outputToWrite: number[] = output;\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.TRANSLATION:\r\n if (convertToRightHanded) {\r\n Vector3.FromArrayToRef(output, 0, position);\r\n ConvertToRightHandedPosition(position);\r\n position.toArray(outputToWrite);\r\n }\r\n break;\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n if (isCamera) {\r\n Rotate180Y(rotationQuaternion);\r\n }\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n outputData.set(outputToWrite, index * elementCount);\r\n });\r\n\r\n // Create buffer view and accessor for keyed values.\r\n bufferView = bufferManager.createBufferView(outputData);\r\n accessor = bufferManager.createAccessor(bufferView, dataAccessorType, AccessorComponentType.FLOAT, animationData.outputs.length);\r\n accessors.push(accessor);\r\n dataAccessorIndex = accessors.length - 1;\r\n\r\n // create sampler\r\n animationSampler = {\r\n interpolation: animationData.samplerInterpolation,\r\n input: keyframeAccessorIndex,\r\n output: dataAccessorIndex,\r\n };\r\n glTFAnimation.samplers.push(animationSampler);\r\n\r\n // create channel\r\n animationChannel = {\r\n sampler: glTFAnimation.samplers.length - 1,\r\n target: {\r\n node: nodeIndex,\r\n path: animationChannelTargetPath,\r\n },\r\n };\r\n glTFAnimation.channels.push(animationChannel);\r\n }\r\n }\r\n\r\n /**\r\n * Create a baked animation\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation corresponding to the BabylonJS mesh\r\n * @param animationChannelTargetPath animation target channel\r\n * @param minFrame minimum animation frame\r\n * @param maxFrame maximum animation frame\r\n * @param fps frames per second of the animation\r\n * @param sampleRate\r\n * @param inputs input key frames of the animation\r\n * @param outputs output key frame data of the animation\r\n * @param minMaxFrames\r\n * @param minMaxFrames.min\r\n * @param minMaxFrames.max\r\n * @param useQuaternion specifies if quaternions should be used\r\n */\r\n private static _CreateBakedAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n minFrame: number,\r\n maxFrame: number,\r\n fps: number,\r\n sampleRate: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n minMaxFrames: { min: number; max: number },\r\n useQuaternion: boolean\r\n ) {\r\n let value: number | Vector3 | Quaternion;\r\n const quaternionCache: Quaternion = Quaternion.Identity();\r\n let previousTime: Nullable<number> = null;\r\n let time: number;\r\n let maxUsedFrame: Nullable<number> = null;\r\n let currKeyFrame: Nullable<IAnimationKey> = null;\r\n let nextKeyFrame: Nullable<IAnimationKey> = null;\r\n let prevKeyFrame: Nullable<IAnimationKey> = null;\r\n let endFrame: Nullable<number> = null;\r\n minMaxFrames.min = Tools.FloatRound(minFrame / fps);\r\n\r\n const keyFrames = animation.getKeys();\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n endFrame = null;\r\n currKeyFrame = keyFrames[i];\r\n\r\n if (i + 1 < length) {\r\n nextKeyFrame = keyFrames[i + 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(nextKeyFrame.value)) || currKeyFrame.value === nextKeyFrame.value) {\r\n if (i === 0) {\r\n // set the first frame to itself\r\n endFrame = currKeyFrame.frame;\r\n } else {\r\n continue;\r\n }\r\n } else {\r\n endFrame = nextKeyFrame.frame;\r\n }\r\n } else {\r\n // at the last key frame\r\n prevKeyFrame = keyFrames[i - 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(prevKeyFrame.value)) || currKeyFrame.value === prevKeyFrame.value) {\r\n continue;\r\n } else {\r\n endFrame = maxFrame;\r\n }\r\n }\r\n if (endFrame) {\r\n for (let f = currKeyFrame.frame; f <= endFrame; f += sampleRate) {\r\n time = Tools.FloatRound(f / fps);\r\n if (time === previousTime) {\r\n continue;\r\n }\r\n previousTime = time;\r\n maxUsedFrame = time;\r\n const state = {\r\n key: 0,\r\n repeatCount: 0,\r\n loopMode: animation.loopMode,\r\n };\r\n value = animation._interpolate(f, state);\r\n\r\n _GLTFAnimation._SetInterpolatedValue(babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion);\r\n }\r\n }\r\n }\r\n if (maxUsedFrame) {\r\n minMaxFrames.max = maxUsedFrame;\r\n }\r\n }\r\n\r\n private static _ConvertFactorToVector3OrQuaternion(\r\n factor: number,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): Vector3 | Quaternion {\r\n const basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(babylonTransformNode, animationChannelTargetPath, useQuaternion);\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n const property = animation.targetProperty.split(\".\");\r\n const componentName = property ? property[1] : \"\"; // x, y, z, or w component\r\n const value = useQuaternion ? Quaternion.FromArray(basePositionRotationOrScale).normalize() : Vector3.FromArray(basePositionRotationOrScale);\r\n\r\n switch (componentName) {\r\n case \"x\":\r\n case \"y\":\r\n case \"z\": {\r\n value[componentName] = factor;\r\n break;\r\n }\r\n case \"w\": {\r\n (value as Quaternion).w = factor;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`glTFAnimation: Unsupported component name \"${componentName}\"!`);\r\n }\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private static _SetInterpolatedValue(\r\n babylonTransformNode: Node,\r\n value: number | Vector3 | Quaternion,\r\n time: number,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n quaternionCache: Quaternion,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n let cacheValue: Vector3 | Quaternion | number;\r\n inputs.push(time);\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([value as number]);\r\n return;\r\n }\r\n\r\n if (animation.dataType === Animation.ANIMATIONTYPE_FLOAT) {\r\n value = this._ConvertFactorToVector3OrQuaternion(value as number, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion);\r\n }\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n quaternionCache = value as Quaternion;\r\n } else {\r\n cacheValue = value as Vector3;\r\n Quaternion.RotationYawPitchRollToRef(cacheValue.y, cacheValue.x, cacheValue.z, quaternionCache);\r\n }\r\n outputs.push(quaternionCache.asArray());\r\n } else {\r\n // scaling and position animation\r\n cacheValue = value as Vector3;\r\n outputs.push(cacheValue.asArray());\r\n }\r\n }\r\n\r\n /**\r\n * Creates linear animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateLinearOrStepAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n for (const keyFrame of animation.getKeys()) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n }\r\n }\r\n\r\n /**\r\n * Creates cubic spline animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateCubicSplineAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n animation.getKeys().forEach(function (keyFrame) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddSplineTangent(_TangentType.INTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n\r\n _GLTFAnimation._AddSplineTangent(_TangentType.OUTTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n });\r\n }\r\n\r\n private static _GetBasePositionRotationOrScale(babylonTransformNode: Node, animationChannelTargetPath: AnimationChannelTargetPath, useQuaternion: boolean) {\r\n let basePositionRotationOrScale: number[];\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n const q = (babylonTransformNode as TransformNode).rotationQuaternion;\r\n basePositionRotationOrScale = (q ?? Quaternion.Identity()).asArray();\r\n } else {\r\n const r: Vector3 = (babylonTransformNode as TransformNode).rotation;\r\n basePositionRotationOrScale = (r ?? Vector3.Zero()).asArray();\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n const p: Vector3 = (babylonTransformNode as TransformNode).position;\r\n basePositionRotationOrScale = (p ?? Vector3.Zero()).asArray();\r\n } else {\r\n // scale\r\n const s: Vector3 = (babylonTransformNode as TransformNode).scaling;\r\n basePositionRotationOrScale = (s ?? Vector3.One()).asArray();\r\n }\r\n return basePositionRotationOrScale;\r\n }\r\n\r\n /**\r\n * Adds a key frame value\r\n * @param keyFrame\r\n * @param animation\r\n * @param outputs\r\n * @param animationChannelTargetPath\r\n * @param babylonTransformNode\r\n * @param useQuaternion\r\n */\r\n private static _AddKeyframeValue(\r\n keyFrame: IAnimationKey,\r\n animation: Animation,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n babylonTransformNode: Node,\r\n useQuaternion: boolean\r\n ) {\r\n let newPositionRotationOrScale: Nullable<Vector3 | Quaternion | number>;\r\n const animationType = animation.dataType;\r\n if (animationType === Animation.ANIMATIONTYPE_VECTOR3) {\r\n let value = keyFrame.value.asArray();\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const array = Vector3.FromArray(value);\r\n const rotationQuaternion = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z);\r\n value = rotationQuaternion.asArray();\r\n }\r\n outputs.push(value); // scale vector.\r\n } else if (animationType === Animation.ANIMATIONTYPE_FLOAT) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([keyFrame.value]);\r\n } else {\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(\r\n keyFrame.value as number,\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n useQuaternion\r\n );\r\n if (newPositionRotationOrScale) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const posRotScale = useQuaternion\r\n ? (newPositionRotationOrScale as Quaternion)\r\n : Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();\r\n outputs.push(posRotScale.asArray());\r\n }\r\n outputs.push(newPositionRotationOrScale.asArray());\r\n }\r\n }\r\n } else if (animationType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n outputs.push((keyFrame.value as Quaternion).normalize().asArray());\r\n } else {\r\n Tools.Error(\"glTFAnimation: Unsupported key frame values for animation!\");\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Determine the interpolation based on the key frames\r\n * @param keyFrames\r\n * @param animationChannelTargetPath\r\n * @param useQuaternion\r\n */\r\n private static _DeduceInterpolation(\r\n keyFrames: IAnimationKey[],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): { interpolationType: AnimationSamplerInterpolation; shouldBakeAnimation: boolean } {\r\n let interpolationType: AnimationSamplerInterpolation | undefined;\r\n let shouldBakeAnimation = false;\r\n let key: IAnimationKey;\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION && !useQuaternion) {\r\n return { interpolationType: AnimationSamplerInterpolation.LINEAR, shouldBakeAnimation: true };\r\n }\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n key = keyFrames[i];\r\n if (key.inTangent || key.outTangent) {\r\n if (interpolationType) {\r\n if (interpolationType !== AnimationSamplerInterpolation.CUBICSPLINE) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.CUBICSPLINE;\r\n }\r\n } else {\r\n if (interpolationType) {\r\n if (\r\n interpolationType === AnimationSamplerInterpolation.CUBICSPLINE ||\r\n (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP && interpolationType !== AnimationSamplerInterpolation.STEP)\r\n ) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n if (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP) {\r\n interpolationType = AnimationSamplerInterpolation.STEP;\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n }\r\n }\r\n }\r\n if (!interpolationType) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n\r\n return { interpolationType: interpolationType, shouldBakeAnimation: shouldBakeAnimation };\r\n }\r\n\r\n /**\r\n * Adds an input tangent or output tangent to the output data\r\n * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion\r\n * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent)\r\n * @param outputs The animation data by keyframe\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param interpolation The interpolation type\r\n * @param keyFrame The key frame with the animation data\r\n * @param useQuaternion Specifies if quaternions are used\r\n */\r\n private static _AddSplineTangent(\r\n tangentType: _TangentType,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n interpolation: AnimationSamplerInterpolation,\r\n keyFrame: IAnimationKey,\r\n useQuaternion: boolean\r\n ) {\r\n let tangent: number[];\r\n const tangentValue: Vector3 | Quaternion | number = tangentType === _TangentType.INTANGENT ? keyFrame.inTangent : keyFrame.outTangent;\r\n if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (tangentValue) {\r\n if (useQuaternion) {\r\n tangent = (tangentValue as Quaternion).asArray();\r\n } else {\r\n const array = tangentValue as Vector3;\r\n tangent = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z).asArray();\r\n }\r\n } else {\r\n tangent = [0, 0, 0, 0];\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n if (tangentValue) {\r\n tangent = [tangentValue as number];\r\n } else {\r\n tangent = [0];\r\n }\r\n } else {\r\n if (tangentValue) {\r\n tangent = (tangentValue as Vector3).asArray();\r\n } else {\r\n tangent = [0, 0, 0];\r\n }\r\n }\r\n\r\n outputs.push(tangent);\r\n }\r\n }\r\n\r\n /**\r\n * Get the minimum and maximum key frames' frame values\r\n * @param keyFrames animation key frames\r\n * @returns the minimum and maximum key frame value\r\n */\r\n private static _CalculateMinMaxKeyFrames(keyFrames: IAnimationKey[]): { min: number; max: number } {\r\n let min: number = Infinity;\r\n let max: number = -Infinity;\r\n keyFrames.forEach(function (keyFrame) {\r\n min = Math.min(min, keyFrame.frame);\r\n max = Math.max(max, keyFrame.frame);\r\n });\r\n\r\n return { min: min, max: max };\r\n }\r\n}\r\n","import type { IBufferView, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType } from \"babylonjs-gltf2interface\";\r\nimport type { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\nimport { NormalizeTangent } from \"./glTFUtilities\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Interface to store morph target information.\r\n * @internal\r\n */\r\nexport interface IMorphTargetData {\r\n attributes: Record<string, number>;\r\n influence: number;\r\n name: string;\r\n}\r\n\r\nexport function BuildMorphTargetBuffers(\r\n morphTarget: MorphTarget,\r\n mesh: AbstractMesh,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHanded: boolean\r\n): IMorphTargetData {\r\n const result: IMorphTargetData = {\r\n attributes: {},\r\n influence: morphTarget.influence,\r\n name: morphTarget.name,\r\n };\r\n\r\n const geometry = mesh.geometry;\r\n if (!geometry) {\r\n Tools.Warn(\"Attempted to export morph target data from a mesh without geometry. This should not happen.\");\r\n return result;\r\n }\r\n\r\n const flipX = convertToRightHanded ? -1 : 1;\r\n const floatSize = 4;\r\n const difference = Vector3.Zero();\r\n let vertexStart = 0;\r\n let vertexCount = 0;\r\n\r\n if (morphTarget.hasPositions) {\r\n const morphPositions = morphTarget.getPositions()!;\r\n const originalPositions = geometry.getVerticesData(VertexBuffer.PositionKind); // Bypasses any instance data of mesh\r\n\r\n if (originalPositions) {\r\n const positionData = new Float32Array(originalPositions.length);\r\n const min = [Infinity, Infinity, Infinity];\r\n const max = [-Infinity, -Infinity, -Infinity];\r\n vertexCount = originalPositions.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalPosition = Vector3.FromArray(originalPositions, i * 3);\r\n const morphPosition = Vector3.FromArray(morphPositions, i * 3);\r\n morphPosition.subtractToRef(originalPosition, difference);\r\n difference.x *= flipX;\r\n\r\n min[0] = Math.min(min[0], difference.x);\r\n max[0] = Math.max(max[0], difference.x);\r\n\r\n min[1] = Math.min(min[1], difference.y);\r\n max[1] = Math.max(max[1], difference.y);\r\n\r\n min[2] = Math.min(min[2], difference.z);\r\n max[2] = Math.max(max[2], difference.z);\r\n\r\n positionData[i * 3] = difference.x;\r\n positionData[i * 3 + 1] = difference.y;\r\n positionData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(positionData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphPositions.length / 3, 0, { min, max });\r\n accessors.push(accessor);\r\n result.attributes[\"POSITION\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target positions for mesh ${mesh.name} were not exported. Mesh does not have position vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasNormals) {\r\n const morphNormals = morphTarget.getNormals()!;\r\n const originalNormals = geometry.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n if (originalNormals) {\r\n const normalData = new Float32Array(originalNormals.length);\r\n vertexCount = originalNormals.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalNormal = Vector3.FromArray(originalNormals, i * 3).normalize();\r\n const morphNormal = Vector3.FromArray(morphNormals, i * 3).normalize();\r\n morphNormal.subtractToRef(originalNormal, difference);\r\n\r\n normalData[i * 3] = difference.x * flipX;\r\n normalData[i * 3 + 1] = difference.y;\r\n normalData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(normalData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphNormals.length / 3, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"NORMAL\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target normals for mesh ${mesh.name} were not exported. Mesh does not have normals vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasTangents) {\r\n const morphTangents = morphTarget.getTangents()!;\r\n const originalTangents = geometry.getVerticesData(VertexBuffer.TangentKind);\r\n\r\n if (originalTangents) {\r\n vertexCount = originalTangents.length / 4;\r\n const tangentData = new Float32Array(vertexCount * 3);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n // Only read the x, y, z components and ignore w\r\n const originalTangent = Vector3.FromArray(originalTangents, i * 4);\r\n NormalizeTangent(originalTangent);\r\n\r\n // Morph target tangents omit the w component so it won't be present in the data\r\n const morphTangent = Vector3.FromArray(morphTangents, i * 3);\r\n NormalizeTangent(morphTangent);\r\n\r\n morphTangent.subtractToRef(originalTangent, difference);\r\n tangentData[i * 3] = difference.x * flipX;\r\n tangentData[i * 3 + 1] = difference.y;\r\n tangentData[i * 3 + 2] = difference.z;\r\n }\r\n const bufferView = bufferManager.createBufferView(tangentData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"TANGENT\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target tangents for mesh ${mesh.name} were not exported. Mesh does not have tangents vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasColors) {\r\n const morphColors = morphTarget.getColors()!;\r\n const originalColors = geometry.getVerticesData(VertexBuffer.ColorKind);\r\n const buffer = geometry.getVertexBuffer(VertexBuffer.ColorKind);\r\n\r\n if (originalColors && buffer) {\r\n const componentSize = buffer.getSize();\r\n\r\n vertexCount = originalColors.length / componentSize;\r\n const colorData = new Float32Array(vertexCount * componentSize);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n if (componentSize === 3) {\r\n const originalColor = Vector3.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector3.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference);\r\n colorData[i * 3] = difference.x;\r\n colorData[i * 3 + 1] = difference.y;\r\n colorData[i * 3 + 2] = difference.z;\r\n } else if (componentSize === 4) {\r\n const difference4 = new Vector4();\r\n const originalColor = Vector4.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector4.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference4);\r\n colorData[i * 4] = difference4.x;\r\n colorData[i * 4 + 1] = difference4.y;\r\n colorData[i * 4 + 2] = difference4.z;\r\n colorData[i * 4 + 3] = difference4.w;\r\n } else {\r\n Tools.Warn(`Unsupported number of components for color attribute: ${componentSize}`);\r\n }\r\n }\r\n const bufferView = bufferManager.createBufferView(colorData, floatSize * componentSize);\r\n const accessor = bufferManager.createAccessor(bufferView, componentSize === 3 ? AccessorType.VEC3 : AccessorType.VEC4, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"COLOR_0\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target colors for mesh ${mesh.name} were not exported. Mesh does not have colors vertex data`);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import type {\r\n IBufferView,\r\n IAccessor,\r\n INode,\r\n IScene,\r\n IMesh,\r\n IMaterial,\r\n ITexture,\r\n IImage,\r\n ISampler,\r\n IAnimation,\r\n IMeshPrimitive,\r\n IBuffer,\r\n IGLTF,\r\n ITextureInfo,\r\n ISkin,\r\n ICamera,\r\n} from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType, CameraType } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, IndicesArray, Nullable } from \"core/types\";\r\nimport { TmpVectors, Quaternion } from \"core/Maths/math.vector\";\r\nimport type { Matrix } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Buffer } from \"core/Buffers/buffer\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Node } from \"core/node\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { Engine } from \"core/Engines/engine\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\n\r\nimport type { IGLTFExporterExtensionV2 } from \"./glTFExporterExtension\";\r\nimport { GLTFMaterialExporter } from \"./glTFMaterialExporter\";\r\nimport type { IExportOptions } from \"./glTFSerializer\";\r\nimport { GLTFData } from \"./glTFData\";\r\nimport {\r\n ConvertToRightHandedPosition,\r\n ConvertToRightHandedRotation,\r\n DataArrayToUint8Array,\r\n GetAccessorType,\r\n GetAttributeType,\r\n GetMinMax,\r\n GetPrimitiveMode,\r\n IsTriangleFillMode,\r\n IsChildCollapsible,\r\n FloatsNeed16BitInteger,\r\n IsStandardVertexAttribute,\r\n IndicesArrayToTypedSubarray,\r\n GetVertexBufferInfo,\r\n CollapseChildIntoParent,\r\n Rotate180Y,\r\n DefaultTranslation,\r\n DefaultScale,\r\n DefaultRotation,\r\n ConvertToRightHandedTransformMatrix,\r\n} from \"./glTFUtilities\";\r\nimport { IsNoopNode } from \"../../exportUtils\";\r\nimport { BufferManager } from \"./bufferManager\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { EnumerateFloatValues, AreIndices32Bits } from \"core/Buffers/bufferUtils\";\r\nimport type { Bone, Skeleton } from \"core/Bones\";\r\nimport { _GLTFAnimation } from \"./glTFAnimation\";\r\nimport type { MorphTarget } from \"core/Morph\";\r\nimport { BuildMorphTargetBuffers } from \"./glTFMorphTargetsUtilities\";\r\nimport type { IMorphTargetData } from \"./glTFMorphTargetsUtilities\";\r\nimport { LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { GreasedLineBaseMesh } from \"core/Meshes/GreasedLine/greasedLineBaseMesh\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport { TargetCamera } from \"core/Cameras/targetCamera\";\r\nimport { Epsilon } from \"core/Maths/math.constants\";\r\nimport { DataWriter } from \"./dataWriter\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\n\r\nclass ExporterState {\r\n // Babylon indices array, start, count, offset, flip -> glTF accessor index\r\n private _indicesAccessorMap = new Map<Nullable<IndicesArray>, Map<number, Map<number, Map<number, Map<boolean, number>>>>>();\r\n\r\n // Babylon buffer -> glTF buffer view\r\n private _vertexBufferViewMap = new Map<Buffer, IBufferView>();\r\n\r\n // Babylon vertex buffer, start, count -> glTF accessor index\r\n private _vertexAccessorMap = new Map<VertexBuffer, Map<number, Map<number, number>>>();\r\n\r\n private _remappedBufferView = new Map<Buffer, Map<VertexBuffer, IBufferView>>();\r\n\r\n private _meshMorphTargetMap = new Map<AbstractMesh, IMorphTargetData[]>();\r\n\r\n private _vertexMapColorAlpha = new Map<VertexBuffer, boolean>();\r\n\r\n private _exportedNodes = new Set<Node>();\r\n\r\n // Babylon mesh -> glTF mesh index\r\n private _meshMap = new Map<AbstractMesh, number>();\r\n\r\n public constructor(convertToRightHanded: boolean, wasAddedByNoopNode: boolean) {\r\n this.convertToRightHanded = convertToRightHanded;\r\n this.wasAddedByNoopNode = wasAddedByNoopNode;\r\n }\r\n\r\n public readonly convertToRightHanded: boolean;\r\n\r\n public readonly wasAddedByNoopNode: boolean;\r\n\r\n // Only used when convertToRightHanded is true.\r\n public readonly convertedToRightHandedBuffers = new Map<Buffer, Uint8Array>();\r\n\r\n public getIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean): number | undefined {\r\n return this._indicesAccessorMap.get(indices)?.get(start)?.get(count)?.get(offset)?.get(flip);\r\n }\r\n\r\n public setIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean, accessorIndex: number): void {\r\n let map1 = this._indicesAccessorMap.get(indices);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, Map<number, Map<boolean, number>>>>();\r\n this._indicesAccessorMap.set(indices, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, Map<number, Map<boolean, number>>>();\r\n map1.set(start, map2);\r\n }\r\n\r\n let map3 = map2.get(count);\r\n if (!map3) {\r\n map3 = new Map<number, Map<boolean, number>>();\r\n map2.set(count, map3);\r\n }\r\n\r\n let map4 = map3.get(offset);\r\n if (!map4) {\r\n map4 = new Map<boolean, number>();\r\n map3.set(offset, map4);\r\n }\r\n\r\n map4.set(flip, accessorIndex);\r\n }\r\n\r\n public pushExportedNode(node: Node) {\r\n if (!this._exportedNodes.has(node)) {\r\n this._exportedNodes.add(node);\r\n }\r\n }\r\n\r\n public getNodesSet(): Set<Node> {\r\n return this._exportedNodes;\r\n }\r\n\r\n public getVertexBufferView(buffer: Buffer): IBufferView | undefined {\r\n return this._vertexBufferViewMap.get(buffer);\r\n }\r\n\r\n public setVertexBufferView(buffer: Buffer, bufferView: IBufferView): void {\r\n this._vertexBufferViewMap.set(buffer, bufferView);\r\n }\r\n\r\n public setRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer, bufferView: IBufferView) {\r\n this._remappedBufferView.set(buffer, new Map<VertexBuffer, IBufferView>());\r\n this._remappedBufferView.get(buffer)!.set(vertexBuffer, bufferView);\r\n }\r\n\r\n public getRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer): IBufferView | undefined {\r\n return this._remappedBufferView.get(buffer)?.get(vertexBuffer);\r\n }\r\n\r\n public getVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number): number | undefined {\r\n return this._vertexAccessorMap.get(vertexBuffer)?.get(start)?.get(count);\r\n }\r\n\r\n public setVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number, accessorIndex: number): void {\r\n let map1 = this._vertexAccessorMap.get(vertexBuffer);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, number>>();\r\n this._vertexAccessorMap.set(vertexBuffer, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, number>();\r\n map1.set(start, map2);\r\n }\r\n\r\n map2.set(count, accessorIndex);\r\n }\r\n\r\n public hasVertexColorAlpha(vertexBuffer: VertexBuffer): boolean {\r\n return this._vertexMapColorAlpha.get(vertexBuffer) || false;\r\n }\r\n\r\n public setHasVertexColorAlpha(vertexBuffer: VertexBuffer, hasAlpha: boolean) {\r\n return this._vertexMapColorAlpha.set(vertexBuffer, hasAlpha);\r\n }\r\n\r\n public getMesh(mesh: AbstractMesh): number | undefined {\r\n return this._meshMap.get(mesh);\r\n }\r\n\r\n public setMesh(mesh: AbstractMesh, meshIndex: number): void {\r\n this._meshMap.set(mesh, meshIndex);\r\n }\r\n\r\n public bindMorphDataToMesh(mesh: AbstractMesh, morphData: IMorphTargetData) {\r\n const morphTargets = this._meshMorphTargetMap.get(mesh) || [];\r\n this._meshMorphTargetMap.set(mesh, morphTargets);\r\n if (morphTargets.indexOf(morphData) === -1) {\r\n morphTargets.push(morphData);\r\n }\r\n }\r\n\r\n public getMorphTargetsFromMesh(mesh: AbstractMesh): IMorphTargetData[] | undefined {\r\n return this._meshMorphTargetMap.get(mesh);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class GLTFExporter {\r\n public readonly _glTF: IGLTF = {\r\n asset: { generator: `Babylon.js v${Engine.Version}`, version: \"2.0\" },\r\n };\r\n\r\n public readonly _animations: IAnimation[] = [];\r\n public readonly _accessors: IAccessor[] = [];\r\n public readonly _bufferViews: IBufferView[] = [];\r\n public readonly _cameras: ICamera[] = [];\r\n public readonly _images: IImage[] = [];\r\n public readonly _materials: IMaterial[] = [];\r\n public readonly _meshes: IMesh[] = [];\r\n public readonly _nodes: INode[] = [];\r\n public readonly _samplers: ISampler[] = [];\r\n public readonly _scenes: IScene[] = [];\r\n public readonly _skins: ISkin[] = [];\r\n public readonly _textures: ITexture[] = [];\r\n\r\n public readonly _babylonScene: Scene;\r\n public readonly _imageData: { [fileName: string]: Blob } = {};\r\n\r\n /**\r\n * Baked animation sample rate\r\n */\r\n private _animationSampleRate: number;\r\n\r\n private readonly _options: Required<IExportOptions>;\r\n\r\n public _shouldUseGlb: boolean = false;\r\n\r\n public readonly _materialExporter = new GLTFMaterialExporter(this);\r\n\r\n private readonly _extensions: { [name: string]: IGLTFExporterExtensionV2 } = {};\r\n\r\n public readonly _bufferManager = new BufferManager();\r\n\r\n private readonly _shouldExportNodeMap = new Map<Node, boolean>();\r\n\r\n // Babylon node -> glTF node index\r\n private readonly _nodeMap = new Map<Node, number>();\r\n\r\n // Babylon material -> glTF material index\r\n public readonly _materialMap = new Map<Material, number>();\r\n private readonly _camerasMap = new Map<Camera, ICamera>();\r\n private readonly _nodesCameraMap = new Map<ICamera, INode[]>();\r\n private readonly _skinMap = new Map<Skeleton, ISkin>();\r\n private readonly _nodesSkinMap = new Map<ISkin, INode[]>();\r\n\r\n // A material in this set requires UVs\r\n public readonly _materialNeedsUVsSet = new Set<Material>();\r\n\r\n private static readonly _ExtensionNames = new Array<string>();\r\n private static readonly _ExtensionFactories: { [name: string]: (exporter: GLTFExporter) => IGLTFExporterExtensionV2 } = {};\r\n private static readonly _ExtensionOrders: { [name: string]: number } = {};\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtension<T>(\r\n node: T,\r\n extensions: IGLTFExporterExtensionV2[],\r\n index: number,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined\r\n ): Promise<Nullable<T>> {\r\n if (index >= extensions.length) {\r\n return Promise.resolve(node);\r\n }\r\n\r\n const currentPromise = actionAsync(extensions[index], node);\r\n\r\n if (!currentPromise) {\r\n return this._ApplyExtension(node, extensions, index + 1, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line github/no-then\r\n return currentPromise.then(async (newNode) => (newNode ? await this._ApplyExtension(newNode, extensions, index + 1, actionAsync) : null));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtensions<T>(node: T, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {\r\n const extensions: IGLTFExporterExtensionV2[] = [];\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n extensions.push(this._extensions[name]);\r\n }\r\n\r\n return this._ApplyExtension(node, extensions, 0, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return this._ApplyExtensions(\r\n node,\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this._bufferManager)\r\n );\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportMaterialAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<Nullable<IMaterial>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));\r\n }\r\n\r\n /**\r\n * Get additional textures for a material\r\n * @param context The context when loading the asset\r\n * @param material The glTF material\r\n * @param babylonMaterial The Babylon.js material\r\n * @returns List of additional textures\r\n */\r\n public async _extensionsPostExportMaterialAdditionalTexturesAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const output: BaseTexture[] = [];\r\n\r\n await Promise.all(\r\n GLTFExporter._ExtensionNames.map(async (name) => {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMaterialAdditionalTexturesAsync) {\r\n const textures = await extension.postExportMaterialAdditionalTexturesAsync(context, material, babylonMaterial);\r\n output.push(...textures);\r\n }\r\n })\r\n );\r\n\r\n return output;\r\n }\r\n\r\n public _extensionsPostExportTextures(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportTexture) {\r\n extension.postExportTexture(context, textureInfo, babylonTexture);\r\n }\r\n }\r\n }\r\n\r\n public _extensionsPostExportMeshPrimitive(primitive: IMeshPrimitive): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMeshPrimitive) {\r\n extension.postExportMeshPrimitive(primitive, this._bufferManager, this._accessors);\r\n }\r\n }\r\n }\r\n\r\n public async _extensionsPreGenerateBinaryAsync(): Promise<void> {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.preGenerateBinaryAsync) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await extension.preGenerateBinaryAsync(this._bufferManager);\r\n }\r\n }\r\n }\r\n\r\n private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n if (extension.enabled) {\r\n action(extension);\r\n }\r\n }\r\n }\r\n\r\n private _extensionsOnExporting(): void {\r\n this._forEachExtensions((extension) => {\r\n if (extension.wasUsed) {\r\n this._glTF.extensionsUsed ||= [];\r\n if (this._glTF.extensionsUsed.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsUsed.push(extension.name);\r\n }\r\n\r\n if (extension.required) {\r\n this._glTF.extensionsRequired ||= [];\r\n if (this._glTF.extensionsRequired.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsRequired.push(extension.name);\r\n }\r\n }\r\n\r\n this._glTF.extensions ||= {};\r\n if (extension.onExporting) {\r\n extension.onExporting();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _loadExtensions(): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = GLTFExporter._ExtensionFactories[name](this);\r\n this._extensions[name] = extension;\r\n }\r\n }\r\n\r\n public constructor(babylonScene: Nullable<Scene> = EngineStore.LastCreatedScene, options?: IExportOptions) {\r\n if (!babylonScene) {\r\n throw new Error(\"No scene available to export\");\r\n }\r\n\r\n this._babylonScene = babylonScene;\r\n\r\n this._options = {\r\n shouldExportNode: () => true,\r\n shouldExportAnimation: () => true,\r\n metadataSelector: (metadata) => metadata?.gltf?.extras,\r\n animationSampleRate: 1 / 60,\r\n exportWithoutWaitingForScene: false,\r\n exportUnusedUVs: false,\r\n removeNoopRootNodes: true,\r\n includeCoordinateSystemConversionNodes: false,\r\n meshCompressionMethod: \"None\",\r\n ...options,\r\n };\r\n\r\n this._loadExtensions();\r\n }\r\n\r\n public dispose() {\r\n for (const key in this._extensions) {\r\n const extension = this._extensions[key];\r\n extension.dispose();\r\n }\r\n }\r\n\r\n public get options() {\r\n return this._options;\r\n }\r\n\r\n public static RegisterExtension(name: string, factory: (exporter: GLTFExporter) => IGLTFExporterExtensionV2, order: number = 100): void {\r\n if (GLTFExporter.UnregisterExtension(name)) {\r\n Tools.Warn(`Extension with the name ${name} already exists`);\r\n }\r\n\r\n GLTFExporter._ExtensionFactories[name] = factory;\r\n const extensionOrder = order ?? 0; // Use provided order or default to 0\r\n GLTFExporter._ExtensionOrders[name] = extensionOrder;\r\n\r\n // Find the correct position to insert the extension based on order\r\n let insertIndex = GLTFExporter._ExtensionNames.length;\r\n for (let i = 0; i < GLTFExporter._ExtensionNames.length; i++) {\r\n const existingName = GLTFExporter._ExtensionNames[i];\r\n const existingOrder = GLTFExporter._ExtensionOrders[existingName];\r\n\r\n // If the order is less, insert before.\r\n if (extensionOrder < existingOrder) {\r\n insertIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n GLTFExporter._ExtensionNames.splice(insertIndex, 0, name);\r\n }\r\n\r\n public static UnregisterExtension(name: string): boolean {\r\n if (!GLTFExporter._ExtensionFactories[name]) {\r\n return false;\r\n }\r\n delete GLTFExporter._ExtensionFactories[name];\r\n delete GLTFExporter._ExtensionOrders[name];\r\n\r\n const index = GLTFExporter._ExtensionNames.indexOf(name);\r\n if (index !== -1) {\r\n GLTFExporter._ExtensionNames.splice(index, 1);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _generateJSON(bufferByteLength: number, fileName?: string, prettyPrint?: boolean): string {\r\n const buffer: IBuffer = { byteLength: bufferByteLength };\r\n\r\n if (buffer.byteLength) {\r\n this._glTF.buffers = [buffer];\r\n }\r\n if (this._nodes && this._nodes.length) {\r\n this._glTF.nodes = this._nodes;\r\n }\r\n if (this._meshes && this._meshes.length) {\r\n this._glTF.meshes = this._meshes;\r\n }\r\n if (this._scenes && this._scenes.length) {\r\n this._glTF.scenes = this._scenes;\r\n this._glTF.scene = 0;\r\n }\r\n if (this._cameras && this._cameras.length) {\r\n this._glTF.cameras = this._cameras;\r\n }\r\n if (this._bufferViews && this._bufferViews.length) {\r\n this._glTF.bufferViews = this._bufferViews;\r\n }\r\n if (this._accessors && this._accessors.length) {\r\n this._glTF.accessors = this._accessors;\r\n }\r\n if (this._animations && this._animations.length) {\r\n this._glTF.animations = this._animations;\r\n }\r\n if (this._materials && this._materials.length) {\r\n this._glTF.materials = this._materials;\r\n }\r\n if (this._textures && this._textures.length) {\r\n this._glTF.textures = this._textures;\r\n }\r\n if (this._samplers && this._samplers.length) {\r\n this._glTF.samplers = this._samplers;\r\n }\r\n if (this._skins && this._skins.length) {\r\n this._glTF.skins = this._skins;\r\n }\r\n if (this._images && this._images.length) {\r\n this._glTF.images = this._images;\r\n }\r\n\r\n if (!this._shouldUseGlb) {\r\n buffer.uri = fileName + \".bin\";\r\n }\r\n\r\n return prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);\r\n }\r\n\r\n public async generateGLTFAsync(glTFPrefix: string): Promise<GLTFData> {\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength, glTFPrefix, true);\r\n\r\n const bin = new Blob([binaryBuffer], { type: \"application/octet-stream\" });\r\n\r\n const glTFFileName = glTFPrefix + \".gltf\";\r\n const glTFBinFile = glTFPrefix + \".bin\";\r\n\r\n const container = new GLTFData();\r\n\r\n container.files[glTFFileName] = jsonText;\r\n container.files[glTFBinFile] = bin;\r\n\r\n if (this._imageData) {\r\n for (const image in this._imageData) {\r\n container.files[image] = this._imageData[image];\r\n }\r\n }\r\n\r\n return container;\r\n }\r\n\r\n private async _generateBinaryAsync(): Promise<Uint8Array> {\r\n await this._exportSceneAsync();\r\n await this._extensionsPreGenerateBinaryAsync();\r\n return this._bufferManager.generateBinary(this._bufferViews);\r\n }\r\n\r\n /**\r\n * Pads the number to a multiple of 4\r\n * @param num number to pad\r\n * @returns padded number\r\n */\r\n private _getPadding(num: number): number {\r\n const remainder = num % 4;\r\n const padding = remainder === 0 ? remainder : 4 - remainder;\r\n\r\n return padding;\r\n }\r\n\r\n public async generateGLBAsync(glTFPrefix: string): Promise<GLTFData> {\r\n this._shouldUseGlb = true;\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength);\r\n\r\n const glbFileName = glTFPrefix + \".glb\";\r\n const headerLength = 12;\r\n const chunkLengthPrefix = 8;\r\n let jsonLength = jsonText.length;\r\n let encodedJsonText;\r\n // Make use of TextEncoder when available\r\n if (typeof TextEncoder !== \"undefined\") {\r\n const encoder = new TextEncoder();\r\n encodedJsonText = encoder.encode(jsonText);\r\n jsonLength = encodedJsonText.length;\r\n }\r\n const jsonPadding = this._getPadding(jsonLength);\r\n const binPadding = this._getPadding(binaryBuffer.byteLength);\r\n\r\n const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding;\r\n\r\n const dataWriter = new DataWriter(byteLength);\r\n\r\n // Header\r\n dataWriter.writeUInt32(0x46546c67); // \"glTF\"\r\n dataWriter.writeUInt32(2); // Version\r\n dataWriter.writeUInt32(byteLength); // Total bytes in file\r\n\r\n // JSON chunk length prefix\r\n dataWriter.writeUInt32(jsonLength + jsonPadding);\r\n dataWriter.writeUInt32(0x4e4f534a); // \"JSON\"\r\n\r\n // JSON chunk bytes\r\n if (encodedJsonText) {\r\n // If TextEncoder was available, we can simply copy the encoded array\r\n dataWriter.writeTypedArray(encodedJsonText);\r\n } else {\r\n const blankCharCode = \"_\".charCodeAt(0);\r\n for (let i = 0; i < jsonLength; ++i) {\r\n const charCode = jsonText.charCodeAt(i);\r\n // If the character doesn't fit into a single UTF-16 code unit, just put a blank character\r\n if (charCode != jsonText.codePointAt(i)) {\r\n dataWriter.writeUInt8(blankCharCode);\r\n } else {\r\n dataWriter.writeUInt8(charCode);\r\n }\r\n }\r\n }\r\n\r\n // JSON padding\r\n for (let i = 0; i < jsonPadding; ++i) {\r\n dataWriter.writeUInt8(0x20);\r\n }\r\n\r\n // Binary chunk length prefix\r\n dataWriter.writeUInt32(binaryBuffer.byteLength + binPadding);\r\n dataWriter.writeUInt32(0x004e4942); // \"BIN\"\r\n\r\n // Binary chunk bytes\r\n dataWriter.writeTypedArray(binaryBuffer);\r\n\r\n // Binary padding\r\n for (let i = 0; i < binPadding; ++i) {\r\n dataWriter.writeUInt8(0);\r\n }\r\n\r\n const container = new GLTFData();\r\n container.files[glbFileName] = new Blob([dataWriter.getOutputData()], { type: \"application/octet-stream\" });\r\n\r\n return container;\r\n }\r\n\r\n private _setNodeTransformation(node: INode, babylonTransformNode: TransformNode, convertToRightHanded: boolean): void {\r\n if (!babylonTransformNode.getPivotPoint().equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n Tools.Warn(\"Pivot points are not supported in the glTF serializer\");\r\n }\r\n\r\n if (!babylonTransformNode.position.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonTransformNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!babylonTransformNode.scaling.equalsWithEpsilon(DefaultScale, Epsilon)) {\r\n node.scale = babylonTransformNode.scaling.asArray();\r\n }\r\n\r\n const rotationQuaternion =\r\n babylonTransformNode.rotationQuaternion?.clone() ||\r\n Quaternion.FromEulerAngles(babylonTransformNode.rotation.x, babylonTransformNode.rotation.y, babylonTransformNode.rotation.z);\r\n\r\n if (!rotationQuaternion.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _setCameraTransformation(node: INode, babylonCamera: TargetCamera, convertToRightHanded: boolean): void {\r\n // Camera types store rotation differently (e.g., ArcRotateCamera uses alpha/beta, others use rotationQuaternion).\r\n // Extract the transform from the world matrix instead of handling each case separately.\r\n const translation = TmpVectors.Vector3[0];\r\n const rotationQuaternion = TmpVectors.Quaternion[0];\r\n const cameraWorldMatrix = babylonCamera.getWorldMatrix();\r\n\r\n if (babylonCamera.parent) {\r\n // Camera.getWorldMatrix returns global coordinates. GLTF node must use local coordinates. If camera has parent we need to use local translation/rotation.\r\n const parentInvWorldMatrix = babylonCamera.parent.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n const cameraLocal = cameraWorldMatrix.multiplyToRef(parentInvWorldMatrix, TmpVectors.Matrix[1]);\r\n cameraLocal.decompose(undefined, rotationQuaternion, translation);\r\n } else {\r\n cameraWorldMatrix.decompose(undefined, rotationQuaternion, translation);\r\n }\r\n\r\n if (!translation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n // Left-handed scenes have cameras that always face Z+ (opposite of glTF's Z-).\r\n // Use scene coordinate system rather than convertToRightHanded, since some\r\n // cameras may not need convertToRightHanded but still need correction to face Z-.\r\n if (!this._babylonScene.useRightHandedSystem) {\r\n Rotate180Y(rotationQuaternion);\r\n }\r\n\r\n if (!rotationQuaternion.equalsWithEpsilon(DefaultRotation, Epsilon)) {\r\n node.rotation = rotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n // Export babylon cameras to glTF cameras\r\n private _listAvailableCameras(): void {\r\n for (const camera of this._babylonScene.cameras) {\r\n const glTFCamera: ICamera = {\r\n type: camera.mode === Camera.PERSPECTIVE_CAMERA ? CameraType.PERSPECTIVE : CameraType.ORTHOGRAPHIC,\r\n };\r\n\r\n if (camera.name) {\r\n glTFCamera.name = camera.name;\r\n }\r\n\r\n if (glTFCamera.type === CameraType.PERSPECTIVE) {\r\n glTFCamera.perspective = {\r\n aspectRatio: camera.getEngine().getAspectRatio(camera),\r\n yfov: camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera),\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n } else if (glTFCamera.type === CameraType.ORTHOGRAPHIC) {\r\n const halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;\r\n const halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;\r\n glTFCamera.orthographic = {\r\n xmag: halfWidth,\r\n ymag: halfHeight,\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n }\r\n this._camerasMap.set(camera, glTFCamera);\r\n }\r\n }\r\n\r\n // Cleanup unused cameras and assign index to nodes.\r\n private _exportAndAssignCameras(): void {\r\n const gltfCameras = Array.from(this._camerasMap.values());\r\n for (const gltfCamera of gltfCameras) {\r\n const usedNodes = this._nodesCameraMap.get(gltfCamera);\r\n if (usedNodes !== undefined) {\r\n this._cameras.push(gltfCamera);\r\n for (const node of usedNodes) {\r\n node.camera = this._cameras.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Collects all skins in a skins map so nodes can reference it during node parsing.\r\n private _listAvailableSkeletons(): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin: ISkin = { joints: [] };\r\n this._skinMap.set(skeleton, skin);\r\n }\r\n }\r\n\r\n private _exportAndAssignSkeletons(leftHandNodes: Set<Node>): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin = this._skinMap.get(skeleton);\r\n if (skin == undefined) {\r\n continue;\r\n }\r\n\r\n // The bones (joints) of a skeleton (skin) must be exported in the same order as they appear in vertex attributes,\r\n // which is indicated by getIndex and may not match a bone's index in skeleton.bones\r\n const boneIndexMap: { [index: number]: Bone } = {};\r\n let maxBoneIndex = -1;\r\n for (let i = 0; i < skeleton.bones.length; ++i) {\r\n const bone = skeleton.bones[i];\r\n const boneIndex = bone.getIndex() ?? i;\r\n if (boneIndex !== -1) {\r\n boneIndexMap[boneIndex] = bone;\r\n if (boneIndex > maxBoneIndex) {\r\n maxBoneIndex = boneIndex;\r\n }\r\n }\r\n }\r\n\r\n // Set joints indices to scene nodes.\r\n const inverseBindMatrices: Matrix[] = [];\r\n for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {\r\n const bone = boneIndexMap[boneIndex]; // Assumes no gaps in bone indices\r\n const transformNode = bone.getTransformNode();\r\n const nodeIndex = transformNode ? this._nodeMap.get(transformNode) : undefined;\r\n if (nodeIndex === undefined) {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported.\");\r\n continue; // The indices may be out-of-sync after this and break the skinning.\r\n }\r\n skin.joints.push(nodeIndex);\r\n\r\n const boneMatrix = bone.getAbsoluteInverseBindMatrix().clone();\r\n if (leftHandNodes.has(transformNode!)) {\r\n ConvertToRightHandedTransformMatrix(boneMatrix);\r\n }\r\n inverseBindMatrices.push(boneMatrix);\r\n }\r\n\r\n // Nodes that use this skin.\r\n const skinnedNodes = this._nodesSkinMap.get(skin);\r\n\r\n // Only export the skin if it has at least one joint and is used by a mesh.\r\n if (skin.joints.length > 0 && skinnedNodes !== undefined) {\r\n const inverseBindMatricesData = new Float32Array(inverseBindMatrices.length * 16); // Always a 4 x 4 matrix of 32 bit float\r\n inverseBindMatrices.forEach((mat: Matrix, index: number) => {\r\n inverseBindMatricesData.set(mat.m, index * 16);\r\n });\r\n\r\n const bufferView = this._bufferManager.createBufferView(inverseBindMatricesData);\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.MAT4, AccessorComponentType.FLOAT, inverseBindMatrices.length));\r\n skin.inverseBindMatrices = this._accessors.length - 1;\r\n\r\n this._skins.push(skin);\r\n const skinIndex = this._skins.length - 1;\r\n for (const skinnedNode of skinnedNodes) {\r\n skinnedNode.skin = skinIndex;\r\n }\r\n }\r\n }\r\n }\r\n\r\n private async _exportSceneAsync(): Promise<void> {\r\n const scene: IScene = { nodes: [] };\r\n\r\n // Scene metadata\r\n if (this._babylonScene.metadata) {\r\n const extras = this._options.metadataSelector(this._babylonScene.metadata);\r\n if (extras) {\r\n scene.extras = extras;\r\n }\r\n }\r\n\r\n // TODO:\r\n // deal with this from the loader:\r\n // babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;\r\n // babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem;\r\n\r\n const rootNodesRH = new Array<Node>();\r\n const rootNodesLH = new Array<Node>();\r\n const rootNoopNodesRH = new Array<Node>();\r\n\r\n for (const rootNode of this._babylonScene.rootNodes) {\r\n if (this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes && IsNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) {\r\n rootNoopNodesRH.push(...rootNode.getChildren());\r\n } else if (this._babylonScene.useRightHandedSystem) {\r\n rootNodesRH.push(rootNode);\r\n } else {\r\n rootNodesLH.push(rootNode);\r\n }\r\n }\r\n\r\n this._listAvailableCameras();\r\n this._listAvailableSkeletons();\r\n\r\n const stateLH = new ExporterState(true, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesLH, stateLH)));\r\n const stateRH = new ExporterState(false, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesRH, stateRH)));\r\n const noopRH = new ExporterState(false, true);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNoopNodesRH, noopRH)));\r\n\r\n if (scene.nodes.length) {\r\n this._scenes.push(scene);\r\n }\r\n\r\n this._exportAndAssignCameras();\r\n this._exportAndAssignSkeletons(stateLH.getNodesSet());\r\n\r\n if (this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(\r\n this._babylonScene,\r\n this._animations,\r\n this._nodeMap,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n stateLH.getNodesSet(),\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n private _shouldExportNode(babylonNode: Node): boolean {\r\n let result = this._shouldExportNodeMap.get(babylonNode);\r\n\r\n if (result === undefined) {\r\n result = this._options.shouldExportNode(babylonNode);\r\n this._shouldExportNodeMap.set(babylonNode, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async _exportNodesAsync(babylonRootNodes: Node[], state: ExporterState): Promise<number[]> {\r\n const nodes = new Array<number>();\r\n\r\n this._exportBuffers(babylonRootNodes, state);\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonNode, nodes, state);\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n private _collectBuffers(\r\n babylonNode: Node,\r\n bufferToVertexBuffersMap: Map<Buffer, VertexBuffer[]>,\r\n vertexBufferToMeshesMap: Map<VertexBuffer, AbstractMesh[]>,\r\n morphTargetsToMeshesMap: Map<MorphTarget, AbstractMesh[]>,\r\n state: ExporterState\r\n ): void {\r\n if (this._shouldExportNode(babylonNode) && babylonNode instanceof AbstractMesh && babylonNode.geometry) {\r\n const vertexBuffers = babylonNode.geometry.getVertexBuffers();\r\n if (vertexBuffers) {\r\n for (const kind in vertexBuffers) {\r\n if (!IsStandardVertexAttribute(kind)) {\r\n continue;\r\n }\r\n const vertexBuffer = vertexBuffers[kind];\r\n state.setHasVertexColorAlpha(vertexBuffer, babylonNode.hasVertexAlpha);\r\n const buffer = vertexBuffer._buffer;\r\n const vertexBufferArray = bufferToVertexBuffersMap.get(buffer) || [];\r\n bufferToVertexBuffersMap.set(buffer, vertexBufferArray);\r\n if (vertexBufferArray.indexOf(vertexBuffer) === -1) {\r\n vertexBufferArray.push(vertexBuffer);\r\n }\r\n\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer) || [];\r\n vertexBufferToMeshesMap.set(vertexBuffer, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n\r\n if (morphTargetManager) {\r\n for (let morphIndex = 0; morphIndex < morphTargetManager.numTargets; morphIndex++) {\r\n const morphTarget = morphTargetManager.getTarget(morphIndex);\r\n\r\n const meshes = morphTargetsToMeshesMap.get(morphTarget) || [];\r\n morphTargetsToMeshesMap.set(morphTarget, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n this._collectBuffers(babylonChildNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsToMeshesMap, state);\r\n }\r\n }\r\n\r\n private _exportBuffers(babylonRootNodes: Node[], state: ExporterState): void {\r\n const bufferToVertexBuffersMap = new Map<Buffer, VertexBuffer[]>();\r\n const vertexBufferToMeshesMap = new Map<VertexBuffer, AbstractMesh[]>();\r\n const morphTargetsMeshesMap = new Map<MorphTarget, AbstractMesh[]>();\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n this._collectBuffers(babylonNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsMeshesMap, state);\r\n }\r\n\r\n const buffers = Array.from(bufferToVertexBuffersMap.keys());\r\n\r\n for (const buffer of buffers) {\r\n const data = buffer.getData();\r\n if (!data) {\r\n throw new Error(\"Buffer data is not available\");\r\n }\r\n\r\n const vertexBuffers = bufferToVertexBuffersMap.get(buffer);\r\n\r\n if (!vertexBuffers) {\r\n continue;\r\n }\r\n\r\n const byteStride = vertexBuffers[0].byteStride;\r\n if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {\r\n throw new Error(\"Vertex buffers pointing to the same buffer must have the same byte stride\");\r\n }\r\n\r\n const bytes = DataArrayToUint8Array(data).slice();\r\n\r\n // Apply normalizations and color corrections to buffer data in-place.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n // Normalize normals and tangents.\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);\r\n if (length > 0) {\r\n const invLength = 1 / length;\r\n values[0] *= invLength;\r\n values[1] *= invLength;\r\n values[2] *= invLength;\r\n }\r\n });\r\n break;\r\n }\r\n // Convert StandardMaterial vertex colors from gamma to linear space.\r\n case VertexBuffer.ColorKind: {\r\n const stdMaterialCount = meshes.filter((mesh) => mesh.material instanceof StandardMaterial || mesh.material == null).length;\r\n if (stdMaterialCount == 0) {\r\n break; // Buffer not used by StandardMaterials, so no conversion needed.\r\n }\r\n // TODO: Implement this case.\r\n if (stdMaterialCount != meshes.length) {\r\n Logger.Warn(\"Not converting vertex color space, as buffer is shared by StandardMaterials and other material types. Results may look incorrect.\");\r\n break;\r\n }\r\n if (type == VertexBuffer.UNSIGNED_BYTE) {\r\n Logger.Warn(\"Converting uint8 vertex colors to linear space. Results may look incorrect.\");\r\n }\r\n\r\n const vertexData3 = new Color3();\r\n const vertexData4 = new Color4();\r\n const useExactSrgbConversions = this._babylonScene.getEngine().useExactSrgbConversions;\r\n\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n // Using separate Color3 and Color4 objects to ensure the right functions are called.\r\n if (values.length === 3) {\r\n vertexData3.fromArray(values, 0);\r\n vertexData3.toLinearSpaceToRef(vertexData3, useExactSrgbConversions);\r\n vertexData3.toArray(values, 0);\r\n } else {\r\n vertexData4.fromArray(values, 0);\r\n vertexData4.toLinearSpaceToRef(vertexData4, useExactSrgbConversions);\r\n vertexData4.toArray(values, 0);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Perform coordinate conversions, if needed, to buffer data in-place (only for positions, normals and tangents).\r\n if (state.convertToRightHanded) {\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n values[0] = -values[0];\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Save converted bytes for min/max computation.\r\n state.convertedToRightHandedBuffers.set(buffer, bytes);\r\n }\r\n\r\n // Create buffer view, but defer accessor creation for later. Instead, track it via ExporterState.\r\n const bufferView = this._bufferManager.createBufferView(bytes, byteStride);\r\n state.setVertexBufferView(buffer, bufferView);\r\n\r\n const floatMatricesIndices = new Map<VertexBuffer, FloatArray>();\r\n\r\n // If buffers are of type MatricesIndicesKind and have float values, we need to create a new buffer instead.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { kind, totalVertices } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n switch (kind) {\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n if (vertexBuffer.type == VertexBuffer.FLOAT) {\r\n const floatData = vertexBuffer.getFloatData(totalVertices);\r\n if (floatData !== null) {\r\n floatMatricesIndices.set(vertexBuffer, floatData);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (floatMatricesIndices.size !== 0) {\r\n Logger.Warn(\r\n `Joint indices conversion needed: some joint indices are stored as floats in Babylon but GLTF requires UNSIGNED BYTES. We will perform the conversion but this might lead to unused data in the buffer.`\r\n );\r\n }\r\n\r\n const floatArrayVertexBuffers = Array.from(floatMatricesIndices.keys());\r\n\r\n for (const vertexBuffer of floatArrayVertexBuffers) {\r\n const array = floatMatricesIndices.get(vertexBuffer);\r\n\r\n if (!array) {\r\n continue;\r\n }\r\n\r\n const is16Bit = FloatsNeed16BitInteger(array);\r\n const newArray = new (is16Bit ? Uint16Array : Uint8Array)(array.length);\r\n for (let index = 0; index < array.length; index++) {\r\n newArray[index] = array[index];\r\n }\r\n const bufferView = this._bufferManager.createBufferView(newArray, 4 * (is16Bit ? 2 : 1));\r\n state.setRemappedBufferView(buffer, vertexBuffer, bufferView);\r\n }\r\n }\r\n\r\n // Build morph targets buffers\r\n const morphTargets = Array.from(morphTargetsMeshesMap.keys());\r\n\r\n for (const morphTarget of morphTargets) {\r\n const meshes = morphTargetsMeshesMap.get(morphTarget);\r\n\r\n if (!meshes) {\r\n continue;\r\n }\r\n\r\n const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this._bufferManager, this._bufferViews, this._accessors, state.convertToRightHanded);\r\n\r\n for (const mesh of meshes) {\r\n state.bindMorphDataToMesh(mesh, glTFMorphTarget);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Processes a node to be exported to the glTF file\r\n * @returns A promise that resolves once the node has been exported\r\n * @internal\r\n */\r\n private async _exportNodeAsync(babylonNode: Node, parentNodeChildren: Array<number>, state: ExporterState): Promise<void> {\r\n let nodeIndex = this._nodeMap.get(babylonNode);\r\n if (nodeIndex !== undefined) {\r\n if (!parentNodeChildren.includes(nodeIndex)) {\r\n parentNodeChildren.push(nodeIndex);\r\n }\r\n return;\r\n }\r\n\r\n const node = await this._createNodeAsync(babylonNode, state);\r\n\r\n if (node) {\r\n nodeIndex = this._nodes.length;\r\n this._nodes.push(node);\r\n this._nodeMap.set(babylonNode, nodeIndex);\r\n state.pushExportedNode(babylonNode);\r\n parentNodeChildren.push(nodeIndex);\r\n\r\n // Process node's animations once the node has been added to nodeMap (TODO: This should be refactored)\r\n const runtimeGLTFAnimation: IAnimation = {\r\n name: \"runtime animations\",\r\n channels: [],\r\n samplers: [],\r\n };\r\n const idleGLTFAnimations: IAnimation[] = [];\r\n\r\n if (!this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n if (babylonNode.animations.length) {\r\n _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {\r\n this._animations.push(runtimeGLTFAnimation);\r\n }\r\n idleGLTFAnimations.forEach((idleGLTFAnimation) => {\r\n if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {\r\n this._animations.push(idleGLTFAnimation);\r\n }\r\n });\r\n }\r\n\r\n // Begin processing child nodes once parent has been added to the node list\r\n const children = node ? [] : parentNodeChildren;\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonChildNode, children, state);\r\n }\r\n\r\n if (node && children.length) {\r\n node.children = children;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a glTF node from a Babylon.js node. If skipped, returns null.\r\n * @internal\r\n */\r\n private async _createNodeAsync(babylonNode: Node, state: ExporterState): Promise<Nullable<INode>> {\r\n if (!this._shouldExportNode(babylonNode)) {\r\n return null;\r\n }\r\n\r\n const node: INode = {};\r\n\r\n if (babylonNode.name) {\r\n node.name = babylonNode.name;\r\n }\r\n\r\n // Node metadata\r\n if (babylonNode.metadata) {\r\n const extras = this._options.metadataSelector(babylonNode.metadata);\r\n if (extras) {\r\n node.extras = extras;\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TransformNode) {\r\n this._setNodeTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n if (babylonNode instanceof AbstractMesh) {\r\n const babylonMesh = babylonNode instanceof InstancedMesh ? babylonNode.sourceMesh : (babylonNode as Mesh);\r\n if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {\r\n node.mesh = await this._exportMeshAsync(babylonMesh, state);\r\n }\r\n\r\n if (babylonNode.skeleton) {\r\n const skin = this._skinMap.get(babylonNode.skeleton);\r\n\r\n if (skin !== undefined) {\r\n if (this._nodesSkinMap.get(skin) === undefined) {\r\n this._nodesSkinMap.set(skin, []);\r\n }\r\n\r\n this._nodesSkinMap.get(skin)?.push(node);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TargetCamera) {\r\n const gltfCamera = this._camerasMap.get(babylonNode);\r\n\r\n if (gltfCamera) {\r\n if (this._nodesCameraMap.get(gltfCamera) === undefined) {\r\n this._nodesCameraMap.set(gltfCamera, []);\r\n }\r\n\r\n this._setCameraTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n // If a parent node exists and can be collapsed, merge their transformations and mark the parent as the camera-containing node.\r\n const parentBabylonNode = babylonNode.parent;\r\n if (parentBabylonNode !== null && IsChildCollapsible(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = this._nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex !== undefined) {\r\n const parentNode = this._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n this._nodesCameraMap.get(gltfCamera)?.push(parentNode);\r\n return null; // Skip exporting the original child node\r\n }\r\n }\r\n\r\n this._nodesCameraMap.get(gltfCamera)?.push(node);\r\n }\r\n }\r\n\r\n // Apply extensions to the node. If this resolves to null, it means we should skip exporting this node\r\n const processedNode = await this._extensionsPostExportNodeAsync(\"exportNodeAsync\", node, babylonNode, this._nodeMap, state.convertToRightHanded);\r\n if (!processedNode) {\r\n Logger.Warn(`Not exporting node ${babylonNode.name}`);\r\n return null;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n private _exportIndices(\r\n indices: Nullable<IndicesArray>,\r\n is32Bits: boolean,\r\n start: number,\r\n count: number,\r\n offset: number,\r\n fillMode: number,\r\n sideOrientation: number,\r\n state: ExporterState,\r\n primitive: IMeshPrimitive\r\n ): void {\r\n let indicesToExport = indices;\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n // Flip indices if triangle winding order is not CCW, as glTF is always CCW.\r\n const flip = sideOrientation !== Material.CounterClockWiseSideOrientation && IsTriangleFillMode(fillMode);\r\n if (flip) {\r\n if (fillMode === Material.TriangleStripDrawMode || fillMode === Material.TriangleFanDrawMode) {\r\n throw new Error(\"Triangle strip/fan fill mode is not implemented\");\r\n }\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n\r\n if (indices) {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = indices[start + i] + offset;\r\n newIndices[i + 1] = indices[start + i + 2] + offset;\r\n newIndices[i + 2] = indices[start + i + 1] + offset;\r\n }\r\n } else {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = i;\r\n newIndices[i + 1] = i + 2;\r\n newIndices[i + 2] = i + 1;\r\n }\r\n }\r\n\r\n indicesToExport = newIndices;\r\n } else if (indices && offset !== 0) {\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n for (let i = 0; i < count; i++) {\r\n newIndices[i] = indices[start + i] + offset;\r\n }\r\n\r\n indicesToExport = newIndices;\r\n }\r\n\r\n if (indicesToExport) {\r\n let accessorIndex = state.getIndicesAccessor(indices, start, count, offset, flip);\r\n if (accessorIndex === undefined) {\r\n const bytes = IndicesArrayToTypedSubarray(indicesToExport, start, count, is32Bits);\r\n const bufferView = this._bufferManager.createBufferView(bytes);\r\n\r\n const componentType = is32Bits ? AccessorComponentType.UNSIGNED_INT : AccessorComponentType.UNSIGNED_SHORT;\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.SCALAR, componentType, count, 0));\r\n accessorIndex = this._accessors.length - 1;\r\n state.setIndicesAccessor(indices, start, count, offset, flip, accessorIndex);\r\n }\r\n\r\n primitive.indices = accessorIndex;\r\n }\r\n }\r\n\r\n private _exportVertexBuffer(vertexBuffer: VertexBuffer, babylonMaterial: Material, start: number, count: number, state: ExporterState, primitive: IMeshPrimitive): void {\r\n const kind = vertexBuffer.getKind();\r\n\r\n if (!IsStandardVertexAttribute(kind)) {\r\n return;\r\n }\r\n\r\n if (kind.startsWith(\"uv\") && !this._options.exportUnusedUVs) {\r\n if (!babylonMaterial || !this._materialNeedsUVsSet.has(babylonMaterial)) {\r\n return;\r\n }\r\n }\r\n\r\n let accessorIndex = state.getVertexAccessor(vertexBuffer, start, count);\r\n\r\n if (accessorIndex === undefined) {\r\n // Get min/max from converted or original data.\r\n const data = state.convertedToRightHandedBuffers.get(vertexBuffer._buffer) || vertexBuffer._buffer.getData()!;\r\n const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) : undefined;\r\n\r\n // For the remapped buffer views we created for float matrices indices, make sure to use their updated information.\r\n const isFloatMatricesIndices =\r\n (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) && vertexBuffer.type === VertexBuffer.FLOAT;\r\n\r\n const vertexBufferType = isFloatMatricesIndices ? VertexBuffer.UNSIGNED_BYTE : vertexBuffer.type;\r\n const vertexBufferNormalized = isFloatMatricesIndices ? undefined : vertexBuffer.normalized;\r\n const bufferView = isFloatMatricesIndices ? state.getRemappedBufferView(vertexBuffer._buffer, vertexBuffer)! : state.getVertexBufferView(vertexBuffer._buffer)!;\r\n\r\n const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;\r\n this._accessors.push(\r\n this._bufferManager.createAccessor(\r\n bufferView,\r\n GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)),\r\n vertexBufferType,\r\n count,\r\n byteOffset,\r\n minMax,\r\n vertexBufferNormalized // TODO: Find other places where this is needed.\r\n )\r\n );\r\n accessorIndex = this._accessors.length - 1;\r\n state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);\r\n }\r\n\r\n primitive.attributes[GetAttributeType(kind)] = accessorIndex;\r\n }\r\n\r\n private async _exportMaterialAsync(babylonMaterial: Material, vertexBuffers: { [kind: string]: VertexBuffer }, subMesh: SubMesh, primitive: IMeshPrimitive): Promise<void> {\r\n let materialIndex = this._materialMap.get(babylonMaterial);\r\n if (materialIndex === undefined) {\r\n const hasUVs = vertexBuffers && Object.keys(vertexBuffers).some((kind) => kind.startsWith(\"uv\"));\r\n babylonMaterial = babylonMaterial instanceof MultiMaterial ? babylonMaterial.subMaterials[subMesh.materialIndex]! : babylonMaterial;\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n materialIndex = await this._materialExporter.exportPBRMaterialAsync(babylonMaterial, hasUVs);\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n materialIndex = await this._materialExporter.exportStandardMaterialAsync(babylonMaterial, hasUVs);\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n materialIndex = await this._materialExporter.exportOpenPBRMaterialAsync(babylonMaterial, hasUVs);\r\n } else {\r\n Logger.Warn(`Unsupported material '${babylonMaterial.name}' with type ${babylonMaterial.getClassName()}`);\r\n return;\r\n }\r\n\r\n this._materialMap.set(babylonMaterial, materialIndex);\r\n }\r\n\r\n primitive.material = materialIndex;\r\n }\r\n\r\n private async _exportMeshAsync(babylonMesh: Mesh, state: ExporterState): Promise<number> {\r\n let meshIndex = state.getMesh(babylonMesh);\r\n if (meshIndex !== undefined) {\r\n return meshIndex;\r\n }\r\n\r\n const mesh: IMesh = { primitives: [] };\r\n meshIndex = this._meshes.length;\r\n this._meshes.push(mesh);\r\n state.setMesh(babylonMesh, meshIndex);\r\n\r\n const indices = babylonMesh.isUnIndexed ? null : babylonMesh.getIndices();\r\n const vertexBuffers = babylonMesh.geometry?.getVertexBuffers();\r\n const morphTargets = state.getMorphTargetsFromMesh(babylonMesh);\r\n\r\n const isLinesMesh = babylonMesh instanceof LinesMesh;\r\n const isGreasedLineMesh = babylonMesh instanceof GreasedLineBaseMesh;\r\n\r\n const subMeshes = babylonMesh.subMeshes;\r\n if (vertexBuffers && subMeshes && subMeshes.length > 0) {\r\n for (const subMesh of subMeshes) {\r\n const primitive: IMeshPrimitive = { attributes: {} };\r\n\r\n const babylonMaterial = subMesh.getMaterial() || this._babylonScene.defaultMaterial;\r\n\r\n if (isGreasedLineMesh) {\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n const colorWhite = Color3.White();\r\n const alpha = babylonLinesMesh.material?.alpha ?? 1;\r\n const color = babylonLinesMesh.greasedLineMaterial?.color ?? colorWhite;\r\n if (!color.equalsWithEpsilon(colorWhite, Epsilon) || alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...color.asArray(), alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else if (isLinesMesh) {\r\n // Special case for LinesMesh\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n if (!babylonLinesMesh.color.equalsWithEpsilon(Color3.White(), Epsilon) || babylonLinesMesh.alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...babylonLinesMesh.color.asArray(), babylonLinesMesh.alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else {\r\n // Material\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportMaterialAsync(babylonMaterial, vertexBuffers, subMesh, primitive);\r\n }\r\n\r\n // Index buffer\r\n const fillMode = isLinesMesh || isGreasedLineMesh ? Material.LineListDrawMode : (babylonMesh.overrideRenderingFillMode ?? babylonMaterial.fillMode);\r\n\r\n let sideOrientation = babylonMaterial._getEffectiveOrientation(babylonMesh);\r\n if (state.wasAddedByNoopNode && !babylonMesh.getScene().useRightHandedSystem) {\r\n // To properly remove a conversion node, we must also cancel out the implicit flip in its children's side orientations.\r\n sideOrientation = sideOrientation === Material.ClockWiseSideOrientation ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;\r\n }\r\n\r\n this._exportIndices(\r\n indices,\r\n indices ? AreIndices32Bits(indices, subMesh.indexCount, subMesh.indexStart, subMesh.verticesStart) : subMesh.verticesCount > 65535,\r\n indices ? subMesh.indexStart : subMesh.verticesStart,\r\n indices ? subMesh.indexCount : subMesh.verticesCount,\r\n -subMesh.verticesStart,\r\n fillMode,\r\n sideOrientation,\r\n state,\r\n primitive\r\n );\r\n\r\n // Vertex buffers\r\n for (const vertexBuffer of Object.values(vertexBuffers)) {\r\n this._exportVertexBuffer(vertexBuffer, babylonMaterial, subMesh.verticesStart, subMesh.verticesCount, state, primitive);\r\n }\r\n\r\n if (morphTargets) {\r\n primitive.targets = [];\r\n for (const gltfMorphTarget of morphTargets) {\r\n primitive.targets.push(gltfMorphTarget.attributes);\r\n }\r\n }\r\n\r\n mesh.primitives.push(primitive);\r\n this._extensionsPostExportMeshPrimitive(primitive);\r\n }\r\n }\r\n\r\n if (morphTargets) {\r\n mesh.weights = [];\r\n\r\n if (!mesh.extras) {\r\n mesh.extras = {};\r\n }\r\n mesh.extras.targetNames = [];\r\n\r\n for (const gltfMorphTarget of morphTargets) {\r\n mesh.weights.push(gltfMorphTarget.influence);\r\n mesh.extras.targetNames.push(gltfMorphTarget.name);\r\n }\r\n }\r\n\r\n return meshIndex;\r\n }\r\n}\r\n","import type { Node } from \"core/node\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Animation } from \"core/Animations/animation\";\r\nimport type { GLTFData } from \"./glTFData\";\r\nimport { GLTFExporter } from \"./glTFExporter\";\r\n\r\n/**\r\n * Mesh compression methods.\r\n */\r\nexport type MeshCompressionMethod = \"None\" | \"Draco\";\r\n\r\n/**\r\n * Holds a collection of exporter options and parameters\r\n */\r\nexport interface IExportOptions {\r\n /**\r\n * Function which indicates whether a babylon node should be exported or not\r\n * @param node source Babylon node. It is used to check whether it should be exported to glTF or not\r\n * @returns boolean, which indicates whether the node should be exported (true) or not (false)\r\n */\r\n shouldExportNode?(node: Node): boolean;\r\n\r\n /**\r\n * Function which indicates whether an animation on the scene should be exported or not\r\n * @param animation source animation\r\n * @returns boolean, which indicates whether the animation should be exported (true) or not (false)\r\n */\r\n shouldExportAnimation?(animation: Animation): boolean;\r\n\r\n /**\r\n * Function to extract the part of the scene or node's `metadata` that will populate the corresponding\r\n * glTF object's `extras` field. If not defined, `node.metadata.gltf.extras` will be used.\r\n * @param metadata source metadata to read from\r\n * @returns the data to store into the glTF extras field\r\n */\r\n metadataSelector?(metadata: any): any;\r\n\r\n /**\r\n * The sample rate to bake animation curves. Defaults to 1 / 60.\r\n */\r\n animationSampleRate?: number;\r\n\r\n /**\r\n * Begin serialization without waiting for the scene to be ready. Defaults to false.\r\n */\r\n exportWithoutWaitingForScene?: boolean;\r\n\r\n /**\r\n * Indicates if unused vertex uv attributes should be included in export. Defaults to false.\r\n */\r\n exportUnusedUVs?: boolean;\r\n\r\n /**\r\n * Remove no-op root nodes when possible. Defaults to true.\r\n */\r\n removeNoopRootNodes?: boolean;\r\n\r\n /**\r\n * Indicates if coordinate system swapping root nodes should be included in export. Defaults to false.\r\n * @deprecated Please use removeNoopRootNodes instead\r\n */\r\n includeCoordinateSystemConversionNodes?: boolean;\r\n\r\n /**\r\n * Indicates what compression method to apply to mesh data.\r\n */\r\n meshCompressionMethod?: MeshCompressionMethod;\r\n}\r\n\r\n/**\r\n * Class for generating glTF data from a Babylon scene.\r\n */\r\nexport class GLTF2Export {\r\n /**\r\n * Exports the scene to .gltf file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .gltf file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLTFAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLTFAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Exports the scene to .glb file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .glb file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLBAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLBAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n}\r\n","import type { INode, IEXTMeshGpuInstancing } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport type { BufferManager } from \"../bufferManager\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Node } from \"core/node\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { TmpVectors, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { ConvertToRightHandedPosition, ConvertToRightHandedRotation } from \"../glTFUtilities\";\r\n\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"EXT_mesh_gpu_instancing\";\r\n\r\nfunction ColorBufferToRGBAToRGB(colorBuffer: Float32Array, instanceCount: number) {\r\n const colorBufferRgb = new Float32Array(instanceCount * 3);\r\n\r\n for (let i = 0; i < instanceCount; i++) {\r\n colorBufferRgb[i * 3 + 0] = colorBuffer[i * 4 + 0];\r\n colorBufferRgb[i * 3 + 1] = colorBuffer[i * 4 + 1];\r\n colorBufferRgb[i * 3 + 2] = colorBuffer[i * 4 + 2];\r\n }\r\n return colorBufferRgb;\r\n}\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_mesh_gpu_instancing implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /**\r\n * Internal state to emit warning about instance color alpha once\r\n */\r\n private _instanceColorWarned = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After node is exported\r\n * @param context the GLTF context when loading the asset\r\n * @param node the node exported\r\n * @param babylonNode the corresponding babylon node\r\n * @param nodeMap map from babylon node id to node index\r\n * @param convertToRightHanded true if we need to convert data from left hand to right hand system.\r\n * @param bufferManager buffer manager\r\n * @returns nullable promise, resolves with the node\r\n */\r\n public async postExportNodeAsync(\r\n context: string,\r\n node: Nullable<INode>,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (node && babylonNode instanceof Mesh) {\r\n if (babylonNode.hasThinInstances && this._exporter) {\r\n this._wasUsed = true;\r\n\r\n const noTranslation = Vector3.Zero();\r\n const noRotation = Quaternion.Identity();\r\n const noScale = Vector3.One();\r\n\r\n // retrieve all the instance world matrix\r\n const matrix = babylonNode.thinInstanceGetWorldMatrices();\r\n\r\n const iwt = TmpVectors.Vector3[2];\r\n const iwr = TmpVectors.Quaternion[1];\r\n const iws = TmpVectors.Vector3[3];\r\n\r\n let hasAnyInstanceWorldTranslation = false;\r\n let hasAnyInstanceWorldRotation = false;\r\n let hasAnyInstanceWorldScale = false;\r\n\r\n // prepare temp buffers\r\n const translationBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n const rotationBuffer = new Float32Array(babylonNode.thinInstanceCount * 4);\r\n const scaleBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n\r\n let i = 0;\r\n for (const m of matrix) {\r\n m.decompose(iws, iwr, iwt);\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(iwt);\r\n ConvertToRightHandedRotation(iwr);\r\n }\r\n\r\n // fill the temp buffer\r\n translationBuffer.set(iwt.asArray(), i * 3);\r\n rotationBuffer.set(iwr.normalize().asArray(), i * 4); // ensure the quaternion is normalized\r\n scaleBuffer.set(iws.asArray(), i * 3);\r\n\r\n // this is where we decide if there is any transformation\r\n hasAnyInstanceWorldTranslation = hasAnyInstanceWorldTranslation || !iwt.equalsWithEpsilon(noTranslation);\r\n hasAnyInstanceWorldRotation = hasAnyInstanceWorldRotation || !iwr.equalsWithEpsilon(noRotation);\r\n hasAnyInstanceWorldScale = hasAnyInstanceWorldScale || !iws.equalsWithEpsilon(noScale);\r\n\r\n i++;\r\n }\r\n\r\n const extension: IEXTMeshGpuInstancing = {\r\n attributes: {},\r\n };\r\n\r\n // do we need to write TRANSLATION ?\r\n if (hasAnyInstanceWorldTranslation) {\r\n extension.attributes[\"TRANSLATION\"] = this._buildAccessor(translationBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write ROTATION ?\r\n if (hasAnyInstanceWorldRotation) {\r\n // we decided to stay on FLOAT for now see https://github.com/BabylonJS/Babylon.js/pull/12495\r\n extension.attributes[\"ROTATION\"] = this._buildAccessor(rotationBuffer, AccessorType.VEC4, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write SCALE ?\r\n if (hasAnyInstanceWorldScale) {\r\n extension.attributes[\"SCALE\"] = this._buildAccessor(scaleBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n let colorBuffer = babylonNode._userThinInstanceBuffersStorage?.data?.instanceColor;\r\n if (colorBuffer) {\r\n const instanceCount = babylonNode.thinInstanceCount;\r\n const accessorType = AccessorType.VEC3;\r\n if (babylonNode.hasVertexAlpha && colorBuffer.length === instanceCount * 4) {\r\n if (!this._instanceColorWarned) {\r\n Logger.Warn(\"EXT_mesh_gpu_instancing: Exporting instance colors as RGB, alpha channel of instance color is not exported\");\r\n this._instanceColorWarned = true;\r\n }\r\n colorBuffer = ColorBufferToRGBAToRGB(colorBuffer, instanceCount);\r\n } else if (colorBuffer.length === instanceCount * 4) {\r\n colorBuffer = ColorBufferToRGBAToRGB(colorBuffer, instanceCount);\r\n }\r\n if (colorBuffer.length === instanceCount * 3) {\r\n extension.attributes[\"_COLOR_0\"] = this._buildAccessor(colorBuffer, accessorType, instanceCount, bufferManager);\r\n }\r\n }\r\n\r\n /* eslint-enable @typescript-eslint/naming-convention*/\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = extension;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n\r\n private _buildAccessor(buffer: Float32Array, type: AccessorType, count: number, bufferManager: BufferManager): number {\r\n // build the buffer view\r\n const bv = bufferManager.createBufferView(buffer);\r\n\r\n // finally build the accessor\r\n const accessor = bufferManager.createAccessor(bv, type, AccessorComponentType.FLOAT, count);\r\n this._exporter._accessors.push(accessor);\r\n return this._exporter._accessors.length - 1;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_mesh_gpu_instancing(exporter));\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\nimport type { IAccessor, IBufferView, IKHRDracoMeshCompression, IMeshPrimitive } from \"babylonjs-gltf2interface\";\nimport type { BufferManager } from \"../bufferManager\";\nimport { DracoEncoder } from \"core/Meshes/Compression/dracoEncoder\";\nimport { GetTypedArrayData, GetTypeByteLength } from \"core/Buffers/bufferUtils\";\nimport { GetAccessorElementCount } from \"../glTFUtilities\";\nimport type { DracoAttributeName, IDracoAttributeData, IDracoEncoderOptions } from \"core/Meshes/Compression/dracoEncoder.types\";\nimport { Logger } from \"core/Misc/logger\";\nimport type { Nullable } from \"core/types\";\n\nconst NAME = \"KHR_draco_mesh_compression\";\n\nfunction GetDracoAttributeName(glTFName: string): DracoAttributeName {\n if (glTFName === \"POSITION\") {\n return \"POSITION\";\n } else if (glTFName === \"NORMAL\") {\n return \"NORMAL\";\n } else if (glTFName.startsWith(\"COLOR\")) {\n return \"COLOR\";\n } else if (glTFName.startsWith(\"TEXCOORD\")) {\n return \"TEX_COORD\";\n }\n return \"GENERIC\";\n}\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_draco_mesh_compression implements IGLTFExporterExtensionV2 {\n /** Name of this extension */\n public readonly name = NAME;\n\n /** Defines whether this extension is enabled */\n public enabled;\n\n /** KHR_draco_mesh_compression is required, as uncompressed fallback data is not yet implemented. */\n public required = true;\n\n /** BufferViews used for Draco data, which may be eligible for removal after Draco encoding */\n private _bufferViewsUsed: Set<IBufferView> = new Set();\n\n /** Accessors that were replaced with Draco data, which may be eligible for removal after Draco encoding */\n private _accessorsUsed: Set<IAccessor> = new Set();\n\n /** Promise pool for Draco encoding work */\n private _encodePromises: Promise<void>[] = [];\n\n private _wasUsed = false;\n\n /** @internal */\n public get wasUsed() {\n return this._wasUsed;\n }\n\n /** @internal */\n constructor(exporter: GLTFExporter) {\n this.enabled = exporter.options.meshCompressionMethod === \"Draco\" && DracoEncoder.DefaultAvailable;\n }\n\n /** @internal */\n public dispose() {}\n\n /** @internal */\n public postExportMeshPrimitive(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void {\n if (!this.enabled) {\n return;\n }\n\n if (primitive.mode !== MeshPrimitiveMode.TRIANGLES && primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP) {\n Logger.Warn(\"Cannot compress primitive with mode \" + primitive.mode + \".\");\n return;\n }\n\n // Collect bufferViews and accessors used by this primitive\n const primitiveBufferViews: IBufferView[] = [];\n const primitiveAccessors: IAccessor[] = [];\n\n // Prepare indices for Draco encoding\n let indices: Nullable<Uint32Array | Uint16Array> = null;\n if (primitive.indices !== undefined) {\n const accessor = accessors[primitive.indices];\n const bufferView = bufferManager.getBufferView(accessor);\n // Per exportIndices, indices must be either Uint16Array or Uint32Array\n indices = bufferManager.getData(bufferView).slice() as Uint32Array | Uint16Array;\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Prepare attributes for Draco encoding\n const attributes: IDracoAttributeData[] = [];\n for (const [name, accessorIndex] of Object.entries(primitive.attributes)) {\n const accessor = accessors[accessorIndex];\n const bufferView = bufferManager.getBufferView(accessor);\n\n const size = GetAccessorElementCount(accessor.type);\n const data = GetTypedArrayData(\n bufferManager.getData(bufferView),\n size,\n accessor.componentType,\n accessor.byteOffset || 0,\n bufferView.byteStride || GetTypeByteLength(accessor.componentType) * size,\n accessor.count,\n true\n );\n\n attributes.push({ kind: name, dracoName: GetDracoAttributeName(name), size: GetAccessorElementCount(accessor.type), data: data });\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Use sequential encoding to preserve vertex order for cases like morph targets\n const options: IDracoEncoderOptions = {\n method: primitive.targets ? \"MESH_SEQUENTIAL_ENCODING\" : \"MESH_EDGEBREAKER_ENCODING\",\n };\n\n const promise = DracoEncoder.Default._encodeAsync(attributes, indices, options)\n // eslint-disable-next-line github/no-then\n .then((encodedData) => {\n if (!encodedData) {\n Logger.Error(\"Draco encoding failed for primitive.\");\n return;\n }\n\n const dracoInfo: IKHRDracoMeshCompression = {\n bufferView: -1, // bufferView will be set to a real index later, when we write the binary and decide bufferView ordering\n attributes: encodedData.attributeIds,\n };\n const bufferView = bufferManager.createBufferView(encodedData.data);\n bufferManager.setBufferView(dracoInfo, bufferView);\n\n for (const bufferView of primitiveBufferViews) {\n this._bufferViewsUsed.add(bufferView);\n }\n for (const accessor of primitiveAccessors) {\n this._accessorsUsed.add(accessor);\n }\n\n primitive.extensions ||= {};\n primitive.extensions[NAME] = dracoInfo;\n })\n // eslint-disable-next-line github/no-then\n .catch((error) => {\n Logger.Error(\"Draco encoding failed for primitive: \" + error);\n });\n\n this._encodePromises.push(promise);\n\n this._wasUsed = true;\n }\n\n /** @internal */\n public async preGenerateBinaryAsync(bufferManager: BufferManager): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n await Promise.all(this._encodePromises);\n\n // Cull obsolete bufferViews that were replaced with Draco data\n this._bufferViewsUsed.forEach((bufferView) => {\n const references = bufferManager.getPropertiesWithBufferView(bufferView);\n const onlyUsedByEncodedPrimitives = references.every((object) => {\n return this._accessorsUsed.has(object as IAccessor); // has() can handle any object, but TS doesn't know that\n });\n if (onlyUsedByEncodedPrimitives) {\n bufferManager.removeBufferView(bufferView);\n }\n });\n\n this._bufferViewsUsed.clear();\n this._accessorsUsed.clear();\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_draco_mesh_compression(exporter));\n","import type { SpotLight } from \"core/Lights/spotLight\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport type { INode, IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from \"babylonjs-gltf2interface\";\r\nimport { KHRLightsPunctual_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"KHR_lights_punctual\";\r\nconst DEFAULTS: Omit<IKHRLightsPunctual_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n range: Number.MAX_VALUE,\r\n};\r\nconst SPOTDEFAULTS: NonNullable<IKHRLightsPunctual_Light[\"spot\"]> = {\r\n innerConeAngle: 0,\r\n outerConeAngle: Math.PI / 4.0,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_lights_punctual implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IKHRLightsPunctual;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof Light)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType =\r\n babylonNode.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT\r\n ? KHRLightsPunctual_LightType.POINT\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT\r\n ? KHRLightsPunctual_LightType.DIRECTIONAL\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT\r\n ? KHRLightsPunctual_LightType.SPOT\r\n : null;\r\n if (!lightType || !(babylonNode instanceof ShadowLight)) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n if (babylonNode.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!babylonNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Represent the Babylon light's direction as a quaternion\r\n // relative to glTF lights' forward direction, (0, 0, -1).\r\n if (lightType !== KHRLightsPunctual_LightType.POINT) {\r\n const direction = babylonNode.direction.normalizeToRef(TmpVectors.Vector3[0]);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n\r\n const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n const light: IKHRLightsPunctual_Light = {\r\n type: lightType,\r\n name: babylonNode.name,\r\n color: babylonNode.diffuse.asArray(),\r\n intensity: babylonNode.intensity,\r\n range: babylonNode.range,\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n // Separately handle the required 'spot' field for spot lights\r\n if (lightType === KHRLightsPunctual_LightType.SPOT) {\r\n const babylonSpotLight = babylonNode as SpotLight;\r\n light.spot = {\r\n innerConeAngle: babylonSpotLight.innerAngle / 2.0,\r\n outerConeAngle: babylonSpotLight.angle / 2.0,\r\n };\r\n OmitDefaultValues(light.spot, SPOTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IKHRLightsPunctual_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsChildCollapsible(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_lights_punctual(exporter));\r\n","import type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport type { INode, IEXTLightsArea_LightReference, IEXTLightsArea_Light, IEXTLightsArea } from \"babylonjs-gltf2interface\";\r\nimport { EXTLightsArea_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseChildIntoParent, IsChildCollapsible } from \"../glTFUtilities\";\r\nimport type { RectAreaLight } from \"core/Lights/rectAreaLight\";\r\n\r\nconst NAME = \"EXT_lights_area\";\r\nconst DEFAULTS: Omit<IEXTLightsArea_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n size: 1,\r\n};\r\nconst RECTDEFAULTS: NonNullable<IEXTLightsArea_Light[\"rect\"]> = {\r\n aspect: 1,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/EXT_lights_area/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_lights_area implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IEXTLightsArea;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof Light)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType = babylonNode.getTypeID() == Light.LIGHTTYPEID_RECT_AREALIGHT ? EXTLightsArea_LightType.RECT : null;\r\n if (!lightType) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const areaLight = babylonNode as RectAreaLight;\r\n\r\n if (areaLight.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!areaLight.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(areaLight.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Represent the Babylon light's direction as a quaternion\r\n // relative to glTF lights' forward direction, (0, 0, -1).\r\n const direction = Vector3.Forward();\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n\r\n const lightRotationQuaternion = Quaternion.FromUnitVectorsToRef(LIGHTDIRECTION, direction, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n\r\n const light: IEXTLightsArea_Light = {\r\n type: lightType,\r\n name: areaLight.name,\r\n color: areaLight.diffuse.asArray(),\r\n intensity: areaLight.intensity,\r\n size: areaLight.height,\r\n rect: {\r\n aspect: areaLight.width / areaLight.height,\r\n },\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n if (light.rect) {\r\n OmitDefaultValues(light.rect, RECTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IEXTLightsArea_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsChildCollapsible(areaLight, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseChildIntoParent(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_lights_area(exporter));\r\n","import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged anisotropy textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged anisotropy textures\r\n * @internal\r\n */\r\nfunction GetAnisoTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture!.getInternalTexture()!.uniqueId : \"NoStrength\";\r\n const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture!.getInternalTexture()!.uniqueId : \"NoTangent\";\r\n return `${strengthId}_${tangentId}`;\r\n}\r\n\r\n// In your postExportMaterialAsync method:\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<ProceduralTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n return await MergeTexturesAsync(\r\n \"AnisotropyTexture\",\r\n CreateRGBAConfiguration(\r\n tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel\r\n tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel\r\n anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel\r\n ),\r\n scene\r\n );\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n private _anisoTexturesMap: Record<string, ProceduralTexture> = {};\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n if (this._anisoTexturesMap[texId]) {\r\n additionalTextures.push(this._anisoTexturesMap[texId]);\r\n } else {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._anisoTexturesMap[texId] = anisoTexture;\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.specularRoughnessAnisotropy > 0) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n let roughnessTexture: Nullable<BaseTexture> = babylonMaterial.specularRoughnessTexture;\r\n if (babylonMaterial._useRoughnessFromMetallicTextureGreen) {\r\n roughnessTexture = babylonMaterial.baseMetalnessTexture;\r\n }\r\n const mergedAnisoTexture = this._anisoTexturesMap[babylonMaterial.id];\r\n\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.specularRoughness;\r\n let newAnisotropyStrength = babylonMaterial.specularRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.specularRoughness, babylonMaterial.specularRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: newAnisotropyStrength,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle + Math.PI * 0.5,\r\n anisotropyTexture: undefined,\r\n };\r\n node.extensions[NAME] = anisotropyInfo;\r\n return resolve(node);\r\n }\r\n\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.specularRoughnessAnisotropy,\r\n anisotropyRotation: babylonMaterial.geometryTangentAngle,\r\n anisotropyTexture: mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined,\r\n extensions: {},\r\n };\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n // Enable OpenPBR extension on this material.\r\n node.extensions![\"KHR_materials_openpbr\"] = {};\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"KHR_materials_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"KHR_materials_openpbr\");\r\n }\r\n }\r\n\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n","import type { IMaterial, IKHRMaterialsClearcoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_clearcoat\";\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetCoatTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatId = coatTexture && coatTexture.getInternalTexture() ? coatTexture!.getInternalTexture()!.uniqueId : \"NoCoat\";\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const roughnessId = coatRoughnessTexture && coatRoughnessTexture.getInternalTexture() ? coatRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoRoughness\";\r\n return `${coatId}_${roughnessId}`;\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedCoatInternalTextureAsync(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(coatTexture || coatRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"CoatTexture\",\r\n CreateRGBAConfiguration(\r\n coatTexture ? CreateTextureInput(coatTexture, 0) : CreateConstantInput(1.0), // coat weight from red channel\r\n // coat roughness goes in the green channel but may come from red or green channels in the source\r\n coatRoughnessTexture ? CreateTextureInput(coatRoughnessTexture, babylonMaterial._useCoatRoughnessFromGreenChannel ? 1 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight > 0) {\r\n // We will merge the coat_weight and coat_roughness textures, if needed.\r\n // However, we want to retain the original texture's transforms and sampling info.\r\n let coatNeedsMerge = false;\r\n if (babylonMaterial.coatWeightTexture) {\r\n // If we don't have a coat_roughness texture or if the coat_weight and coat_roughness\r\n // textures are already merged, export them as-is.\r\n if (!babylonMaterial.coatRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n } else if (\r\n babylonMaterial._useCoatRoughnessFromGreenChannel &&\r\n babylonMaterial.coatWeightTexture.getInternalTexture() === babylonMaterial.coatRoughnessTexture.getInternalTexture()\r\n ) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n } else if (babylonMaterial.coatRoughnessTexture) {\r\n if (babylonMaterial._useCoatRoughnessFromGreenChannel) {\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n }\r\n if (coatNeedsMerge) {\r\n // Merge the two textures together but retain the transforms for each.\r\n // We do this by caching the internal texture that is created during the merge,\r\n // and then creating temporary textures that use that internal texture but\r\n // have the original texture's transforms/sampling info.\r\n const texId = GetCoatTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const internalTexture = await CreateMergedCoatInternalTextureAsync(babylonMaterial);\r\n if (internalTexture) {\r\n this._cachedInternalTexturesMap[texId] = internalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.coatWeightTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatWeightTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n\r\n if (babylonMaterial.geometryCoatNormalTexture) {\r\n additionalTextures.push(babylonMaterial.geometryCoatNormalTexture);\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const clearCoatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let clearCoatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.remapF0OnInterfaceChange) {\r\n Tools.Warn(`Clear Color F0 remapping is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.clearCoat.intensity,\r\n clearcoatTexture: clearCoatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n let coatWeightTexture: Nullable<BaseTexture> = null;\r\n let coatTextureInfo;\r\n if (babylonMaterial.coatWeightTexture) {\r\n coatWeightTexture = this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId];\r\n coatTextureInfo = this._exporter._materialExporter.getTextureInfo(coatWeightTexture);\r\n }\r\n\r\n let coatRoughnessTexture: Nullable<BaseTexture> = null;\r\n let coatRoughnessTextureInfo;\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n coatRoughnessTexture = this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId];\r\n coatRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(coatRoughnessTexture);\r\n }\r\n\r\n if (babylonMaterial.coatColorTexture) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.geometryCoatNormalTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.coatWeight,\r\n clearcoatTexture: coatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.coatRoughness,\r\n clearcoatRoughnessTexture: coatRoughnessTextureInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_clearcoat(exporter));\r\n","import type { IMaterial, IKHRMaterialsCoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\n\r\nconst NAME = \"KHR_materials_coat\";\r\n\r\n// Convert OpenPBR anisotropy values to glTF-compatible values\r\nfunction OpenpbrAnisotropyStrengthToGltf(baseRoughness: number, anisotropy: number) {\r\n const baseAlpha = baseRoughness * baseRoughness;\r\n const roughnessT = baseAlpha * Math.sqrt(2.0 / (1.0 + (1 - anisotropy) * (1 - anisotropy)));\r\n const roughnessB = (1 - anisotropy) * roughnessT;\r\n const newBaseRoughness = Math.sqrt(roughnessB);\r\n const newAnisotropyStrength = Math.min(Math.sqrt((roughnessT - baseAlpha) / Math.max(1.0 - baseAlpha, 0.0001)), 1.0);\r\n\r\n return { newBaseRoughness, newAnisotropyStrength };\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged anisotropy textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged anisotropy textures\r\n * @internal\r\n */\r\nfunction GetAnisoTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryCoatTangentTexture;\r\n const strengthId = anisoStrengthTexture && anisoStrengthTexture.getInternalTexture() ? anisoStrengthTexture!.getInternalTexture()!.uniqueId : \"NoStrength\";\r\n const tangentId = tangentTexture && tangentTexture.getInternalTexture() ? tangentTexture!.getInternalTexture()!.uniqueId : \"NoTangent\";\r\n return `${strengthId}_${tangentId}`;\r\n}\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetCoatTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatId = coatTexture && coatTexture.getInternalTexture() ? coatTexture!.getInternalTexture()!.uniqueId : \"NoCoat\";\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const roughnessId = coatRoughnessTexture && coatRoughnessTexture.getInternalTexture() ? coatRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoRoughness\";\r\n return `${coatId}_${roughnessId}`;\r\n}\r\n\r\n/**\r\n * Creates a new texture with the anisotropy data merged together for export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new texture with the merged anisotropy data\r\n * @internal\r\n */\r\nasync function CreateMergedAnisotropyTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<BaseTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n\r\n const anisoStrengthTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessAnisotropyTexture;\r\n const tangentTexture = babylonMaterial.geometryCoatTangentTexture;\r\n\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(anisoStrengthTexture || tangentTexture)) {\r\n return null;\r\n }\r\n\r\n return await MergeTexturesAsync(\r\n \"AnisotropyTexture\",\r\n CreateRGBAConfiguration(\r\n tangentTexture ? CreateTextureInput(tangentTexture, 0) : CreateConstantInput(1.0), // tangent x from red channel\r\n tangentTexture ? CreateTextureInput(tangentTexture, 1) : CreateConstantInput(0.0), // tangent y from green channel\r\n anisoStrengthTexture ? CreateTextureInput(anisoStrengthTexture, 0) : CreateConstantInput(1.0) // Anisotropy from red channel\r\n ),\r\n scene\r\n );\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedCoatInternalTextureAsync(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const coatTexture: Nullable<BaseTexture> = babylonMaterial.coatWeightTexture;\r\n const coatRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(coatTexture || coatRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"CoatTexture\",\r\n CreateRGBAConfiguration(\r\n coatTexture ? CreateTextureInput(coatTexture, 0) : CreateConstantInput(1.0), // coat weight from red channel\r\n // coat roughness goes in the green channel but may come from red or green channels in the source\r\n coatRoughnessTexture ? CreateTextureInput(coatRoughnessTexture, babylonMaterial._useCoatRoughnessFromGreenChannel ? 1 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_coat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n if (babylonMaterial.clearCoat.tintTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.tintTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight > 0) {\r\n // We will merge the coat_weight and coat_roughness textures, if needed.\r\n // However, we want to retain the original texture's transforms and sampling info.\r\n let coatNeedsMerge = false;\r\n if (babylonMaterial.coatWeightTexture) {\r\n // If we don't have a coat_roughness texture or if the coat_weight and coat_roughness\r\n // textures are already merged, export them as-is.\r\n if (!babylonMaterial.coatRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n } else if (\r\n babylonMaterial._useCoatRoughnessFromGreenChannel &&\r\n babylonMaterial.coatWeightTexture.getInternalTexture() === babylonMaterial.coatRoughnessTexture.getInternalTexture()\r\n ) {\r\n additionalTextures.push(babylonMaterial.coatWeightTexture);\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n } else if (babylonMaterial.coatRoughnessTexture) {\r\n if (babylonMaterial._useCoatRoughnessFromGreenChannel) {\r\n additionalTextures.push(babylonMaterial.coatRoughnessTexture);\r\n } else {\r\n coatNeedsMerge = true;\r\n }\r\n }\r\n if (coatNeedsMerge) {\r\n // Merge the two textures together but retain the transforms for each.\r\n // We do this by caching the internal texture that is created during the merge,\r\n // and then creating temporary textures that use that internal texture but\r\n // have the original texture's transforms/sampling info.\r\n const texId = GetCoatTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const internalTexture = await CreateMergedCoatInternalTextureAsync(babylonMaterial);\r\n if (internalTexture) {\r\n this._cachedInternalTexturesMap[texId] = internalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.coatWeightTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatWeightTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.coatRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n\r\n if (babylonMaterial.geometryCoatNormalTexture) {\r\n additionalTextures.push(babylonMaterial.geometryCoatNormalTexture);\r\n }\r\n\r\n if (babylonMaterial.coatColorTexture) {\r\n additionalTextures.push(babylonMaterial.coatColorTexture);\r\n }\r\n if (babylonMaterial.coatRoughnessAnisotropy > 0) {\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n if (this._mergedTexturesMap[texId]) {\r\n additionalTextures.push(this._mergedTexturesMap[texId]);\r\n } else {\r\n const anisoTexture = await CreateMergedAnisotropyTexture(babylonMaterial);\r\n if (anisoTexture) {\r\n additionalTextures.push(anisoTexture);\r\n this._mergedTexturesMap[texId] = anisoTexture;\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const coatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let coatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n coatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n coatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n let coatColorTextureInfo;\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n coatColorTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.tintTexture);\r\n }\r\n\r\n const coatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n const coatIor: number = babylonMaterial.clearCoat.indexOfRefraction;\r\n\r\n const coatInfo: IKHRMaterialsCoat = {\r\n coatFactor: babylonMaterial.clearCoat.intensity,\r\n coatTexture: coatTextureInfo ?? undefined,\r\n coatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n coatRoughnessTexture: coatTextureRoughnessInfo ?? undefined,\r\n coatNormalTexture: coatNormalTextureInfo ?? undefined,\r\n coatColorFactor: babylonMaterial.clearCoat.tintColor.asArray(),\r\n coatColorTexture: coatColorTextureInfo ?? undefined,\r\n coatIor: coatIor !== 1.5 ? coatIor : undefined,\r\n };\r\n\r\n if (coatInfo.coatTexture !== null || coatInfo.coatRoughnessTexture !== null || coatInfo.coatRoughnessTexture !== null || coatInfo.coatColorTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = coatInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.coatWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n let coatWeightTexture: Nullable<BaseTexture> = null;\r\n let coatTextureInfo;\r\n if (babylonMaterial.coatWeightTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId]) {\r\n coatWeightTexture = this._mergedTexturesMap[babylonMaterial.coatWeightTexture.uniqueId];\r\n } else {\r\n coatWeightTexture = babylonMaterial.coatWeightTexture;\r\n }\r\n coatTextureInfo = this._exporter._materialExporter.getTextureInfo(coatWeightTexture);\r\n }\r\n\r\n let coatRoughnessTexture: Nullable<BaseTexture> = null;\r\n let coatRoughnessTextureInfo;\r\n if (babylonMaterial.coatRoughnessTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId]) {\r\n coatRoughnessTexture = this._mergedTexturesMap[babylonMaterial.coatRoughnessTexture.uniqueId];\r\n } else {\r\n coatRoughnessTexture = babylonMaterial.coatRoughnessTexture;\r\n }\r\n coatRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(coatRoughnessTexture);\r\n }\r\n\r\n const coatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.geometryCoatNormalTexture);\r\n const coatColorTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.coatColorTexture);\r\n const coatIor: number = babylonMaterial.coatIor;\r\n const coatDarkeningFactor = babylonMaterial.coatDarkening;\r\n\r\n // Check if we can convert from OpenPBR anisotropy to glTF anisotropy\r\n // Conversion involves both specular roughness and anisotropic roughness changes so,\r\n // if there are textures for either, we can't reliably convert due to there potentially\r\n // being different mappings between the textures.\r\n const roughnessTexture: Nullable<BaseTexture> = babylonMaterial.coatRoughnessTexture;\r\n const texId = GetAnisoTextureId(babylonMaterial);\r\n const mergedAnisoTexture = this._mergedTexturesMap[texId];\r\n let coatAnisotropyStrength = 0;\r\n let coatAnisotropyRotation = 0;\r\n let coatAnisotropyTexture = undefined;\r\n if (babylonMaterial.coatRoughnessAnisotropy > 0.0) {\r\n // If no textures are being used, we'll always output glTF-style anisotropy.\r\n // If using OpenPBR anisotropy, convert the constants. Otherwise, just export what we have.\r\n if (!roughnessTexture && !mergedAnisoTexture) {\r\n // Convert constants\r\n let newBaseRoughness = babylonMaterial.coatRoughness;\r\n let newAnisotropyStrength = babylonMaterial.coatRoughnessAnisotropy;\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n const newParams = OpenpbrAnisotropyStrengthToGltf(babylonMaterial.coatRoughness, babylonMaterial.coatRoughnessAnisotropy);\r\n newBaseRoughness = newParams.newBaseRoughness;\r\n newAnisotropyStrength = newParams.newAnisotropyStrength;\r\n }\r\n if (node.pbrMetallicRoughness) {\r\n node.pbrMetallicRoughness.roughnessFactor = newBaseRoughness;\r\n }\r\n coatAnisotropyStrength = newAnisotropyStrength;\r\n coatAnisotropyRotation = babylonMaterial.geometryCoatTangentAngle + Math.PI * 0.5;\r\n coatAnisotropyTexture = undefined;\r\n } else {\r\n const mergedAnisoTextureInfo = mergedAnisoTexture ? this._exporter._materialExporter.getTextureInfo(mergedAnisoTexture) : null;\r\n\r\n coatAnisotropyStrength = babylonMaterial.coatRoughnessAnisotropy;\r\n coatAnisotropyRotation = babylonMaterial.geometryCoatTangentAngle;\r\n coatAnisotropyTexture = mergedAnisoTextureInfo ? mergedAnisoTextureInfo : undefined;\r\n }\r\n\r\n if (!babylonMaterial._useGltfStyleAnisotropy) {\r\n // Enable OpenPBR extension on this material.\r\n node.extensions![\"KHR_materials_openpbr\"] = {};\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"KHR_materials_openpbr\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"KHR_materials_openpbr\");\r\n }\r\n }\r\n }\r\n\r\n const coatInfo: IKHRMaterialsCoat = {\r\n coatFactor: babylonMaterial.coatWeight,\r\n coatTexture: coatTextureInfo ?? undefined,\r\n coatRoughnessFactor: babylonMaterial.coatRoughness,\r\n coatRoughnessTexture: coatRoughnessTextureInfo ?? undefined,\r\n coatNormalTexture: coatNormalTextureInfo ?? undefined,\r\n coatColorFactor: babylonMaterial.coatColor.asArray(),\r\n coatColorTexture: coatColorTextureInfo ?? undefined,\r\n coatIor: coatIor !== 1.5 ? coatIor : undefined,\r\n coatDarkeningFactor: coatDarkeningFactor !== 1.0 ? coatDarkeningFactor : undefined,\r\n coatAnisotropyRotation: coatAnisotropyRotation,\r\n coatAnisotropyStrength: coatAnisotropyStrength,\r\n coatAnisotropyTexture: coatAnisotropyTexture,\r\n };\r\n\r\n if (\r\n coatInfo.coatTexture !== null ||\r\n coatInfo.coatRoughnessTexture !== null ||\r\n coatInfo.coatRoughnessTexture !== null ||\r\n coatInfo.coatAnisotropyTexture !== null ||\r\n coatInfo.coatColorTexture !== null\r\n ) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = coatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_coat(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_transmission\";\r\n\r\n/**\r\n * Get the appropriate translucency intensity texture for the material.\r\n * @internal\r\n */\r\nfunction GetTranslucencyIntensityTexture(context: string, babylonMaterial: PBRMaterial): Nullable<BaseTexture> {\r\n const subs = babylonMaterial.subSurface;\r\n let texture = null;\r\n\r\n // Check if translucency intensity texture is available or can be derived from thickness texture\r\n if (subs.translucencyIntensityTexture) {\r\n texture = subs.translucencyIntensityTexture;\r\n } else if (subs.thicknessTexture && subs.useMaskFromThicknessTexture) {\r\n texture = subs.thicknessTexture;\r\n }\r\n\r\n if (texture && !subs.useGltfStyleTextures) {\r\n Logger.Warn(`${context}: Translucency intensity texture is not supported when useGltfStyleTextures = false. Ignoring for: ${babylonMaterial.name}`, 1);\r\n return null;\r\n }\r\n\r\n return texture;\r\n}\r\n\r\n/**\r\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)\r\n * !!! Experimental Extension Subject to Changes !!!\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n if (translucencyIntensityTexture) {\r\n additionalTextures.push(translucencyIntensityTexture);\r\n }\r\n if (babylonMaterial.subSurface.translucencyColorTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.translucencyColorTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n if (!subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n\r\n return (\r\n !mat.unlit &&\r\n !subs.useAlbedoToTintTranslucency &&\r\n subs.useGltfStyleTextures &&\r\n subs.volumeIndexOfRefraction === 1 &&\r\n subs.minimumThickness === 0 &&\r\n subs.maximumThickness === 0\r\n );\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n\r\n const diffuseTransmissionFactor = subs.translucencyIntensity == 0 ? undefined : subs.translucencyIntensity;\r\n const diffuseTransmissionTexture = this._exporter._materialExporter.getTextureInfo(translucencyIntensityTexture) ?? undefined;\r\n const diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray();\r\n const diffuseTransmissionColorTexture = this._exporter._materialExporter.getTextureInfo(subs.translucencyColorTexture) ?? undefined;\r\n\r\n const diffuseTransmissionInfo: IKHRMaterialsDiffuseTransmission = {\r\n diffuseTransmissionFactor,\r\n diffuseTransmissionTexture,\r\n diffuseTransmissionColorFactor,\r\n diffuseTransmissionColorTexture,\r\n };\r\n\r\n if (diffuseTransmissionTexture || diffuseTransmissionColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = diffuseTransmissionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_transmission(exporter));\r\n","import type { IMaterial, IKHRMaterialsDispersion } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_dispersion\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md)\r\n * @experimental\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_dispersion implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Constructor */\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires refraction to be enabled.\r\n if (!subs.isRefractionEnabled && !subs.isDispersionEnabled) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const dispersion = subs.dispersion;\r\n\r\n const dispersionInfo: IKHRMaterialsDispersion = {\r\n dispersion: dispersion,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = dispersionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_dispersion());\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { IMaterial, IKHRMaterialsEmissiveStrength } from \"babylonjs-gltf2interface\";\r\n\r\nconst NAME = \"KHR_materials_emissive_strength\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_emissive_strength implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonMaterial instanceof PBRMaterial)) {\r\n return resolve(node);\r\n }\r\n\r\n const emissiveColor = babylonMaterial.emissiveColor.scale(babylonMaterial.emissiveIntensity);\r\n const tempEmissiveStrength = Math.max(...emissiveColor.asArray());\r\n\r\n if (tempEmissiveStrength > 1) {\r\n // If the strength is greater than 1, normalize the color and store the strength\r\n node.emissiveFactor = emissiveColor.scale(1 / tempEmissiveStrength).asArray();\r\n\r\n this._wasUsed = true;\r\n const emissiveStrengthInfo: IKHRMaterialsEmissiveStrength = {\r\n emissiveStrength: tempEmissiveStrength,\r\n };\r\n node.extensions ||= {};\r\n node.extensions[NAME] = emissiveStrengthInfo;\r\n } else {\r\n // Otherwise, just store the adjusted emissive color in emissiveFactor\r\n node.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n return resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_emissive_strength());\r\n","import type { IMaterial, IKHRMaterialsIor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_ior\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_ior implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value.\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const iorInfo: IKHRMaterialsIor = {\r\n ior: babylonMaterial.indexOfRefraction,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = iorInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior());\r\n","import type { IMaterial, IKHRMaterialsIridescence } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_iridescence\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_iridescence implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.iridescence.isEnabled) {\r\n if (babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.texture);\r\n }\r\n if (babylonMaterial.iridescence.thicknessTexture && babylonMaterial.iridescence.thicknessTexture !== babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.thinFilmWeight > 0) {\r\n if (babylonMaterial.thinFilmWeightTexture) {\r\n additionalTextures.push(babylonMaterial.thinFilmWeightTexture);\r\n }\r\n if (babylonMaterial.thinFilmThicknessTexture && babylonMaterial.thinFilmThicknessTexture !== babylonMaterial.thinFilmWeightTexture) {\r\n additionalTextures.push(babylonMaterial.thinFilmThicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.iridescence.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const iridescenceTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.texture);\r\n const iridescenceThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.thicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.iridescence.intensity,\r\n iridescenceIor: babylonMaterial.iridescence.indexOfRefraction,\r\n iridescenceThicknessMinimum: babylonMaterial.iridescence.minimumThickness,\r\n iridescenceThicknessMaximum: babylonMaterial.iridescence.maximumThickness,\r\n\r\n iridescenceTexture: iridescenceTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: iridescenceThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.thinFilmWeight <= 0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const thinFilmWeightTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.thinFilmWeightTexture);\r\n const thinFilmThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.thinFilmThicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.thinFilmWeight,\r\n iridescenceIor: babylonMaterial.thinFilmIor,\r\n iridescenceThicknessMinimum: babylonMaterial.thinFilmThicknessMin * 1000, // Convert to nanometers for glTF\r\n iridescenceThicknessMaximum: babylonMaterial.thinFilmThickness * 1000, // Convert to nanometers for glTF\r\n\r\n iridescenceTexture: thinFilmWeightTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: thinFilmThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_iridescence(exporter));\r\n","import type { IMaterial, IKHRMaterialsSheen } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_sheen\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_sheen implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (babylonMaterial.sheen.isEnabled && babylonMaterial.sheen.texture) {\r\n return [babylonMaterial.sheen.texture];\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (!babylonMaterial.sheen.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const sheenInfo: IKHRMaterialsSheen = {\r\n sheenColorFactor: babylonMaterial.sheen.color.asArray(),\r\n sheenRoughnessFactor: babylonMaterial.sheen.roughness ?? 0,\r\n };\r\n\r\n if (sheenInfo.sheenColorTexture !== null || sheenInfo.sheenRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (babylonMaterial.sheen.texture) {\r\n sheenInfo.sheenColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.textureRoughness) ?? undefined;\r\n } else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n node.extensions[NAME] = sheenInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_sheen(exporter));\r\n","import type { IMaterial, IKHRMaterialsFuzz } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport { MergeTexturesAsync, CreateRGBAConfiguration, CreateTextureInput, CreateConstantInput } from \"core/Materials/Textures/textureMerger\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { InternalTexture } from \"core/Materials/Textures/internalTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\n\r\nconst NAME = \"KHR_materials_fuzz\";\r\n\r\n/**\r\n * Generate a unique ID for the merged coat textures based on the internal texture data.\r\n * This is used for caching merged textures.\r\n * @param babylonMaterial Source OpenPBR material\r\n * @returns A unique ID string for the merged coat textures\r\n * @internal\r\n */\r\nfunction GetFuzzColorTextureId(babylonMaterial: OpenPBRMaterial): string {\r\n const fuzzColorTexture: Nullable<BaseTexture> = babylonMaterial.fuzzColorTexture;\r\n const fuzzColorId = fuzzColorTexture && fuzzColorTexture.getInternalTexture() ? fuzzColorTexture!.getInternalTexture()!.uniqueId : \"NoFuzzColor\";\r\n const fuzzRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.fuzzRoughnessTexture;\r\n const fuzzRoughnessId = fuzzRoughnessTexture && fuzzRoughnessTexture.getInternalTexture() ? fuzzRoughnessTexture!.getInternalTexture()!.uniqueId : \"NoFuzzRoughness\";\r\n return `FuzzColor_${fuzzColorId}_FuzzRoughness_${fuzzRoughnessId}`;\r\n}\r\n\r\n/**\r\n * Using the coat weight and coat roughness textures, create a merged internal texture that can be used\r\n * for multiple textures (with potentially different transforms) on export.\r\n * @param babylonMaterial The source OpenPBR material\r\n * @returns A new, internal texture with the coat weight in the red channel and coat roughness in the green channel\r\n * @internal\r\n */\r\nasync function CreateMergedFuzzInternalTexture(babylonMaterial: OpenPBRMaterial): Promise<Nullable<InternalTexture>> {\r\n const scene = babylonMaterial.getScene();\r\n const fuzzColorTexture: Nullable<BaseTexture> = babylonMaterial.fuzzColorTexture;\r\n const fuzzRoughnessTexture: Nullable<BaseTexture> = babylonMaterial.fuzzRoughnessTexture;\r\n // If we don't have any textures, we don't need to generate anything.\r\n if (!(fuzzColorTexture || fuzzRoughnessTexture)) {\r\n return null;\r\n }\r\n\r\n const texture = await MergeTexturesAsync(\r\n \"FuzzTexture\",\r\n CreateRGBAConfiguration(\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 0) : CreateConstantInput(1.0), // fuzz color from red channel\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 1) : CreateConstantInput(1.0), // fuzz color from green channel\r\n fuzzColorTexture ? CreateTextureInput(fuzzColorTexture, 2) : CreateConstantInput(1.0), // fuzz color from blue channel\r\n // fuzz roughness goes in the alpha channel but may come from red or alpha channels in the source\r\n fuzzRoughnessTexture ? CreateTextureInput(fuzzRoughnessTexture, babylonMaterial._useFuzzRoughnessFromTextureAlpha ? 3 : 0) : CreateConstantInput(1.0)\r\n ),\r\n scene\r\n );\r\n\r\n return texture.getInternalTexture();\r\n}\r\n\r\n/**\r\n * Creates a temporary texture based on the source texture.\r\n * @param internalTexture The source internal texture\r\n * @param sourceTexture The source of the new texture's name, and sampler info\r\n * @returns The new texture\r\n */\r\nfunction CreateTempTexture(internalTexture: InternalTexture, sourceTexture: BaseTexture): Texture {\r\n const tempTexture = new Texture(sourceTexture.name, sourceTexture.getScene());\r\n tempTexture._texture = internalTexture;\r\n tempTexture.coordinatesIndex = sourceTexture.coordinatesIndex;\r\n if (sourceTexture instanceof Texture) {\r\n tempTexture.uOffset = sourceTexture.uOffset;\r\n tempTexture.vOffset = sourceTexture.vOffset;\r\n tempTexture.uScale = sourceTexture.uScale;\r\n tempTexture.vScale = sourceTexture.vScale;\r\n tempTexture.wAng = sourceTexture.wAng;\r\n }\r\n tempTexture.wrapU = sourceTexture.wrapU;\r\n tempTexture.wrapV = sourceTexture.wrapV;\r\n return tempTexture;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_fuzz implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Cache that holds temporary merged textures created during export\r\n */\r\n private _mergedTexturesMap: Record<string, BaseTexture> = {};\r\n\r\n /**\r\n * Cache that holds internal textures of merged textures created during export\r\n */\r\n private _cachedInternalTexturesMap: Record<string, InternalTexture> = {};\r\n\r\n public dispose() {\r\n for (const key of Object.keys(this._mergedTexturesMap)) {\r\n const texture = this._mergedTexturesMap[key];\r\n texture.dispose();\r\n }\r\n this._mergedTexturesMap = {};\r\n for (const key of Object.keys(this._cachedInternalTexturesMap)) {\r\n const internalTexture = this._cachedInternalTexturesMap[key];\r\n internalTexture.dispose();\r\n }\r\n this._cachedInternalTexturesMap = {};\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n if (babylonMaterial instanceof OpenPBRMaterial) {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial.fuzzWeight > 0.0) {\r\n if (babylonMaterial.fuzzWeightTexture) {\r\n additionalTextures.push(babylonMaterial.fuzzWeightTexture);\r\n }\r\n let fuzzTexturesNeedMerge = false;\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n if (babylonMaterial._useFuzzRoughnessFromTextureAlpha) {\r\n additionalTextures.push(babylonMaterial.fuzzRoughnessTexture);\r\n } else {\r\n fuzzTexturesNeedMerge = true;\r\n }\r\n }\r\n if (babylonMaterial.fuzzColorTexture && !fuzzTexturesNeedMerge) {\r\n additionalTextures.push(babylonMaterial.fuzzColorTexture);\r\n }\r\n if (fuzzTexturesNeedMerge) {\r\n const texId = GetFuzzColorTextureId(babylonMaterial);\r\n if (!this._cachedInternalTexturesMap[texId]) {\r\n const mergedInternalTexture = await CreateMergedFuzzInternalTexture(babylonMaterial);\r\n if (mergedInternalTexture) {\r\n this._cachedInternalTexturesMap[texId] = mergedInternalTexture;\r\n }\r\n }\r\n if (this._cachedInternalTexturesMap[texId]) {\r\n if (babylonMaterial.fuzzColorTexture) {\r\n this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.fuzzColorTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId]);\r\n }\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId] = CreateTempTexture(\r\n this._cachedInternalTexturesMap[texId],\r\n babylonMaterial.fuzzRoughnessTexture\r\n );\r\n additionalTextures.push(this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId]);\r\n }\r\n }\r\n }\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.fuzzWeight == 0.0) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const fuzzInfo: IKHRMaterialsFuzz = {\r\n fuzzFactor: babylonMaterial.fuzzWeight,\r\n fuzzColorFactor: babylonMaterial.fuzzColor.asArray(),\r\n fuzzRoughnessFactor: babylonMaterial.fuzzRoughness,\r\n };\r\n\r\n if (babylonMaterial.fuzzWeightTexture) {\r\n fuzzInfo.fuzzTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.fuzzWeightTexture) ?? undefined;\r\n }\r\n\r\n let fuzzColorTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial.fuzzColorTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId]) {\r\n fuzzColorTexture = this._mergedTexturesMap[babylonMaterial.fuzzColorTexture.uniqueId];\r\n } else {\r\n fuzzColorTexture = babylonMaterial.fuzzColorTexture;\r\n }\r\n fuzzInfo.fuzzColorTexture = this._exporter._materialExporter.getTextureInfo(fuzzColorTexture) ?? undefined;\r\n }\r\n\r\n let fuzzRoughnessTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial.fuzzRoughnessTexture) {\r\n if (this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId]) {\r\n fuzzRoughnessTexture = this._mergedTexturesMap[babylonMaterial.fuzzRoughnessTexture.uniqueId];\r\n } else {\r\n fuzzRoughnessTexture = babylonMaterial.fuzzRoughnessTexture;\r\n }\r\n fuzzInfo.fuzzRoughnessTexture = this._exporter._materialExporter.getTextureInfo(fuzzRoughnessTexture) ?? undefined;\r\n }\r\n\r\n if (fuzzInfo.fuzzColorTexture !== null || fuzzInfo.fuzzRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = fuzzInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_fuzz(exporter));\r\n","import type { IMaterial, IKHRMaterialsSpecular, IEXTMaterialsSpecularEdgeColor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_specular\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_specular implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.metallicReflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.metallicReflectanceTexture);\r\n }\r\n if (babylonMaterial.reflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.reflectanceTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return (\r\n (mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) ||\r\n (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.metallicReflectanceTexture != null || mat.reflectanceTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const metallicReflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.metallicReflectanceTexture) ?? undefined;\r\n const reflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.reflectanceTexture) ?? undefined;\r\n const metallicF0Factor = babylonMaterial.metallicF0Factor == 1.0 ? undefined : babylonMaterial.metallicF0Factor;\r\n const metallicReflectanceColor = babylonMaterial.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)\r\n ? undefined\r\n : babylonMaterial.metallicReflectanceColor.asArray();\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: metallicF0Factor,\r\n specularTexture: metallicReflectanceTexture,\r\n specularColorFactor: metallicReflectanceColor,\r\n specularColorTexture: reflectanceTexture,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n node.extensions = node.extensions || {};\r\n\r\n const specularWeightTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.specularWeightTexture) ?? undefined;\r\n const specularColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.specularColorTexture) ?? undefined;\r\n const specularWeight = babylonMaterial.specularWeight == 1.0 ? undefined : babylonMaterial.specularWeight;\r\n const specularColor = babylonMaterial.specularColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : babylonMaterial.specularColor.asArray();\r\n\r\n if (!specularColorTexture && !specularWeightTexture && specularWeight === undefined && specularColor === undefined) {\r\n return resolve(node);\r\n }\r\n this._wasUsed = true;\r\n\r\n const specularEdgeColorInfo: IEXTMaterialsSpecularEdgeColor = {\r\n specularEdgeColorEnabled: true,\r\n };\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: specularWeight,\r\n specularTexture: specularWeightTexture,\r\n specularColorFactor: specularColor,\r\n specularColorTexture: specularColorTexture,\r\n extensions: {},\r\n };\r\n\r\n specularInfo.extensions![\"EXT_materials_specular_edge_color\"] = specularEdgeColorInfo;\r\n this._exporter._glTF.extensionsUsed ||= [];\r\n if (this._exporter._glTF.extensionsUsed.indexOf(\"EXT_materials_specular_edge_color\") === -1) {\r\n this._exporter._glTF.extensionsUsed.push(\"EXT_materials_specular_edge_color\");\r\n }\r\n\r\n if (specularWeightTexture || specularColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_specular(exporter));\r\n","import type { IMaterial, IKHRMaterialsTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"KHR_materials_transmission\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat);\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.refractionIntensityTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns true if successful\r\n */\r\n public async postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subSurface = babylonMaterial.subSurface;\r\n const transmissionFactor = subSurface.refractionIntensity === 0 ? undefined : subSurface.refractionIntensity;\r\n\r\n const volumeInfo: IKHRMaterialsTransmission = {\r\n transmissionFactor: transmissionFactor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (subSurface.refractionIntensityTexture) {\r\n if (subSurface.useGltfStyleTextures) {\r\n const transmissionTexture = await this._exporter._materialExporter.exportTextureAsync(subSurface.refractionIntensityTexture);\r\n if (transmissionTexture) {\r\n volumeInfo.transmissionTexture = transmissionTexture;\r\n }\r\n } else {\r\n Logger.Warn(`${context}: Exporting a subsurface refraction intensity texture without \\`useGltfStyleTextures\\` is not supported`);\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n\r\n return node;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter));\r\n","import type { IMaterial } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\n\r\nconst NAME = \"KHR_materials_unlit\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_unlit implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public dispose() {}\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let unlitMaterial = false;\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n unlitMaterial = babylonMaterial.unlit;\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n unlitMaterial = babylonMaterial.disableLighting;\r\n }\r\n\r\n if (unlitMaterial) {\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n\r\n node.extensions[NAME] = {};\r\n }\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_unlit());\r\n","import type { IMaterial, IKHRMaterialsVolume } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\n\r\nconst NAME = \"KHR_materials_volume\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_volume implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions.\r\n if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n return (\r\n (subs.maximumThickness != undefined && subs.maximumThickness != 0) ||\r\n (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) ||\r\n (subs.tintColor != undefined && subs.tintColor != Color3.White()) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.thicknessTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness;\r\n const thicknessTexture = this._exporter._materialExporter.getTextureInfo(subs.thicknessTexture) ?? undefined;\r\n const attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance;\r\n const attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray();\r\n\r\n const volumeInfo: IKHRMaterialsVolume = {\r\n thicknessFactor: thicknessFactor,\r\n thicknessTexture: thicknessTexture,\r\n attenuationDistance: attenuationDistance,\r\n attenuationColor: attenuationColor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseRoughness } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { OpenPBRMaterial } from \"core/Materials/PBR/openpbrMaterial\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_roughness\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_roughness implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public async postExportMaterialAdditionalTexturesAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<BaseTexture[]> {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial._baseDiffuseRoughness) {\r\n if (babylonMaterial._baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial._baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n if (babylonMaterial.baseDiffuseRoughness) {\r\n if (babylonMaterial.baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial.baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let diffuseRoughnessFactor: Nullable<number> = null;\r\n let diffuseRoughnessTexture: Nullable<BaseTexture> = null;\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n diffuseRoughnessFactor = babylonMaterial._baseDiffuseRoughness;\r\n diffuseRoughnessTexture = babylonMaterial._baseDiffuseRoughnessTexture;\r\n } else if (babylonMaterial instanceof OpenPBRMaterial) {\r\n diffuseRoughnessFactor = babylonMaterial.baseDiffuseRoughness;\r\n diffuseRoughnessTexture = babylonMaterial.baseDiffuseRoughnessTexture;\r\n }\r\n if (!diffuseRoughnessFactor) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const diffuseRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(diffuseRoughnessTexture);\r\n\r\n const diffuseRoughnessInfo: IKHRMaterialsDiffuseRoughness = {\r\n diffuseRoughnessFactor: diffuseRoughnessFactor,\r\n diffuseRoughnessTexture: diffuseRoughnessTextureInfo ?? undefined,\r\n };\r\n\r\n if (diffuseRoughnessInfo.diffuseRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = diffuseRoughnessInfo;\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_roughness(exporter));\r\n","import type { ITextureInfo, IKHRTextureTransform } from \"babylonjs-gltf2interface\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\n\r\nconst NAME = \"KHR_texture_transform\";\r\n\r\n/**\r\n * Computes the adjusted offset for a rotation centered about the origin.\r\n * @internal\r\n */\r\nfunction AdjustOffsetForRotationCenter(babylonTexture: Texture): [number, number] {\r\n const { uOffset, vOffset, uRotationCenter, vRotationCenter, uScale, vScale, wAng } = babylonTexture;\r\n const cosAngle = Math.cos(wAng);\r\n const sinAngle = Math.sin(wAng);\r\n const scaledURotationCenter = uRotationCenter * uScale;\r\n const scaledVRotationCenter = vRotationCenter * vScale;\r\n const deltaU = scaledURotationCenter * (1 - cosAngle) + scaledVRotationCenter * sinAngle;\r\n const deltaV = scaledVRotationCenter * (1 - cosAngle) - scaledURotationCenter * sinAngle;\r\n return [uOffset + deltaU, vOffset + deltaV];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_texture_transform implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: Texture): void {\r\n const scene = babylonTexture.getScene();\r\n if (!scene) {\r\n Tools.Warn(`${context}: \"scene\" is not defined for Babylon texture ${babylonTexture.name}!`);\r\n }\r\n\r\n /*\r\n * The KHR_texture_transform schema only supports w rotation around the origin.\r\n * See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates.\r\n */\r\n if (babylonTexture.uAng !== 0 || babylonTexture.vAng !== 0) {\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with rotation in the u or v axis is not supported in glTF.`);\r\n // Usually, we'd always early return here if the texture uses an unsupported combination of transform properties,\r\n // but we're making an exception here to maintain backwards compatibility.\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n return;\r\n }\r\n }\r\n\r\n const textureTransform: IKHRTextureTransform = {};\r\n let transformIsRequired = false;\r\n\r\n if (babylonTexture.uOffset !== 0 || babylonTexture.vOffset !== 0) {\r\n textureTransform.offset = [babylonTexture.uOffset, babylonTexture.vOffset];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.uScale !== 1 || babylonTexture.vScale !== 1) {\r\n textureTransform.scale = [babylonTexture.uScale, babylonTexture.vScale];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.wAng !== 0) {\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n // See https://github.com/mrdoob/three.js/issues/15831 for more details.\r\n if (babylonTexture.homogeneousRotationInUVTransform && babylonTexture.uScale !== babylonTexture.vScale) {\r\n Tools.Warn(\r\n `${context}: Texture ${babylonTexture.name} with homogenousRotationInUVTransform, non-uniform scaling, and non-zero rotation cannot be exported with ${NAME}.`\r\n );\r\n return;\r\n }\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with non-origin rotation center will be exported using an adjusted offset with ${NAME}.`);\r\n textureTransform.offset = AdjustOffsetForRotationCenter(babylonTexture);\r\n }\r\n textureTransform.rotation = -babylonTexture.wAng;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.coordinatesIndex !== 0) {\r\n textureTransform.texCoord = babylonTexture.coordinatesIndex;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (!transformIsRequired) {\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n if (!textureInfo.extensions) {\r\n textureInfo.extensions = {};\r\n }\r\n textureInfo.extensions[NAME] = textureTransform;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_texture_transform());\r\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"KHR_texture_basisu\";\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_texture_basisu/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_texture_basisu implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.KTX2) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_texture_basisu(exporter));\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"EXT_texture_webp\";\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_texture_webp/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class EXT_texture_webp implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.WEBP) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_texture_webp(exporter));\n","/* eslint-disable jsdoc/require-jsdoc */\n/* eslint-disable babylonjs/available */\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { GetMimeType } from \"core/Misc/fileTools\";\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\n\nconst NAME = \"EXT_texture_avif\";\n\n/**\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/blob/5cb7518cf9a1bfb8268320026961b21caf5a4aac/extensions/2.0/Vendor/EXT_texture_avif/README.md)\n * @experimental\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class EXT_texture_avif implements IGLTFExporterExtensionV2 {\n public readonly name = NAME;\n\n public enabled = true;\n\n public required = true;\n\n private _wasUsed = false;\n\n public get wasUsed() {\n return this._wasUsed;\n }\n\n private _exporter: GLTFExporter;\n\n constructor(exporter: GLTFExporter) {\n this._exporter = exporter;\n }\n\n public dispose() {}\n\n public postExportTexture(_: string, textureInfo: BABYLON.GLTF2.ITextureInfo): void {\n const texture = this._exporter._textures[textureInfo.index];\n const imageIndex = texture.source;\n if (imageIndex === undefined) {\n return;\n }\n\n const image = this._exporter._images[imageIndex];\n const sourceMimeType = image.mimeType || GetMimeType(image.uri!);\n if (sourceMimeType !== ImageMimeType.AVIF) {\n return;\n }\n\n texture.source = undefined;\n texture.extensions ||= {};\n texture.extensions[NAME] = {\n source: imageIndex,\n };\n\n this._wasUsed = true;\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_texture_avif(exporter));\n","/* eslint-disable @typescript-eslint/no-restricted-imports */\r\nimport * as Exporters from \"serializers/glTF/glTFFileExporter\";\r\nimport * as Datas from \"serializers/glTF/2.0/glTFData\";\r\nimport * as Serializers from \"serializers/glTF/2.0/glTFSerializer\";\r\nimport * as Extensions from \"serializers/glTF/2.0/Extensions/index\";\r\nimport * as GLTF2 from \"serializers/glTF/2.0/index\";\r\n\r\n/**\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nif (typeof globalObject !== \"undefined\") {\r\n (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};\r\n const BABYLON = (<any>globalObject).BABYLON;\r\n BABYLON.GLTF2 = BABYLON.GLTF2 || {};\r\n BABYLON.GLTF2.Exporter = BABYLON.GLTF2.Exporter || {};\r\n BABYLON.GLTF2.Exporter.Extensions = BABYLON.GLTF2.Exporter.Extensions || {};\r\n\r\n const keys = [];\r\n for (const key in Exporters) {\r\n BABYLON[key] = (<any>Exporters)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Datas) {\r\n BABYLON[key] = (<any>Datas)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Serializers) {\r\n BABYLON[key] = (<any>Serializers)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in Extensions) {\r\n BABYLON.GLTF2.Exporter.Extensions[key] = (<any>Extensions)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in GLTF2) {\r\n // Prevent Reassignment.\r\n if (keys.indexOf(key) > -1) {\r\n continue;\r\n }\r\n\r\n BABYLON.GLTF2.Exporter[key] = (<any>GLTF2)[key];\r\n }\r\n}\r\n\r\nexport * from \"serializers/glTF/glTFFileExporter\";\r\nexport * from \"serializers/glTF/2.0/index\";\r\n","import * as serializers from \"@lts/serializers/legacy/legacy-glTF2Serializer\";\r\nexport { serializers };\r\nexport default serializers;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","key","o","Object","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","__IGLTFExporterExtension","files","downloadFiles","blob","Blob","type","GetMimeType","Tools","Download","__assign","assign","t","s","i","n","arguments","length","p","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","rejected","result","done","then","__generator","body","f","y","_","label","sent","trys","ops","create","Iterator","verb","iterator","v","op","TypeError","pop","push","__spreadArray","to","from","pack","ar","l","Array","slice","concat","SuppressedError","Epsilon","DielectricSpecular","Color3","MaxSpecularPower","White","Black","BlackReadOnly","IsSupportedMimeType","mimeType","GetCachedImageAsync","babylonTexture","internalTexture","getInternalTexture","source","invertY","buffer","_buffer","LoadFileAsync","url","data","ArrayBuffer","isView","byteOffset","byteLength","arrayBuffer","HTMLImageElement","src","_SolveMetallic","diffuse","specular","oneMinusSpecularStrength","a","b","Scalar","Clamp","Math","sqrt","_ConvertToGLTFPBRMetallicRoughness","babylonStandardMaterial","diffuseColor","toLinearSpace","getScene","getEngine","useExactSrgbConversions","scale","opacity","alpha","specularPower","roughness","SpecularPowerToRoughness","baseColorFactor","metallicFactor","roughnessFactor","SetAlphaMode","glTFMaterial","babylonMaterial","needAlphaBlending","alphaMode","needAlphaTesting","alphaCutoff","alphaCutOff","CreateWhiteTexture","width","height","scene","Uint8Array","RawTexture","CreateRGBATexture","ConvertPixelArrayToFloat32","pixels","Float32Array","Error","_exporter","_textureMap","Map","_internalTextureToImage","getTextureInfo","uniqueId","exportStandardMaterialAsync","hasUVs","pbrMetallicRoughness","material","name","backFaceCulling","twoSidedLighting","Warn","doubleSided","promises","diffuseTexture","exportTextureAsync","textureInfo","baseColorTexture","bumpTexture","normalTexture","level","emissiveTexture","emissiveFactor","ambientTexture","occlusionTexture","index","_materialNeedsUVsSet","add","all","opacityTexture","Constants","ALPHA_COMBINE","toString","emissiveColor","equalsWithEpsilon","asArray","_finishMaterialAsync","materials","_materials","_extensionsPostExportMaterialAdditionalTexturesAsync","textures","texture","_extensionsPostExportMaterialAsync","_resizeTexturesToSameDimensions","texture1","texture2","resizedTexture1","resizedTexture2","texture1Size","getSize","texture2Size","Texture","TextureTools","CreateResizedCopy","_convertSpecularGlossinessTexturesToMetallicRoughnessAsync","specularGlossinessTexture","factors","resizedTextures","diffuseSize","diffuseBuffer","specularGlossinessBuffer","readPixels","diffusePixels","specularPixels","metallicRoughnessBuffer","baseColorBuffer","maxBaseColor","maxMetallic","maxRoughness","h","w","offset","multiply","specularColor","glossiness","specularGlossiness","metallicRoughness","_convertSpecularGlossinessToMetallicRoughness","max","baseColor","metallic","hasAlpha","writeOutMetallicRoughnessTexture","writeOutBaseColorTexture","destinationOffset","linearBaseColorPixel","FromInts","sRGBBaseColorPixel","toGammaSpace","EncodeImageAsync","metallicRoughnessTextureData","baseColorTextureData","diffusePerceivedBrightness","_getPerceivedBrightness","specularPerceivedBrightness","_getMaxComponent","baseColorFromDiffuse","baseColorFromSpecular","subtract","Lerp","clampToRef","color","_convertMetalRoughFactorsToMetallicRoughnessAsync","albedoTexture","metallicTexture","roughnessTexture","babylonPBRMaterial","glTFPbrMetallicRoughness","OpenPBRMaterial","geometryOpacityTexture","albedoId","opacityId","Number","glTFTexture","MergeTexturesAsync","CreateRGBAConfiguration","CreateTextureInput","CreateConstantInput","mergedTexture","_useMetallicFromMetallicTextureBlue","metallicRoughnessTexture","metallicId","roughnessId","ambientOcclusionTexture","_getTextureSampler","sampler","wrapS","_getGLTFTextureWrapMode","wrapU","wrapT","wrapV","samplingMode","LINEAR_LINEAR","magFilter","minFilter","LINEAR_NEAREST","NEAREST_LINEAR","NEAREST_LINEAR_MIPLINEAR","NEAREST_NEAREST","NEAREST_LINEAR_MIPNEAREST","LINEAR_NEAREST_MIPNEAREST","LINEAR_NEAREST_MIPLINEAR","NEAREST_NEAREST_MIPLINEAR","LINEAR_LINEAR_MIPLINEAR","LINEAR_LINEAR_MIPNEAREST","NEAREST_NEAREST_MIPNEAREST","wrapMode","WRAP_ADDRESSMODE","CLAMP_ADDRESSMODE","MIRROR_ADDRESSMODE","_convertSpecGlossFactorsToMetallicRoughnessAsync","specGloss","_albedoColor","_reflectivityColor","_microSurface","_albedoTexture","reflectivityTexture","_reflectivityTexture","useMicrosurfaceFromReflectivityMapAlpha","_useMicroSurfaceFromReflectivityMapAlpha","samplerIndex","_exportTextureSampler","metallicRoughnessFactors","_textures","_exportImageAsync","imageIndex","_exportTextureInfo","coordinatesIndex","exportPBRMaterialAsync","useMetallicRoughness","isMetallicWorkflow","albedoColor","_metallic","_roughness","_metallicTexture","_setMetallicRoughnessPbrMaterialAsync","WithinEpsilon","_twoSidedLighting","PBRBaseMaterial","_bumpTexture","geometryNormalTexture","_ambientTexture","set","_extensionsPostExportTextures","texCoord","extensions","strength","_ambientTextureStrength","_emissiveTexture","emissionColorTexture","_emissiveColor","emissionColor","exportOpenPBRMaterialAsync","babylonOpenPBRMaterial","geometryOpacity","baseMetalness","specularRoughness","baseMetalnessTexture","specularRoughnessTexture","overrideId","_exportTextureImageAsync","requestedMimeType","internalTextureToImage","internalTextureUniqueId","imageIndexPromise","cache","size","GetTextureDataAsync","imageData","images","_images","_shouldUseGlb","image","bufferView","_bufferManager","createBufferView","setBufferView","baseName","replace","extension","GetFileExtensionFromMimeType","some","uri","RandomId","_imageData","textureIndex","findIndex","samplers","_samplers","ConvertHandednessMatrix","Matrix","Compose","Vector3","Quaternion","Identity","Zero","IsNoopNode","node","useRightHandedSystem","TransformNode","getWorldMatrix","IdentityReadOnly","multiplyToRef","TmpVectors","AbstractMesh","geometry","DefaultTranslation","ZeroReadOnly","DefaultRotation","DefaultScale","OneReadOnly","DefaultLoaderCameraParentScaleLh","GetVertexBufferInfo","vertexBuffer","meshes","byteStride","normalized","componentCount","totalVertices","reduce","current","getTotalVertices","MAX_VALUE","count","kind","getKind","GetAccessorElementCount","accessorType","IsStandardVertexAttribute","VertexBuffer","PositionKind","NormalKind","TangentKind","ColorKind","MatricesIndicesKind","MatricesIndicesExtraKind","MatricesWeightsKind","MatricesWeightsExtraKind","UVKind","UV2Kind","UV3Kind","UV4Kind","UV5Kind","UV6Kind","GetPrimitiveMode","fillMode","Material","TriangleFillMode","TriangleStripDrawMode","TriangleFanDrawMode","PointListDrawMode","PointFillMode","LineLoopDrawMode","LineListDrawMode","LineStripDrawMode","NormalizeTangent","tangent","x","z","ConvertToRightHandedPosition","ConvertToRightHandedRotation","absX","abs","absY","sign","absZ","absW","Rotate180Y","rotation","copyFromFloats","CollapseChildIntoParent","parentNode","parentTranslation","FromArrayToRef","translation","parentRotation","parentMatrix","ComposeToRef","matrix","decompose","IsChildCollapsible","babylonNode","parentBabylonNode","getChildren","parent","expectedScale","TargetCamera","scaling","Logger","OmitDefaultValues","object","defaultValues","entries","defaultValue","isArray","AreArraysEqual","array1","array2","every","val","TypedArrayToWriteMethod","Int8Array","setInt8","dv","bo","setUint8","Uint8ClampedArray","Int16Array","setInt16","Uint16Array","setUint16","Int32Array","setInt32","Uint32Array","setUint32","setFloat32","Float64Array","setFloat64","_data","_dataView","DataView","_byteOffset","writeTypedArray","_checkGrowBuffer","setMethod","constructor","BYTES_PER_ELEMENT","getOutputData","writeUInt8","writeInt8","writeInt16","entry","writeUInt16","writeInt32","writeUInt32","writeFloat32","writeFloat64","newByteLength","newData","GetHighestByteAlignment","_TangentType","_bufferViewToData","_bufferViewToProperties","_accessorToBufferView","generateBinary","bufferViews","totalByteLength","forEach","dataWriter","DataWriter","keys","sort","bufferViewIndex","getPropertiesWithBufferView","delete","createAccessor","componentType","minMax","_verifyBufferView","accessor","min","removeBufferView","bv","getBufferView","getData","has","_IsTransformable","Camera","Light","_CreateNodeAnimation","babylonTransformNode","animation","animationChannelTargetPath","useQuaternion","animationSampleRate","inputs","outputs","keyFrames","getKeys","minMaxKeyFrames","_GLTFAnimation","_CalculateMinMaxKeyFrames","interpolationOrBake","_DeduceInterpolation","interpolation","interpolationType","shouldBakeAnimation","_CreateBakedAnimation","framePerSecond","_CreateLinearOrStepAnimation","_CreateCubicSplineAnimation","samplerInterpolation","inputsMin","FloatRound","inputsMax","_DeduceAnimationInfo","dataAccessorType","property","targetProperty","split","_CreateNodeAnimationFromNodeAnimations","runtimeGLTFAnimation","idleGLTFAnimations","nodeMap","nodes","bufferManager","accessors","useRightHanded","shouldExportAnimation","glTFAnimation","animations","animationInfo","channels","_AddAnimation","hasRunningRuntimeAnimations","_CreateMorphTargetAnimationFromMorphTargetAnimations","Mesh","morphTargetManager","numTargets","getTarget","combinedAnimation","Animation","dataType","loopMode","enableBlending","combinedAnimationKeys","animationKeys","j","animationKey","k","frame","setKeys","_CreateNodeAndMorphAnimationFromAnimationGroups","babylonScene","glTFAnimations","leftHandedNodes","animationGroups","animationGroup","morphAnimations","sampleAnimations","morphAnimationMeshes","Set","animationGroupFrameDiff","targetAnimation","targetedAnimations","target","convertToRightHanded","MorphTarget","morphTargetManagers","find","babylonMesh","mesh","combinedAnimationGroup","sampleAnimationKeys","numAnimationKeys","morphTarget","animationsByMorphTarget","morphTargetAnimation","ANIMATIONTYPE_FLOAT","influence","inTangent","outTangent","morphAnimationChannels","keyframeAccessorIndex","dataAccessorIndex","animationSampler","animationChannel","animationData","currentInput","newInputs","shift","nodeIndex","inputData","output","outputToWrite","toArray","FromEulerVectorToRef","input","path","minFrame","maxFrame","fps","sampleRate","minMaxFrames","time","quaternionCache","previousTime","maxUsedFrame","currKeyFrame","nextKeyFrame","prevKeyFrame","endFrame","equals","state","repeatCount","_interpolate","_SetInterpolatedValue","_ConvertFactorToVector3OrQuaternion","factor","basePositionRotationOrScale","_GetBasePositionRotationOrScale","componentName","FromArray","normalize","cacheValue","RotationYawPitchRollToRef","keyFrame","_AddKeyframeValue","_AddSplineTangent","INTANGENT","OUTTANGENT","q","rotationQuaternion","position","One","newPositionRotationOrScale","animationType","ANIMATIONTYPE_VECTOR3","array","RotationYawPitchRoll","posRotScale","ANIMATIONTYPE_QUATERNION","tangentType","tangentValue","Infinity","BuildMorphTargetBuffers","attributes","flipX","difference","vertexCount","hasPositions","morphPositions","getPositions","originalPositions","getVerticesData","positionData","originalPosition","subtractToRef","floatSize","hasNormals","morphNormals","getNormals","originalNormals","normalData","originalNormal","hasTangents","morphTangents","getTangents","originalTangents","tangentData","originalTangent","morphTangent","hasColors","morphColors","getColors","originalColors","getVertexBuffer","componentSize","colorData","originalColor","difference4","Vector4","wasAddedByNoopNode","_indicesAccessorMap","_vertexBufferViewMap","_vertexAccessorMap","_remappedBufferView","_meshMorphTargetMap","_vertexMapColorAlpha","_exportedNodes","_meshMap","convertedToRightHandedBuffers","getIndicesAccessor","indices","start","flip","setIndicesAccessor","accessorIndex","map1","map2","map3","map4","pushExportedNode","getNodesSet","getVertexBufferView","setVertexBufferView","setRemappedBufferView","getRemappedBufferView","getVertexAccessor","setVertexAccessor","hasVertexColorAlpha","setHasVertexColorAlpha","getMesh","setMesh","meshIndex","bindMorphDataToMesh","morphData","morphTargets","indexOf","getMorphTargetsFromMesh","options","EngineStore","LastCreatedScene","_glTF","asset","Engine","Version","version","_animations","_accessors","_bufferViews","_cameras","_meshes","_nodes","_scenes","_skins","_materialExporter","GLTFMaterialExporter","_extensions","BufferManager","_shouldExportNodeMap","_nodeMap","_materialMap","_camerasMap","_nodesCameraMap","_skinMap","_nodesSkinMap","_babylonScene","_options","shouldExportNode","metadataSelector","metadata","gltf","extras","exportWithoutWaitingForScene","exportUnusedUVs","removeNoopRootNodes","includeCoordinateSystemConversionNodes","meshCompressionMethod","_loadExtensions","_ApplyExtension","actionAsync","currentPromise","newNode","_ApplyExtensions","GLTFExporter","_ExtensionNames","_extensionsPostExportNodeAsync","context","postExportNodeAsync","postExportMaterialAsync","map","postExportMaterialAdditionalTexturesAsync","postExportTexture","_extensionsPostExportMeshPrimitive","primitive","postExportMeshPrimitive","_extensionsPreGenerateBinaryAsync","preGenerateBinaryAsync","_forEachExtensions","action","enabled","_extensionsOnExporting","wasUsed","extensionsUsed","required","extensionsRequired","onExporting","_ExtensionFactories","dispose","RegisterExtension","order","UnregisterExtension","extensionOrder","_ExtensionOrders","insertIndex","existingName","splice","_generateJSON","bufferByteLength","fileName","prettyPrint","buffers","scenes","cameras","skins","JSON","stringify","generateGLTFAsync","glTFPrefix","_generateBinaryAsync","binaryBuffer","jsonText","bin","glTFFileName","glTFBinFile","container","GLTFData","_exportSceneAsync","_getPadding","num","remainder","generateGLBAsync","glbFileName","jsonLength","TextEncoder","encoder","encodedJsonText","encode","jsonPadding","binPadding","headerLength","blankCharCode","charCodeAt","charCode","codePointAt","_setNodeTransformation","getPivotPoint","copyFrom","clone","FromEulerAngles","_setCameraTransformation","babylonCamera","cameraWorldMatrix","parentInvWorldMatrix","invertToRef","_listAvailableCameras","camera","glTFCamera","mode","PERSPECTIVE_CAMERA","perspective","aspectRatio","getAspectRatio","yfov","fovMode","FOVMODE_VERTICAL_FIXED","fov","znear","minZ","zfar","maxZ","halfWidth","orthoLeft","orthoRight","getRenderWidth","halfHeight","orthoBottom","orthoTop","getRenderHeight","orthographic","xmag","ymag","_exportAndAssignCameras","values","gltfCamera","usedNodes","_listAvailableSkeletons","skeletons","skeleton","bones","joints","_exportAndAssignSkeletons","leftHandNodes","skin","boneIndexMap","maxBoneIndex","bone","boneIndex","getIndex","inverseBindMatrices","transformNode","getTransformNode","boneMatrix","getAbsoluteInverseBindMatrix","skinnedNodes","mat","m","skinIndex","rootNodesRH","rootNodesLH","rootNoopNodesRH","rootNodes","rootNode","stateLH","ExporterState","_exportNodesAsync","stateRH","noopRH","_animationSampleRate","_shouldExportNode","babylonRootNodes","_exportBuffers","_exportNodeAsync","_collectBuffers","bufferToVertexBuffersMap","vertexBufferToMeshesMap","morphTargetsToMeshesMap","vertexBuffers","getVertexBuffers","hasVertexAlpha","vertexBufferArray","morphIndex","babylonChildNode","morphTargetsMeshesMap","bytes","floatData","DataArrayToUint8Array","EnumerateFloatValues","invLength","stdMaterialCount","filter","StandardMaterial","UNSIGNED_BYTE","Color4","fromArray","toLinearSpaceToRef","floatMatricesIndices","FLOAT","getFloatData","is16Bit","newArray","glTFMorphTarget","parentNodeChildren","includes","_createNodeAsync","idleGLTFAnimation","children","InstancedMesh","sourceMesh","subMeshes","_exportMeshAsync","parentNodeIndex","_exportIndices","is32Bits","sideOrientation","indicesToExport","CounterClockWiseSideOrientation","IsTriangleFillMode","newIndices","processedIndices","subarray","IndicesArrayToTypedSubarray","_exportVertexBuffer","startsWith","fill","GetMinMax","isFloatMatricesIndices","vertexBufferType","vertexBufferNormalized","GetAccessorType","GetAttributeType","_exportMaterialAsync","subMesh","materialIndex","MultiMaterial","subMaterials","getClassName","primitives","isUnIndexed","getIndices","isLinesMesh","LinesMesh","isGreasedLineMesh","GreasedLineBaseMesh","getMaterial","defaultMaterial","babylonLinesMesh","colorWhite","greasedLineMaterial","overrideRenderingFillMode","_getEffectiveOrientation","ClockWiseSideOrientation","AreIndices32Bits","indexCount","indexStart","verticesStart","verticesCount","targets","gltfMorphTarget","weights","targetNames","GLTFAsync","whenReadyAsync","exporter","GLBAsync","NAME","ColorBufferToRGBAToRGB","colorBuffer","instanceCount","colorBufferRgb","_instanceColorWarned","_wasUsed","hasThinInstances","noTranslation","noRotation","noScale","thinInstanceGetWorldMatrices","iwt","iwr","iws","hasAnyInstanceWorldTranslation","hasAnyInstanceWorldRotation","hasAnyInstanceWorldScale","translationBuffer","thinInstanceCount","rotationBuffer","scaleBuffer","_buildAccessor","_userThinInstanceBuffersStorage","instanceColor","EXT_mesh_gpu_instancing","_bufferViewsUsed","_accessorsUsed","_encodePromises","DracoEncoder","DefaultAvailable","primitiveBufferViews","primitiveAccessors","glTFName","GetTypedArrayData","GetTypeByteLength","dracoName","method","promise","Default","_encodeAsync","encodedData","dracoInfo","attributeIds","catch","error","clear","KHR_draco_mesh_compression","DEFAULTS","intensity","range","SPOTDEFAULTS","innerConeAngle","outerConeAngle","PI","LIGHTDIRECTION","Backward","_lights","lightType","getTypeID","LIGHTTYPEID_POINTLIGHT","LIGHTTYPEID_DIRECTIONALLIGHT","LIGHTTYPEID_SPOTLIGHT","ShadowLight","falloffType","FALLOFF_GLTF","equalsToFloats","direction","normalizeToRef","lightRotationQuaternion","FromUnitVectorsToRef","IsIdentity","light","babylonSpotLight","spot","innerAngle","angle","lights","lightReference","KHR_lights_punctual","RECTDEFAULTS","aspect","LIGHTTYPEID_RECT_AREALIGHT","areaLight","Forward","rect","EXT_lights_area","CreateMergedAnisotropyTexture","anisoStrengthTexture","specularRoughnessAnisotropyTexture","tangentTexture","geometryTangentTexture","_anisoTexturesMap","additionalTextures","anisotropy","isEnabled","legacy","specularRoughnessAnisotropy","texId","strengthId","tangentId","GetAnisoTextureId","anisoTexture","baseRoughness","baseAlpha","roughnessT","roughnessB","anisotropyTextureInfo","anisotropyInfo","anisotropyStrength","anisotropyRotation","anisotropyTexture","_useRoughnessFromMetallicTextureGreen","mergedAnisoTexture","id","newBaseRoughness","newAnisotropyStrength","_useGltfStyleAnisotropy","newParams","geometryTangentAngle","mergedAnisoTextureInfo","KHR_materials_anisotropy","CreateMergedCoatInternalTextureAsync","coatTexture","coatWeightTexture","coatRoughnessTexture","_useCoatRoughnessFromGreenChannel","CreateTempTexture","sourceTexture","tempTexture","_texture","uOffset","vOffset","uScale","vScale","wAng","_mergedTexturesMap","_cachedInternalTexturesMap","clearCoat","useRoughnessFromMainTexture","textureRoughness","coatWeight","coatNeedsMerge","coatId","GetCoatTextureId","geometryCoatNormalTexture","clearCoatTextureRoughnessInfo","clearCoatTextureInfo","isTintEnabled","remapF0OnInterfaceChange","clearCoatNormalTextureInfo","clearCoatInfo","clearcoatFactor","clearcoatTexture","clearcoatRoughnessFactor","clearcoatRoughnessTexture","clearcoatNormalTexture","coatTextureInfo","coatRoughnessTextureInfo","coatColorTexture","coatRoughness","KHR_materials_clearcoat","coatRoughnessAnisotropyTexture","geometryCoatTangentTexture","tintTexture","coatRoughnessAnisotropy","coatTextureRoughnessInfo","coatColorTextureInfo","coatNormalTextureInfo","coatIor","indexOfRefraction","coatInfo","coatFactor","coatRoughnessFactor","coatNormalTexture","coatColorFactor","tintColor","coatDarkeningFactor","coatDarkening","coatAnisotropyStrength","coatAnisotropyRotation","coatAnisotropyTexture","geometryCoatTangentAngle","coatColor","KHR_materials_coat","GetTranslucencyIntensityTexture","subs","subSurface","translucencyIntensityTexture","thicknessTexture","useMaskFromThicknessTexture","useGltfStyleTextures","PBRMaterial","_isExtensionEnabled","translucencyColorTexture","unlit","isTranslucencyEnabled","useAlbedoToTintTranslucency","volumeIndexOfRefraction","minimumThickness","maximumThickness","diffuseTransmissionFactor","translucencyIntensity","diffuseTransmissionTexture","diffuseTransmissionColorFactor","translucencyColor","equalsFloats","diffuseTransmissionColorTexture","diffuseTransmissionInfo","KHR_materials_diffuse_transmission","isRefractionEnabled","isDispersionEnabled","dispersionInfo","dispersion","KHR_materials_dispersion","emissiveIntensity","tempEmissiveStrength","emissiveStrengthInfo","emissiveStrength","KHR_materials_emissive_strength","iorInfo","ior","KHR_materials_ior","iridescence","thinFilmWeight","thinFilmWeightTexture","thinFilmThicknessTexture","iridescenceTextureInfo","iridescenceThicknessTextureInfo","iridescenceInfo","iridescenceFactor","iridescenceIor","iridescenceThicknessMinimum","iridescenceThicknessMaximum","iridescenceTexture","iridescenceThicknessTexture","thinFilmWeightTextureInfo","thinFilmThicknessTextureInfo","thinFilmIor","thinFilmThicknessMin","thinFilmThickness","KHR_materials_iridescence","sheen","sheenInfo","sheenColorFactor","sheenRoughnessFactor","sheenColorTexture","sheenRoughnessTexture","KHR_materials_sheen","CreateMergedFuzzInternalTexture","fuzzColorTexture","fuzzRoughnessTexture","_useFuzzRoughnessFromTextureAlpha","fuzzWeight","fuzzWeightTexture","fuzzTexturesNeedMerge","fuzzColorId","fuzzRoughnessId","GetFuzzColorTextureId","mergedInternalTexture","fuzzInfo","fuzzFactor","fuzzColorFactor","fuzzColor","fuzzRoughnessFactor","fuzzRoughness","fuzzTexture","KHR_materials_fuzz","metallicReflectanceTexture","reflectanceTexture","metallicF0Factor","metallicReflectanceColor","_hasTexturesExtension","specularInfo","specularFactor","specularTexture","specularColorFactor","specularColorTexture","specularWeightTexture","specularWeight","specularEdgeColorEnabled","KHR_materials_specular","refractionIntensity","refractionIntensityTexture","transmissionFactor","volumeInfo","transmissionTexture","KHR_materials_transmission","unlitMaterial","disableLighting","KHR_materials_unlit","tintColorAtDistance","POSITIVE_INFINITY","thicknessFactor","attenuationDistance","attenuationColor","KHR_materials_volume","_baseDiffuseRoughness","_baseDiffuseRoughnessTexture","baseDiffuseRoughness","baseDiffuseRoughnessTexture","diffuseRoughnessFactor","diffuseRoughnessTexture","diffuseRoughnessTextureInfo","diffuseRoughnessInfo","KHR_materials_diffuse_roughness","uAng","vAng","uRotationCenter","vRotationCenter","textureTransform","transformIsRequired","homogeneousRotationInUVTransform","cosAngle","cos","sinAngle","sin","scaledURotationCenter","scaledVRotationCenter","AdjustOffsetForRotationCenter","KHR_texture_transform","KHR_texture_basisu","EXT_texture_webp","EXT_texture_avif","globalObject","BABYLON","GLTF2","Exporter","Extensions"],"ignoreList":[],"sourceRoot":""}
|