12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114
import { H as N, d as ke, i as z, T as v, cI as xe, cJ as re, aB as le, cK as Ae, cL as we, cM as $, cN as Q, bQ as _e, U as Y, bM as Ue, cO as Be, cP as De, cQ as ee, ai as Z, bH as b, ch as K, x as P, ak as ue, V as O, Q as W, o as A, aK as Ne, a3 as J, N as k, cR as te, J as ne, ah as We, ag as Le, bR as H, cS as oe, j as ae, a8 as Ke, O as Pe, aA as ye, F as ze, b5 as qe, aC as Ge, cT as $e, cU as He, cV as je } from "./chunk-CrnJfeNw.js";
const L = 1e-6, j = new z(0.04, 0.04, 0.04), Qe = 1024, ce = z.White(), Te = z.BlackReadOnly;
function Ye(a) {
  switch (a) {
    case "image/jpeg":
      return ".jpg";
    case "image/png":
      return ".png";
    case "image/webp":
      return ".webp";
    case "image/avif":
      return ".avif";
    case "image/ktx2":
      return ".ktx2";
  }
}
function Oe(a) {
  switch (a) {
    case "image/jpeg":
    case "image/png":
    case "image/webp":
    case "image/avif":
    case "image/ktx2":
      return !0;
    default:
      return !1;
  }
}
async function Je(a) {
  const e = a.getInternalTexture();
  if (!e || e.source !== 1 || e.invertY)
    return null;
  const t = e._buffer;
  let s, n = a.mimeType;
  try {
    t ? ArrayBuffer.isView(t) ? s = t.buffer.slice(t.byteOffset, t.byteOffset + t.byteLength) : t instanceof ArrayBuffer ? s = t : t instanceof Blob ? (s = await t.arrayBuffer(), n = t.type || n) : typeof t == "string" ? (s = await N.LoadFileAsync(t), n = ee(t) || n) : typeof HTMLImageElement < "u" && t instanceof HTMLImageElement && (s = await N.LoadFileAsync(t.src), n = ee(t.src) || n) : (s = await N.LoadFileAsync(e.url), n = ee(e.url) || n);
  } catch {
    return null;
  }
  return s && Oe(n) ? new Blob([s], { type: n }) : null;
}
function Xe(a, e, t) {
  if (e < j.r)
    return 0;
  const s = j.r, n = a * t / (1 - j.r) + e - 2 * j.r, i = j.r - e, r = n * n - 4 * s * i;
  return _e.Clamp((-n + Math.sqrt(r)) / (2 * s), 0, 1);
}
function Ze(a) {
  const e = a.diffuseColor.toLinearSpace(a.getScene().getEngine().useExactSrgbConversions).scale(0.5), t = a.alpha, s = _e.Clamp(a.specularPower, 0, Qe), n = Be(s);
  return {
    baseColorFactor: [e.r, e.g, e.b, t],
    metallicFactor: 0,
    roughnessFactor: n
  };
}
function Ee(a, e) {
  e.needAlphaBlending() ? a.alphaMode = "BLEND" : e.needAlphaTesting() && (a.alphaMode = "MASK", a.alphaCutoff = e.alphaCutOff);
}
function Me(a, e, t) {
  const s = new Uint8Array(a * e * 4);
  for (let i = 0; i < s.length; i = i + 4)
    s[i] = s[i + 1] = s[i + 2] = s[i + 3] = 255;
  return De.CreateRGBATexture(s, a, e, t);
}
function Ce(a) {
  if (a instanceof Uint8Array) {
    const e = a.length, t = new Float32Array(a.length);
    for (let s = 0; s < e; ++s)
      t[s] = a[s] / 255;
    return t;
  } else {
    if (a instanceof Float32Array)
      return a;
    throw new Error("Unsupported pixel format!");
  }
}
class be {
  constructor(e) {
    this._exporter = e, this._textureMap = /* @__PURE__ */ new Map(), this._internalTextureToImage = {};
  }
  getTextureInfo(e) {
    return e ? this._textureMap.get(e.uniqueId) ?? null : null;
  }
  async exportStandardMaterialAsync(e, t) {
    const s = Ze(e), n = { name: e.name };
    if (e.backFaceCulling != null && !e.backFaceCulling && (e.twoSidedLighting || N.Warn(e.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF."), n.doubleSided = !0), t) {
      const r = [], o = e.diffuseTexture;
      o && r.push(this.exportTextureAsync(o).then((u) => {
        u && (s.baseColorTexture = u);
      }));
      const c = e.bumpTexture;
      c && r.push(this.exportTextureAsync(c).then((u) => {
        u && (n.normalTexture = u, c.level !== 1 && (n.normalTexture.scale = c.level));
      }));
      const h = e.emissiveTexture;
      h && (n.emissiveFactor = [1, 1, 1], r.push(this.exportTextureAsync(h).then((u) => {
        u && (n.emissiveTexture = u);
      })));
      const f = e.ambientTexture;
      f && r.push(this.exportTextureAsync(f).then((u) => {
        if (u) {
          const l = {
            index: u.index
          };
          n.occlusionTexture = l;
        }
      })), r.length > 0 && (this._exporter._materialNeedsUVsSet.add(e), await Promise.all(r));
    }
    (e.alpha < 1 || e.opacityTexture) && (e.alphaMode === ke.ALPHA_COMBINE ? n.alphaMode = "BLEND" : N.Warn(e.name + ": glTF 2.0 does not support alpha mode: " + e.alphaMode.toString())), e.emissiveColor && !e.emissiveColor.equalsWithEpsilon(Te, L) && (n.emissiveFactor = e.emissiveColor.asArray()), n.pbrMetallicRoughness = s, Ee(n, e), await this._finishMaterialAsync(n, e);
    const i = this._exporter._materials;
    return i.push(n), i.length - 1;
  }
  async _finishMaterialAsync(e, t) {
    const s = await this._exporter._extensionsPostExportMaterialAdditionalTexturesAsync("exportMaterial", e, t), n = [];
    for (const i of s)
      n.push(this.exportTextureAsync(i));
    await Promise.all(n), await this._exporter._extensionsPostExportMaterialAsync("exportMaterial", e, t);
  }
  /**
   * 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
   * @param texture1 first texture to resize
   * @param texture2 second texture to resize
   * @param scene babylonjs scene
   * @returns resized textures or null
   */
  _resizeTexturesToSameDimensions(e, t, s) {
    const n = e ? e.getSize() : { width: 0, height: 0 }, i = t ? t.getSize() : { width: 0, height: 0 };
    let r, o;
    return n.width < i.width ? (e && e instanceof v ? r = xe.CreateResizedCopy(e, i.width, i.height, !0) : r = Me(i.width, i.height, s), o = t) : n.width > i.width ? (t && t instanceof v ? o = xe.CreateResizedCopy(t, n.width, n.height, !0) : o = Me(n.width, n.height, s), r = e) : (r = e, o = t), {
      texture1: r,
      texture2: o
    };
  }
  /**
   * Convert Specular Glossiness Textures to Metallic Roughness
   * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
   * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-.js/babylon.pbrUtilities.js
   * @param diffuseTexture texture used to store diffuse information
   * @param specularGlossinessTexture texture used to store specular and glossiness information
   * @param factors specular glossiness material factors
   * @returns pbr metallic roughness interface or null
   */
  async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(e, t, s) {
    const n = new Array();
    if (!(e || t))
      return await Promise.reject("diffuse and specular glossiness textures are not defined!");
    const i = e ? e.getScene() : t ? t.getScene() : null;
    if (i) {
      const r = this._resizeTexturesToSameDimensions(e, t, i), o = r.texture1?.getSize();
      let c, h;
      const f = o.width, u = o.height, l = await r.texture1.readPixels(), m = await r.texture2.readPixels();
      if (l)
        c = Ce(l);
      else
        return await Promise.reject("Failed to retrieve pixels from diffuse texture!");
      if (m)
        h = Ce(m);
      else
        return await Promise.reject("Failed to retrieve pixels from specular glossiness texture!");
      const _ = h.byteLength, g = new Uint8Array(_), p = new Uint8Array(_), d = 4, w = new z(0, 0, 0);
      let y = 0, x = 0;
      for (let I = 0; I < u; ++I)
        for (let M = 0; M < f; ++M) {
          const T = (f * I + M) * d, U = new z(c[T], c[T + 1], c[T + 2]).toLinearSpace(i.getEngine().useExactSrgbConversions).multiply(s.diffuseColor), B = new z(h[T], h[T + 1], h[T + 2]).toLinearSpace(i.getEngine().useExactSrgbConversions).multiply(s.specularColor), F = h[T + 3] * s.glossiness, q = {
            diffuseColor: U,
            specularColor: B,
            glossiness: F
          }, D = this._convertSpecularGlossinessToMetallicRoughness(q);
          w.r = Math.max(w.r, D.baseColor.r), w.g = Math.max(w.g, D.baseColor.g), w.b = Math.max(w.b, D.baseColor.b), y = Math.max(y, D.metallic), x = Math.max(x, D.roughness), p[T] = D.baseColor.r * 255, p[T + 1] = D.baseColor.g * 255, p[T + 2] = D.baseColor.b * 255, p[T + 3] = r.texture1.hasAlpha ? c[T + 3] * 255 : 255, g[T] = 0, g[T + 1] = D.roughness * 255, g[T + 2] = D.metallic * 255, g[T + 3] = 255;
        }
      const E = {
        baseColor: w,
        metallic: y,
        roughness: x
      };
      let C = !1, S = !1;
      for (let I = 0; I < u; ++I)
        for (let M = 0; M < f; ++M) {
          const T = (f * I + M) * d;
          p[T] /= E.baseColor.r > L ? E.baseColor.r : 1, p[T + 1] /= E.baseColor.g > L ? E.baseColor.g : 1, p[T + 2] /= E.baseColor.b > L ? E.baseColor.b : 1;
          const B = z.FromInts(p[T], p[T + 1], p[T + 2]).toGammaSpace(i.getEngine().useExactSrgbConversions);
          p[T] = B.r * 255, p[T + 1] = B.g * 255, p[T + 2] = B.b * 255, B.equalsWithEpsilon(ce, L) || (S = !0), g[T + 1] /= E.roughness > L ? E.roughness : 1, g[T + 2] /= E.metallic > L ? E.metallic : 1, z.FromInts(255, g[T + 1], g[T + 2]).equalsWithEpsilon(ce, L) || (C = !0);
        }
      return C && n.push(re(g, f, u).then((I) => {
        E.metallicRoughnessTextureData = I;
      })), S && n.push(re(p, f, u).then((I) => {
        E.baseColorTextureData = I;
      })), await Promise.all(n).then(() => E);
    } else
      return await Promise.reject("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
  }
  /**
   * Converts specular glossiness material properties to metallic roughness
   * @param specularGlossiness interface with specular glossiness material properties
   * @returns interface with metallic roughness material properties
   */
  _convertSpecularGlossinessToMetallicRoughness(e) {
    const t = this._getPerceivedBrightness(e.diffuseColor), s = this._getPerceivedBrightness(e.specularColor), n = 1 - this._getMaxComponent(e.specularColor), i = Xe(t, s, n), r = e.diffuseColor.scale(n / (1 - j.r) / Math.max(1 - i, L)), o = e.specularColor.subtract(j.scale(1 - i)).scale(1 / Math.max(i, L));
    let c = z.Lerp(r, o, i * i);
    return c = c.clampToRef(0, 1, c), {
      baseColor: c,
      metallic: i,
      roughness: 1 - e.glossiness
    };
  }
  /**
   * Calculates the surface reflectance, independent of lighting conditions
   * @param color Color source to calculate brightness from
   * @returns number representing the perceived brightness, or zero if color is undefined
   */
  _getPerceivedBrightness(e) {
    return Math.sqrt(0.299 * e.r * e.r + 0.587 * e.g * e.g + 0.114 * e.b * e.b);
  }
  /**
   * Returns the maximum color component value
   * @param color
   * @returns maximum color component value, or zero if color is null or undefined
   */
  _getMaxComponent(e) {
    return Math.max(e.r, Math.max(e.g, e.b));
  }
  /**
   * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors
   * @param baseColor Base color of the material
   * @param metallic Metallic factor of the material
   * @param roughness Roughness factor of the material
   * @param albedoTexture Albedo texture of the material
   * @param metallicTexture Metallic texture of the material
   * @param roughnessTexture Roughness texture of the material
   * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
   * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface
   * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
   * @returns glTF PBR Metallic Roughness factors
   */
  async _convertMetalRoughFactorsToMetallicRoughnessAsync(e, t, s, n, i, r, o, c, h) {
    const f = [], u = {
      baseColor: e,
      metallic: t,
      roughness: s
    };
    if (h)
      if (o instanceof le) {
        if (o.geometryOpacityTexture) {
          const l = n && n.getInternalTexture() ? n.getInternalTexture().uniqueId : 0, m = o.geometryOpacityTexture && o.geometryOpacityTexture.getInternalTexture() ? o.geometryOpacityTexture.getInternalTexture().uniqueId : 0, _ = +`${l}${m}`, g = this._textureMap.get(_);
          g ? c.baseColorTexture = g : f.push(Ae("baseColorOpacityTexture", we(n ? $(n, 0) : Q(1), n ? $(n, 1) : Q(1), n ? $(n, 2) : Q(1), $(o.geometryOpacityTexture, 0)), o.getScene()).then(async (p) => {
            const d = await this.exportTextureAsync(p, _);
            d && (c.baseColorTexture = d);
          }));
        } else
          n && f.push(this.exportTextureAsync(n).then((l) => {
            l && (c.baseColorTexture = l);
          }));
        if (o._useMetallicFromMetallicTextureBlue && i)
          f.push(this.exportTextureAsync(i).then((l) => {
            l && (c.metallicRoughnessTexture = l);
          }));
        else if (r || i) {
          const l = i && i.getInternalTexture() ? i.getInternalTexture().uniqueId : 0, m = r && r.getInternalTexture() ? r.getInternalTexture().uniqueId : 0, _ = +`${l}${m}`, g = this._textureMap.get(_);
          g ? c.metallicRoughnessTexture = g : f.push(Ae("MetalRoughTexture", we(o.ambientOcclusionTexture ? $(o.ambientOcclusionTexture, 0) : Q(1), r ? $(r, 0) : Q(1), i ? $(i, 0) : Q(1)), o.getScene()).then(async (p) => {
            const d = await this.exportTextureAsync(p, _);
            d && (c.metallicRoughnessTexture = d);
          }));
        }
      } else
        n && f.push(this.exportTextureAsync(n).then((l) => {
          l && (c.baseColorTexture = l);
        })), i && f.push(this.exportTextureAsync(i).then((l) => {
          l && (c.metallicRoughnessTexture = l);
        }));
    return f.length > 0 && (this._exporter._materialNeedsUVsSet.add(o), await Promise.all(f)), u;
  }
  _getTextureSampler(e) {
    const t = {};
    if (!e || !(e instanceof v))
      return t;
    const s = this._getGLTFTextureWrapMode(e.wrapU);
    s !== 10497 && (t.wrapS = s);
    const n = this._getGLTFTextureWrapMode(e.wrapV);
    switch (n !== 10497 && (t.wrapT = n), e.samplingMode) {
      case v.LINEAR_LINEAR: {
        t.magFilter = 9729, t.minFilter = 9729;
        break;
      }
      case v.LINEAR_NEAREST: {
        t.magFilter = 9729, t.minFilter = 9728;
        break;
      }
      case v.NEAREST_LINEAR: {
        t.magFilter = 9728, t.minFilter = 9729;
        break;
      }
      case v.NEAREST_LINEAR_MIPLINEAR: {
        t.magFilter = 9728, t.minFilter = 9987;
        break;
      }
      case v.NEAREST_NEAREST: {
        t.magFilter = 9728, t.minFilter = 9728;
        break;
      }
      case v.NEAREST_LINEAR_MIPNEAREST: {
        t.magFilter = 9728, t.minFilter = 9985;
        break;
      }
      case v.LINEAR_NEAREST_MIPNEAREST: {
        t.magFilter = 9729, t.minFilter = 9984;
        break;
      }
      case v.LINEAR_NEAREST_MIPLINEAR: {
        t.magFilter = 9729, t.minFilter = 9986;
        break;
      }
      case v.NEAREST_NEAREST_MIPLINEAR: {
        t.magFilter = 9728, t.minFilter = 9986;
        break;
      }
      case v.LINEAR_LINEAR_MIPLINEAR: {
        t.magFilter = 9729, t.minFilter = 9987;
        break;
      }
      case v.LINEAR_LINEAR_MIPNEAREST: {
        t.magFilter = 9729, t.minFilter = 9985;
        break;
      }
      case v.NEAREST_NEAREST_MIPNEAREST: {
        t.magFilter = 9728, t.minFilter = 9984;
        break;
      }
    }
    return t;
  }
  _getGLTFTextureWrapMode(e) {
    switch (e) {
      case v.WRAP_ADDRESSMODE:
        return 10497;
      case v.CLAMP_ADDRESSMODE:
        return 33071;
      case v.MIRROR_ADDRESSMODE:
        return 33648;
      default:
        return N.Error(`Unsupported Texture Wrap Mode ${e}!`), 10497;
    }
  }
  /**
   * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors
   * @param babylonPBRMaterial BJS PBR Metallic Roughness Material
   * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface
   * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied
   * @returns glTF PBR Metallic Roughness factors
   */
  async _convertSpecGlossFactorsToMetallicRoughnessAsync(e, t, s) {
    const n = {
      diffuseColor: e._albedoColor,
      specularColor: e._reflectivityColor,
      glossiness: e._microSurface
    }, i = e._albedoTexture, r = e._reflectivityTexture, o = e._useMicroSurfaceFromReflectivityMapAlpha;
    if (r && !o)
      return await Promise.reject("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported");
    if ((i || r) && s) {
      this._exporter._materialNeedsUVsSet.add(e);
      const c = this._exportTextureSampler(i || r), h = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(i, r, n), f = this._exporter._textures;
      if (h.baseColorTextureData) {
        const u = await this._exportImageAsync(`baseColor${f.length}`, h.baseColorTextureData);
        t.baseColorTexture = this._exportTextureInfo(u, c, i?.coordinatesIndex);
      }
      if (h.metallicRoughnessTextureData) {
        const u = await this._exportImageAsync(`metallicRoughness${f.length}`, h.metallicRoughnessTextureData);
        t.metallicRoughnessTexture = this._exportTextureInfo(u, c, r?.coordinatesIndex);
      }
      return h;
    } else
      return this._convertSpecularGlossinessToMetallicRoughness(n);
  }
  async exportPBRMaterialAsync(e, t) {
    const s = {}, n = {
      name: e.name
    }, i = e.isMetallicWorkflow();
    if (i) {
      const c = e._albedoColor, h = e.alpha;
      c && (s.baseColorFactor = [c.r, c.g, c.b, h]);
    }
    const r = i ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(e._albedoColor, e._metallic, e._roughness, e._albedoTexture, e._metallicTexture, e._metallicTexture, e, s, t) : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(e, s, t);
    await this._setMetallicRoughnessPbrMaterialAsync(r, e, n, s, t), await this._finishMaterialAsync(n, e);
    const o = this._exporter._materials;
    return o.push(n), o.length - 1;
  }
  async _setMetallicRoughnessPbrMaterialAsync(e, t, s, n, i) {
    if (Ee(s, t), (!e.baseColor.equalsWithEpsilon(ce, L) || !_e.WithinEpsilon(t.alpha, 1, L)) && (n.baseColorFactor = [e.baseColor.r, e.baseColor.g, e.baseColor.b, t.alpha]), e.metallic != null && e.metallic !== 1 && (n.metallicFactor = e.metallic), e.roughness != null && e.roughness !== 1 && (n.roughnessFactor = e.roughness), t.backFaceCulling != null && !t.backFaceCulling && (t._twoSidedLighting || N.Warn(t.name + ": Back-face culling disabled and two-sided lighting disabled is not supported in glTF."), s.doubleSided = !0), i) {
      const o = [], c = t instanceof Y ? t._bumpTexture : t.geometryNormalTexture;
      c && o.push(this.exportTextureAsync(c).then((u) => {
        u && (s.normalTexture = u, c.level !== 1 && (s.normalTexture.scale = c.level));
      }));
      const h = t instanceof Y ? t._ambientTexture : t.ambientOcclusionTexture;
      h && o.push(new Promise(async (u) => {
        if (t instanceof le && n.metallicRoughnessTexture) {
          const l = this._exportTextureSampler(h), m = this._exporter._textures[n.metallicRoughnessTexture.index].source, _ = this._exportTextureInfo(m, l, h.coordinatesIndex);
          return this._textureMap.set(h.uniqueId, _), this._exporter._extensionsPostExportTextures("exporter", _, h), u(_);
        } else
          return u(await this.exportTextureAsync(h));
      }).then(async (u) => {
        if (u) {
          const l = {
            index: u.index,
            texCoord: u.texCoord,
            extensions: u.extensions
          };
          s.occlusionTexture = l, t instanceof Y ? l.strength = t._ambientTextureStrength : l.strength = t.ambientOcclusionTexture.level;
        }
      }));
      const f = t instanceof Y ? t._emissiveTexture : t.emissionColorTexture;
      f && o.push(this.exportTextureAsync(f).then((u) => {
        u && (s.emissiveTexture = u);
      })), o.length > 0 && (this._exporter._materialNeedsUVsSet.add(t), await Promise.all(o));
    }
    const r = t instanceof Y ? t._emissiveColor : t.emissionColor;
    r.equalsWithEpsilon(Te, L) || (s.emissiveFactor = r.asArray()), s.pbrMetallicRoughness = n;
  }
  async exportOpenPBRMaterialAsync(e, t) {
    const s = {}, n = {
      name: e.name
    }, i = e.baseColor, r = e.geometryOpacity;
    i && (s.baseColorFactor = [i.r, i.g, i.b, r]);
    const o = await this._convertMetalRoughFactorsToMetallicRoughnessAsync(e.baseColor, e.baseMetalness, e.specularRoughness, e.baseColorTexture, e.baseMetalnessTexture, e.specularRoughnessTexture, e, s, t);
    await this._setMetallicRoughnessPbrMaterialAsync(o, e, n, s, t), await this._finishMaterialAsync(n, e);
    const c = this._exporter._materials;
    return c.push(n), c.length - 1;
  }
  async exportTextureAsync(e, t = null) {
    let s = this._textureMap.get(t ?? e.uniqueId);
    if (s)
      return s;
    const n = this._exportTextureSampler(e), i = await this._exportTextureImageAsync(e);
    return s = this._exportTextureInfo(i, n, e.coordinatesIndex), this._textureMap.set(t ?? e.uniqueId, s), this._exporter._extensionsPostExportTextures("exporter", s, e), s;
  }
  async _exportTextureImageAsync(e) {
    const t = e.mimeType ?? "none", s = this._internalTextureToImage, n = e.getInternalTexture().uniqueId;
    s[n] = s[n] || {};
    let i = s[n][t];
    return i === void 0 && (i = (async () => {
      const r = await Je(e);
      if (r && (t === "none" || r.type === t))
        return await this._exportImageAsync(e.name, r);
      let o = "image/png";
      t !== "none" && (Oe(t) ? o = t : (o = "image/png", N.Warn(`Unsupported media type: ${t}. Exporting texture as PNG.`)));
      const c = e.getSize(), h = await Ue(e), f = await re(h, c.width, c.height, o);
      return await this._exportImageAsync(e.name, f);
    })(), s[n][t] = i), await i;
  }
  async _exportImageAsync(e, t) {
    const s = this._exporter._images;
    let n;
    if (this._exporter._shouldUseGlb) {
      n = {
        name: e,
        mimeType: t.type,
        bufferView: void 0
        // Will be updated later by BufferManager
      };
      const i = await t.arrayBuffer(), r = this._exporter._bufferManager.createBufferView(new Uint8Array(i));
      this._exporter._bufferManager.setBufferView(n, r);
    } else {
      const i = e.replace(/\.\/|\/|\.\\|\\/g, "_"), r = Ye(t.type);
      let o = i + r;
      s.some((c) => c.uri === o) && (o = `${i}_${N.RandomId()}${r}`), n = {
        name: e,
        uri: o
      }, this._exporter._imageData[o] = t;
    }
    return s.push(n), s.length - 1;
  }
  _exportTextureInfo(e, t, s) {
    const n = this._exporter._textures;
    let i = n.findIndex((o) => o.sampler == t && o.source === e);
    i === -1 && (i = n.length, n.push({
      source: e,
      sampler: t
    }));
    const r = { index: i };
    return s && (r.texCoord = s), r;
  }
  _exportTextureSampler(e) {
    const t = this._getTextureSampler(e), s = this._exporter._samplers, n = s.findIndex((i) => i.minFilter === t.minFilter && i.magFilter === t.magFilter && i.wrapS === t.wrapS && i.wrapT === t.wrapT);
    return n !== -1 ? n : (s.push(t), s.length - 1);
  }
}
class Ie {
  constructor() {
    this.files = {};
  }
  /**
   * @deprecated Use files instead
   */
  get glTFFiles() {
    return this.files;
  }
  /**
   * Downloads the glTF data as files based on their names and data
   */
  downloadFiles() {
    for (const e in this.files) {
      const t = this.files[e], s = new Blob([t], { type: ee(e) });
      N.Download(s, e);
    }
  }
}
const pe = b.Compose(new O(-1, 1, 1), W.Identity(), O.Zero());
function et(a, e) {
  if (!(a instanceof Z))
    return !1;
  if (e) {
    if (!a.getWorldMatrix().equalsWithEpsilon(b.IdentityReadOnly, K))
      return !1;
  } else if (!a.getWorldMatrix().multiplyToRef(pe, P.Matrix[0]).equalsWithEpsilon(b.IdentityReadOnly, K))
    return !1;
  return !(a instanceof ue && a.geometry);
}
const se = O.ZeroReadOnly, me = W.Identity(), ie = O.OneReadOnly, tt = new O(-1, 1, 1);
function fe(a, e) {
  const { byteOffset: t, byteStride: s, type: n, normalized: i } = a, r = a.getSize(), o = e.reduce((f, u) => u.getTotalVertices() > f ? u.getTotalVertices() : f, -Number.MAX_VALUE), c = o * r, h = a.getKind();
  return { byteOffset: t, byteStride: s, componentCount: r, type: n, count: c, normalized: i, totalVertices: o, kind: h };
}
function st(a) {
  switch (a) {
    case "MAT2":
      return 4;
    case "MAT3":
      return 9;
    case "MAT4":
      return 16;
    case "SCALAR":
      return 1;
    case "VEC2":
      return 2;
    case "VEC3":
      return 3;
    case "VEC4":
      return 4;
  }
}
function nt(a) {
  return a.some((e) => e >= 256);
}
function Se(a) {
  switch (a) {
    case A.PositionKind:
    case A.NormalKind:
    case A.TangentKind:
    case A.ColorKind:
    case A.MatricesIndicesKind:
    case A.MatricesIndicesExtraKind:
    case A.MatricesWeightsKind:
    case A.MatricesWeightsExtraKind:
    case A.UVKind:
    case A.UV2Kind:
    case A.UV3Kind:
    case A.UV4Kind:
    case A.UV5Kind:
    case A.UV6Kind:
      return !0;
  }
  return !1;
}
function it(a, e) {
  if (a == A.ColorKind)
    return e ? "VEC4" : "VEC3";
  switch (a) {
    case A.PositionKind:
    case A.NormalKind:
      return "VEC3";
    case A.TangentKind:
    case A.MatricesIndicesKind:
    case A.MatricesIndicesExtraKind:
    case A.MatricesWeightsKind:
    case A.MatricesWeightsExtraKind:
      return "VEC4";
    case A.UVKind:
    case A.UV2Kind:
    case A.UV3Kind:
    case A.UV4Kind:
    case A.UV5Kind:
    case A.UV6Kind:
      return "VEC2";
  }
  throw new Error(`Unknown kind ${a}`);
}
function rt(a) {
  switch (a) {
    case A.PositionKind:
      return "POSITION";
    case A.NormalKind:
      return "NORMAL";
    case A.TangentKind:
      return "TANGENT";
    case A.ColorKind:
      return "COLOR_0";
    case A.UVKind:
      return "TEXCOORD_0";
    case A.UV2Kind:
      return "TEXCOORD_1";
    case A.UV3Kind:
      return "TEXCOORD_2";
    case A.UV4Kind:
      return "TEXCOORD_3";
    case A.UV5Kind:
      return "TEXCOORD_4";
    case A.UV6Kind:
      return "TEXCOORD_5";
    case A.MatricesIndicesKind:
      return "JOINTS_0";
    case A.MatricesIndicesExtraKind:
      return "JOINTS_1";
    case A.MatricesWeightsKind:
      return "WEIGHTS_0";
    case A.MatricesWeightsExtraKind:
      return "WEIGHTS_1";
  }
  throw new Error(`Unknown kind: ${a}`);
}
function ot(a) {
  switch (a) {
    case k.TriangleFillMode:
      return 4;
    case k.TriangleStripDrawMode:
      return 5;
    case k.TriangleFanDrawMode:
      return 6;
    case k.PointListDrawMode:
    case k.PointFillMode:
      return 0;
    case k.LineLoopDrawMode:
      return 2;
    case k.LineListDrawMode:
      return 1;
    case k.LineStripDrawMode:
      return 3;
  }
  throw new Error(`Unknown fill mode: ${a}`);
}
function at(a) {
  switch (a) {
    case k.TriangleFillMode:
    case k.TriangleStripDrawMode:
    case k.TriangleFanDrawMode:
      return !0;
  }
  return !1;
}
function Ve(a) {
  const e = Math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
  e > 0 && (a.x /= e, a.y /= e, a.z /= e);
}
function de(a) {
  return a.x *= -1, a;
}
function ct(a) {
  return pe.invertToRef(P.Matrix[0]).multiplyToRef(a, a).multiplyToRef(pe, a), a;
}
function ge(a) {
  if (a.x * a.x + a.y * a.y > 0.5) {
    const e = Math.abs(a.x), t = Math.abs(a.y);
    if (e > t) {
      const s = Math.sign(a.x);
      a.x = e, a.y *= -s, a.z *= -s, a.w *= s;
    } else {
      const s = Math.sign(a.y);
      a.x *= -s, a.y = t, a.z *= s, a.w *= -s;
    }
  } else {
    const e = Math.abs(a.z), t = Math.abs(a.w);
    if (e > t) {
      const s = Math.sign(a.z);
      a.x *= -s, a.y *= s, a.z = e, a.w *= -s;
    } else {
      const s = Math.sign(a.w);
      a.x *= s, a.y *= -s, a.z *= -s, a.w = t;
    }
  }
  return a;
}
function Fe(a) {
  a.copyFromFloats(-a.z, a.w, a.x, -a.y);
}
function ft(a, e) {
  const t = O.FromArrayToRef(e.translation || [0, 0, 0], 0, P.Vector3[0]), s = W.FromArrayToRef(e.rotation || [0, 0, 0, 1], 0, P.Quaternion[0]), n = b.ComposeToRef(ie, s, t, P.Matrix[0]), i = O.FromArrayToRef(a.translation || [0, 0, 0], 0, P.Vector3[2]), r = W.FromArrayToRef(a.rotation || [0, 0, 0, 1], 0, P.Quaternion[1]), o = b.ComposeToRef(ie, r, i, P.Matrix[1]);
  n.multiplyToRef(o, o), o.decompose(void 0, s, t), t.equalsWithEpsilon(se, K) ? delete e.translation : e.translation = t.asArray(), s.equalsWithEpsilon(me, K) ? delete e.rotation : e.rotation = s.asArray(), e.scale && delete e.scale;
}
function ht(a, e) {
  if (!(e instanceof Z) || !(e.getChildren().length === 1 && a.getChildren().length === 0 && a.parent === e))
    return !1;
  const s = a.getScene(), n = a instanceof Ne && !s.useRightHandedSystem ? tt : ie;
  return e.scaling.equalsWithEpsilon(n, K) ? !0 : (J.Warn(`Cannot collapse node ${a.name} into parent node ${e.name} with modified scaling.`), !1);
}
function lt(a, e, t, s) {
  let n = a;
  return (e !== 0 || t !== a.length) && (n = Array.isArray(a) ? a.slice(e, e + t) : a.subarray(e, e + t)), n instanceof Int32Array ? new Uint32Array(n.buffer, n.byteOffset, n.length) : Array.isArray(n) ? s ? new Uint32Array(n) : new Uint16Array(n) : n;
}
function ut(a) {
  if (a instanceof Array) {
    const e = new Float32Array(a);
    return new Uint8Array(e.buffer, e.byteOffset, e.byteLength);
  }
  return ArrayBuffer.isView(a) ? new Uint8Array(a.buffer, a.byteOffset, a.byteLength) : new Uint8Array(a);
}
function pt(a, e, t, s) {
  const { byteOffset: n, byteStride: i, type: r, normalized: o } = e, c = e.getSize(), h = new Array(c).fill(1 / 0), f = new Array(c).fill(-1 / 0);
  return te(a, n + t * i, i, c, r, s * c, o, (u) => {
    for (let l = 0; l < c; l++)
      h[l] = Math.min(h[l], u[l]), f[l] = Math.max(f[l], u[l]);
  }), { min: h, max: f };
}
const mt = /* @__PURE__ */ new Map([
  [Int8Array, (a, e, t) => a.setInt8(e, t)],
  [Uint8Array, (a, e, t) => a.setUint8(e, t)],
  [Uint8ClampedArray, (a, e, t) => a.setUint8(e, t)],
  [Int16Array, (a, e, t) => a.setInt16(e, t, !0)],
  [Uint16Array, (a, e, t) => a.setUint16(e, t, !0)],
  [Int32Array, (a, e, t) => a.setInt32(e, t, !0)],
  [Uint32Array, (a, e, t) => a.setUint32(e, t, !0)],
  [Float32Array, (a, e, t) => a.setFloat32(e, t, !0)],
  [Float64Array, (a, e, t) => a.setFloat64(e, t, !0)]
]);
class ve {
  writeTypedArray(e) {
    this._checkGrowBuffer(e.byteLength);
    const t = mt.get(e.constructor);
    for (let s = 0; s < e.length; s++)
      t(this._dataView, this._byteOffset, e[s]), this._byteOffset += e.BYTES_PER_ELEMENT;
  }
  constructor(e) {
    this._data = new Uint8Array(e), this._dataView = new DataView(this._data.buffer), this._byteOffset = 0;
  }
  get byteOffset() {
    return this._byteOffset;
  }
  getOutputData() {
    return new Uint8Array(this._data.buffer, 0, this._byteOffset);
  }
  writeUInt8(e) {
    this._checkGrowBuffer(1), this._dataView.setUint8(this._byteOffset, e), this._byteOffset++;
  }
  writeInt8(e) {
    this._checkGrowBuffer(1), this._dataView.setInt8(this._byteOffset, e), this._byteOffset++;
  }
  writeInt16(e) {
    this._checkGrowBuffer(2), this._dataView.setInt16(this._byteOffset, e, !0), this._byteOffset += 2;
  }
  writeUInt16(e) {
    this._checkGrowBuffer(2), this._dataView.setUint16(this._byteOffset, e, !0), this._byteOffset += 2;
  }
  writeInt32(e) {
    this._checkGrowBuffer(4), this._dataView.setInt32(this._byteOffset, e, !0), this._byteOffset += 4;
  }
  writeUInt32(e) {
    this._checkGrowBuffer(4), this._dataView.setUint32(this._byteOffset, e, !0), this._byteOffset += 4;
  }
  writeFloat32(e) {
    this._checkGrowBuffer(4), this._dataView.setFloat32(this._byteOffset, e, !0), this._byteOffset += 4;
  }
  writeFloat64(e) {
    this._checkGrowBuffer(8), this._dataView.setFloat64(this._byteOffset, e, !0), this._byteOffset += 8;
  }
  _checkGrowBuffer(e) {
    const t = this.byteOffset + e;
    if (t > this._data.byteLength) {
      const s = new Uint8Array(t * 2);
      s.set(this._data), this._data = s, this._dataView = new DataView(this._data.buffer);
    }
  }
}
function Re(a) {
  return a % 4 === 0 ? 4 : a % 2 === 0 ? 2 : 1;
}
class dt {
  constructor() {
    this._bufferViewToData = /* @__PURE__ */ new Map(), this._bufferViewToProperties = /* @__PURE__ */ new Map(), this._accessorToBufferView = /* @__PURE__ */ new Map();
  }
  /**
   * Generates a binary buffer from the stored bufferViews. Also populates the bufferViews list.
   * @param bufferViews The list of bufferViews to be populated while writing the binary
   * @returns The binary buffer
   */
  generateBinary(e) {
    let t = 0;
    this._bufferViewToData.forEach((i) => {
      t += i.byteLength;
    });
    const s = new ve(t), n = Array.from(this._bufferViewToData.keys()).sort((i, r) => Re(r.byteLength) - Re(i.byteLength));
    for (const i of n) {
      i.byteOffset = s.byteOffset, e.push(i);
      const r = e.length - 1, o = this.getPropertiesWithBufferView(i);
      for (const c of o)
        c.bufferView = r;
      s.writeTypedArray(this._bufferViewToData.get(i)), this._bufferViewToData.delete(i);
    }
    return s.getOutputData();
  }
  /**
   * Creates a buffer view based on the supplied arguments
   * @param data a TypedArray to create the bufferView for
   * @param byteStride byte distance between consecutive elements
   * @returns bufferView for glTF
   */
  createBufferView(e, t) {
    const s = {
      buffer: 0,
      byteOffset: void 0,
      // byteOffset will be set later, when we write the binary and decide bufferView ordering
      byteLength: e.byteLength,
      byteStride: t
    };
    return this._bufferViewToData.set(s, e), s;
  }
  /**
   * Creates an accessor based on the supplied arguments and assigns it to the bufferView
   * @param bufferView The glTF bufferView referenced by this accessor
   * @param type The type of the accessor
   * @param componentType The datatype of components in the attribute
   * @param count The number of attributes referenced by this accessor
   * @param byteOffset The offset relative to the start of the bufferView in bytes
   * @param minMax Minimum and maximum value of each component in this attribute
   * @param normalized Specifies whether integer data values are normalized before usage
   * @returns accessor for glTF
   */
  createAccessor(e, t, s, n, i, r, o) {
    this._verifyBufferView(e);
    const c = {
      bufferView: void 0,
      // bufferView will be set to a real index later, once we write the binary and decide bufferView ordering
      componentType: s,
      count: n,
      type: t,
      min: r?.min,
      max: r?.max,
      normalized: o,
      byteOffset: i
    };
    return this.setBufferView(c, e), this._accessorToBufferView.set(c, e), c;
  }
  /**
   * Assigns a bufferView to a glTF object that references it
   * @param object The glTF object
   * @param bufferView The bufferView to assign
   */
  setBufferView(e, t) {
    this._verifyBufferView(t), this.getPropertiesWithBufferView(t).push(e);
  }
  /**
   * Removes buffer view from the binary data, as well as from all its known references
   * @param bufferView the bufferView to remove
   */
  removeBufferView(e) {
    const t = this.getPropertiesWithBufferView(e);
    for (const s of t)
      s.bufferView !== void 0 && delete s.bufferView;
    this._bufferViewToData.delete(e), this._bufferViewToProperties.delete(e), this._accessorToBufferView.forEach((s, n) => {
      s === e && (n.byteOffset !== void 0 && delete n.byteOffset, this._accessorToBufferView.delete(n));
    });
  }
  getBufferView(e) {
    const t = this._accessorToBufferView.get(e);
    return this._verifyBufferView(t), t;
  }
  getPropertiesWithBufferView(e) {
    return this._verifyBufferView(e), this._bufferViewToProperties.set(e, this._bufferViewToProperties.get(e) ?? []), this._bufferViewToProperties.get(e);
  }
  getData(e) {
    return this._verifyBufferView(e), this._bufferViewToData.get(e);
  }
  _verifyBufferView(e) {
    if (e === void 0 || !this._bufferViewToData.has(e))
      throw new Error(`BufferView ${e} not found in BufferManager.`);
  }
}
var X;
(function(a) {
  a[a.INTANGENT = 0] = "INTANGENT", a[a.OUTTANGENT = 1] = "OUTTANGENT";
})(X || (X = {}));
class V {
  /**
   * Determine if a node is transformable - ie has properties it should be part of animation of transformation.
   * @param babylonNode the node to test
   * @returns true if can be animated, false otherwise. False if the parameter is null or undefined.
   */
  static _IsTransformable(e) {
    return e && (e instanceof Z || e instanceof ne || e instanceof We);
  }
  /**
   * @ignore
   *
   * Creates glTF channel animation from BabylonJS animation.
   * @param babylonTransformNode - BabylonJS mesh.
   * @param animation - animation.
   * @param animationChannelTargetPath - The target animation channel.
   * @param useQuaternion - Specifies if quaternions are used.
   * @returns nullable IAnimationData
   */
  static _CreateNodeAnimation(e, t, s, n, i) {
    if (this._IsTransformable(e)) {
      const r = [], o = [], c = t.getKeys(), h = V._CalculateMinMaxKeyFrames(c), f = V._DeduceInterpolation(c, s, n), u = f.interpolationType, l = f.shouldBakeAnimation;
      if (l ? V._CreateBakedAnimation(e, t, s, h.min, h.max, t.framePerSecond, i, r, o, h, n) : u === "LINEAR" || u === "STEP" ? V._CreateLinearOrStepAnimation(e, t, s, r, o, n) : u === "CUBICSPLINE" ? V._CreateCubicSplineAnimation(e, t, s, r, o, n) : V._CreateBakedAnimation(e, t, s, h.min, h.max, t.framePerSecond, i, r, o, h, n), r.length && o.length)
        return {
          inputs: r,
          outputs: o,
          samplerInterpolation: u,
          inputsMin: l ? h.min : N.FloatRound(h.min / t.framePerSecond),
          inputsMax: l ? h.max : N.FloatRound(h.max / t.framePerSecond)
        };
    }
    return null;
  }
  static _DeduceAnimationInfo(e) {
    let t = null, s = "VEC3", n = !1;
    const i = e.targetProperty.split(".");
    switch (i[0]) {
      case "scaling": {
        t = "scale";
        break;
      }
      case "position": {
        t = "translation";
        break;
      }
      case "rotation": {
        s = "VEC4", t = "rotation";
        break;
      }
      case "rotationQuaternion": {
        s = "VEC4", n = !0, t = "rotation";
        break;
      }
      case "influence": {
        s = "SCALAR", t = "weights";
        break;
      }
      default:
        N.Error(`Unsupported animatable property ${i[0]}`);
    }
    return t ? { animationChannelTargetPath: t, dataAccessorType: s, useQuaternion: n } : (N.Error("animation channel target path and data accessor type could be deduced"), null);
  }
  /**
   * @ignore
   * Create node animations from the transform node animations
   * @param babylonNode
   * @param runtimeGLTFAnimation
   * @param idleGLTFAnimations
   * @param nodeMap
   * @param nodes
   * @param bufferManager
   * @param bufferViews
   * @param accessors
   * @param animationSampleRate
   */
  static _CreateNodeAnimationFromNodeAnimations(e, t, s, n, i, r, o, c, h, f, u) {
    let l;
    if (V._IsTransformable(e) && e.animations)
      for (const m of e.animations) {
        if (u && !u(m))
          continue;
        const _ = V._DeduceAnimationInfo(m);
        _ && (l = {
          name: m.name,
          samplers: [],
          channels: []
        }, V._AddAnimation(`${m.name}`, m.hasRunningRuntimeAnimations ? t : l, e, m, _.dataAccessorType, _.animationChannelTargetPath, n, r, o, c, _.useQuaternion, h, f), l.samplers.length && l.channels.length && s.push(l));
      }
  }
  /**
   * @ignore
   * Create individual morph animations from the mesh's morph target animation tracks
   * @param babylonNode
   * @param runtimeGLTFAnimation
   * @param idleGLTFAnimations
   * @param nodeMap
   * @param nodes
   * @param bufferManager
   * @param bufferViews
   * @param accessors
   * @param animationSampleRate
   */
  static _CreateMorphTargetAnimationFromMorphTargetAnimations(e, t, s, n, i, r, o, c, h, f, u) {
    let l;
    if (e instanceof Le) {
      const m = e.morphTargetManager;
      if (m)
        for (let _ = 0; _ < m.numTargets; ++_) {
          const g = m.getTarget(_);
          for (const p of g.animations) {
            if (u && !u(p))
              continue;
            const d = new H(`${p.name}`, "influence", p.framePerSecond, p.dataType, p.loopMode, p.enableBlending), w = [], y = p.getKeys();
            for (let E = 0; E < y.length; ++E) {
              const C = y[E];
              for (let S = 0; S < m.numTargets; ++S)
                S == _ ? w.push(C) : w.push({ frame: C.frame, value: 0 });
            }
            d.setKeys(w, !0);
            const x = V._DeduceAnimationInfo(d);
            x && (l = {
              name: d.name,
              samplers: [],
              channels: []
            }, V._AddAnimation(p.name, p.hasRunningRuntimeAnimations ? t : l, e, d, x.dataAccessorType, x.animationChannelTargetPath, n, r, o, c, x.useQuaternion, h, f, m.numTargets), l.samplers.length && l.channels.length && s.push(l));
          }
        }
    }
  }
  /**
   * @internal
   * Create node and morph animations from the animation groups
   * @param babylonScene
   * @param glTFAnimations
   * @param nodeMap
   * @param nodes
   * @param bufferManager
   * @param bufferViews
   * @param accessors
   * @param animationSampleRate
   */
  static _CreateNodeAndMorphAnimationFromAnimationGroups(e, t, s, n, i, r, o, c, h) {
    let f;
    if (e.animationGroups) {
      const u = e.animationGroups;
      for (const l of u) {
        const m = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Set(), p = l.to - l.from;
        f = {
          name: l.name,
          channels: [],
          samplers: []
        };
        for (let d = 0; d < l.targetedAnimations.length; ++d) {
          const w = l.targetedAnimations[d], y = w.target, x = w.animation;
          if (h && !h(x))
            continue;
          const E = c.has(y);
          if (this._IsTransformable(y) || y.length === 1 && this._IsTransformable(y[0])) {
            const C = V._DeduceAnimationInfo(w.animation);
            if (C) {
              const S = this._IsTransformable(y) ? y : this._IsTransformable(y[0]) ? y[0] : null;
              S && V._AddAnimation(`${x.name}`, f, S, x, C.dataAccessorType, C.animationChannelTargetPath, s, n, i, r, C.useQuaternion, o, E);
            }
          } else if ((y instanceof oe || y.length === 1 && y[0] instanceof oe) && V._DeduceAnimationInfo(w.animation)) {
            const S = y instanceof oe ? y : y[0];
            if (S) {
              const I = e.morphTargetManagers.find((M) => {
                for (let T = 0; T < M.numTargets; ++T)
                  if (M.getTarget(T) === S)
                    return !0;
                return !1;
              });
              if (I) {
                const M = e.meshes.find((T) => T.morphTargetManager === I);
                M && (m.has(M) || m.set(M, /* @__PURE__ */ new Map()), m.get(M)?.set(S, x), g.add(M), _.set(M, x));
              }
            }
          }
        }
        g.forEach((d) => {
          const w = d.morphTargetManager;
          let y = null;
          const x = [], C = _.get(d).getKeys(), S = C.length;
          for (let M = 0; M < S; ++M)
            for (let T = 0; T < w.numTargets; ++T) {
              const U = w.getTarget(T), B = m.get(d);
              if (B) {
                const F = B.get(U);
                F ? (y || (y = new H(`${l.name}_${d.name}_MorphWeightAnimation`, "influence", F.framePerSecond, H.ANIMATIONTYPE_FLOAT, F.loopMode, F.enableBlending)), x.push(F.getKeys()[M])) : x.push({
                  frame: l.from + p / S * M,
                  value: U.influence,
                  inTangent: C[0].inTangent ? 0 : void 0,
                  outTangent: C[0].outTangent ? 0 : void 0
                });
              }
            }
          y.setKeys(x, !0);
          const I = V._DeduceAnimationInfo(y);
          I && V._AddAnimation(`${l.name}_${d.name}_MorphWeightAnimation`, f, d, y, I.dataAccessorType, I.animationChannelTargetPath, s, n, i, r, I.useQuaternion, o, !1, w?.numTargets);
        }), f.channels.length && f.samplers.length && t.push(f);
      }
    }
  }
  static _AddAnimation(e, t, s, n, i, r, o, c, h, f, u, l, m, _) {
    const g = V._CreateNodeAnimation(s, n, r, u, l);
    let p, d, w, y, x, E;
    if (g) {
      if (_) {
        let q = 0, D;
        const G = [];
        for (; g.inputs.length > 0; )
          D = g.inputs.shift(), q % _ == 0 && G.push(D), q++;
        g.inputs = G;
      }
      const C = o.get(s), S = new Float32Array(g.inputs);
      p = c.createBufferView(S), d = c.createAccessor(p, "SCALAR", 5126, g.inputs.length, void 0, {
        min: [g.inputsMin],
        max: [g.inputsMax]
      }), f.push(d), w = f.length - 1;
      const I = new W(), M = new O(), T = new O(), U = s instanceof ne, B = st(i), F = new Float32Array(g.outputs.length * B);
      g.outputs.forEach(function(q, D) {
        let G = q;
        switch (r) {
          case "translation":
            m && (O.FromArrayToRef(q, 0, T), de(T), T.toArray(G));
            break;
          case "rotation":
            q.length === 4 ? W.FromArrayToRef(q, 0, I) : (G = new Array(4), O.FromArrayToRef(q, 0, M), W.FromEulerVectorToRef(M, I)), m && (ge(I), U && Fe(I)), I.toArray(G);
            break;
        }
        F.set(G, D * B);
      }), p = c.createBufferView(F), d = c.createAccessor(p, i, 5126, g.outputs.length), f.push(d), y = f.length - 1, x = {
        interpolation: g.samplerInterpolation,
        input: w,
        output: y
      }, t.samplers.push(x), E = {
        sampler: t.samplers.length - 1,
        target: {
          node: C,
          path: r
        }
      }, t.channels.push(E);
    }
  }
  /**
   * Create a baked animation
   * @param babylonTransformNode BabylonJS mesh
   * @param animation BabylonJS animation corresponding to the BabylonJS mesh
   * @param animationChannelTargetPath animation target channel
   * @param minFrame minimum animation frame
   * @param maxFrame maximum animation frame
   * @param fps frames per second of the animation
   * @param sampleRate
   * @param inputs input key frames of the animation
   * @param outputs output key frame data of the animation
   * @param minMaxFrames
   * @param minMaxFrames.min
   * @param minMaxFrames.max
   * @param useQuaternion specifies if quaternions should be used
   */
  static _CreateBakedAnimation(e, t, s, n, i, r, o, c, h, f, u) {
    let l;
    const m = W.Identity();
    let _ = null, g, p = null, d, w, y, x;
    f.min = N.FloatRound(n / r);
    const E = t.getKeys();
    for (let C = 0, S = E.length; C < S; ++C) {
      if (d = E[C], C + 1 < S)
        if (w = E[C + 1], d.value.equals && d.value.equals(w.value) || d.value === w.value)
          if (C === 0)
            x = d.frame;
          else
            continue;
        else
          x = w.frame;
      else {
        if (y = E[C - 1], d.value.equals && d.value.equals(y.value) || d.value === y.value)
          continue;
        x = i;
      }
      if (x)
        for (let I = d.frame; I <= x; I += o) {
          if (g = N.FloatRound(I / r), g === _)
            continue;
          _ = g, p = g;
          const M = {
            key: 0,
            repeatCount: 0,
            loopMode: t.loopMode
          };
          l = t._interpolate(I, M), V._SetInterpolatedValue(e, l, g, t, s, m, c, h, u);
        }
    }
    p && (f.max = p);
  }
  static _ConvertFactorToVector3OrQuaternion(e, t, s, n, i) {
    const r = V._GetBasePositionRotationOrScale(t, n, i), o = s.targetProperty.split("."), c = o ? o[1] : "", h = i ? W.FromArray(r).normalize() : O.FromArray(r);
    switch (c) {
      case "x":
      case "y":
      case "z": {
        h[c] = e;
        break;
      }
      case "w": {
        h.w = e;
        break;
      }
      default:
        N.Error(`glTFAnimation: Unsupported component name "${c}"!`);
    }
    return h;
  }
  static _SetInterpolatedValue(e, t, s, n, i, r, o, c, h) {
    let f;
    if (o.push(s), i === "weights") {
      c.push([t]);
      return;
    }
    n.dataType === H.ANIMATIONTYPE_FLOAT && (t = this._ConvertFactorToVector3OrQuaternion(t, e, n, i, h)), i === "rotation" ? (h ? r = t : (f = t, W.RotationYawPitchRollToRef(f.y, f.x, f.z, r)), c.push(r.asArray())) : (f = t, c.push(f.asArray()));
  }
  /**
   * Creates linear animation from the animation key frames
   * @param babylonTransformNode BabylonJS mesh
   * @param animation BabylonJS animation
   * @param animationChannelTargetPath The target animation channel
   * @param inputs Array to store the key frame times
   * @param outputs Array to store the key frame data
   * @param useQuaternion Specifies if quaternions are used in the animation
   */
  static _CreateLinearOrStepAnimation(e, t, s, n, i, r) {
    for (const o of t.getKeys())
      n.push(o.frame / t.framePerSecond), V._AddKeyframeValue(o, t, i, s, e, r);
  }
  /**
   * Creates cubic spline animation from the animation key frames
   * @param babylonTransformNode BabylonJS mesh
   * @param animation BabylonJS animation
   * @param animationChannelTargetPath The target animation channel
   * @param inputs Array to store the key frame times
   * @param outputs Array to store the key frame data
   * @param useQuaternion Specifies if quaternions are used in the animation
   */
  static _CreateCubicSplineAnimation(e, t, s, n, i, r) {
    t.getKeys().forEach(function(o) {
      n.push(o.frame / t.framePerSecond), V._AddSplineTangent(X.INTANGENT, i, s, "CUBICSPLINE", o, r), V._AddKeyframeValue(o, t, i, s, e, r), V._AddSplineTangent(X.OUTTANGENT, i, s, "CUBICSPLINE", o, r);
    });
  }
  static _GetBasePositionRotationOrScale(e, t, s) {
    let n;
    return t === "rotation" ? s ? n = (e.rotationQuaternion ?? W.Identity()).asArray() : n = (e.rotation ?? O.Zero()).asArray() : t === "translation" ? n = (e.position ?? O.Zero()).asArray() : n = (e.scaling ?? O.One()).asArray(), n;
  }
  /**
   * Adds a key frame value
   * @param keyFrame
   * @param animation
   * @param outputs
   * @param animationChannelTargetPath
   * @param babylonTransformNode
   * @param useQuaternion
   */
  static _AddKeyframeValue(e, t, s, n, i, r) {
    let o;
    const c = t.dataType;
    if (c === H.ANIMATIONTYPE_VECTOR3) {
      let h = e.value.asArray();
      if (n === "rotation") {
        const f = O.FromArray(h);
        h = W.RotationYawPitchRoll(f.y, f.x, f.z).asArray();
      }
      s.push(h);
    } else if (c === H.ANIMATIONTYPE_FLOAT) {
      if (n === "weights")
        s.push([e.value]);
      else if (o = this._ConvertFactorToVector3OrQuaternion(e.value, i, t, n, r), o) {
        if (n === "rotation") {
          const h = r ? o : W.RotationYawPitchRoll(o.y, o.x, o.z).normalize();
          s.push(h.asArray());
        }
        s.push(o.asArray());
      }
    } else c === H.ANIMATIONTYPE_QUATERNION ? s.push(e.value.normalize().asArray()) : N.Error("glTFAnimation: Unsupported key frame values for animation!");
  }
  /**
   * @internal
   * Determine the interpolation based on the key frames
   * @param keyFrames
   * @param animationChannelTargetPath
   * @param useQuaternion
   */
  static _DeduceInterpolation(e, t, s) {
    let n, i = !1, r;
    if (t === "rotation" && !s)
      return { interpolationType: "LINEAR", shouldBakeAnimation: !0 };
    for (let o = 0, c = e.length; o < c; ++o)
      if (r = e[o], r.inTangent || r.outTangent)
        if (n) {
          if (n !== "CUBICSPLINE") {
            n = "LINEAR", i = !0;
            break;
          }
        } else
          n = "CUBICSPLINE";
      else if (n) {
        if (n === "CUBICSPLINE" || r.interpolation && r.interpolation === 1 && n !== "STEP") {
          n = "LINEAR", i = !0;
          break;
        }
      } else
        r.interpolation && r.interpolation === 1 ? n = "STEP" : n = "LINEAR";
    return n || (n = "LINEAR"), { interpolationType: n, shouldBakeAnimation: i };
  }
  /**
   * Adds an input tangent or output tangent to the output data
   * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion
   * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent)
   * @param outputs The animation data by keyframe
   * @param animationChannelTargetPath The target animation channel
   * @param interpolation The interpolation type
   * @param keyFrame The key frame with the animation data
   * @param useQuaternion Specifies if quaternions are used
   */
  static _AddSplineTangent(e, t, s, n, i, r) {
    let o;
    const c = e === X.INTANGENT ? i.inTangent : i.outTangent;
    if (n === "CUBICSPLINE") {
      if (s === "rotation")
        if (c)
          if (r)
            o = c.asArray();
          else {
            const h = c;
            o = W.RotationYawPitchRoll(h.y, h.x, h.z).asArray();
          }
        else
          o = [0, 0, 0, 0];
      else s === "weights" ? c ? o = [c] : o = [0] : c ? o = c.asArray() : o = [0, 0, 0];
      t.push(o);
    }
  }
  /**
   * Get the minimum and maximum key frames' frame values
   * @param keyFrames animation key frames
   * @returns the minimum and maximum key frame value
   */
  static _CalculateMinMaxKeyFrames(e) {
    let t = 1 / 0, s = -1 / 0;
    return e.forEach(function(n) {
      t = Math.min(t, n.frame), s = Math.max(s, n.frame);
    }), { min: t, max: s };
  }
}
function gt(a, e, t, s, n, i) {
  const r = {
    attributes: {},
    influence: a.influence,
    name: a.name
  }, o = e.geometry;
  if (!o)
    return N.Warn("Attempted to export morph target data from a mesh without geometry. This should not happen."), r;
  const c = i ? -1 : 1, h = 4, f = O.Zero();
  let u, l;
  if (a.hasPositions) {
    const m = a.getPositions(), _ = o.getVerticesData(A.PositionKind);
    if (_) {
      const g = new Float32Array(_.length), p = [1 / 0, 1 / 0, 1 / 0], d = [-1 / 0, -1 / 0, -1 / 0];
      l = _.length / 3, u = 0;
      for (let x = u; x < l; ++x) {
        const E = O.FromArray(_, x * 3);
        O.FromArray(m, x * 3).subtractToRef(E, f), f.x *= c, p[0] = Math.min(p[0], f.x), d[0] = Math.max(d[0], f.x), p[1] = Math.min(p[1], f.y), d[1] = Math.max(d[1], f.y), p[2] = Math.min(p[2], f.z), d[2] = Math.max(d[2], f.z), g[x * 3] = f.x, g[x * 3 + 1] = f.y, g[x * 3 + 2] = f.z;
      }
      const w = t.createBufferView(g, h * 3), y = t.createAccessor(w, "VEC3", 5126, m.length / 3, 0, { min: p, max: d });
      n.push(y), r.attributes.POSITION = n.length - 1;
    } else
      N.Warn(`Morph target positions for mesh ${e.name} were not exported. Mesh does not have position vertex data`);
  }
  if (a.hasNormals) {
    const m = a.getNormals(), _ = o.getVerticesData(A.NormalKind);
    if (_) {
      const g = new Float32Array(_.length);
      l = _.length / 3, u = 0;
      for (let w = u; w < l; ++w) {
        const y = O.FromArray(_, w * 3).normalize();
        O.FromArray(m, w * 3).normalize().subtractToRef(y, f), g[w * 3] = f.x * c, g[w * 3 + 1] = f.y, g[w * 3 + 2] = f.z;
      }
      const p = t.createBufferView(g, h * 3), d = t.createAccessor(p, "VEC3", 5126, m.length / 3, 0);
      n.push(d), r.attributes.NORMAL = n.length - 1;
    } else
      N.Warn(`Morph target normals for mesh ${e.name} were not exported. Mesh does not have normals vertex data`);
  }
  if (a.hasTangents) {
    const m = a.getTangents(), _ = o.getVerticesData(A.TangentKind);
    if (_) {
      l = _.length / 4;
      const g = new Float32Array(l * 3);
      u = 0;
      for (let w = u; w < l; ++w) {
        const y = O.FromArray(_, w * 4);
        Ve(y);
        const x = O.FromArray(m, w * 3);
        Ve(x), x.subtractToRef(y, f), g[w * 3] = f.x * c, g[w * 3 + 1] = f.y, g[w * 3 + 2] = f.z;
      }
      const p = t.createBufferView(g, h * 3), d = t.createAccessor(p, "VEC3", 5126, l, 0);
      n.push(d), r.attributes.TANGENT = n.length - 1;
    } else
      N.Warn(`Morph target tangents for mesh ${e.name} were not exported. Mesh does not have tangents vertex data`);
  }
  if (a.hasColors) {
    const m = a.getColors(), _ = o.getVerticesData(A.ColorKind), g = o.getVertexBuffer(A.ColorKind);
    if (_ && g) {
      const p = g.getSize();
      l = _.length / p;
      const d = new Float32Array(l * p);
      u = 0;
      for (let x = u; x < l; ++x)
        if (p === 3) {
          const E = O.FromArray(_, x * p);
          O.FromArray(m, x * p).subtractToRef(E, f), d[x * 3] = f.x, d[x * 3 + 1] = f.y, d[x * 3 + 2] = f.z;
        } else if (p === 4) {
          const E = new ae(), C = ae.FromArray(_, x * p);
          ae.FromArray(m, x * p).subtractToRef(C, E), d[x * 4] = E.x, d[x * 4 + 1] = E.y, d[x * 4 + 2] = E.z, d[x * 4 + 3] = E.w;
        } else
          N.Warn(`Unsupported number of components for color attribute: ${p}`);
      const w = t.createBufferView(d, h * p), y = t.createAccessor(w, p === 3 ? "VEC3" : "VEC4", 5126, l, 0);
      n.push(y), r.attributes.COLOR_0 = n.length - 1;
    } else
      N.Warn(`Morph target colors for mesh ${e.name} were not exported. Mesh does not have colors vertex data`);
  }
  return r;
}
class he {
  constructor(e, t) {
    this._indicesAccessorMap = /* @__PURE__ */ new Map(), this._vertexBufferViewMap = /* @__PURE__ */ new Map(), this._vertexAccessorMap = /* @__PURE__ */ new Map(), this._remappedBufferView = /* @__PURE__ */ new Map(), this._meshMorphTargetMap = /* @__PURE__ */ new Map(), this._vertexMapColorAlpha = /* @__PURE__ */ new Map(), this._exportedNodes = /* @__PURE__ */ new Set(), this._meshMap = /* @__PURE__ */ new Map(), this.convertedToRightHandedBuffers = /* @__PURE__ */ new Map(), this.convertToRightHanded = e, this.wasAddedByNoopNode = t;
  }
  getIndicesAccessor(e, t, s, n, i) {
    return this._indicesAccessorMap.get(e)?.get(t)?.get(s)?.get(n)?.get(i);
  }
  setIndicesAccessor(e, t, s, n, i, r) {
    let o = this._indicesAccessorMap.get(e);
    o || (o = /* @__PURE__ */ new Map(), this._indicesAccessorMap.set(e, o));
    let c = o.get(t);
    c || (c = /* @__PURE__ */ new Map(), o.set(t, c));
    let h = c.get(s);
    h || (h = /* @__PURE__ */ new Map(), c.set(s, h));
    let f = h.get(n);
    f || (f = /* @__PURE__ */ new Map(), h.set(n, f)), f.set(i, r);
  }
  pushExportedNode(e) {
    this._exportedNodes.has(e) || this._exportedNodes.add(e);
  }
  getNodesSet() {
    return this._exportedNodes;
  }
  getVertexBufferView(e) {
    return this._vertexBufferViewMap.get(e);
  }
  setVertexBufferView(e, t) {
    this._vertexBufferViewMap.set(e, t);
  }
  setRemappedBufferView(e, t, s) {
    this._remappedBufferView.set(e, /* @__PURE__ */ new Map()), this._remappedBufferView.get(e).set(t, s);
  }
  getRemappedBufferView(e, t) {
    return this._remappedBufferView.get(e)?.get(t);
  }
  getVertexAccessor(e, t, s) {
    return this._vertexAccessorMap.get(e)?.get(t)?.get(s);
  }
  setVertexAccessor(e, t, s, n) {
    let i = this._vertexAccessorMap.get(e);
    i || (i = /* @__PURE__ */ new Map(), this._vertexAccessorMap.set(e, i));
    let r = i.get(t);
    r || (r = /* @__PURE__ */ new Map(), i.set(t, r)), r.set(s, n);
  }
  hasVertexColorAlpha(e) {
    return this._vertexMapColorAlpha.get(e) || !1;
  }
  setHasVertexColorAlpha(e, t) {
    return this._vertexMapColorAlpha.set(e, t);
  }
  getMesh(e) {
    return this._meshMap.get(e);
  }
  setMesh(e, t) {
    this._meshMap.set(e, t);
  }
  bindMorphDataToMesh(e, t) {
    const s = this._meshMorphTargetMap.get(e) || [];
    this._meshMorphTargetMap.set(e, s), s.indexOf(t) === -1 && s.push(t);
  }
  getMorphTargetsFromMesh(e) {
    return this._meshMorphTargetMap.get(e);
  }
}
class R {
  // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async
  _ApplyExtension(e, t, s, n) {
    if (s >= t.length)
      return Promise.resolve(e);
    const i = n(t[s], e);
    return i ? i.then(async (r) => r ? await this._ApplyExtension(r, t, s + 1, n) : null) : this._ApplyExtension(e, t, s + 1, n);
  }
  // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async
  _ApplyExtensions(e, t) {
    const s = [];
    for (const n of R._ExtensionNames)
      s.push(this._extensions[n]);
    return this._ApplyExtension(e, s, 0, t);
  }
  // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async
  _extensionsPostExportNodeAsync(e, t, s, n, i) {
    return this._ApplyExtensions(
      t,
      // eslint-disable-next-line @typescript-eslint/promise-function-async
      (r, o) => r.postExportNodeAsync && r.postExportNodeAsync(e, o, s, n, i, this._bufferManager)
    );
  }
  // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async
  _extensionsPostExportMaterialAsync(e, t, s) {
    return this._ApplyExtensions(t, (n, i) => n.postExportMaterialAsync && n.postExportMaterialAsync(e, i, s));
  }
  /**
   * Get additional textures for a material
   * @param context The context when loading the asset
   * @param material The glTF material
   * @param babylonMaterial The Babylon.js material
   * @returns List of additional textures
   */
  async _extensionsPostExportMaterialAdditionalTexturesAsync(e, t, s) {
    const n = [];
    return await Promise.all(R._ExtensionNames.map(async (i) => {
      const r = this._extensions[i];
      if (r.postExportMaterialAdditionalTexturesAsync) {
        const o = await r.postExportMaterialAdditionalTexturesAsync(e, t, s);
        n.push(...o);
      }
    })), n;
  }
  _extensionsPostExportTextures(e, t, s) {
    for (const n of R._ExtensionNames) {
      const i = this._extensions[n];
      i.postExportTexture && i.postExportTexture(e, t, s);
    }
  }
  _extensionsPostExportMeshPrimitive(e) {
    for (const t of R._ExtensionNames) {
      const s = this._extensions[t];
      s.postExportMeshPrimitive && s.postExportMeshPrimitive(e, this._bufferManager, this._accessors);
    }
  }
  async _extensionsPreGenerateBinaryAsync() {
    for (const e of R._ExtensionNames) {
      const t = this._extensions[e];
      t.preGenerateBinaryAsync && await t.preGenerateBinaryAsync(this._bufferManager);
    }
  }
  _forEachExtensions(e) {
    for (const t of R._ExtensionNames) {
      const s = this._extensions[t];
      s.enabled && e(s);
    }
  }
  _extensionsOnExporting() {
    this._forEachExtensions((e) => {
      var t, s, n;
      e.wasUsed && ((t = this._glTF).extensionsUsed || (t.extensionsUsed = []), this._glTF.extensionsUsed.indexOf(e.name) === -1 && this._glTF.extensionsUsed.push(e.name), e.required && ((s = this._glTF).extensionsRequired || (s.extensionsRequired = []), this._glTF.extensionsRequired.indexOf(e.name) === -1 && this._glTF.extensionsRequired.push(e.name)), (n = this._glTF).extensions || (n.extensions = {}), e.onExporting && e.onExporting());
    });
  }
  _loadExtensions() {
    for (const e of R._ExtensionNames) {
      const t = R._ExtensionFactories[e](this);
      this._extensions[e] = t;
    }
  }
  constructor(e = Ke.LastCreatedScene, t) {
    if (this._glTF = {
      asset: { generator: `Babylon.js v${Pe.Version}`, version: "2.0" }
    }, this._animations = [], this._accessors = [], this._bufferViews = [], this._cameras = [], this._images = [], this._materials = [], this._meshes = [], this._nodes = [], this._samplers = [], this._scenes = [], this._skins = [], this._textures = [], this._imageData = {}, this._shouldUseGlb = !1, this._materialExporter = new be(this), this._extensions = {}, this._bufferManager = new dt(), this._shouldExportNodeMap = /* @__PURE__ */ new Map(), this._nodeMap = /* @__PURE__ */ new Map(), this._materialMap = /* @__PURE__ */ new Map(), this._camerasMap = /* @__PURE__ */ new Map(), this._nodesCameraMap = /* @__PURE__ */ new Map(), this._skinMap = /* @__PURE__ */ new Map(), this._nodesSkinMap = /* @__PURE__ */ new Map(), this._materialNeedsUVsSet = /* @__PURE__ */ new Set(), !e)
      throw new Error("No scene available to export");
    this._babylonScene = e, this._options = {
      shouldExportNode: () => !0,
      shouldExportAnimation: () => !0,
      metadataSelector: (s) => s?.gltf?.extras,
      animationSampleRate: 1 / 60,
      exportWithoutWaitingForScene: !1,
      exportUnusedUVs: !1,
      removeNoopRootNodes: !0,
      includeCoordinateSystemConversionNodes: !1,
      meshCompressionMethod: "None",
      ...t
    }, this._loadExtensions();
  }
  dispose() {
    for (const e in this._extensions)
      this._extensions[e].dispose();
  }
  get options() {
    return this._options;
  }
  static RegisterExtension(e, t, s = 100) {
    R.UnregisterExtension(e) && N.Warn(`Extension with the name ${e} already exists`), R._ExtensionFactories[e] = t;
    const n = s ?? 0;
    R._ExtensionOrders[e] = n;
    let i = R._ExtensionNames.length;
    for (let r = 0; r < R._ExtensionNames.length; r++) {
      const o = R._ExtensionNames[r], c = R._ExtensionOrders[o];
      if (n < c) {
        i = r;
        break;
      }
    }
    R._ExtensionNames.splice(i, 0, e);
  }
  static UnregisterExtension(e) {
    if (!R._ExtensionFactories[e])
      return !1;
    delete R._ExtensionFactories[e], delete R._ExtensionOrders[e];
    const t = R._ExtensionNames.indexOf(e);
    return t !== -1 && R._ExtensionNames.splice(t, 1), !0;
  }
  _generateJSON(e, t, s) {
    const n = { byteLength: e };
    return n.byteLength && (this._glTF.buffers = [n]), this._nodes && this._nodes.length && (this._glTF.nodes = this._nodes), this._meshes && this._meshes.length && (this._glTF.meshes = this._meshes), this._scenes && this._scenes.length && (this._glTF.scenes = this._scenes, this._glTF.scene = 0), this._cameras && this._cameras.length && (this._glTF.cameras = this._cameras), this._bufferViews && this._bufferViews.length && (this._glTF.bufferViews = this._bufferViews), this._accessors && this._accessors.length && (this._glTF.accessors = this._accessors), this._animations && this._animations.length && (this._glTF.animations = this._animations), this._materials && this._materials.length && (this._glTF.materials = this._materials), this._textures && this._textures.length && (this._glTF.textures = this._textures), this._samplers && this._samplers.length && (this._glTF.samplers = this._samplers), this._skins && this._skins.length && (this._glTF.skins = this._skins), this._images && this._images.length && (this._glTF.images = this._images), this._shouldUseGlb || (n.uri = t + ".bin"), s ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
  }
  async generateGLTFAsync(e) {
    const t = await this._generateBinaryAsync();
    this._extensionsOnExporting();
    const s = this._generateJSON(t.byteLength, e, !0), n = new Blob([t], { type: "application/octet-stream" }), i = e + ".gltf", r = e + ".bin", o = new Ie();
    if (o.files[i] = s, o.files[r] = n, this._imageData)
      for (const c in this._imageData)
        o.files[c] = this._imageData[c];
    return o;
  }
  async _generateBinaryAsync() {
    return await this._exportSceneAsync(), await this._extensionsPreGenerateBinaryAsync(), this._bufferManager.generateBinary(this._bufferViews);
  }
  /**
   * Pads the number to a multiple of 4
   * @param num number to pad
   * @returns padded number
   */
  _getPadding(e) {
    const t = e % 4;
    return t === 0 ? t : 4 - t;
  }
  async generateGLBAsync(e) {
    this._shouldUseGlb = !0;
    const t = await this._generateBinaryAsync();
    this._extensionsOnExporting();
    const s = this._generateJSON(t.byteLength), n = e + ".glb", i = 12, r = 8;
    let o = s.length, c;
    typeof TextEncoder < "u" && (c = new TextEncoder().encode(s), o = c.length);
    const h = this._getPadding(o), f = this._getPadding(t.byteLength), u = i + 2 * r + o + h + t.byteLength + f, l = new ve(u);
    if (l.writeUInt32(1179937895), l.writeUInt32(2), l.writeUInt32(u), l.writeUInt32(o + h), l.writeUInt32(1313821514), c)
      l.writeTypedArray(c);
    else
      for (let g = 0; g < o; ++g) {
        const p = s.charCodeAt(g);
        p != s.codePointAt(g) ? l.writeUInt8(95) : l.writeUInt8(p);
      }
    for (let _ = 0; _ < h; ++_)
      l.writeUInt8(32);
    l.writeUInt32(t.byteLength + f), l.writeUInt32(5130562), l.writeTypedArray(t);
    for (let _ = 0; _ < f; ++_)
      l.writeUInt8(0);
    const m = new Ie();
    return m.files[n] = new Blob([l.getOutputData()], { type: "application/octet-stream" }), m;
  }
  _setNodeTransformation(e, t, s) {
    if (t.getPivotPoint().equalsWithEpsilon(se, K) || N.Warn("Pivot points are not supported in the glTF serializer"), !t.position.equalsWithEpsilon(se, K)) {
      const i = P.Vector3[0].copyFrom(t.position);
      s && de(i), e.translation = i.asArray();
    }
    t.scaling.equalsWithEpsilon(ie, K) || (e.scale = t.scaling.asArray());
    const n = t.rotationQuaternion?.clone() || W.FromEulerAngles(t.rotation.x, t.rotation.y, t.rotation.z);
    n.equalsWithEpsilon(me, K) || (s && ge(n), e.rotation = n.normalize().asArray());
  }
  _setCameraTransformation(e, t, s) {
    const n = P.Vector3[0], i = P.Quaternion[0], r = t.getWorldMatrix();
    if (t.parent) {
      const o = t.parent.getWorldMatrix().invertToRef(P.Matrix[0]);
      r.multiplyToRef(o, P.Matrix[1]).decompose(void 0, i, n);
    } else
      r.decompose(void 0, i, n);
    n.equalsWithEpsilon(se, K) || (s && de(n), e.translation = n.asArray()), s && ge(i), this._babylonScene.useRightHandedSystem || Fe(i), i.equalsWithEpsilon(me, K) || (e.rotation = i.asArray());
  }
  // Export babylon cameras to glTF cameras
  _listAvailableCameras() {
    for (const e of this._babylonScene.cameras) {
      const t = {
        type: e.mode === ne.PERSPECTIVE_CAMERA ? "perspective" : "orthographic"
      };
      if (e.name && (t.name = e.name), t.type === "perspective")
        t.perspective = {
          aspectRatio: e.getEngine().getAspectRatio(e),
          yfov: e.fovMode === ne.FOVMODE_VERTICAL_FIXED ? e.fov : e.fov * e.getEngine().getAspectRatio(e),
          znear: e.minZ,
          zfar: e.maxZ
        };
      else if (t.type === "orthographic") {
        const s = e.orthoLeft && e.orthoRight ? 0.5 * (e.orthoRight - e.orthoLeft) : e.getEngine().getRenderWidth() * 0.5, n = e.orthoBottom && e.orthoTop ? 0.5 * (e.orthoTop - e.orthoBottom) : e.getEngine().getRenderHeight() * 0.5;
        t.orthographic = {
          xmag: s,
          ymag: n,
          znear: e.minZ,
          zfar: e.maxZ
        };
      }
      this._camerasMap.set(e, t);
    }
  }
  // Cleanup unused cameras and assign index to nodes.
  _exportAndAssignCameras() {
    const e = Array.from(this._camerasMap.values());
    for (const t of e) {
      const s = this._nodesCameraMap.get(t);
      if (s !== void 0) {
        this._cameras.push(t);
        for (const n of s)
          n.camera = this._cameras.length - 1;
      }
    }
  }
  // Collects all skins in a skins map so nodes can reference it during node parsing.
  _listAvailableSkeletons() {
    for (const e of this._babylonScene.skeletons) {
      if (e.bones.length <= 0)
        continue;
      const t = { joints: [] };
      this._skinMap.set(e, t);
    }
  }
  _exportAndAssignSkeletons(e) {
    for (const t of this._babylonScene.skeletons) {
      if (t.bones.length <= 0)
        continue;
      const s = this._skinMap.get(t);
      if (s == null)
        continue;
      const n = {};
      let i = -1;
      for (let c = 0; c < t.bones.length; ++c) {
        const h = t.bones[c], f = h.getIndex() ?? c;
        f !== -1 && (n[f] = h, f > i && (i = f));
      }
      const r = [];
      for (let c = 0; c <= i; ++c) {
        const h = n[c], f = h.getTransformNode(), u = f ? this._nodeMap.get(f) : void 0;
        if (u === void 0) {
          N.Warn("Exporting a bone without a linked transform node is currently unsupported.");
          continue;
        }
        s.joints.push(u);
        const l = h.getAbsoluteInverseBindMatrix().clone();
        e.has(f) && ct(l), r.push(l);
      }
      const o = this._nodesSkinMap.get(s);
      if (s.joints.length > 0 && o !== void 0) {
        const c = new Float32Array(r.length * 16);
        r.forEach((u, l) => {
          c.set(u.m, l * 16);
        });
        const h = this._bufferManager.createBufferView(c);
        this._accessors.push(this._bufferManager.createAccessor(h, "MAT4", 5126, r.length)), s.inverseBindMatrices = this._accessors.length - 1, this._skins.push(s);
        const f = this._skins.length - 1;
        for (const u of o)
          u.skin = f;
      }
    }
  }
  async _exportSceneAsync() {
    const e = { nodes: [] };
    if (this._babylonScene.metadata) {
      const h = this._options.metadataSelector(this._babylonScene.metadata);
      h && (e.extras = h);
    }
    const t = new Array(), s = new Array(), n = new Array();
    let i;
    if (this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes)
      for (const h of this._babylonScene.animationGroups)
        for (const f of h.targetedAnimations) {
          const u = f.target;
          u instanceof Z && !u.parent && (i ?? (i = /* @__PURE__ */ new Set())).add(u);
        }
    for (const h of this._babylonScene.rootNodes) {
      const f = h.animations, u = !!f && f.length > 0 || i?.has(h);
      this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes && et(h, this._babylonScene.useRightHandedSystem) && !u ? n.push(...h.getChildren()) : this._babylonScene.useRightHandedSystem ? t.push(h) : s.push(h);
    }
    this._listAvailableCameras(), this._listAvailableSkeletons();
    const r = new he(!0, !1);
    e.nodes.push(...await this._exportNodesAsync(s, r));
    const o = new he(!1, !1);
    e.nodes.push(...await this._exportNodesAsync(t, o));
    const c = new he(!1, !0);
    e.nodes.push(...await this._exportNodesAsync(n, c)), e.nodes.length && this._scenes.push(e), this._exportAndAssignCameras(), this._exportAndAssignSkeletons(r.getNodesSet()), this._babylonScene.animationGroups.length && V._CreateNodeAndMorphAnimationFromAnimationGroups(this._babylonScene, this._animations, this._nodeMap, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, r.getNodesSet(), this._options.shouldExportAnimation);
  }
  _shouldExportNode(e) {
    let t = this._shouldExportNodeMap.get(e);
    return t === void 0 && (t = this._options.shouldExportNode(e), this._shouldExportNodeMap.set(e, t)), t;
  }
  async _exportNodesAsync(e, t) {
    const s = new Array();
    this._exportBuffers(e, t);
    for (const n of e)
      await this._exportNodeAsync(n, s, t);
    return s;
  }
  _collectBuffers(e, t, s, n, i) {
    if (this._shouldExportNode(e) && e instanceof ue && e.geometry) {
      const r = e.geometry.getVertexBuffers();
      if (r)
        for (const c in r) {
          if (!Se(c))
            continue;
          const h = r[c];
          i.setHasVertexColorAlpha(h, e.hasVertexAlpha);
          const f = h._buffer, u = t.get(f) || [];
          t.set(f, u), u.indexOf(h) === -1 && u.push(h);
          const l = s.get(h) || [];
          s.set(h, l), l.indexOf(e) === -1 && l.push(e);
        }
      const o = e.morphTargetManager;
      if (o)
        for (let c = 0; c < o.numTargets; c++) {
          const h = o.getTarget(c), f = n.get(h) || [];
          n.set(h, f), f.indexOf(e) === -1 && f.push(e);
        }
    }
    for (const r of e.getChildren())
      this._collectBuffers(r, t, s, n, i);
  }
  _exportBuffers(e, t) {
    const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
    for (const c of e)
      this._collectBuffers(c, s, n, i, t);
    const r = Array.from(s.keys());
    for (const c of r) {
      const h = c.getData();
      if (!h)
        throw new Error("Buffer data is not available");
      const f = s.get(c);
      if (!f)
        continue;
      const u = f[0].byteStride;
      if (f.some((p) => p.byteStride !== u))
        throw new Error("Vertex buffers pointing to the same buffer must have the same byte stride");
      const l = ut(h).slice();
      for (const p of f) {
        const d = n.get(p), { byteOffset: w, byteStride: y, componentCount: x, type: E, count: C, normalized: S, kind: I } = fe(p, d);
        switch (I) {
          case A.NormalKind:
          case A.TangentKind: {
            te(l, w, y, x, E, C, S, (M) => {
              const T = Math.sqrt(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]);
              if (T > 0) {
                const U = 1 / T;
                M[0] *= U, M[1] *= U, M[2] *= U;
              }
            });
            break;
          }
          case A.ColorKind: {
            const M = d.filter((F) => F.material instanceof ye || F.material == null).length;
            if (M == 0)
              break;
            if (M != d.length) {
              J.Warn("Not converting vertex color space, as buffer is shared by StandardMaterials and other material types. Results may look incorrect.");
              break;
            }
            E == A.UNSIGNED_BYTE && J.Warn("Converting uint8 vertex colors to linear space. Results may look incorrect.");
            const T = new z(), U = new ze(), B = this._babylonScene.getEngine().useExactSrgbConversions;
            te(l, w, y, x, E, C, S, (F) => {
              F.length === 3 ? (T.fromArray(F, 0), T.toLinearSpaceToRef(T, B), T.toArray(F, 0)) : (U.fromArray(F, 0), U.toLinearSpaceToRef(U, B), U.toArray(F, 0));
            });
          }
        }
      }
      if (t.convertToRightHanded) {
        for (const p of f) {
          const d = n.get(p), { byteOffset: w, byteStride: y, componentCount: x, type: E, count: C, normalized: S, kind: I } = fe(p, d);
          switch (I) {
            case A.PositionKind:
            case A.NormalKind:
            case A.TangentKind:
              te(l, w, y, x, E, C, S, (M) => {
                M[0] = -M[0];
              });
          }
        }
        t.convertedToRightHandedBuffers.set(c, l);
      }
      const m = this._bufferManager.createBufferView(l, u);
      t.setVertexBufferView(c, m);
      const _ = /* @__PURE__ */ new Map();
      for (const p of f) {
        const d = n.get(p), { kind: w, totalVertices: y } = fe(p, d);
        switch (w) {
          case A.MatricesIndicesKind:
          case A.MatricesIndicesExtraKind:
            if (p.type == A.FLOAT) {
              const x = p.getFloatData(y);
              x !== null && _.set(p, x);
            }
        }
      }
      _.size !== 0 && J.Warn("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.");
      const g = Array.from(_.keys());
      for (const p of g) {
        const d = _.get(p);
        if (!d)
          continue;
        const w = nt(d), y = new (w ? Uint16Array : Uint8Array)(d.length);
        for (let E = 0; E < d.length; E++)
          y[E] = d[E];
        const x = this._bufferManager.createBufferView(y, 4 * (w ? 2 : 1));
        t.setRemappedBufferView(c, p, x);
      }
    }
    const o = Array.from(i.keys());
    for (const c of o) {
      const h = i.get(c);
      if (!h)
        continue;
      const f = gt(c, h[0], this._bufferManager, this._bufferViews, this._accessors, t.convertToRightHanded);
      for (const u of h)
        t.bindMorphDataToMesh(u, f);
    }
  }
  /**
   * Processes a node to be exported to the glTF file
   * @returns A promise that resolves once the node has been exported
   * @internal
   */
  async _exportNodeAsync(e, t, s) {
    let n = this._nodeMap.get(e);
    if (n !== void 0) {
      t.includes(n) || t.push(n);
      return;
    }
    const i = await this._createNodeAsync(e, s);
    if (i) {
      n = this._nodes.length, this._nodes.push(i), this._nodeMap.set(e, n), s.pushExportedNode(e), t.push(n);
      const o = {
        name: "runtime animations",
        channels: [],
        samplers: []
      }, c = [];
      this._babylonScene.animationGroups.length || (V._CreateMorphTargetAnimationFromMorphTargetAnimations(e, o, c, this._nodeMap, this._nodes, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, s.convertToRightHanded, this._options.shouldExportAnimation), e.animations.length && V._CreateNodeAnimationFromNodeAnimations(e, o, c, this._nodeMap, this._nodes, this._bufferManager, this._bufferViews, this._accessors, this._animationSampleRate, s.convertToRightHanded, this._options.shouldExportAnimation)), o.channels.length && o.samplers.length && this._animations.push(o), c.forEach((h) => {
        h.channels.length && h.samplers.length && this._animations.push(h);
      });
    }
    const r = i ? [] : t;
    for (const o of e.getChildren())
      await this._exportNodeAsync(o, r, s);
    i && r.length && (i.children = r);
  }
  /**
   * Creates a glTF node from a Babylon.js node. If skipped, returns null.
   * @internal
   */
  async _createNodeAsync(e, t) {
    if (!this._shouldExportNode(e))
      return null;
    const s = {};
    if (e.name && (s.name = e.name), e.metadata) {
      const i = this._options.metadataSelector(e.metadata);
      i && (s.extras = i);
    }
    if (e instanceof Z && (this._setNodeTransformation(s, e, t.convertToRightHanded), e instanceof ue)) {
      const i = e instanceof qe ? e.sourceMesh : e;
      if (i.subMeshes && i.subMeshes.length > 0 && (s.mesh = await this._exportMeshAsync(i, t)), e.skeleton) {
        const r = this._skinMap.get(e.skeleton);
        r !== void 0 && (this._nodesSkinMap.get(r) === void 0 && this._nodesSkinMap.set(r, []), this._nodesSkinMap.get(r)?.push(s));
      }
    }
    if (e instanceof Ne) {
      const i = this._camerasMap.get(e);
      if (i) {
        this._nodesCameraMap.get(i) === void 0 && this._nodesCameraMap.set(i, []), this._setCameraTransformation(s, e, t.convertToRightHanded);
        const r = e.parent;
        if (r !== null && ht(e, r)) {
          const o = this._nodeMap.get(r);
          if (o !== void 0) {
            const c = this._nodes[o];
            return ft(s, c), this._nodesCameraMap.get(i)?.push(c), null;
          }
        }
        this._nodesCameraMap.get(i)?.push(s);
      }
    }
    return await this._extensionsPostExportNodeAsync("exportNodeAsync", s, e, this._nodeMap, t.convertToRightHanded) ? s : (J.Warn(`Not exporting node ${e.name}`), null);
  }
  _exportIndices(e, t, s, n, i, r, o, c, h) {
    let f = null;
    h.mode = ot(r);
    const u = o !== k.CounterClockWiseSideOrientation && at(r);
    if (u) {
      if (r === k.TriangleStripDrawMode || r === k.TriangleFanDrawMode)
        throw new Error("Triangle strip/fan fill mode is not implemented");
      const l = t ? new Uint32Array(n) : new Uint16Array(n);
      if (e)
        for (let m = 0; m + 2 < n; m += 3)
          l[m] = e[s + m] + i, l[m + 1] = e[s + m + 2] + i, l[m + 2] = e[s + m + 1] + i;
      else
        for (let m = 0; m + 2 < n; m += 3)
          l[m] = m, l[m + 1] = m + 2, l[m + 2] = m + 1;
      f = l;
    } else if (e && i !== 0) {
      const l = t ? new Uint32Array(n) : new Uint16Array(n);
      for (let m = 0; m < n; m++)
        l[m] = e[s + m] + i;
      f = l;
    } else e && (f = lt(e, s, n, t));
    if (f) {
      let l = c.getIndicesAccessor(e, s, n, i, u);
      if (l === void 0) {
        const m = this._bufferManager.createBufferView(f), _ = t ? 5125 : 5123;
        this._accessors.push(this._bufferManager.createAccessor(m, "SCALAR", _, n, 0)), l = this._accessors.length - 1, c.setIndicesAccessor(e, s, n, i, u, l);
      }
      h.indices = l;
    }
  }
  _exportVertexBuffer(e, t, s, n, i, r) {
    const o = e.getKind();
    if (!Se(o) || o.startsWith("uv") && !this._options.exportUnusedUVs && (!t || !this._materialNeedsUVsSet.has(t)))
      return;
    let c = i.getVertexAccessor(e, s, n);
    if (c === void 0) {
      const h = i.convertedToRightHandedBuffers.get(e._buffer) || e._buffer.getData(), f = o === A.PositionKind ? pt(h, e, s, n) : void 0, u = (o === A.MatricesIndicesKind || o === A.MatricesIndicesExtraKind) && e.type === A.FLOAT, l = u ? A.UNSIGNED_BYTE : e.type, m = u ? void 0 : e.normalized, _ = u ? i.getRemappedBufferView(e._buffer, e) : i.getVertexBufferView(e._buffer), g = e.byteOffset + s * e.byteStride;
      this._accessors.push(this._bufferManager.createAccessor(
        _,
        it(o, i.hasVertexColorAlpha(e)),
        l,
        n,
        g,
        f,
        m
        // TODO: Find other places where this is needed.
      )), c = this._accessors.length - 1, i.setVertexAccessor(e, s, n, c);
    }
    r.attributes[rt(o)] = c;
  }
  async _exportMaterialAsync(e, t, s, n) {
    let i = this._materialMap.get(e);
    if (i === void 0) {
      const r = t && Object.keys(t).some((o) => o.startsWith("uv"));
      if (e = e instanceof Ge ? e.subMaterials[s.materialIndex] : e, e instanceof Y)
        i = await this._materialExporter.exportPBRMaterialAsync(e, r);
      else if (e instanceof ye)
        i = await this._materialExporter.exportStandardMaterialAsync(e, r);
      else if (e instanceof le)
        i = await this._materialExporter.exportOpenPBRMaterialAsync(e, r);
      else {
        J.Warn(`Unsupported material '${e.name}' with type ${e.getClassName()}`);
        return;
      }
      this._materialMap.set(e, i);
    }
    n.material = i;
  }
  async _exportMeshAsync(e, t) {
    let s = t.getMesh(e);
    if (s !== void 0)
      return s;
    const n = { primitives: [] };
    s = this._meshes.length, this._meshes.push(n), t.setMesh(e, s);
    const i = e.isUnIndexed ? null : e.getIndices(), r = e.geometry?.getVertexBuffers(), o = t.getMorphTargetsFromMesh(e), c = e instanceof He, h = e instanceof je, f = e.subMeshes;
    if (r && f && f.length > 0)
      for (const u of f) {
        const l = { attributes: {} }, m = u.getMaterial() || this._babylonScene.defaultMaterial;
        if (h) {
          const p = {
            name: m.name
          }, d = e, w = z.White(), y = d.material?.alpha ?? 1, x = d.greasedLineMaterial?.color ?? w;
          (!x.equalsWithEpsilon(w, K) || y < 1) && (p.pbrMetallicRoughness = {
            baseColorFactor: [...x.asArray(), y]
          }), this._materials.push(p), l.material = this._materials.length - 1;
        } else if (c) {
          const p = {
            name: m.name
          }, d = e;
          (!d.color.equalsWithEpsilon(z.White(), K) || d.alpha < 1) && (p.pbrMetallicRoughness = {
            baseColorFactor: [...d.color.asArray(), d.alpha]
          }), this._materials.push(p), l.material = this._materials.length - 1;
        } else
          await this._exportMaterialAsync(m, r, u, l);
        const _ = c || h ? k.LineListDrawMode : e.overrideRenderingFillMode ?? m.fillMode;
        let g = m._getEffectiveOrientation(e);
        t.wasAddedByNoopNode && !e.getScene().useRightHandedSystem && (g = g === k.ClockWiseSideOrientation ? k.CounterClockWiseSideOrientation : k.ClockWiseSideOrientation), this._exportIndices(i, i ? $e(i, u.indexCount, u.indexStart, u.verticesStart) : u.verticesCount > 65535, i ? u.indexStart : u.verticesStart, i ? u.indexCount : u.verticesCount, -u.verticesStart, _, g, t, l);
        for (const p of Object.values(r))
          this._exportVertexBuffer(p, m, u.verticesStart, u.verticesCount, t, l);
        if (o) {
          l.targets = [];
          for (const p of o)
            l.targets.push(p.attributes);
        }
        n.primitives.push(l), this._extensionsPostExportMeshPrimitive(l);
      }
    if (o) {
      n.weights = [], n.extras || (n.extras = {}), n.extras.targetNames = [];
      for (const u of o)
        n.weights.push(u.influence), n.extras.targetNames.push(u.name);
    }
    return s;
  }
}
R._ExtensionNames = new Array();
R._ExtensionFactories = {};
R._ExtensionOrders = {};
class xt {
  /**
   * Exports the scene to .gltf file format
   * @param scene Babylon scene
   * @param fileName Name to use for the .gltf file
   * @param options Exporter options
   * @returns Returns the exported data
   */
  static async GLTFAsync(e, t, s) {
    (!s || !s.exportWithoutWaitingForScene) && await e.whenReadyAsync();
    const n = new R(e, s), i = await n.generateGLTFAsync(t.replace(/\.[^/.]+$/, ""));
    return n.dispose(), i;
  }
  /**
   * Exports the scene to .glb file format
   * @param scene Babylon scene
   * @param fileName Name to use for the .glb file
   * @param options Exporter options
   * @returns Returns the exported data
   */
  static async GLBAsync(e, t, s) {
    (!s || !s.exportWithoutWaitingForScene) && await e.whenReadyAsync();
    const n = new R(e, s), i = await n.generateGLBAsync(t.replace(/\.[^/.]+$/, ""));
    return n.dispose(), i;
  }
}
export {
  xt as GLTF2Export
};