UNPKG

lingo3d-react

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

1,330 lines 69.2 kB
import { V as te, a as U, C as _e, E as b, L as Ke, b as We, F as Ye, T as $e, R as we, c as xe, d as Ie, M as Te, e as _, f as Q, g as Ze, h as I, G as Pe, B as Ae, P as ee, O as se, i as qe, j as He, k as Le, l as E, S as Qe, D as Ne, m as Je, n as et, o as tt, p as nt, q as rt, A as it, r as ae, s as K, U as st, t as at, u as ot, v as lt, Q as N, w as ct, N as pt, x as ut, y as ft, z as ht, H as mt } from "./index-895cfa2f.mjs"; import { p as dt, c as gt } from "./processChildren-cb5144fc.mjs"; import "react"; import "react-dom"; /*! fflate - fast JavaScript compression/decompression <https://101arrowz.github.io/fflate> Licensed under MIT. https://github.com/101arrowz/fflate/blob/master/LICENSE version 0.6.9 */ var De = function(c) { return URL.createObjectURL(new Blob([c], { type: "text/javascript" })); }; try { URL.revokeObjectURL(De("")); } catch { De = function(e) { return "data:application/javascript;charset=UTF-8," + encodeURI(e); }; } var M = Uint8Array, V = Uint16Array, ue = Uint32Array, Me = new M([ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0 ]), Se = new M([ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0 ]), yt = new M([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), Oe = function(c, e) { for (var t = new V(31), n = 0; n < 31; ++n) t[n] = e += 1 << c[n - 1]; for (var r = new ue(t[30]), n = 1; n < 30; ++n) for (var i = t[n]; i < t[n + 1]; ++i) r[i] = i - t[n] << 5 | n; return [t, r]; }, Ee = Oe(Me, 2), Be = Ee[0], vt = Ee[1]; Be[28] = 258, vt[258] = 28; var wt = Oe(Se, 0), xt = wt[0], fe = new V(32768); for (var w = 0; w < 32768; ++w) { var R = (w & 43690) >>> 1 | (w & 21845) << 1; R = (R & 52428) >>> 2 | (R & 13107) << 2, R = (R & 61680) >>> 4 | (R & 3855) << 4, fe[w] = ((R & 65280) >>> 8 | (R & 255) << 8) >>> 1; } var Z = function(c, e, t) { for (var n = c.length, r = 0, i = new V(e); r < n; ++r) ++i[c[r] - 1]; var s = new V(e); for (r = 0; r < e; ++r) s[r] = s[r - 1] + i[r - 1] << 1; var a; if (t) { a = new V(1 << e); var o = 15 - e; for (r = 0; r < n; ++r) if (c[r]) for (var p = r << 4 | c[r], u = e - c[r], l = s[c[r] - 1]++ << u, f = l | (1 << u) - 1; l <= f; ++l) a[fe[l] >>> o] = p; } else for (a = new V(n), r = 0; r < n; ++r) c[r] && (a[r] = fe[s[c[r] - 1]++] >>> 15 - c[r]); return a; }, q = new M(288); for (var w = 0; w < 144; ++w) q[w] = 8; for (var w = 144; w < 256; ++w) q[w] = 9; for (var w = 256; w < 280; ++w) q[w] = 7; for (var w = 280; w < 288; ++w) q[w] = 8; var Re = new M(32); for (var w = 0; w < 32; ++w) Re[w] = 5; var It = /* @__PURE__ */ Z(q, 9, 1), Tt = /* @__PURE__ */ Z(Re, 5, 1), oe = function(c) { for (var e = c[0], t = 1; t < c.length; ++t) c[t] > e && (e = c[t]); return e; }, O = function(c, e, t) { var n = e / 8 | 0; return (c[n] | c[n + 1] << 8) >> (e & 7) & t; }, le = function(c, e) { var t = e / 8 | 0; return (c[t] | c[t + 1] << 8 | c[t + 2] << 16) >> (e & 7); }, Pt = function(c) { return (c / 8 | 0) + (c & 7 && 1); }, At = function(c, e, t) { (e == null || e < 0) && (e = 0), (t == null || t > c.length) && (t = c.length); var n = new (c instanceof V ? V : c instanceof ue ? ue : M)(t - e); return n.set(c.subarray(e, t)), n; }, Lt = function(c, e, t) { var n = c.length; if (!n || t && !t.l && n < 5) return e || new M(0); var r = !e || t, i = !t || t.i; t || (t = {}), e || (e = new M(n * 3)); var s = function(ge) { var ye = e.length; if (ge > ye) { var ve = new M(Math.max(ye * 2, ge)); ve.set(e), e = ve; } }, a = t.f || 0, o = t.p || 0, p = t.b || 0, u = t.l, l = t.d, f = t.m, h = t.n, m = n * 8; do { if (!u) { t.f = a = O(c, o, 1); var d = O(c, o + 1, 3); if (o += 3, d) if (d == 1) u = It, l = Tt, f = 9, h = 5; else if (d == 2) { var y = O(c, o, 31) + 257, L = O(c, o + 10, 15) + 4, S = y + O(c, o + 5, 31) + 1; o += 14; for (var A = new M(S), C = new M(19), D = 0; D < L; ++D) C[yt[D]] = O(c, o + D * 3, 7); o += L * 3; for (var X = oe(C), F = (1 << X) - 1, Y = Z(C, X, 1), D = 0; D < S; ) { var j = Y[O(c, o, F)]; o += j & 15; var v = j >>> 4; if (v < 16) A[D++] = v; else { var G = 0, H = 0; for (v == 16 ? (H = 3 + O(c, o, 3), o += 2, G = A[D - 1]) : v == 17 ? (H = 3 + O(c, o, 7), o += 3) : v == 18 && (H = 11 + O(c, o, 127), o += 7); H--; ) A[D++] = G; } } var he = A.subarray(0, y), B = A.subarray(y); f = oe(he), h = oe(B), u = Z(he, f, 1), l = Z(B, h, 1); } else throw "invalid block type"; else { var v = Pt(o) + 4, P = c[v - 4] | c[v - 3] << 8, x = v + P; if (x > n) { if (i) throw "unexpected EOF"; break; } r && s(p + P), e.set(c.subarray(v, x), p), t.b = p += P, t.p = o = x * 8; continue; } if (o > m) { if (i) throw "unexpected EOF"; break; } } r && s(p + 131072); for (var Ge = (1 << f) - 1, ze = (1 << h) - 1, ne = o; ; ne = o) { var G = u[le(c, o) & Ge], z = G >>> 4; if (o += G & 15, o > m) { if (i) throw "unexpected EOF"; break; } if (!G) throw "invalid length/literal"; if (z < 256) e[p++] = z; else if (z == 256) { ne = o, u = null; break; } else { var me = z - 254; if (z > 264) { var D = z - 257, $ = Me[D]; me = O(c, o, (1 << $) - 1) + Be[D], o += $; } var re = l[le(c, o) & ze], ie = re >>> 4; if (!re) throw "invalid distance"; o += re & 15; var B = xt[ie]; if (ie > 3) { var $ = Se[ie]; B += le(c, o) & (1 << $) - 1, o += $; } if (o > m) { if (i) throw "unexpected EOF"; break; } r && s(p + 131072); for (var de = p + me; p < de; p += 4) e[p] = e[p - B], e[p + 1] = e[p + 1 - B], e[p + 2] = e[p + 2 - B], e[p + 3] = e[p + 3 - B]; p = de; } } t.l = u, t.p = ne, t.b = p, u && (a = 1, t.m = f, t.d = l, t.n = h); } while (!a); return p == e.length ? e : At(e, 0, p); }, Dt = /* @__PURE__ */ new M(0), Ft = function(c) { if ((c[0] & 15) != 8 || c[0] >>> 4 > 7 || (c[0] << 8 | c[1]) % 31) throw "invalid zlib data"; if (c[1] & 32) throw "invalid zlib data: preset dictionaries not supported"; }; function kt(c, e) { return Lt((Ft(c), c.subarray(2, -4)), e); } var Ct = typeof TextDecoder < "u" && /* @__PURE__ */ new TextDecoder(), Mt = 0; try { Ct.decode(Dt, { stream: !0 }), Mt = 1; } catch { } function be(c, e, t) { const n = t.length - c - 1; if (e >= t[n]) return n - 1; if (e <= t[c]) return c; let r = c, i = n, s = Math.floor((r + i) / 2); for (; e < t[s] || e >= t[s + 1]; ) e < t[s] ? i = s : r = s, s = Math.floor((r + i) / 2); return s; } function St(c, e, t, n) { const r = [], i = [], s = []; r[0] = 1; for (let a = 1; a <= t; ++a) { i[a] = e - n[c + 1 - a], s[a] = n[c + a] - e; let o = 0; for (let p = 0; p < a; ++p) { const u = s[p + 1], l = i[a - p], f = r[p] / (u + l); r[p] = o + u * f, o = l * f; } r[a] = o; } return r; } function Ot(c, e, t, n) { const r = be(c, n, e), i = St(r, n, c, e), s = new te(0, 0, 0, 0); for (let a = 0; a <= c; ++a) { const o = t[r - c + a], p = i[a], u = o.w * p; s.x += o.x * u, s.y += o.y * u, s.z += o.z * u, s.w += o.w * p; } return s; } function Et(c, e, t, n, r) { const i = []; for (let l = 0; l <= t; ++l) i[l] = 0; const s = []; for (let l = 0; l <= n; ++l) s[l] = i.slice(0); const a = []; for (let l = 0; l <= t; ++l) a[l] = i.slice(0); a[0][0] = 1; const o = i.slice(0), p = i.slice(0); for (let l = 1; l <= t; ++l) { o[l] = e - r[c + 1 - l], p[l] = r[c + l] - e; let f = 0; for (let h = 0; h < l; ++h) { const m = p[h + 1], d = o[l - h]; a[l][h] = m + d; const v = a[h][l - 1] / a[l][h]; a[h][l] = f + m * v, f = d * v; } a[l][l] = f; } for (let l = 0; l <= t; ++l) s[0][l] = a[l][t]; for (let l = 0; l <= t; ++l) { let f = 0, h = 1; const m = []; for (let d = 0; d <= t; ++d) m[d] = i.slice(0); m[0][0] = 1; for (let d = 1; d <= n; ++d) { let v = 0; const P = l - d, x = t - d; l >= d && (m[h][0] = m[f][0] / a[x + 1][P], v = m[h][0] * a[P][x]); const y = P >= -1 ? 1 : -P, L = l - 1 <= x ? d - 1 : t - l; for (let A = y; A <= L; ++A) m[h][A] = (m[f][A] - m[f][A - 1]) / a[x + 1][P + A], v += m[h][A] * a[P + A][x]; l <= x && (m[h][d] = -m[f][d - 1] / a[x + 1][l], v += m[h][d] * a[l][x]), s[d][l] = v; const S = f; f = h, h = S; } } let u = t; for (let l = 1; l <= n; ++l) { for (let f = 0; f <= t; ++f) s[l][f] *= u; u *= t - l; } return s; } function Bt(c, e, t, n, r) { const i = r < c ? r : c, s = [], a = be(c, n, e), o = Et(a, n, c, i, e), p = []; for (let u = 0; u < t.length; ++u) { const l = t[u].clone(), f = l.w; l.x *= f, l.y *= f, l.z *= f, p[u] = l; } for (let u = 0; u <= i; ++u) { const l = p[a - c].clone().multiplyScalar(o[u][0]); for (let f = 1; f <= c; ++f) l.add(p[a - c + f].clone().multiplyScalar(o[u][f])); s[u] = l; } for (let u = i + 1; u <= r + 1; ++u) s[u] = new te(0, 0, 0); return s; } function Rt(c, e) { let t = 1; for (let r = 2; r <= c; ++r) t *= r; let n = 1; for (let r = 2; r <= e; ++r) n *= r; for (let r = 2; r <= c - e; ++r) n *= r; return t / n; } function bt(c) { const e = c.length, t = [], n = []; for (let i = 0; i < e; ++i) { const s = c[i]; t[i] = new U(s.x, s.y, s.z), n[i] = s.w; } const r = []; for (let i = 0; i < e; ++i) { const s = t[i].clone(); for (let a = 1; a <= i; ++a) s.sub(r[i - a].clone().multiplyScalar(Rt(i, a) * n[a])); r[i] = s.divideScalar(n[0]); } return r; } function Vt(c, e, t, n, r) { const i = Bt(c, e, t, n, r); return bt(i); } class Ut extends _e { constructor(e, t, n, r, i) { super(), this.degree = e, this.knots = t, this.controlPoints = [], this.startKnot = r || 0, this.endKnot = i || this.knots.length - 1; for (let s = 0; s < n.length; ++s) { const a = n[s]; this.controlPoints[s] = new te(a.x, a.y, a.z, a.w); } } getPoint(e, t = new U()) { const n = t, r = this.knots[this.startKnot] + e * (this.knots[this.endKnot] - this.knots[this.startKnot]), i = Ot(this.degree, this.knots, this.controlPoints, r); return i.w !== 1 && i.divideScalar(i.w), n.set(i.x, i.y, i.z); } getTangent(e, t = new U()) { const n = t, r = this.knots[0] + e * (this.knots[this.knots.length - 1] - this.knots[0]), i = Vt(this.degree, this.knots, this.controlPoints, r, 1); return n.copy(i[1]).normalize(), n; } } let g, T, k; class Xt extends Ke { constructor(e) { super(e); } load(e, t, n, r) { const i = this, s = i.path === "" ? We.extractUrlBase(e) : i.path, a = new Ye(this.manager); a.setPath(i.path), a.setResponseType("arraybuffer"), a.setRequestHeader(i.requestHeader), a.setWithCredentials(i.withCredentials), a.load(e, function(o) { try { t(i.parse(o, s)); } catch (p) { r ? r(p) : console.error(p), i.manager.itemError(e); } }, n, r); } parse(e, t) { if (Wt(e)) g = new Kt().parse(e); else { const r = je(e); if (!Yt(r)) throw new Error("FBXLoader: Unknown format."); if (ke(r) < 7e3) throw new Error("FBXLoader: FBX version not supported, FileVersion: " + ke(r)); g = new _t().parse(r); } const n = new $e(this.manager).setPath(this.resourcePath || t).setCrossOrigin(this.crossOrigin); return new jt(n, this.manager).parse(g); } } class jt { constructor(e, t) { this.textureLoader = e, this.manager = t; } parse() { T = this.parseConnections(); const e = this.parseImages(), t = this.parseTextures(e), n = this.parseMaterials(t), r = this.parseDeformers(), i = new Gt().parse(r); return this.parseScene(r, i, n), k; } // Parses FBXTree.Connections which holds parent-child connections between objects (e.g. material -> texture, model->geometry ) // and details the connection type parseConnections() { const e = /* @__PURE__ */ new Map(); return "Connections" in g && g.Connections.connections.forEach(function(n) { const r = n[0], i = n[1], s = n[2]; e.has(r) || e.set(r, { parents: [], children: [] }); const a = { ID: i, relationship: s }; e.get(r).parents.push(a), e.has(i) || e.set(i, { parents: [], children: [] }); const o = { ID: r, relationship: s }; e.get(i).children.push(o); }), e; } // Parse FBXTree.Objects.Video for embedded image data // These images are connected to textures in FBXTree.Objects.Textures // via FBXTree.Connections. parseImages() { const e = {}, t = {}; if ("Video" in g.Objects) { const n = g.Objects.Video; for (const r in n) { const i = n[r], s = parseInt(r); if (e[s] = i.RelativeFilename || i.Filename, "Content" in i) { const a = i.Content instanceof ArrayBuffer && i.Content.byteLength > 0, o = typeof i.Content == "string" && i.Content !== ""; if (a || o) { const p = this.parseImage(n[r]); t[i.RelativeFilename || i.Filename] = p; } } } } for (const n in e) { const r = e[n]; t[r] !== void 0 ? e[n] = t[r] : e[n] = e[n].split("\\").pop(); } return e; } // Parse embedded image data in FBXTree.Video.Content parseImage(e) { const t = e.Content, n = e.RelativeFilename || e.Filename, r = n.slice(n.lastIndexOf(".") + 1).toLowerCase(); let i; switch (r) { case "bmp": i = "image/bmp"; break; case "jpg": case "jpeg": i = "image/jpeg"; break; case "png": i = "image/png"; break; case "tif": i = "image/tiff"; break; case "tga": this.manager.getHandler(".tga") === null && console.warn("FBXLoader: TGA loader not found, skipping ", n), i = "image/tga"; break; default: console.warn('FBXLoader: Image type "' + r + '" is not supported.'); return; } if (typeof t == "string") return "data:" + i + ";base64," + t; { const s = new Uint8Array(t); return window.URL.createObjectURL(new Blob([s], { type: i })); } } // Parse nodes in FBXTree.Objects.Texture // These contain details such as UV scaling, cropping, rotation etc and are connected // to images in FBXTree.Objects.Video parseTextures(e) { const t = /* @__PURE__ */ new Map(); if ("Texture" in g.Objects) { const n = g.Objects.Texture; for (const r in n) { const i = this.parseTexture(n[r], e); t.set(parseInt(r), i); } } return t; } // Parse individual node in FBXTree.Objects.Texture parseTexture(e, t) { const n = this.loadTexture(e, t); n.ID = e.id, n.name = e.attrName; const r = e.WrapModeU, i = e.WrapModeV, s = r !== void 0 ? r.value : 0, a = i !== void 0 ? i.value : 0; if (n.wrapS = s === 0 ? we : xe, n.wrapT = a === 0 ? we : xe, "Scaling" in e) { const o = e.Scaling.value; n.repeat.x = o[0], n.repeat.y = o[1]; } if ("Translation" in e) { const o = e.Translation.value; n.offset.x = o[0], n.offset.y = o[1]; } return n; } // load a texture specified as a blob or data URI, or via an external URL using TextureLoader loadTexture(e, t) { let n; const r = this.textureLoader.path, i = T.get(e.id).children; i !== void 0 && i.length > 0 && t[i[0].ID] !== void 0 && (n = t[i[0].ID], (n.indexOf("blob:") === 0 || n.indexOf("data:") === 0) && this.textureLoader.setPath(void 0)); let s; const a = e.FileName.slice(-3).toLowerCase(); if (a === "tga") { const o = this.manager.getHandler(".tga"); o === null ? (console.warn("FBXLoader: TGA loader not found, creating placeholder texture for", e.RelativeFilename), s = new Ie()) : (o.setPath(this.textureLoader.path), s = o.load(n)); } else a === "psd" ? (console.warn("FBXLoader: PSD textures are not supported, creating placeholder texture for", e.RelativeFilename), s = new Ie()) : s = this.textureLoader.load(n); return this.textureLoader.setPath(r), s; } // Parse nodes in FBXTree.Objects.Material parseMaterials(e) { const t = /* @__PURE__ */ new Map(); if ("Material" in g.Objects) { const n = g.Objects.Material; for (const r in n) { const i = this.parseMaterial(n[r], e); i !== null && t.set(parseInt(r), i); } } return t; } // Parse single node in FBXTree.Objects.Material // Materials are connected to texture maps in FBXTree.Objects.Textures // FBX format currently only supports Lambert and Phong shading models parseMaterial(e, t) { const n = e.id, r = e.attrName; let i = e.ShadingModel; if (typeof i == "object" && (i = i.value), !T.has(n)) return null; const s = this.parseParameters(e, t, n), a = new Te(); return a.setValues(s), a.name = r, a; } // Parse FBX material and return parameters suitable for a three.js material // Also parse the texture map and return any textures associated with the material parseParameters(e, t, n) { const r = {}; e.BumpFactor && (r.bumpScale = e.BumpFactor.value), e.Diffuse ? r.color = new _().fromArray(e.Diffuse.value) : e.DiffuseColor && (e.DiffuseColor.type === "Color" || e.DiffuseColor.type === "ColorRGB") && (r.color = new _().fromArray(e.DiffuseColor.value)), e.DisplacementFactor && (r.displacementScale = e.DisplacementFactor.value), e.Emissive ? r.emissive = new _().fromArray(e.Emissive.value) : e.EmissiveColor && (e.EmissiveColor.type === "Color" || e.EmissiveColor.type === "ColorRGB") && (r.emissive = new _().fromArray(e.EmissiveColor.value)), e.EmissiveFactor && (r.emissiveIntensity = parseFloat(e.EmissiveFactor.value)), e.Opacity && (r.opacity = parseFloat(e.Opacity.value)), r.opacity < 1 && (r.transparent = !0); const i = this; return T.get(n).children.forEach(function(s) { const a = s.relationship; switch (a) { case "Bump": r.bumpMap = i.getTexture(t, s.ID); break; case "Maya|TEX_ao_map": r.aoMap = i.getTexture(t, s.ID); break; case "DiffuseColor": case "Maya|TEX_color_map": r.map = i.getTexture(t, s.ID), r.map !== void 0 && (r.map.encoding = Q); break; case "DisplacementColor": r.displacementMap = i.getTexture(t, s.ID); break; case "EmissiveColor": r.emissiveMap = i.getTexture(t, s.ID), r.emissiveMap !== void 0 && (r.emissiveMap.encoding = Q); break; case "NormalMap": case "Maya|TEX_normal_map": r.normalMap = i.getTexture(t, s.ID); break; case "ReflectionColor": r.envMap = i.getTexture(t, s.ID), r.envMap !== void 0 && (r.envMap.mapping = Ze, r.envMap.encoding = Q); break; case "SpecularColor": r.specularMap = i.getTexture(t, s.ID), r.specularMap !== void 0 && (r.specularMap.encoding = Q); break; case "TransparentColor": case "TransparencyFactor": r.alphaMap = i.getTexture(t, s.ID), r.transparent = !0; break; case "AmbientColor": case "ShininessExponent": case "SpecularFactor": case "VectorDisplacementColor": default: console.warn("FBXLoader: %s map is not supported, skipping texture.", a); break; } }), r; } // get a texture from the textureMap for use by a material. getTexture(e, t) { return "LayeredTexture" in g.Objects && t in g.Objects.LayeredTexture && (console.warn("FBXLoader: layered textures are not supported. Discarding all but first layer."), t = T.get(t).children[0].ID), e.get(t); } // Parse nodes in FBXTree.Objects.Deformer // Deformer node can contain skinning or Vertex Cache animation data, however only skinning is supported here // Generates map of Skeleton-like objects for use later when generating and binding skeletons. parseDeformers() { const e = {}, t = {}; if ("Deformer" in g.Objects) { const n = g.Objects.Deformer; for (const r in n) { const i = n[r], s = T.get(parseInt(r)); if (i.attrType === "Skin") { const a = this.parseSkeleton(s, n); a.ID = r, s.parents.length > 1 && console.warn("FBXLoader: skeleton attached to more than one geometry is not supported."), a.geometryID = s.parents[0].ID, e[r] = a; } else if (i.attrType === "BlendShape") { const a = { id: r }; a.rawTargets = this.parseMorphTargets(s, n), a.id = r, s.parents.length > 1 && console.warn("FBXLoader: morph target attached to more than one geometry is not supported."), t[r] = a; } } } return { skeletons: e, morphTargets: t }; } // Parse single nodes in FBXTree.Objects.Deformer // The top level skeleton node has type 'Skin' and sub nodes have type 'Cluster' // Each skin node represents a skeleton and each cluster node represents a bone parseSkeleton(e, t) { const n = []; return e.children.forEach(function(r) { const i = t[r.ID]; if (i.attrType !== "Cluster") return; const s = { ID: r.ID, indices: [], weights: [], transformLink: new I().fromArray(i.TransformLink.a) // transform: new Matrix4().fromArray( boneNode.Transform.a ), // linkMode: boneNode.Mode, }; "Indexes" in i && (s.indices = i.Indexes.a, s.weights = i.Weights.a), n.push(s); }), { rawBones: n, bones: [] }; } // The top level morph deformer node has type "BlendShape" and sub nodes have type "BlendShapeChannel" parseMorphTargets(e, t) { const n = []; for (let r = 0; r < e.children.length; r++) { const i = e.children[r], s = t[i.ID], a = { name: s.attrName, initialWeight: s.DeformPercent, id: s.id, fullWeights: s.FullWeights.a }; if (s.attrType !== "BlendShapeChannel") return; a.geoID = T.get(parseInt(i.ID)).children.filter(function(o) { return o.relationship === void 0; })[0].ID, n.push(a); } return n; } // create the main Group() to be returned by the loader parseScene(e, t, n) { k = new Pe(); const r = this.parseModels(e.skeletons, t, n), i = g.Objects.Model, s = this; r.forEach(function(o) { const p = i[o.ID]; s.setLookAtProperties(o, p), T.get(o.ID).parents.forEach(function(l) { const f = r.get(l.ID); f !== void 0 && f.add(o); }), o.parent === null && k.add(o); }), this.bindSkeleton(e.skeletons, t, r), this.createAmbientLight(), k.traverse(function(o) { if (o.userData.transformData) { o.parent && (o.userData.transformData.parentMatrix = o.parent.matrix, o.userData.transformData.parentMatrixWorld = o.parent.matrixWorld); const p = Ue(o.userData.transformData); o.applyMatrix4(p), o.updateWorldMatrix(); } }); const a = new zt().parse(); k.children.length === 1 && k.children[0].isGroup && (k.children[0].animations = a, k = k.children[0]), k.animations = a; } // parse nodes in FBXTree.Objects.Model parseModels(e, t, n) { const r = /* @__PURE__ */ new Map(), i = g.Objects.Model; for (const s in i) { const a = parseInt(s), o = i[s], p = T.get(a); let u = this.buildSkeleton(p, e, a, o.attrName); if (!u) { switch (o.attrType) { case "Camera": u = this.createCamera(p); break; case "Light": u = this.createLight(p); break; case "Mesh": u = this.createMesh(p, t, n); break; case "NurbsCurve": u = this.createCurve(p, t); break; case "LimbNode": case "Root": u = new Ae(); break; case "Null": default: u = new Pe(); break; } u.name = o.attrName ? ee.sanitizeNodeName(o.attrName) : "", u.ID = a; } this.getTransformData(u, o), r.set(a, u); } return r; } buildSkeleton(e, t, n, r) { let i = null; return e.parents.forEach(function(s) { for (const a in t) { const o = t[a]; o.rawBones.forEach(function(p, u) { if (p.ID === s.ID) { const l = i; i = new Ae(), i.matrixWorld.copy(p.transformLink), i.name = r ? ee.sanitizeNodeName(r) : "", i.ID = n, o.bones[u] = i, l !== null && i.add(l); } }); } }), i; } // create a PerspectiveCamera or OrthographicCamera createCamera(e) { let t, n; if (e.children.forEach(function(r) { const i = g.Objects.NodeAttribute[r.ID]; i !== void 0 && (n = i); }), n === void 0) t = new se(); else { let r = 0; n.CameraProjectionType !== void 0 && n.CameraProjectionType.value === 1 && (r = 1); let i = 1; n.NearPlane !== void 0 && (i = n.NearPlane.value / 1e3); let s = 1e3; n.FarPlane !== void 0 && (s = n.FarPlane.value / 1e3); let a = window.innerWidth, o = window.innerHeight; n.AspectWidth !== void 0 && n.AspectHeight !== void 0 && (a = n.AspectWidth.value, o = n.AspectHeight.value); const p = a / o; let u = 45; n.FieldOfView !== void 0 && (u = n.FieldOfView.value); const l = n.FocalLength ? n.FocalLength.value : null; switch (r) { case 0: t = new He(u, p, i, s), l !== null && t.setFocalLength(l); break; case 1: t = new qe(-a / 2, a / 2, o / 2, -o / 2, i, s); break; default: console.warn("FBXLoader: Unknown camera type " + r + "."), t = new se(); break; } } return t; } // Create a DirectionalLight, PointLight or SpotLight createLight(e) { let t, n; if (e.children.forEach(function(r) { const i = g.Objects.NodeAttribute[r.ID]; i !== void 0 && (n = i); }), n === void 0) t = new se(); else { let r; n.LightType === void 0 ? r = 0 : r = n.LightType.value; let i = 16777215; n.Color !== void 0 && (i = new _().fromArray(n.Color.value)); let s = n.Intensity === void 0 ? 1 : n.Intensity.value / 100; n.CastLightOnObject !== void 0 && n.CastLightOnObject.value === 0 && (s = 0); let a = 0; n.FarAttenuationEnd !== void 0 && (n.EnableFarAttenuation !== void 0 && n.EnableFarAttenuation.value === 0 ? a = 0 : a = n.FarAttenuationEnd.value); const o = 1; switch (r) { case 0: t = new Le(i, s, a, o); break; case 1: t = new Ne(i, s); break; case 2: let p = Math.PI / 3; n.InnerAngle !== void 0 && (p = E.degToRad(n.InnerAngle.value)); let u = 0; n.OuterAngle !== void 0 && (u = E.degToRad(n.OuterAngle.value), u = Math.max(u, 1)), t = new Qe(i, s, a, p, u, o); break; default: console.warn("FBXLoader: Unknown light type " + n.LightType.value + ", defaulting to a PointLight."), t = new Le(i, s); break; } n.CastShadows !== void 0 && n.CastShadows.value === 1 && (t.castShadow = !0); } return t; } createMesh(e, t, n) { let r, i = null, s = null; const a = []; return e.children.forEach(function(o) { t.has(o.ID) && (i = t.get(o.ID)), n.has(o.ID) && a.push(n.get(o.ID)); }), a.length > 1 ? s = a : a.length > 0 ? s = a[0] : (s = new Te({ color: 13421772 }), a.push(s)), "color" in i.attributes && a.forEach(function(o) { o.vertexColors = !0; }), i.FBX_Deformer ? (r = new Je(i, s), r.normalizeSkinWeights()) : r = new et(i, s), r; } createCurve(e, t) { const n = e.children.reduce(function(i, s) { return t.has(s.ID) && (i = t.get(s.ID)), i; }, null), r = new tt({ color: 3342591, linewidth: 1 }); return new nt(n, r); } // parse the model node for transform data getTransformData(e, t) { const n = {}; "InheritType" in t && (n.inheritType = parseInt(t.InheritType.value)), "RotationOrder" in t ? n.eulerOrder = Xe(t.RotationOrder.value) : n.eulerOrder = "ZYX", "Lcl_Translation" in t && (n.translation = t.Lcl_Translation.value), "PreRotation" in t && (n.preRotation = t.PreRotation.value), "Lcl_Rotation" in t && (n.rotation = t.Lcl_Rotation.value), "PostRotation" in t && (n.postRotation = t.PostRotation.value), "Lcl_Scaling" in t && (n.scale = t.Lcl_Scaling.value), "ScalingOffset" in t && (n.scalingOffset = t.ScalingOffset.value), "ScalingPivot" in t && (n.scalingPivot = t.ScalingPivot.value), "RotationOffset" in t && (n.rotationOffset = t.RotationOffset.value), "RotationPivot" in t && (n.rotationPivot = t.RotationPivot.value), e.userData.transformData = n; } setLookAtProperties(e, t) { "LookAtProperty" in t && T.get(e.ID).children.forEach(function(r) { if (r.relationship === "LookAtProperty") { const i = g.Objects.Model[r.ID]; if ("Lcl_Translation" in i) { const s = i.Lcl_Translation.value; e.target !== void 0 ? (e.target.position.fromArray(s), k.add(e.target)) : e.lookAt(new U().fromArray(s)); } } }); } bindSkeleton(e, t, n) { const r = this.parsePoseNodes(); for (const i in e) { const s = e[i]; T.get(parseInt(s.ID)).parents.forEach(function(o) { if (t.has(o.ID)) { const p = o.ID; T.get(p).parents.forEach(function(l) { n.has(l.ID) && n.get(l.ID).bind(new rt(s.bones), r[l.ID]); }); } }); } } parsePoseNodes() { const e = {}; if ("Pose" in g.Objects) { const t = g.Objects.Pose; for (const n in t) if (t[n].attrType === "BindPose" && t[n].NbPoseNodes > 0) { const r = t[n].PoseNode; Array.isArray(r) ? r.forEach(function(i) { e[i.Node] = new I().fromArray(i.Matrix.a); }) : e[r.Node] = new I().fromArray(r.Matrix.a); } } return e; } // Parse ambient color in FBXTree.GlobalSettings - if it's not set to black (default), create an ambient light createAmbientLight() { if ("GlobalSettings" in g && "AmbientColor" in g.GlobalSettings) { const e = g.GlobalSettings.AmbientColor.value, t = e[0], n = e[1], r = e[2]; if (t !== 0 || n !== 0 || r !== 0) { const i = new _(t, n, r); k.add(new it(i, 1)); } } } } class Gt { constructor() { this.negativeMaterialIndices = !1; } // Parse nodes in FBXTree.Objects.Geometry parse(e) { const t = /* @__PURE__ */ new Map(); if ("Geometry" in g.Objects) { const n = g.Objects.Geometry; for (const r in n) { const i = T.get(parseInt(r)), s = this.parseGeometry(i, n[r], e); t.set(parseInt(r), s); } } return this.negativeMaterialIndices === !0 && console.warn("FBXLoader: The FBX file contains invalid (negative) material indices. The asset might not render as expected."), t; } // Parse single node in FBXTree.Objects.Geometry parseGeometry(e, t, n) { switch (t.attrType) { case "Mesh": return this.parseMeshGeometry(e, t, n); case "NurbsCurve": return this.parseNurbsGeometry(t); } } // Parse single node mesh geometry in FBXTree.Objects.Geometry parseMeshGeometry(e, t, n) { const r = n.skeletons, i = [], s = e.parents.map(function(l) { return g.Objects.Model[l.ID]; }); if (s.length === 0) return; const a = e.children.reduce(function(l, f) { return r[f.ID] !== void 0 && (l = r[f.ID]), l; }, null); e.children.forEach(function(l) { n.morphTargets[l.ID] !== void 0 && i.push(n.morphTargets[l.ID]); }); const o = s[0], p = {}; "RotationOrder" in o && (p.eulerOrder = Xe(o.RotationOrder.value)), "InheritType" in o && (p.inheritType = parseInt(o.InheritType.value)), "GeometricTranslation" in o && (p.translation = o.GeometricTranslation.value), "GeometricRotation" in o && (p.rotation = o.GeometricRotation.value), "GeometricScaling" in o && (p.scale = o.GeometricScaling.value); const u = Ue(p); return this.genGeometry(t, a, i, u); } // Generate a BufferGeometry from a node in FBXTree.Objects.Geometry genGeometry(e, t, n, r) { const i = new ae(); e.attrName && (i.name = e.attrName); const s = this.parseGeoNode(e, t), a = this.genBuffers(s), o = new K(a.vertex, 3); if (o.applyMatrix4(r), i.setAttribute("position", o), a.colors.length > 0 && i.setAttribute("color", new K(a.colors, 3)), t && (i.setAttribute("skinIndex", new st(a.weightsIndices, 4)), i.setAttribute("skinWeight", new K(a.vertexWeights, 4)), i.FBX_Deformer = t), a.normal.length > 0) { const p = new at().getNormalMatrix(r), u = new K(a.normal, 3); u.applyNormalMatrix(p), i.setAttribute("normal", u); } if (a.uvs.forEach(function(p, u) { let l = "uv" + (u + 1).toString(); u === 0 && (l = "uv"), i.setAttribute(l, new K(a.uvs[u], 2)); }), s.material && s.material.mappingType !== "AllSame") { let p = a.materialIndex[0], u = 0; if (a.materialIndex.forEach(function(l, f) { l !== p && (i.addGroup(u, f - u, p), p = l, u = f); }), i.groups.length > 0) { const l = i.groups[i.groups.length - 1], f = l.start + l.count; f !== a.materialIndex.length && i.addGroup(f, a.materialIndex.length - f, p); } i.groups.length === 0 && i.addGroup(0, a.materialIndex.length, a.materialIndex[0]); } return this.addMorphTargets(i, e, n, r), i; } parseGeoNode(e, t) { const n = {}; if (n.vertexPositions = e.Vertices !== void 0 ? e.Vertices.a : [], n.vertexIndices = e.PolygonVertexIndex !== void 0 ? e.PolygonVertexIndex.a : [], e.LayerElementColor && (n.color = this.parseVertexColors(e.LayerElementColor[0])), e.LayerElementMaterial && (n.material = this.parseMaterialIndices(e.LayerElementMaterial[0])), e.LayerElementNormal && (n.normal = this.parseNormals(e.LayerElementNormal[0])), e.LayerElementUV) { n.uv = []; let r = 0; for (; e.LayerElementUV[r]; ) e.LayerElementUV[r].UV && n.uv.push(this.parseUVs(e.LayerElementUV[r])), r++; } return n.weightTable = {}, t !== null && (n.skeleton = t, t.rawBones.forEach(function(r, i) { r.indices.forEach(function(s, a) { n.weightTable[s] === void 0 && (n.weightTable[s] = []), n.weightTable[s].push({ id: i, weight: r.weights[a] }); }); })), n; } genBuffers(e) { const t = { vertex: [], normal: [], colors: [], uvs: [], materialIndex: [], vertexWeights: [], weightsIndices: [] }; let n = 0, r = 0, i = !1, s = [], a = [], o = [], p = [], u = [], l = []; const f = this; return e.vertexIndices.forEach(function(h, m) { let d, v = !1; h < 0 && (h = h ^ -1, v = !0); let P = [], x = []; if (s.push(h * 3, h * 3 + 1, h * 3 + 2), e.color) { const y = J(m, n, h, e.color); o.push(y[0], y[1], y[2]); } if (e.skeleton) { if (e.weightTable[h] !== void 0 && e.weightTable[h].forEach(function(y) { x.push(y.weight), P.push(y.id); }), x.length > 4) { i || (console.warn("FBXLoader: Vertex has more than 4 skinning weights assigned to vertex. Deleting additional weights."), i = !0); const y = [0, 0, 0, 0], L = [0, 0, 0, 0]; x.forEach(function(S, A) { let C = S, D = P[A]; L.forEach(function(X, F, Y) { if (C > X) { Y[F] = C, C = X; const j = y[F]; y[F] = D, D = j; } }); }), P = y, x = L; } for (; x.length < 4; ) x.push(0), P.push(0); for (let y = 0; y < 4; ++y) u.push(x[y]), l.push(P[y]); } if (e.normal) { const y = J(m, n, h, e.normal); a.push(y[0], y[1], y[2]); } e.material && e.material.mappingType !== "AllSame" && (d = J(m, n, h, e.material)[0], d < 0 && (f.negativeMaterialIndices = !0, d = 0)), e.uv && e.uv.forEach(function(y, L) { const S = J(m, n, h, y); p[L] === void 0 && (p[L] = []), p[L].push(S[0]), p[L].push(S[1]); }), r++, v && (r > 4 && console.warn("FBXLoader: Polygons with more than four sides are not supported. Make sure to triangulate the geometry during export."), f.genFace(t, e, s, d, a, o, p, u, l, r), n++, r = 0, s = [], a = [], o = [], p = [], u = [], l = []); }), t; } // Generate data for a single face in a geometry. If the face is a quad then split it into 2 tris genFace(e, t, n, r, i, s, a, o, p, u) { for (let l = 2; l < u; l++) e.vertex.push(t.vertexPositions[n[0]]), e.vertex.push(t.vertexPositions[n[1]]), e.vertex.push(t.vertexPositions[n[2]]), e.vertex.push(t.vertexPositions[n[(l - 1) * 3]]), e.vertex.push(t.vertexPositions[n[(l - 1) * 3 + 1]]), e.vertex.push(t.vertexPositions[n[(l - 1) * 3 + 2]]), e.vertex.push(t.vertexPositions[n[l * 3]]), e.vertex.push(t.vertexPositions[n[l * 3 + 1]]), e.vertex.push(t.vertexPositions[n[l * 3 + 2]]), t.skeleton && (e.vertexWeights.push(o[0]), e.vertexWeights.push(o[1]), e.vertexWeights.push(o[2]), e.vertexWeights.push(o[3]), e.vertexWeights.push(o[(l - 1) * 4]), e.vertexWeights.push(o[(l - 1) * 4 + 1]), e.vertexWeights.push(o[(l - 1) * 4 + 2]), e.vertexWeights.push(o[(l - 1) * 4 + 3]), e.vertexWeights.push(o[l * 4]), e.vertexWeights.push(o[l * 4 + 1]), e.vertexWeights.push(o[l * 4 + 2]), e.vertexWeights.push(o[l * 4 + 3]), e.weightsIndices.push(p[0]), e.weightsIndices.push(p[1]), e.weightsIndices.push(p[2]), e.weightsIndices.push(p[3]), e.weightsIndices.push(p[(l - 1) * 4]), e.weightsIndices.push(p[(l - 1) * 4 + 1]), e.weightsIndices.push(p[(l - 1) * 4 + 2]), e.weightsIndices.push(p[(l - 1) * 4 + 3]), e.weightsIndices.push(p[l * 4]), e.weightsIndices.push(p[l * 4 + 1]), e.weightsIndices.push(p[l * 4 + 2]), e.weightsIndices.push(p[l * 4 + 3])), t.color && (e.colors.push(s[0]), e.colors.push(s[1]), e.colors.push(s[2]), e.colors.push(s[(l - 1) * 3]), e.colors.push(s[(l - 1) * 3 + 1]), e.colors.push(s[(l - 1) * 3 + 2]), e.colors.push(s[l * 3]), e.colors.push(s[l * 3 + 1]), e.colors.push(s[l * 3 + 2])), t.material && t.material.mappingType !== "AllSame" && (e.materialIndex.push(r), e.materialIndex.push(r), e.materialIndex.push(r)), t.normal && (e.normal.push(i[0]), e.normal.push(i[1]), e.normal.push(i[2]), e.normal.push(i[(l - 1) * 3]), e.normal.push(i[(l - 1) * 3 + 1]), e.normal.push(i[(l - 1) * 3 + 2]), e.normal.push(i[l * 3]), e.normal.push(i[l * 3 + 1]), e.normal.push(i[l * 3 + 2])), t.uv && t.uv.forEach(function(f, h) { e.uvs[h] === void 0 && (e.uvs[h] = []), e.uvs[h].push(a[h][0]), e.uvs[h].push(a[h][1]), e.uvs[h].push(a[h][(l - 1) * 2]), e.uvs[h].push(a[h][(l - 1) * 2 + 1]), e.uvs[h].push(a[h][l * 2]), e.uvs[h].push(a[h][l * 2 + 1]); }); } addMorphTargets(e, t, n, r) { if (n.length === 0) return; e.morphTargetsRelative = !0, e.morphAttributes.position = []; const i = this; n.forEach(function(s) { s.rawTargets.forEach(function(a) { const o = g.Objects.Geometry[a.geoID]; o !== void 0 && i.genMorphGeometry(e, t, o, r, a.name); }); }); } // a morph geometry node is similar to a standard node, and the node is also contained // in FBXTree.Objects.Geometry, however it can only have attributes for position, normal // and a special attribute Index defining which vertices of the original geometry are affected // Normal and position attributes only have data for the vertices that are affected by the morph genMorphGeometry(e, t, n, r, i) { const s = t.PolygonVertexIndex !== void 0 ? t.PolygonVertexIndex.a : [], a = n.Vertices !== void 0 ? n.Vertices.a : [], o = n.Indexes !== void 0 ? n.Indexes.a : [], p = e.attributes.position.count * 3, u = new Float32Array(p); for (let m = 0; m < o.length; m++) { const d = o[m] * 3; u[d] = a[m * 3], u[d + 1] = a[m * 3 + 1], u[d + 2] = a[m * 3 + 2]; } const l = { vertexIndices: s, vertexPositions: u }, f = this.genBuffers(l), h = new K(f.vertex, 3); h.name = i || n.attrName, h.applyMatrix4(r), e.morphAttributes.position.push(h); } // Parse normal from FBXTree.Objects.Geometry.LayerElementNormal if it exists parseNormals(e) { const t = e.MappingInformationType, n = e.ReferenceInformationType, r = e.Normals.a; let i = []; return n === "IndexToDirect" && ("NormalIndex" in e ? i = e.NormalIndex.a : "NormalsIndex" in e && (i = e.NormalsIndex.a)), { dataSize: 3, buffer: r, indices: i, mappingType: t, referenceType: n }; } // Parse UVs from FBXTree.Objects.Geometry.LayerElementUV if it exists parseUVs(e) { const t = e.MappingInformationType, n = e.ReferenceInformationType, r = e.UV.a; let i = []; return n === "IndexToDirect" && (i = e.UVIndex.a), { dataSize: 2, buffer: r, indices: i, mappingType: t, referenceType: n }; } // Parse Vertex Colors from FBXTree.Objects.Geometry.LayerElementColor if it exists parseVertexColors(e) { const t = e.MappingInformationType, n = e.ReferenceInformationType, r = e.Colors.a; let i = []; return n === "IndexToDirect" && (i = e.ColorIndex.a), { dataSize: 4, buffer: r, indices: i, mappingType: t, referenceType: n }; } // Parse mapping and material data in FBXTree.Objects.Geometry.LayerElementMaterial if it exists parseMaterialIndices(e) { const t = e.MappingInformationType, n = e.ReferenceInformationType; if (t === "NoMappingInformation") return { dataSize: 1, buffer: [0], indices: [0], mappingType: "AllSame", referenceType: n }; const r = e.Materials.a, i = []; for (let s = 0; s < r.length; ++s) i.push(s); return { dataSize: 1, buffer: r, indices: i, mappingType: t, referenceType: n }; } // Generate a NurbGeometry from a node in FBXTree.Objects.Geometry parseNurbsGeometry(e) { const t = parseInt(e.Order); if (isNaN(t)) return console.error("FBXLoader: Invalid Order %s given for geometry ID: %s", e.Order, e.id), new ae(); const n = t - 1, r = e.KnotVector.a, i = [], s = e.Points.a; for (let l = 0, f = s.length; l < f; l += 4) i.push(new te().fromArray(s, l)); let a, o; if (e.Form === "Closed") i.push(i[0]); else if (e.Form === "Periodic") { a = n, o = r.length - 1 - a; for (let l = 0; l < n; ++l) i.push(i[l]); } const u = new Ut(n, r, i, a, o).getPoints(i.length * 12); return new ae().setFromPoints(u); } } class zt { // take raw animation clips and turn them into three.js animation clips parse() { const e = [], t = this.parseClips(); if (t !== void 0) for (const n in t) { const r = t[n], i = this.addClip(r); e.push(i); } return e; } parseClips() { if (g.Objects.AnimationCurve === void 0) return; const e = this.parseAnimationCurveNodes(); this.parseAnimationCurves(e); const t = this.parseAnimationLayers(e); return this.parseAnimStacks(t); } // parse nodes in FBXTree.Objects.AnimationCurveNode // each AnimationCurveNode holds data for an animation transform for a model (e.g. left arm rotation ) // and is referenced by an AnimationLayer parseAnimationCurveNodes() { const e = g.Objects.AnimationCurveNode, t = /* @__PURE__ */ new Map(); for (const n in e) { const r = e[n]; if (r.attrName.match(/S|R|T|DeformPercent/) !== null) { const i = { id: r.id, attr: r.attrName, curves: {} }; t.set(i.id, i); } } return t; } // parse nodes in FBXTree.Objects.AnimationCurve and connect them up to // previously parsed AnimationCurveNodes. Each AnimationCurve holds data for a single animated // axis ( e.g. times and values of x rotation) parseAnimationCurves(e) { const t = g.Objects.AnimationCurve; for (const n in t) { const r = { id: t[n].id, times: t[n].KeyTime.a.map($t), values: t[n].KeyValueFloat.a }, i = T.get(r.id); if (i !== void 0) { const s = i.parents[0].ID, a = i.parents[0].relationship; a.match(/X/) ? e.get(s).curves.x = r : a.match(/Y/) ? e.get(s).curves.y = r : a.match(/Z/) ? e.get(s).curves.z = r : a.match(/d|DeformPercent/) && e.has(s) && (e.get(s).curves.morph = r); } } } // parse nodes in FBXTree.Objects.AnimationLayer. Each layers holds references // to various AnimationCurveNodes and is referenced by an AnimationStack node // note: theoretically a stack can have multiple layers, however in practice there always seems to be one per stack parseAnimationLayers(e) { const t = g.Objects.AnimationLayer, n = /* @__PURE__ */ new Map(); for (const r in t) { const i = [], s = T.get(parseInt(r)); s !== void 0 && (s.children.forEach(function(o, p) { if (e.has(o.ID)) { const u = e.get(o.ID); if (u.curves.x !== void 0 || u.curves.y !== void 0 || u.curves.z !== void 0) { if (i[p] === void 0) { const l = T.get(o.ID).parents.filter(function(f) { return f.relationship !== void 0; })[0].ID; if (l !== void 0) { const f = g.Objects.Model[l.toString()]; if (f === void 0) { console.warn("FBXLoader: Encountered a unused curve.", o); return; } const h = { modelName: f.attrName ? ee.sanitizeNodeName(f.attrName) : "", ID: f.id, initialPosition: [0, 0, 0], initialRotation: [0, 0, 0], initialScale: [1, 1, 1] }; k.traverse(function(m) { m.ID === f.id && (h.transform = m.matrix, m.userData.transformData && (h.eulerOrder = m.userData.transformData.eulerOrder)); }), h.transform || (h.transform = new I()), "PreRotation" in f && (h.preRotation = f.PreRotation.value), "PostRotation" in f && (h.postRotation = f.PostRotation.value), i[p] = h; } } i[p] && (i[p][u.attr] = u); } else if (u.curves.morph !== void 0) { if (i[p] === void 0) { const l = T.get(o.ID).parents.filter(function(P) { return P.relationship !== void 0; })[0].ID, f = T.get(l).parents[0].ID, h = T.get(f).parents[0].ID, m = T.get(h).parents[0].ID, d = g.Objects.Model[m], v = { modelName: d.attrName ? ee.sanitizeNodeName(d.attrName) : "", morphName: g.Objects.Deformer[l].attrName }; i[p] = v; } i[p][u.attr] = u; } } }), n.set(parseInt(r), i)); } return n; } // parse nodes in FBXTree.Objects.AnimationStack. These are the top level node in the animation // hierarchy. Each Stack node will be used to create a AnimationClip parseAnimStacks(e) { const t = g.Objects.AnimationStack, n = {}; for (const r in t) { const i = T.get(parseInt(r)).children; i.length > 1 && console.warn("FBXLoader: Encountered an animation stack with multiple layers, this is currently not supported. Ignoring subsequent layers."); const s = e.get(i[0].ID); n[r] = { name: t[r].attrName, layer: s }; } return n; } addClip(e) { let t = []; const n = this; return e.layer.forEach(function(r) { t = t.concat(n.generateTracks(r)); }), new ot(e.name, -1, t); } generateTracks(e) { const t = []; let n = new U(), r = new N(), i = new U(); if (e.transform && e.transform.decompose(n, r, i), n = n.toArray(), r = new b().setFromQuaternion(r, e.eulerOrder).toArray(), i = i.toArray(), e.T !== void 0 && Object.keys(e.T.curves).length > 0) { const s = this.generateVectorTrack(e.modelName, e.T.curves, n, "position"); s !== void 0 && t.push(s); } if (e.R !== void 0 && Object.keys(e.R.curves).length > 0) { const s = this.generateRotationTrack(e.modelName, e.R.curves, r, e.preRotation, e.postRotation, e.eulerOrder); s !== void 0 && t.push(s); } if (e.S !== void 0 && Object.keys(e.S.curves).length > 0) { const s = this.generateVectorTrack(e.modelName, e.S.curves, i, "scale"); s !== void 0 && t.push(s); } if (e.DeformPercent !== void 0) { const s = this.generateMorphTrack(e); s !== void 0 && t.push(s); } return t; }