app
JST Connector Studio: manufacturer 3D mate editor
Public Unreviewedby John Lauer
Interactive Babylon 9.5 studio for JST wire-to-board connectors: load a system (PH/XH/SH/GH/ZH), see the JST manufacturer housing+wire+ds2sf footprint mate in a looping animation next to the KiCad hou
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
};