@babylonjs/viewer
Version:
The Babylon Viewer aims to simplify a specific but common Babylon.js use case: loading, viewing, and interacting with a 3D model.
3 lines • 106 kB
JavaScript
import{M as e,co as t,bi as n,bu as o,aV as r,F as s,aW as i,V as a,cp as l,i as c,m as u,c1 as f,aU as p,bs as d,aD as h,aR as m,bn as g}from"./index-OM-TXt9s.esm.min.js";import{S as y}from"./standardMaterial.pure-CDkApYCL.esm.min.js";import{S as b}from"./skeleton-CVVbMGoG.esm.min.js";import{B as v}from"./bone.pure-DxlM4RQF.esm.min.js";import{A as x}from"./animationGroup.pure-CtDCPZp-.esm.min.js";import{M,a as I,F as w}from"./morphTargetManager-DVR41bOb.esm.min.js";import{P as A}from"./pointLight.pure-v7CSz3M6.esm.min.js";import{S as T}from"./spotLight.pure-guqQj5Iw.esm.min.js";import{A as S}from"./assetContainer-BpKLnjKZ.esm.min.js";import"./prepass.defines-izweOGjj.esm.min.js";import"./material.detailMapConfiguration-CnvG2ZB5.esm.min.js";const C=15,_=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258],O=[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],N=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],F=[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],B=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];class P{constructor(e,t,n){this.input=e,this.byteOffset=t,this.endOffset=n,this.bitBuffer=0,this.bitCount=0}readBits(e){this.ensureBits(e);const t=this.bitBuffer&(1<<e)-1;return this.bitBuffer>>>=e,this.bitCount-=e,t}readBit(){if(0===this.bitCount){if(this.byteOffset>=this.endOffset)throw new Error("zlib: unexpected end of input");this.bitBuffer=this.input[this.byteOffset++],this.bitCount=8}const e=1&this.bitBuffer;return this.bitBuffer>>>=1,this.bitCount--,e}alignToByte(){this.bitBuffer=0,this.bitCount=0}readUint16LE(){if(this.ensureByteAligned(),this.byteOffset+2>this.endOffset)throw new Error("zlib: unexpected end of input");const e=this.input[this.byteOffset]|this.input[this.byteOffset+1]<<8;return this.byteOffset+=2,e}readByte(){if(this.ensureByteAligned(),this.byteOffset>=this.endOffset)throw new Error("zlib: unexpected end of input");return this.input[this.byteOffset++]}ensureByteAligned(){if(0!==this.bitCount)throw new Error("deflate: expected byte alignment")}ensureBits(e){for(;this.bitCount<e;){if(this.byteOffset>=this.endOffset)throw new Error("zlib: unexpected end of input");this.bitBuffer|=this.input[this.byteOffset++]<<this.bitCount,this.bitCount+=8}}}class E{constructor(e){this.offset=0,this.adlerA=1,this.adlerB=0,this.bytes=new Uint8Array(e)}writeByte(e){if(this.offset>=this.bytes.byteLength)throw new Error("zlib: output length mismatch");const t=255&e;this.bytes[this.offset++]=t,this.adlerA+=t,this.adlerB+=this.adlerA,this.adlerA%=65521,this.adlerB%=65521}copy(e,t){if(e<=0||e>this.offset)throw new Error("deflate: distance out of range");for(let n=0;n<t;n++)this.writeByte(this.bytes[this.offset-e])}finish(){if(this.offset!==this.bytes.byteLength)throw new Error("zlib: output length mismatch")}adler32(){return(this.adlerB<<16|this.adlerA)>>>0}}class L{constructor(e,t={}){const n=new Array(16).fill(0);let o=0,r=0;for(const t of e){if(!Number.isInteger(t)||t<0||t>C)throw new Error("deflate: invalid huffman code lengths");t>0&&(n[t]++,o++,r=Math.max(r,t))}if(0===o){if(t.allowEmpty)return this.symbolsByLength=[],void(this.maxCodeLength=0);throw new Error("deflate: invalid huffman code lengths")}let s=1;for(let e=1;e<=C;e++)if(s=(s<<1)-n[e],s<0)throw new Error("deflate: invalid huffman code lengths");if(0!==s&&1!==o)throw new Error("deflate: invalid huffman code lengths");const i=new Array(16).fill(0);let a=0;for(let e=1;e<=C;e++)a=a+n[e-1]<<1,i[e]=a;this.symbolsByLength=Array.from({length:16},(e,t)=>{if(0===n[t])return;const o=new Int16Array(1<<t);return o.fill(-1),o});for(let t=0;t<e.length;t++){const n=e[t];0!==n&&(this.symbolsByLength[n][i[n]++]=t)}this.maxCodeLength=r}decode(e){if(0===this.maxCodeLength)throw new Error("deflate: invalid huffman code");let t=0;for(let n=1;n<=this.maxCodeLength;n++){t=t<<1|e.readBit();const o=this.symbolsByLength[n]?.[t]??-1;if(o>=0)return o}throw new Error("deflate: invalid huffman code")}}let k,R;function $(){if(!k){const e=new Array(288);for(let t=0;t<=143;t++)e[t]=8;for(let t=144;t<=255;t++)e[t]=9;for(let t=256;t<=279;t++)e[t]=7;for(let t=280;t<=287;t++)e[t]=8;k=new L(e)}return k}function D(){return R||(R=new L(new Array(32).fill(5))),R}function X(e,t){e.alignToByte();const n=e.readUint16LE();if(65535&(n^~e.readUint16LE()))throw new Error("deflate: invalid stored block length");for(let o=0;o<n;o++)t.writeByte(e.readByte())}function V(e,t,n,o){for(;;){const r=n.decode(e);if(r<256){t.writeByte(r);continue}if(256===r)return;if(r>285)throw new Error("deflate: invalid literal/length symbol");const s=r-257,i=_[s]+e.readBits(O[s]),a=o.decode(e);if(a>29)throw new Error("deflate: invalid distance symbol");const l=N[a]+e.readBits(F[a]);t.copy(l,i)}}function j(e){const t=e.readBits(5)+257,n=e.readBits(5)+1,o=e.readBits(4)+4,r=new Array(19).fill(0);for(let t=0;t<o;t++)r[B[t]]=e.readBits(3);const s=function(e,t,n){const o=[];for(;o.length<n;){const r=t.decode(e);if(r<=15){o.push(r);continue}let s,i;switch(r){case 16:if(0===o.length)throw new Error("deflate: invalid code length repeat");i=o[o.length-1],s=e.readBits(2)+3;break;case 17:i=0,s=e.readBits(3)+3;break;case 18:i=0,s=e.readBits(7)+11;break;default:throw new Error("deflate: invalid code length symbol")}if(o.length+s>n)throw new Error("deflate: invalid code length repeat");for(let e=0;e<s;e++)o.push(i)}return o}(e,new L(r),t+n),i=s.slice(0,t),a=s.slice(t);if(0===i[256])throw new Error("deflate: missing end-of-block code");return{literalLengthTree:new L(i),distanceTree:new L(a,{allowEmpty:!0})}}function U(e,t,n,o,r){let s,i,a,l;if(o?(K(t,n,25,r,"FBX node header"),s=z(e,n),i=z(e,n+8),a=z(e,n+16),l=25):(K(t,n,13,r,"FBX node header"),s=e.getUint32(n,!0),i=e.getUint32(n+4,!0),a=e.getUint32(n+8,!0),l=13),0===s)return null;if(s<=n||s>r)throw new Error(`Invalid FBX node end offset ${s} at offset ${n}`);const c=t[n+l-1];K(t,n+l,c,s,"FBX node name");const u=Z(t,n+l,c);let f=n+l+c;const p=f+a;if(p>s)throw new Error(`Invalid FBX property list length for node '${u}' at offset ${n}`);const d=[];for(let n=0;n<i;n++){const n=W(e,t,f,p);d.push(n.property),f=n.nextOffset}if(f!==p)throw new Error(`Invalid FBX property list length for node '${u}' at offset ${n}`);const h=[];if(f<s)for(;f<s;){const n=U(e,t,f,o,s);if(null===n)break;if(n.endOffset<=f||n.endOffset>s)throw new Error(`Invalid FBX child node end offset ${n.endOffset} at offset ${f}`);h.push(n.node),f=n.endOffset}return{node:{name:u,properties:d,children:h},endOffset:s}}function W(e,t,n,o){K(t,n,1,o,"FBX property type");const r=String.fromCharCode(t[n]);switch(n+=1,r){case"C":K(t,n,1,o,"FBX boolean property");return{property:{type:"boolean",value:0!==t[n]},nextOffset:n+1};case"Y":K(t,n,2,o,"FBX int16 property");return{property:{type:"int16",value:e.getInt16(n,!0)},nextOffset:n+2};case"I":K(t,n,4,o,"FBX int32 property");return{property:{type:"int32",value:e.getInt32(n,!0)},nextOffset:n+4};case"F":K(t,n,4,o,"FBX float32 property");return{property:{type:"float32",value:e.getFloat32(n,!0)},nextOffset:n+4};case"D":K(t,n,8,o,"FBX float64 property");return{property:{type:"float64",value:e.getFloat64(n,!0)},nextOffset:n+8};case"L":K(t,n,8,o,"FBX int64 property");return{property:{type:"int64",value:G(e,n)},nextOffset:n+8};case"S":{K(t,n,4,o,"FBX string property length");const r=e.getUint32(n,!0);K(t,n+4,r,o,"FBX string property data");const s=function(e,t,n){return new TextDecoder("utf-8").decode(e.subarray(t,t+n))}(t,n+4,r);return{property:{type:"string",value:s},nextOffset:n+4+r}}case"R":{K(t,n,4,o,"FBX raw property length");const r=e.getUint32(n,!0);K(t,n+4,r,o,"FBX raw property data");return{property:{type:"raw",value:t.slice(n+4,n+4+r)},nextOffset:n+4+r}}case"f":return Y(e,t,n,"float32[]",4,o);case"d":return Y(e,t,n,"float64[]",8,o);case"i":return Y(e,t,n,"int32[]",4,o);case"l":return Y(e,t,n,"int64[]",8,o);case"b":return Y(e,t,n,"boolean[]",1,o);default:throw new Error(`Unknown FBX property type: '${r}' at offset ${n-1}`)}}function Y(e,t,n,o,r,s){K(t,n,12,s,`FBX array property header for ${o}`);const i=e.getUint32(n,!0),a=e.getUint32(n+4,!0),l=e.getUint32(n+8,!0),c=i*r;let u;if(K(t,n+=12,l,s,`FBX array property data for ${o}`),1===a){u=function(e,t){if(!Number.isInteger(t)||t<0)throw new Error("zlib: invalid expected length");if(e.byteLength<6)throw new Error("zlib: unexpected end of input");const n=e[0],o=e[1];if(8!=(15&n)||n>>4>7||((n<<8)+o)%31!=0)throw new Error("zlib: invalid header");if(32&o)throw new Error("zlib: preset dictionary not supported");const r=new P(e,2,e.byteLength-4),s=new E(t);let i=!1;for(;!i;)switch(i=1===r.readBits(1),r.readBits(2)){case 0:X(r,s);break;case 1:V(r,s,$(),D());break;case 2:{const{literalLengthTree:e,distanceTree:t}=j(r);V(r,s,e,t);break}default:throw new Error("deflate: invalid block type")}if(r.byteOffset<e.byteLength-4)throw new Error("zlib: trailing deflate data");s.finish();const a=(e[e.byteLength-4]<<24|e[e.byteLength-3]<<16|e[e.byteLength-2]<<8|e[e.byteLength-1])>>>0;if(s.adler32()!==a)throw new Error("zlib: adler32 mismatch");return s.bytes}(t.subarray(n,n+l),c)}else{if(0!==a)throw new Error(`Unsupported FBX array encoding: ${a}`);if(l!==c)throw new Error(`Invalid FBX array byte length for ${o}`);u=t.slice(n,n+l)}const f=u.buffer.slice(u.byteOffset,u.byteOffset+u.byteLength);let p;switch(o){case"float32[]":p=new Float32Array(f);break;case"float64[]":p=new Float64Array(f);break;case"int32[]":p=new Int32Array(f);break;case"boolean[]":p=u;break;case"int64[]":p=function(e){const t=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new Float64Array(e.byteLength/8);for(let e=0;e<n.length;e++)n[e]=G(t,8*e);return n}(u);break;default:throw new Error(`Unexpected array type: ${o}`)}return{property:{type:o,value:p},nextOffset:n+l}}function K(e,t,n,o,r){if(t<0||n<0||t+n>o||t+n>e.byteLength)throw new Error(`${r}: unexpected end of input`)}function z(e,t){const n=e.getUint32(t,!0);return 4294967296*e.getUint32(t+4,!0)+n}function G(e,t){const n=e.getUint32(t,!0);return 4294967296*e.getInt32(t+4,!0)+n}function Z(e,t,n){let o="";for(let r=0;r<n;r++)o+=String.fromCharCode(e[t+r]);return o}function H(e){const t=new q(e),n=function(e){const t=e.match(/;\s*FBX\s+(\d+)\.(\d+)\.(\d+)/);if(!t)throw new Error("Cannot determine FBX version from ASCII header");return 1e3*parseInt(t[1])+100*parseInt(t[2])+parseInt(t[3])}(e),o=[];for(;!t.isEOF()&&(t.skipWhitespaceAndComments(),!t.isEOF());){const e=J(t);e&&o.push(e)}return{version:n,nodes:o}}var Q;!function(e){e[e.Identifier=0]="Identifier",e[e.Number=1]="Number",e[e.String=2]="String",e[e.OpenBrace=3]="OpenBrace",e[e.CloseBrace=4]="CloseBrace",e[e.Colon=5]="Colon",e[e.Comma=6]="Comma",e[e.Star=7]="Star",e[e.EOF=8]="EOF"}(Q||(Q={}));class q{constructor(e){this.text=e,this.pos=0,this.len=e.length}isEOF(){return this.skipWhitespaceAndComments(),this.pos>=this.len}peek(){const e=this.pos,t=this.next();return this.pos=e,t}next(){if(this.skipWhitespaceAndComments(),this.pos>=this.len)return{type:8,value:"",pos:this.pos};const e=this.text[this.pos],t=this.pos;switch(e){case"{":return this.pos++,{type:3,value:"{",pos:t};case"}":return this.pos++,{type:4,value:"}",pos:t};case":":return this.pos++,{type:5,value:":",pos:t};case",":return this.pos++,{type:6,value:",",pos:t};case"*":return this.pos++,{type:7,value:"*",pos:t};case'"':return this.readString();default:if(this.isNumberStart(e))return this.readNumber();if(this.isIdentStart(e))return this.readIdentifier();throw new Error(`Unexpected character '${e}' at position ${this.pos}`)}}expect(e){const t=this.next();if(t.type!==e)throw new Error(`Expected token type ${e} but got ${t.type} ('${t.value}') at pos ${t.pos}`);return t}isNextNodeStart(){const e=this.pos;if(this.skipWhitespaceAndComments(),this.pos<this.len&&this.isIdentStart(this.text[this.pos])){for(;this.pos<this.len&&this.isIdentChar(this.text[this.pos]);)this.pos++;for(;this.pos<this.len&&(" "===this.text[this.pos]||"\t"===this.text[this.pos]);)this.pos++;const t=this.pos<this.len&&":"===this.text[this.pos];return this.pos=e,t}return this.pos=e,!1}skipWhitespaceAndComments(){for(;this.pos<this.len;){const e=this.text[this.pos];if(" "===e||"\t"===e||"\r"===e||"\n"===e)this.pos++;else{if(";"!==e)break;for(;this.pos<this.len&&"\n"!==this.text[this.pos];)this.pos++}}}readString(){const e=this.pos;this.pos++;let t="";for(;this.pos<this.len&&'"'!==this.text[this.pos];)"\\"===this.text[this.pos]&&this.pos+1<this.len?(this.pos++,t+=this.text[this.pos]):t+=this.text[this.pos],this.pos++;return this.pos<this.len&&this.pos++,{type:2,value:t,pos:e}}readNumber(){const e=this.pos;for("-"!==this.text[this.pos]&&"+"!==this.text[this.pos]||this.pos++;this.pos<this.len&&this.isDigit(this.text[this.pos]);)this.pos++;if(this.pos<this.len&&"."===this.text[this.pos])for(this.pos++;this.pos<this.len&&this.isDigit(this.text[this.pos]);)this.pos++;if(this.pos<this.len&&("e"===this.text[this.pos]||"E"===this.text[this.pos]))for(this.pos++,this.pos<this.len&&("+"===this.text[this.pos]||"-"===this.text[this.pos])&&this.pos++;this.pos<this.len&&this.isDigit(this.text[this.pos]);)this.pos++;return{type:1,value:this.text.substring(e,this.pos),pos:e}}readIdentifier(){const e=this.pos;for(;this.pos<this.len&&this.isIdentChar(this.text[this.pos]);)this.pos++;return{type:0,value:this.text.substring(e,this.pos),pos:e}}isDigit(e){return e>="0"&&e<="9"}isNumberStart(e){return!!this.isDigit(e)||("-"===e||"+"===e)&&this.pos+1<this.len&&(this.isDigit(this.text[this.pos+1])||"."===this.text[this.pos+1])}isIdentStart(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"||"_"===e}isIdentChar(e){return this.isIdentStart(e)||this.isDigit(e)||"|"===e}}function J(e){const t=e.peek();if(4===t.type||8===t.type)return null;const n=e.next();if(0!==n.type)throw new Error(`Expected identifier for node name, got '${n.value}' at pos ${n.pos}`);const o=n.value;e.expect(5);const r=[],s=[];let i=e.peek();if(7===i.type){e.next();const t=e.expect(1),n=parseInt(t.value);e.expect(3);const i=e.next();if(0===i.type&&"a"===i.value){e.expect(5);const t=function(e,t){const n=[];for(;;){const t=e.peek();if(4===t.type||8===t.type)break;if(6!==t.type){if(1!==t.type)break;{const t=e.next();n.push(Number(t.value))}}else e.next()}if(n.length!==t)throw new Error(`ASCII FBX array declared ${t} values but parsed ${n.length}`);return n}(e,n);r.push({type:"float64[]",value:new Float64Array(t)})}return e.expect(4),{name:o,properties:r,children:s}}for(i=e.peek();3!==i.type&&4!==i.type&&8!==i.type;){if(1===i.type){const t=e.next(),n=ee(t.value);!Number.isInteger(n)||t.value.includes(".")||t.value.includes("e")||t.value.includes("E")?r.push({type:"float64",value:n}):r.push({type:te(n)?"int32":"int64",value:n})}else if(2===i.type){const t=e.next();r.push({type:"string",value:t.value})}else if(0===i.type){if(e.isNextNodeStart())break;const t=e.next();r.push({type:"string",value:t.value})}else{if(6!==i.type)break;e.next()}i=e.peek()}if(i=e.peek(),3===i.type){for(e.next();i=e.peek(),4!==i.type&&8!==i.type;){const t=J(e);if(!t)break;s.push(t)}e.expect(4)}return{name:o,properties:r,children:s}}function ee(e){return Number(e)}function te(e){return e>=-2147483648&&e<=2147483647}function ne(e,t){return e.children.find(e=>e.name===t)}function oe(e,t){return e.nodes.find(e=>e.name===t)}function re(e,t){if(t<e.properties.length)return e.properties[t].value}function se(e){const t=e.indexOf("\0");t>=0&&(e=e.substring(0,t));const n=e.indexOf("::");return n>=0&&(e=e.substring(n+2)),e}function ie(e,t,n){const o=e.childrenOf.get(t)??[],r=[];for(const t of o){const o=e.objects.get(t.id);!o||n&&o.name!==n||r.push({id:t.id,node:o,propertyName:t.propertyName})}return r}function ae(e){return function(e){if("number"==typeof e){if(!Number.isSafeInteger(e))throw new Error(`Unsafe FBX object ID ${e.toString()}: object IDs must be safe integers.`);return e}}(e)}function le(e,t){const n=ae(e);if(void 0!==n)return n;if("string"!=typeof e)return;const o=se(e);return"Scene"===o?0:t.get(o)}function ce(e,t,n,o,r,s,i,a,l){e.push({type:r,childId:s,parentId:i,propertyName:a}),t.has(i)||t.set(i,[]),t.get(i).push({id:s,propertyName:a});n.get(s)&&o.push({reason:"duplicate-parent",message:"FBX object has multiple parents; preserving the existing last-parent behavior.",connectionIndex:l,type:r,childId:s,parentId:i,propertyName:a}),n.set(s,{id:i,propertyName:a})}function ue(e,t){const n=se(re(e,0)??e.name),o=re(e,1)??"";return{...e,properties:[{type:"int64",value:t},{type:"string",value:n},{type:"string",value:o}]}}function fe(e,t){return{name:"Geometry",properties:[{type:"int64",value:t},{type:"string",value:se(re(e,0)??"Geometry")},{type:"string",value:"Mesh"}],children:e.children}}function pe(e,t){const n=se(re(e,1)??"Geometry"),o=ne(e,"Vertices");if(!o)throw new Error(`Geometry '${n}' has no Vertices node`);const r=Me(we(o)),s=ne(e,"PolygonVertexIndex");if(!s)throw new Error(`Geometry '${n}' has no PolygonVertexIndex node`);const i=[],a=function(e){const t=[];let n=[],o=0;for(let r=0;r<e.length;r++){const s=e[r];s<0?(n.push(-(s+1)),t.push({indices:n,startIndex:o}),n=[],o=r+1):n.push(s)}return t}(Ie(we(s))),l=function(e,t,n){const o=[];for(let r=0;r<e.length;r++){const s=e[r];o.push(...de(s,r,t,n))}return o}(a,r,i),c=function(e){const t=[];for(let n=0;n<e.length;n++){const o=e[n];for(let e=0;e<o.indices.length;e++)t.push({polyIndex:n,vertexInPoly:e,controlPointIndex:o.indices[e],globalIndex:o.startIndex+e})}return t}(a),u=ne(e,"LayerElementNormal");let f=null;u&&(f=ve(u,"Normals","NormalsIndex",c,r.length/3,3,i));const p=function(e,t){return e.children.filter(e=>e.name===t)}(e,"LayerElementUV"),d=[];for(const e of p){const t=ne(e,"Name"),n=t?re(t,0)??`UVSet${d.length}`:`UVSet${d.length}`,o=ve(e,"UV","UVIndex",c,r.length/3,2,i);o&&d.push({name:n,data:o})}const h=d.length>0?d[0].data:null,m=ne(e,"LayerElementColor");let g=null;if(m){const e=ve(m,"Colors","ColorIndex",c,r.length/3,4,i);if(e){g=new Float32Array(e.length);for(let t=0;t<e.length;t++)g[t]=e[t]}}const y=ne(e,"LayerElementTangent"),b=ne(e,"LayerElementBinormal"),v=b?ve(b,"Binormals","BinormalsIndex",c,r.length/3,3,i):null,x=y?function(e,t,n,o,r,s){const i=function(e,t,n,o,r,s){const i=ne(e,t);if(!i)return 3;const a=Me(we(i)),l=re(ne(e,"MappingInformationType")??{properties:[]},0)??"",c=re(ne(e,"ReferenceInformationType")??{properties:[]},0)??"",u=ne(e,n),f=u?Ie(we(u)):null,p="IndexToDirect"===c&&f?Math.max(...Array.from(f),0)+1:"ByControlPoint"===l||"ByVertice"===l?r:"AllSame"===l?1:o.length;if(p>0&&a.length%p===0){const e=a.length/p;if(3===e||4===e)return e}return s.push({type:"layer-data-too-short",message:`Could not infer stride for layer '${e.name}', defaulting to 3.`,layerName:e.name}),3}(e,"Tangents","TangentsIndex",t,n,s),a=ve(e,"Tangents","TangentsIndex",t,n,i,s);if(!a)return null;const l=new Float64Array(4*t.length);for(let e=0;e<t.length;e++){const t=e*i,n=4*e;l[n]=a[t],l[n+1]=a[t+1],l[n+2]=a[t+2],l[n+3]=i>=4?a[t+3]:xe(e,l,o,r)}return l}(y,c,r.length/3,f,v,i):null,M=ne(e,"LayerElementMaterial");let I=null;M&&(I=function(e,t){const n=ne(e,"MappingInformationType"),o=ne(e,"ReferenceInformationType");if(!n||!o)return null;const r=re(n,0)??"",s=re(o,0)??"";if("AllSame"===r){const n=ne(e,"Materials"),o=n?Ie(we(n)):null,r=o&&o.length>0?o[0]:0,s=new Int32Array(t);return 0!==r&&s.fill(r),s}if("ByPolygon"===r){const t=ne(e,"Materials");if(!t)return null;const n=Ie(we(t));if("Direct"===s||"IndexToDirect"===s)return n}return null}(M,a.length));const w=function(e,t,n,o,r,s,i,a,l){const c=n.length,u=new Float64Array(3*c),f=new Uint32Array(c);for(let t=0;t<n.length;t++){const o=n[t].controlPointIndex;u[3*t]=e[3*o],u[3*t+1]=e[3*o+1],u[3*t+2]=e[3*o+2],f[t]=o}const p=3*t.length,d=new Uint32Array(p);for(let e=0;e<t.length;e++)d[3*e]=t[e].vertices[0],d[3*e+1]=t[e].vertices[1],d[3*e+2]=t[e].vertices[2];return{positions:u,indices:d,normals:o,uvs:r,uvSets:s,colors:i,tangents:a,binormals:l,controlPointIndices:f}}(r,l,c,f,h,d,g,x,v);let A=null;if(I){let e=!0;const t=I[0];for(let n=1;n<I.length;n++)if(I[n]!==t){e=!1;break}if(!e||0!==t){const e=w.indices.length/3;A=new Int32Array(e);for(let e=0;e<l.length;e++)A[e]=I[l[e].polyIndex]??0}}return{id:t,name:n,positions:w.positions,indices:w.indices,normals:w.normals,uvs:w.uvs,uvSets:w.uvSets,colors:w.colors,tangents:w.tangents,binormals:w.binormals,controlPointIndices:w.controlPointIndices,materialIndices:A,diagnostics:i}}function de(e,t,n,o){if(e.indices.length<3)return o.push({type:"degenerate-polygon",message:`Polygon ${t} has fewer than three vertices.`,polygonIndex:t}),[];if(3===e.indices.length)return[{vertices:[e.startIndex,e.startIndex+1,e.startIndex+2],polyIndex:t}];const r=function(e,t){const n=function(e,t){let n=0,o=0,r=0;for(let s=0;s<e.indices.length;s++){const i=3*e.indices[s],a=3*e.indices[(s+1)%e.indices.length],l=t[i],c=t[i+1],u=t[i+2],f=t[a],p=t[a+1],d=t[a+2];n+=(c-p)*(u+d),o+=(u-d)*(l+f),r+=(l-f)*(c+p)}return[n,o,r]}(e,t),o=Math.abs(n[0]),r=Math.abs(n[1]),s=Math.abs(n[2]);if(o+r+s<1e-12)return null;const i=o>r&&o>s?0:r>s?1:2;return e.indices.map(e=>{const o=t[3*e],r=t[3*e+1],s=t[3*e+2];return 0===i?n[0]>=0?[r,s]:[s,r]:1===i?n[1]>=0?[s,o]:[o,s]:n[2]>=0?[o,r]:[r,o]})}(e,n);if(!r)return o.push({type:"degenerate-polygon",message:`Polygon ${t} has a near-zero normal; using fan triangulation.`,polygonIndex:t}),he(e,t);const s=function(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n],r=e[(n+1)%e.length];t+=o[0]*r[1]-r[0]*o[1]}return t/2}(r);if(Math.abs(s)<1e-12)return o.push({type:"degenerate-polygon",message:`Polygon ${t} projects to near-zero area; using fan triangulation.`,polygonIndex:t}),he(e,t);const i=s>0,a=e.indices.map((e,t)=>t),l=[];let c=0;for(;a.length>3&&c++<e.indices.length*e.indices.length;){let n=!1;for(let o=0;o<a.length;o++){const s=a[(o+a.length-1)%a.length],c=a[o],u=a[(o+1)%a.length];if(me(r[s],r[c],r[u],i)&&!ge(r,a,s,c,u)){l.push({vertices:[e.startIndex+s,e.startIndex+c,e.startIndex+u],polyIndex:t}),a.splice(o,1),n=!0;break}}if(!n)return o.push({type:"triangulation-fallback",message:`Polygon ${t} could not be fully ear-clipped; using fan triangulation.`,polygonIndex:t}),he(e,t)}return l.push({vertices:[e.startIndex+a[0],e.startIndex+a[1],e.startIndex+a[2]],polyIndex:t}),l}function he(e,t){const n=[];for(let o=1;o<e.indices.length-1;o++)n.push({vertices:[e.startIndex,e.startIndex+o,e.startIndex+o+1],polyIndex:t});return n}function me(e,t,n,o){const r=(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0]);return o?r>1e-12:r<-1e-12}function ge(e,t,n,o,r){for(const s of t)if(s!==n&&s!==o&&s!==r&&ye(e[s],e[n],e[o],e[r]))return!0;return!1}function ye(e,t,n,o){const r=Math.abs(be(t,n,o)),s=Math.abs(be(e,t,n)),i=Math.abs(be(e,n,o)),a=Math.abs(be(e,o,t));return Math.abs(r-(s+i+a))<1e-10}function be(e,t,n){return(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0])}function ve(e,t,n,o,r,s,i){const a=ne(e,"MappingInformationType"),l=ne(e,"ReferenceInformationType");if(!a||!l)return null;const c=re(a,0)??"",u=re(l,0)??"",f=ne(e,t);if(!f)return null;const p=Me(we(f));let d=null;if("IndexToDirect"===u){const t=ne(e,n);t&&(d=Ie(we(t)))}const h=new Float64Array(o.length*s);for(let t=0;t<o.length;t++){const n=o[t];let r;r="ByPolygonVertex"===c?"IndexToDirect"===u&&d?d[n.globalIndex]:n.globalIndex:"ByControlPoint"===c||"ByVertice"===c?"IndexToDirect"===u&&d?d[n.controlPointIndex]:n.controlPointIndex:"ByPolygon"===c?"IndexToDirect"===u&&d?d[n.polyIndex]:n.polyIndex:"AllSame"===c?0:n.globalIndex;for(let n=0;n<s;n++){const o=r*s+n;r<0||o>=p.length?(i.push({type:o>=p.length?"layer-data-too-short":"layer-index-out-of-bounds",message:`Layer '${e.name}' references unavailable element ${r}.`,layerName:e.name,index:r}),h[t*s+n]=0):h[t*s+n]=p[o]}}return h}function xe(e,t,n,o){if(!n||!o)return 1;const r=4*e,s=3*e,i=n[s],a=n[s+1],l=n[s+2],c=t[r],u=t[r+1],f=t[r+2];return(a*f-l*u)*o[s]+(l*c-i*f)*o[s+1]+(i*u-a*c)*o[s+2]<0?-1:1}function Me(e){if(e instanceof Float64Array)return e;if(e instanceof Float32Array)return new Float64Array(e);if(e instanceof Int32Array)return new Float64Array(e);if(Array.isArray(e)){const t=new Float64Array(e.length);for(let n=0;n<e.length;n++)t[n]=Number(e[n]);return t}throw new Error(`Cannot convert ${typeof e} to Float64Array`)}function Ie(e){if(e instanceof Int32Array)return e;if(e instanceof Float64Array){const t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=Math.round(e[n]);return t}if(e instanceof Float32Array){const t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=Math.round(e[n]);return t}if(Array.isArray(e)){const t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=Math.round(Number(e[n]));return t}throw new Error(`Cannot convert ${typeof e} to Int32Array`)}function we(e){return 1===e.properties.length?e.properties[0].value:e.properties.map(e=>e.value)}function Ae(e,t,n){const o=e.get(t);if(o)return n?o.get(n):o.values().next().value}function Te(e,t,n,o=0){return _e(e,t,n)?.[o]}function Se(e,t,n,o){return Oe(Te(e,t,n))??o}function Ce(e,t,n,o){const r=_e(e,t,n);if(!r)return o;const s=Oe(r[0]),i=Oe(r[1]),a=Oe(r[2]);return void 0!==s&&void 0!==i&&void 0!==a?[s,i,a]:o}function _e(e,t,n){return function(e,t){const n=[ne(e,"Properties70"),ne(e,"Properties60")].filter(e=>void 0!==e);for(const e of n)for(const n of e.children)if(("P"===n.name||"Property"===n.name)&&re(n,0)===t)return n.properties.slice("Property"===n.name?3:4).map(e=>e.value);return}(e,n)??t?.properties.get(n)?.values}function Oe(e){if("number"==typeof e)return e}function Ne(e,t,n){const o=new Map,r=ne(n,"Properties70");for(const e of r?.children??[]){if("P"!==e.name)continue;const t=Fe(e);t&&o.set(t.name,t)}return{objectType:e,templateName:t,properties:o}}function Fe(e){const t=re(e,0);return t?{name:t,propertyType:re(e,1)??"",label:re(e,2)??"",flags:re(e,3)??"",values:e.properties.slice(4).map(e=>e.value)}:null}function Be(e,t,n,o){const r=se(re(e,1)??"Material"),s=function(e,t){if(!t)return;const n=ne(e,"ShadingModel"),o=n?re(n,0):void 0;if("phong"===o?.toLowerCase())return Ae(t,"Material","FbxSurfacePhong")??Ae(t,"Material");if("lambert"===o?.toLowerCase())return Ae(t,"Material","FbxSurfaceLambert")??Ae(t,"Material");return Ae(t,"Material")}(e,o),i=ne(e,"ShadingModel"),a="phong"===(i?re(i,0)??"Lambert":Te(e,s,"ShadingModel")??"Lambert").toLowerCase()?"Phong":"Lambert",l=function(e,t){const n={};return n.diffuseColor=Pe(e,t,"DiffuseColor")??Pe(e,t,"Diffuse"),n.diffuseFactor=Ee(e,t,"DiffuseFactor"),n.ambientColor=Pe(e,t,"AmbientColor")??Pe(e,t,"Ambient"),n.ambientFactor=Ee(e,t,"AmbientFactor"),n.specularColor=Pe(e,t,"SpecularColor")??Pe(e,t,"Specular"),n.specularFactor=Ee(e,t,"SpecularFactor"),n.shininess=Ee(e,t,"Shininess")??Ee(e,t,"ShininessExponent"),n.emissiveColor=Pe(e,t,"EmissiveColor")??Pe(e,t,"Emissive"),n.emissiveFactor=Ee(e,t,"EmissiveFactor"),n.opacity=Ee(e,t,"Opacity"),n.transparencyFactor=Ee(e,t,"TransparencyFactor"),n}(e,s),c=function(e,t,n){const o=[],r=ie(t,e,"Texture");for(const{id:e,node:s,propertyName:i}of r){const r=ne(s,"FileName"),a=ne(s,"RelativeFilename"),l=r?re(r,0)??"":"",c=a?re(a,0)??"":"";let u,f;const p=Ee(s,n,"UVRotation")??Ee(s,n,"Rotation");let d;u=Le(s,n,"UVTranslation")??Le(s,n,"Translation"),f=Le(s,n,"UVScaling")??Le(s,n,"Scaling");const h=Te(s,n,"UVSet");h&&h.length>0&&(d=h),u??=Re(s,"ModelUVTranslation"),f??=Re(s,"ModelUVScaling");let m=null;const g=ie(t,e,"Video");for(const{node:e}of g){const t=ne(e,"Content");if(t&&t.properties.length>0){const e=t.properties[0].value;e instanceof Uint8Array&&e.length>0?m=e:e instanceof ArrayBuffer&&e.byteLength>0&&(m=new Uint8Array(e))}}o.push({propertyName:i??"DiffuseColor",fileName:l,relativeFileName:c,id:e,embeddedData:m,uvTranslation:u,uvScaling:f,uvRotation:p,uvSetName:d})}return o}(t,n,o?Ae(o,"Texture","FbxFileTexture")??Ae(o,"Texture"):void 0);return{id:t,name:r,type:a,properties:l,textures:c}}function Pe(e,t,n){const o=_e(e,t,n);if(!o||o.length<3)return;const r=ke(o[0]),s=ke(o[1]),i=ke(o[2]);return void 0!==r&&void 0!==s&&void 0!==i?[r,s,i]:void 0}function Ee(e,t,n){return ke(Te(e,t,n))}function Le(e,t,n){const o=_e(e,t,n);if(!o)return;const r=ke(o[0]),s=ke(o[1]);return void 0!==r&&void 0!==s?[r,s]:void 0}function ke(e){if("number"==typeof e)return e}function Re(e,t){const n=ne(e,t);if(!n)return;const o=ke(n.properties[0]?.value),r=ke(n.properties[1]?.value);return void 0!==o&&void 0!==r?[o,r]:void 0}function $e(e,t,n){const o=n.parentOf.get(e);if(!o)return null;const r=o.id,s=n.objects.get(r);if(!s||"Geometry"!==s.name)return null;const i=n.parentOf.get(r),a=i?n.objects.get(i.id):void 0,l="Model"===a?.name?i.id:void 0,c=ie(n,e,"Deformer");if(0===c.length)return null;const u=new Map;for(const{id:e,node:t}of c){if("Cluster"!==re(t,2))continue;const o=ie(n,e,"Model");o.length>0&&u.set(o[0].id,{clusterId:e,clusterNode:t})}const f=function(e,t){const n=t.parentOf.get(e),o=n?t.objects.get(n.id):void 0,r="Model"===o?.name?n.id:void 0;if(void 0===r)return new Map;for(const[,e]of Array.from(t.objects)){if("Pose"!==e.name||"BindPose"!==re(e,2))continue;const t=new Map;for(const n of e.children){if("PoseNode"!==n.name)continue;const e=ne(n,"Node"),o=ne(n,"Matrix"),r=e?.properties[0]?.value,s=o?.properties[0]?.value;if("number"!=typeof r)continue;const i=Ke(s);16===i?.length&&t.set(r,i)}if(t.has(r))return t}return new Map}(r,n),p=[],d=function(e,t,n,o){const r=[],s=new Set,i=function(e,t){const n=new Set(Array.from(e.keys()));for(const o of Array.from(e.keys())){let e=De(o,t);for(;void 0!==e;){const o=t.objects.get(e);if(!o||"Model"!==o.name)break;n.add(e),e=De(e,t)}}return n}(e,n),a=function(e,t){const n=new Map;for(const o of Array.from(e)){let r=De(o,t);for(;void 0!==r;){if(e.has(r)){n.set(o,r);break}r=De(r,t)}}return n}(i,n),l=function(e,t){const n=new Map;for(const o of Array.from(e)){const e=t.get(o);void 0!==e&&(n.has(e)||n.set(e,[]),n.get(e).push(o))}return n}(i,a),c=Array.from(i).filter(e=>!a.has(e)).map(e=>({modelId:e,parentIndex:-1}));for(;c.length>0;){const{modelId:i,parentIndex:a}=c.shift();if(s.has(i))continue;s.add(i);const u=n.objects.get(i);if(!u)continue;const f=r.length,p=e.get(i),d=Ve(u),{bindPoseMatrix:h,transformLinkMatrix:m,transformAssociateModelMatrix:g,clusterMode:y}=p?je(p.clusterNode):{bindPoseMatrix:null,transformLinkMatrix:null,transformAssociateModelMatrix:null,clusterMode:"Unknown"},b=Ue(i,se(re(u,1)??`Bone${f}`),void 0!==p,y,h,m,g,t.get(i)??null);o.push(...b),r.push({modelId:i,name:se(re(u,1)??`Bone${f}`),index:f,parentIndex:a,isCluster:void 0!==p,translation:d.translation,rotation:d.rotation,preRotation:d.preRotation,postRotation:d.postRotation,rotationPivot:d.rotationPivot,scalingPivot:d.scalingPivot,rotationOffset:d.rotationOffset,scalingOffset:d.scalingOffset,scale:d.scale,rotationOrder:d.rotationOrder,inheritType:d.inheritType,clusterMode:y,bindPoseMatrix:h,transformLinkMatrix:m,transformAssociateModelMatrix:g,modelBindPoseMatrix:t.get(i)??null,diagnostics:b});for(const e of l.get(i)??[])s.has(e)||c.push({modelId:e,parentIndex:f})}return r}(u,f,n,p);if(0===d.length)return null;const{boneIndices:h,boneWeights:m}=function(e,t){let n=0;for(const o of e){const e=t.get(o.modelId);if(!e)continue;const r=ne(e.clusterNode,"Indexes");if(!r)continue;const s=Ye(r.properties[0]?.value);if(s)for(let e=0;e<s.length;e++)s[e]>n&&(n=s[e])}const o=n+1,r=new Array(o),s=new Array(o);for(let e=0;e<o;e++)r[e]=[],s[e]=[];for(const n of e){const e=t.get(n.modelId);if(!e)continue;const o=ne(e.clusterNode,"Indexes"),i=ne(e.clusterNode,"Weights");if(!o||!i)continue;const a=Ye(o.properties[0]?.value),l=Ke(i.properties[0]?.value);if(a&&l)for(let e=0;e<a.length;e++){const t=a[e];r[t].push(n.index),s[t].push(l[e])}}for(let e=0;e<o;e++){if(0===r[e].length)continue;const t=r[e].map((t,n)=>({index:t,weight:s[e][n]}));t.sort((e,t)=>t.weight-e.weight);const n=t.slice(0,8);r[e]=n.map(e=>e.index),s[e]=n.map(e=>e.weight)}for(let e=0;e<o;e++){const t=s[e].reduce((e,t)=>e+t,0);if(t>0)for(let n=0;n<s[e].length;n++)s[e][n]/=t}return{boneIndices:r,boneWeights:s}}(d,u);return{id:e,geometryId:r,meshBindPoseMatrix:void 0!==l?f.get(l)??null:null,bones:d,boneIndices:h,boneWeights:m,diagnostics:p}}function De(e,t){const n=t.connections.find(n=>"OO"===n.type&&n.childId===e&&"Model"===t.objects.get(n.parentId)?.name);return n?.parentId}function Xe(e){const t=re(e,2);return"Root"===t||"LimbNode"===t}function Ve(e){const t=[0,0,0],n=[0,0,0],o=[0,0,0],r=[0,0,0],s=[0,0,0],i=[0,0,0],a=[0,0,0],l=[0,0,0],c=[1,1,1];let u=0,f=1;const p=ne(e,"Properties70");if(!p)return{translation:t,rotation:n,preRotation:o,postRotation:r,rotationPivot:s,scalingPivot:i,rotationOffset:a,scalingOffset:l,scale:c,rotationOrder:u,inheritType:f};for(const e of p.children){if("P"!==e.name)continue;const p=re(e,0);if(p)switch(p){case"Lcl Translation":t[0]=We(e.properties[4]?.value)??0,t[1]=We(e.properties[5]?.value)??0,t[2]=We(e.properties[6]?.value)??0;break;case"Lcl Rotation":n[0]=We(e.properties[4]?.value)??0,n[1]=We(e.properties[5]?.value)??0,n[2]=We(e.properties[6]?.value)??0;break;case"PreRotation":o[0]=We(e.properties[4]?.value)??0,o[1]=We(e.properties[5]?.value)??0,o[2]=We(e.properties[6]?.value)??0;break;case"PostRotation":r[0]=We(e.properties[4]?.value)??0,r[1]=We(e.properties[5]?.value)??0,r[2]=We(e.properties[6]?.value)??0;break;case"RotationPivot":s[0]=We(e.properties[4]?.value)??0,s[1]=We(e.properties[5]?.value)??0,s[2]=We(e.properties[6]?.value)??0;break;case"ScalingPivot":i[0]=We(e.properties[4]?.value)??0,i[1]=We(e.properties[5]?.value)??0,i[2]=We(e.properties[6]?.value)??0;break;case"RotationOffset":a[0]=We(e.properties[4]?.value)??0,a[1]=We(e.properties[5]?.value)??0,a[2]=We(e.properties[6]?.value)??0;break;case"ScalingOffset":l[0]=We(e.properties[4]?.value)??0,l[1]=We(e.properties[5]?.value)??0,l[2]=We(e.properties[6]?.value)??0;break;case"Lcl Scaling":c[0]=We(e.properties[4]?.value)??1,c[1]=We(e.properties[5]?.value)??1,c[2]=We(e.properties[6]?.value)??1;break;case"RotationOrder":u=We(e.properties[4]?.value)??0;break;case"InheritType":f=We(e.properties[4]?.value)??1}}return{translation:t,rotation:n,preRotation:o,postRotation:r,rotationPivot:s,scalingPivot:i,rotationOffset:a,scalingOffset:l,scale:c,rotationOrder:u,inheritType:f}}function je(e){let t=null,n=null,o=null,r="Normalize";const s=ne(e,"Transform");if(s&&s.properties[0]){const e=s.properties[0].value;e instanceof Float64Array&&16===e.length?t=e:e instanceof Float32Array&&16===e.length&&(t=new Float64Array(e))}const i=ne(e,"TransformLink");if(i&&i.properties[0]){const e=i.properties[0].value;e instanceof Float64Array&&16===e.length?n=e:e instanceof Float32Array&&16===e.length&&(n=new Float64Array(e))}const a=ne(e,"TransformAssociateModel");if(a&&a.properties[0]){const e=a.properties[0].value;e instanceof Float64Array&&16===e.length?o=e:e instanceof Float32Array&&16===e.length&&(o=new Float64Array(e))}const l=ne(e,"Mode"),c=l?re(l,0):void 0;return"Normalize"===c||"Additive"===c||"TotalOne"===c?r=c:c&&(r="Unknown"),{bindPoseMatrix:t,transformLinkMatrix:n,transformAssociateModelMatrix:o,clusterMode:r}}function Ue(e,t,n,o,r,s,i,a){if(!n)return[];const l=[];return"Additive"!==o&&"TotalOne"!==o||l.push({type:"cluster-mode-runtime-unsupported",message:`Cluster mode '${o}' is preserved but not applied by Babylon linear blend skinning.`,boneModelId:e,boneName:t,clusterMode:o}),r||l.push({type:"missing-cluster-transform",message:"Cluster is missing Transform matrix; falling back to rest/bind-pose data.",boneModelId:e,boneName:t,clusterMode:o}),s||l.push({type:"missing-cluster-transform-link",message:"Cluster is missing TransformLink matrix; falling back to model bind pose or rest transform.",boneModelId:e,boneName:t,clusterMode:o}),a||l.push({type:"missing-bind-pose-matrix",message:"No BindPose matrix was found for this bone model.",boneModelId:e,boneName:t,clusterMode:o}),i&&l.push({type:"associate-model-present",message:"TransformAssociateModel is preserved for future associate-model skinning semantics.",boneModelId:e,boneName:t,clusterMode:o}),l}function We(e){if("number"==typeof e)return e}function Ye(e){if(e instanceof Int32Array)return e;if(e instanceof Float64Array){const t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=Math.round(e[n]);return t}return null}function Ke(e){return e instanceof Float64Array?e:e instanceof Float32Array?new Float64Array(e):null}function ze(e,t){if(0===t.length)return[];const n=new Map;for(const o of t){const t=o.bones.filter(e=>e.isCluster).map(e=>e.modelId);if(0===t.length)continue;const r=Ge(t,e),s=n.get(r);s?s.push(o):n.set(r,[o])}return Array.from(n.entries()).sort(([e],[t])=>et(e,t)).map(([t,n])=>function(e,t,n){const o=new Set,r=new Set,s=new Map,i=new Map;for(const e of t)for(const t of e.bones){i.has(t.modelId)||i.set(t.modelId,i.size);let e=s.get(t.modelId);if(e||(e=[],s.set(t.modelId,e)),e.push(t),t.isCluster){o.add(t.modelId);for(const e of Ze(t.modelId,n))r.add(e)}}const a=function(e){const t=[];for(const[n,o]of Array.from(e)){const e=o.filter(e=>e.isCluster&&e.transformLinkMatrix).map(e=>e.transformLinkMatrix);if(e.length<2)continue;const r=e[0];e.some(e=>!qe(r,e,1e-5))&&t.push(`Model ${n.toString()} has differing Cluster.TransformLink matrices across skins`)}return t}(s),l=new Map;for(const[e,t]of Array.from(s))l.set(e,Qe(t));const c=function(e,t){const n=new Map;for(const o of Array.from(e)){const r=He(o,t);void 0!==r&&e.has(r)&&n.set(o,r)}return n}(r,n),u=function(e,t,n){const o=new Map;for(const n of Array.from(e)){const e=t.get(n);if(void 0===e)continue;let r=o.get(e);r||(r=[],o.set(e,r)),r.push(n)}for(const e of Array.from(o.values()))e.sort((e,t)=>tt(e,t,n));const r=Array.from(e).filter(e=>!t.has(e)).sort((e,t)=>tt(e,t,n)),s=[],i=[...r];for(;i.length>0;){const e=i.shift();s.push(e),i.push(...o.get(e)??[])}return s}(r,c,i),f=[],p=new Map;for(const e of u){const t=l.get(e)??Je(e,n);if(!t)continue;const r=c.get(e),s=void 0===r?-1:p.get(r)??-1,i=f.length,a={...t,index:i,parentIndex:s,isCluster:o.has(e)};f.push(a),p.set(e,i)}const d=t.map(t=>function(e,t,n){const o=e.bones.map(e=>{const o=n.get(e.modelId);if(void 0===o&&e.isCluster)throw new Error(`FBX rig resolver: cluster bone ${e.name} is missing from resolved rig ${t}`);return o??-1});return{skinId:e.id,geometryId:e.geometryId,rigId:t,skinBoneIndexToRigBoneIndex:o,clusterModelIds:new Set(e.bones.filter(e=>e.isCluster).map(e=>e.modelId))}}(t,`rig_${e.toString()}`,p));return{id:`rig_${e.toString()}`,rootModelIds:f.filter(e=>e.parentIndex<0).map(e=>e.modelId),bones:f,modelIdToBoneIndex:p,clusterModelIds:o,skinBindings:d,warnings:a}}(t,n,e))}function Ge(e,t){const n=function(e,t){if(0===e.length)return;const n=e.map(e=>Ze(e,t)),o=new Set(n[0]);for(const e of n.slice(1))for(const t of Array.from(o))e.includes(t)||o.delete(t);return n[0].find(e=>o.has(e))}(e,t)??e[0];let o=n,r=He(o,t);for(;void 0!==r;){const e=t.objects.get(r);if(!e||"Model"!==e.name||!Xe(e))break;o=r,r=He(r,t)}return o}function Ze(e,t){const n=[];let o=e;for(;void 0!==o;){const e=t.objects.get(o);if(!e||"Model"!==e.name)break;n.push(o),o=He(o,t)}return n}function He(e,t){const n=t.connections.find(n=>"OO"===n.type&&n.childId===e&&"Model"===t.objects.get(n.parentId)?.name);return n?.parentId}function Qe(e){return e.find(e=>e.isCluster&&e.transformLinkMatrix)??e.find(e=>e.isCluster)??e.find(e=>e.modelBindPoseMatrix)??e[0]}function qe(e,t,n){if(e.length!==t.length)return!1;for(let o=0;o<e.length;o++)if(Math.abs(e[o]-t[o])>n)return!1;return!0}function Je(e,t){const n=t.objects.get(e);if(!n||"Model"!==n.name)return null;const o=Ve(n);return{modelId:e,name:se(re(n,1)??`Bone${e.toString()}`),index:-1,parentIndex:-1,isCluster:!1,translation:o.translation,rotation:o.rotation,preRotation:o.preRotation,postRotation:o.postRotation,rotationPivot:o.rotationPivot,scalingPivot:o.scalingPivot,rotationOffset:o.rotationOffset,scalingOffset:o.scalingOffset,scale:o.scale,rotationOrder:o.rotationOrder,inheritType:o.inheritType,clusterMode:"Unknown",bindPoseMatrix:null,transformLinkMatrix:null,transformAssociateModelMatrix:null,modelBindPoseMatrix:null,diagnostics:[]}}function et(e,t){return e<t?-1:e>t?1:0}function tt(e,t,n){return(n.get(e)??Number.MAX_SAFE_INTEGER)-(n.get(t)??Number.MAX_SAFE_INTEGER)||et(e,t)}const nt=46186158e3,ot=1/23,rt=1e-4,st=1e-5,it=[24,25,30,48,50,60,100,120];function at(e,t,n){const o=se(re(t,1)??"Animation"),r=function(e){const t=ne(e,"Properties70");if(!t)return null;let n=0,o=null;for(const e of t.children){if("P"!==e.name)continue;const t=re(e,0);"LocalStart"===t||"ReferenceStart"===t?n=yt(e.properties[4]?.value)??n:"LocalStop"!==t&&"ReferenceStop"!==t||(o=yt(e.properties[4]?.value)??o)}return null!==o?{start:n,stop:o}:null}(t),s=ie(n,e,"AnimationLayer");if(0===s.length)return null;const i=[],a=[],l=[],c=[];let u=1/0,f=0;for(const{id:e,node:t}of s){const o=se(re(t,1)??"Layer");let r=100,s=0;const p=ne(t,"Properties70");if(p)for(const e of p.children){if("P"!==e.name)continue;const t=re(e,0);if("Weight"===t){const t=e.properties[4]?.value;"number"==typeof t&&(r=t)}else if("BlendMode"===t){const t=e.properties[4]?.value;"number"==typeof t&&(s=t)}}const d=ie(n,e,"AnimationCurveNode"),h=[],m=[],g=[];for(const{id:e,node:t}of d){const r=lt(e,t,n);if(!r){const r=ct(e,t,n);if(r){ut(r.curves,e=>{e<u&&(u=e),e>f&&(f=e)}),m.push(r),a.push(r);const t={type:"unsupported-curve-node",message:`AnimationCurveNode '${r.type}' is preserved as diagnostic data but not evaluated at runtime.`,layerName:o,curveNodeId:e,curveNodeType:r.type,targetId:r.targetId,propertyName:r.propertyName};g.push(t),c.push(t)}continue}for(const e of r.curves)for(const t of e.keys)t.time<u&&(u=t.time),t.time>f&&(f=t.time);h.push(r),i.push(r)}l.push({name:o,weight:r,normalizedWeight:r/100,blendMode:s,curveNodes:h,unsupportedCurveNodes:m,diagnostics:g})}if(0===i.length&&0===a.length)return null;l.length>1&&c.push({type:"multiple-animation-layers",message:"Multiple animation layers are preserved, but runtime blending is not yet evaluated."});for(const e of l){if(0!==e.blendMode){const t={type:"unsupported-layer-blend-mode",message:`Animation layer blend mode ${e.blendMode} is preserved but not yet blended at runtime.`,layerName:e.name};e.diagnostics.push(t),c.push(t)}if(100!==e.weight){const t={type:"partial-layer-weight",message:`Animation layer weight ${e.weight} is preserved but not yet applied at runtime.`,layerName:e.name};e.diagnostics.push(t),c.push(t)}}const p=u>0&&isFinite(u)?u:0;if(p>0){for(const e of i)for(const t of e.curves)for(const e of t.keys)e.time-=p;for(const e of a)for(const t of e.curves)for(const e of t.keys)e.time-=p;f-=p}const d=r?Math.max(r.start-p,0):0,h=r?Math.max(r.stop-p,d):0,m=h>d,g=m?d:0,y=m?h:f;return{name:o,startTime:g,stopTime:y,duration:Math.max(y-g,0),curveNodes:i,layers:l,unsupportedCurveNodes:a,diagnostics:c}}function lt(e,t,n){const o=se(re(t,1)??"");if("T"===o||"R"===o||"S"===o){const t=function(e,t){for(const n of t.connections)if(n.childId===e&&"OP"===n.type){const e=t.objects.get(n.parentId);if(e&&"Model"===e.name)return n.parentId}return null}(e,n);if(null===t)return null;const r=ft(e,n);return 0===r.length?null:{type:o,targetModelId:t,curves:r}}if("DeformPercent"===o){const t=function(e,t){for(const n of t.connections)if(n.childId===e&&"OP"===n.type){const e=t.objects.get(n.parentId);if(e&&"Deformer"===e.name){if("BlendShapeChannel"===re(e,2))return n.parentId}}for(const n of t.connections)if(n.childId===e&&"OO"===n.type){const e=t.objects.get(n.parentId);if(e&&"Deformer"===e.name){if("BlendShapeChannel"===re(e,2))return n.parentId}}return null}(e,n);if(null===t)return null;const o=ft(e,n);return 0===o.length?null:{type:"DeformPercent",targetModelId:t,curves:o}}return null}function ct(e,t,n){const o=se(re(t,1)??""),r=ft(e,n),s=function(e){const t={},n=ne(e,"Properties70");for(const e of n?.children??[]){if("P"!==e.name)continue;const n=re(e,0);if(!n?.startsWith("d|"))continue;const o=bt(e.properties[4]?.value);null!==o&&(t[n]=o)}return t}(t);if(0===r.length&&0===Object.keys(s).length)return null;let i,a=null;for(const t of n.connections)if(t.childId===e&&"OP"===t.type){a=t.parentId,i=t.propertyName;break}return{type:o,id:e,targetId:a,propertyName:i,curveCount:r.length,curves:r,defaultValues:s}}function ut(e,t){for(const n of e)for(const e of n.keys)t(e.time)}function ft(e,t){const n=[];for(const o of t.connections)if(o.parentId===e&&"OP"===o.type){const e=t.objects.get(o.childId);if(!e||"AnimationCurve"!==e.name)continue;const r=o.propertyName??"d|X",s=pt(e);if(s.length>0){const t=dt(e,s);n.push({channel:r,keys:t?ht(s):s,isSampled:t})}}if(0===n.length){const o=ie(t,e,"AnimationCurve"),r=["d|X","d|Y","d|Z"];for(let e=0;e<o.length&&e<3;e++){const t=pt(o[e].node);if(t.length>0){const s=dt(o[e].node,t);n.push({channel:r[e],keys:s?ht(t):t,isSampled:s})}}}return n}function pt(e){const t=ne(e,"KeyTime"),n=ne(e,"KeyValueFloat");if(!t||!n)return[];const o=function(e){if(e instanceof Float64Array)return e;return null}(t.properties[0]?.value),r=vt(n.properties[0]?.value),s=gt(ne(e,"KeyAttrFlags")?.properties[0]?.value),i=vt(ne(e,"KeyAttrDataFloat")?.properties[0]?.value),a=gt(ne(e,"KeyAttrRefCount")?.properties[0]?.value);if(!o||!r)return[];if(o.length!==r.length)return[];const l=function(e,t,n){if(!t||0===t.length)return new Array(e).fill(-1);if(n&&n.length>0){let t=0;for(const e of n)t+=e;if(t===e){const e=[];for(let t=0;t<n.length;t++){const o=n[t];for(let n=0;n<o;n++)e.push(t)}return e}}if(t.length===e)return Array.from({length:e},(e,t)=>t);if(1===t.length)return new Array(e).fill(0);return Array.from({length:e},(e,n)=>Math.min(n,t.length-1))}(o.length,s,a),c=[];for(let e=0;e<o.length;e++){const t=l[e],n=t>=0?s?.[t]??0:0,a=4*t;c.push({time:Number(o[e])/nt,value:r[e],interpolation:xt(n),constantMode:256&n?"next":"standard",rightSlope:Mt(i,a),nextLeftSlope:Mt(i,a+1)})}return c}function dt(e,t){return"FbxMayaSample Curve"===se(re(e,1)??"")||function(e){if(e.length<8)return!1;const t=[];for(let n=1;n<e.length;n++){const o=e[n].time-e[n-1].time;if(!(o>0))return!1;t.push(o)}const n=t.reduce((e,t)=>e+t,0)/t.length;if(n>ot)return!1;const o=Math.max(1e-6,.05*n);if(t.some(e=>Math.abs(e-n)>o))return!1;const r=1/n;if(!it.some(e=>Math.abs(r-e)<=Math.max(.25,.02*e)))return!1;return!function(e){let t=!1,n=!0,o=!0,r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,i=0;for(const t of e)r=Math.min(r,t.value),s=Math.max(s,t.value);for(let r=0;r<e.length-1;r++){const s=e[r],a=e[r+1];if("cubic"!==s.interpolation)continue;t=!0;const l=a.time-s.time;if(!(l>0))continue;const c=(a.value-s.value)/l,u=s.rightSlope,f=s.nextLeftSlope;if(void 0!==u&&void 0!==f){(Math.abs(u)>st||Math.abs(f)>st)&&(o=!1);for(const e of[.25,.5,.75]){const t=It(s.value,a.value,u,f,l,e),n=s.value+e*l*c;i=Math.max(i,Math.abs(t-n))}}else n=!1}if(!t||!n||o)return!1;const a=s-r,l=Math.max(rt,.01*a);return i>l}(e)}(t)}function ht(e){return e.map(e=>({time:e.time,value:e.value,interpolation:"linear"}))}function mt(e,t){if(!e||0===e.keys.length)return null;const n=e.keys;if(t<=n[0].time)return n[0].value;if(t>=n[n.length-1].time)return n[n.length-1].value;for(let o=0;o<n.length-1;o++){const r=n[o],s=n[o+1];if(t<r.time||t>s.time)continue;if(s.time===r.time)return r.value;if("constant"===r.interpolation)return"next"===r.constantMode?s.value:r.value;const i=s.time-r.time,a=(t-r.time)/i;if("cubic"===r.interpolation&&!e.isSampled){const e=(s.value-r.value)/i,t=r.rightSlope??e,n=r.nextLeftSlope??e;return It(r.value,s.value,t,n,i,a)}return r.value+a*(s.value-r.value)}return n[n.length-1].value}function gt(e){if(e instanceof Int32Array)return e;if(e instanceof Float32Array||e instanceof Float64Array){const t=new Int32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n];return t}return null}function yt(e){return"number"==typeof e?e/nt:null}function bt(e){return"number"==typeof e?e:null}function vt(e){if(e instanceof Float32Array)return e;if(e instanceof Float64Array){const t=new Float32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n];return t}return null}function xt(e){return 8&e?"cubic":4&e?"linear":2&e?"constant":"linear"}function Mt(e,t){if(!e||t<0||t>=e.length)return;const n=e[t];return Number.isFinite(n)?n:void 0}function It(e,t,n,o,r,s){const i=s*s,a=i*s;return(2*a-3*i+1)*e+(a-2*i+s)*r*n+(-2*a+3*i)*t+(a-i)*r*o}function wt(e,t,n){const o=n.parentOf.get(e);if(!o)return null;const r=n.objects.get(o.id);if(!r||"Geometry"!==r.name)return null;const s=o.id,i=[],a=ie(n,e,"Deformer");for(const{id:e,node:t}of a){if("BlendShapeChannel"!==re(t,2))continue;const o=se(re(t,1)??"MorphTarget");let r=0;const s=ne(t,"Properties70");if(s)for(const e of s.children){if("P"!==e.name)continue;if("DeformPercent"===re(e,0)){const t=e.properties[4]?.value;"number"==typeof t&&(r=t)}}const a=At(t),l=[],c=ie(n,e,"Geometry");for(const{node:e}of c){if("Shape"!==re(e,2))continue;const t=Ct(e);t&&l.push(t)}if(l.length>0){const t=[],n=Tt(a,l,e,o,t);i.push({name:o,id:e,deformPercent:r,shapes:St(l,n),fullWeights:n?[...n].sort((e,t)=>e-t):null,diagnostics:t})}}return 0===i.length?null:{id:e,geometryId:s,channels:i}}function At(e){const t=ne(e,"FullWeights"),n=t?.properties[0]?.value;return n&&(n instanceof Float64Array||n instanceof Float32Array||n instanceof Int32Array)?Array.from(n,e=>Number(e)):null}function Tt(e,t,n,o,r){return e?e.length!==t.length?(1===t.length||r.push({type:"full-weights-mismatch",message:`FullWeights length ${e.length} does not match shape count ${t.length}; using the first shape for compatibility.`,channelId:n,channelName:o}),null):e:(t.length>1&&r.push({type:"missing-full-weights",message:"Blend shape channel has multiple shapes but no FullWeights; using the first shape for compatibility.",channelId:n,channelName:o}),null)}function St(e,t){return t&&t.length===e.length?e.map((e,n)=>({shape:e,weight:t[n]})).sort((e,t)=>e.weight-t.weight).map(e=>e.shape):e.length>1?[e[0]]:e}function Ct(e){const t=ne(e,"Indexes"),n=ne(e,"Vertices");if(!t||!n)return null;const o=t.properties[0]?.value,r=n.properties[0]?.value;if(!o||!r)return null;const s=function(e){if(e instanceof Uint32Array)return e;if(e instanceof Int32Array||e instanceof Float32Array||e instanceof Float64Array){const t=new Uint32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n];return t}return null}(o);if(!s)return null;let i;if(r instanceof Float64Array)i=r;else{if(!(r instanceof Float32Array))return null;i=new Float64Array(r)}let a=null;const l=ne(e,"Normals");if(l){const e=l.properties[0]?.value;e instanceof Float64Array?a=e:e instanceof Float32Array&&(a=new Float64Array(e))}return{indices:s,vertices:i,normals:a}}const _t=new Set(["Character","CharacterPose","ControlSet","ControlSetPlug","SelectionSet","CollectionExclusive"]);function Ot(e){return"Skin"===e||"Cluster"===e||"BlendShape"===e||"BlendShapeChannel"===e}function Nt(e,t,n,o,r){return{type:o,message:r,objectId:t,objectName:se(re(n,1)??n.name),nodeName:n.name,subType:re(n,2)??"",parentCount:e.connections.filter(e=>e.childId===t).length,childCount:e.childrenOf.get(t)?.length??0}}function Ft(e){const t=function(e){const t=new Map,n=[],o=new Map,r=new Map,s=[],i=[],a=[],l=new Map,c=new Map;let u=-1;const f=e=>{let t=l.get(e);return void 0===t&&(t=u--,l.set(e,t)),t},p=(e,t)=>{let n=c.get(e);n||(n=new Map,c.set(e,n));let o=n.get(t);return void 0===o&&(o=u--,n.set(t,o)),o},d=oe(e,"Objects");if(d)for(const e of d.children){const i=e.properties[0];if(i){const l=ae(i.value);if(void 0!==l)t.set(l,e),n.push({id:l,node:e,source:"Objects",synthetic:!1});else if("string"==typeof i.value){const l=se(i.value),c=f(l),u=ue(e,c);if(t.set(c,u),n.push({id:c,node:u,source:"Objects",legacyName:l,synthetic:!1}),"Model"===e.name&&"Mesh"===re(e,1)){const i=p("Geometry",l),u=fe(e,i);t.set(i,u),n.push({id:i,node:u,source:"legacySyntheticGeometry",legacyName:l,synthetic:!0}),ce(s,o,r,a,"OO",i,c)}}}}const h=oe(e,"Connections");if(h)for(const e of h.children){if("C"!==e.name&&"Connect"!==e.name)continue;const n=i.length,c=re(e,0),u=e.properties[1]?.value,f=e.properties[2]?.value,p={source:e.name,rawType:c,accepted:!1};if(i.push(p),"OO"!==c&&"OP"!==c){const e=void 0===u?void 0:le(u,l),t=void 0===f?void 0:le(f,l);a.push({reason:"unsupported-connection-type",message:`Unsupported FBX connection type '${c??""}' was not added to the graph.`,connectionIndex:n,type:c,childId:e,parentId:t});continue}if(void 0===u||void 0===f){a.push({reason:"missing-connection-endpoint",message:"FBX connection is missing a child or parent endpoint.",connectionIndex:n,type:c});continue}const d=le(u,l),h=le(f,l);if(void 0===d||void 0===h){a.push({reason:"unresolved-legacy-endpoint",message:"FBX connection references a legacy string endpoint that is not present in the object table.",connectionIndex:n,type:c});continue}const m="OP"===c&&e.properties.length>3?re(e,3):void 0;p.childId=d,p.parentId=h,p.propertyName=m,d===h&&a.push({reason:"self-loop",message:"FBX connection references the same object as child and parent.",connectionIndex:n,type:c,childId:d,parentId:h,propertyName:m}),t.has(d)||a.push({reason:"unresolved-object-reference",message:"FBX connection child ID is not present in the object table.",connectionIndex:n,type:c,childId:d,parentId:h,propertyName:m}),0===h||t.has(h)||a.push({reason:"unresolved-object-reference",message:"FBX connection parent ID is not present in the object table.",connectionIndex:n,type:c,childId:d,parentId:h,propertyName:m}),ce(s,o,r,a,c,d,h,m,n),p.accepted=!0}return{objects:t,objectEntries:n,childrenOf:o,parentOf:r,connections:s,connectionEntries:i,diagnostics:a}}(e),n=function(e){const t=new Map,n=oe(e,"Definitions");if(!n)return t;for(const e of n.children){if("ObjectType"!==e.name)continue;const n=re(e,0);if(n)for(const o of e.children){if("PropertyTemplate"!==o.name)continue;const e=re(o,0);if(!e)continue;const r=Ne(n,e,o);let s=t.get(n);s||(s=new Map,t.set(n,s)),s.set(e,r)}}return t}(e),o=function(e){const t={upAxis:1,upAxisSign:1,frontAxis:2,frontAxisSign:1,coordAxis:0,coordAxisSign:1,unitScaleFactor:1},n=oe(e,"GlobalSettings");if(!n)return t;const o=n.children.find(e=>"Properties70"===e.name);if(!o)return t;for(const e of o.children){if("P"!==e.name)continue;const n=re(e,0),o=kt(e.properties[4]?.value);if(n&&void 0!==o)switch(n){case"UpAxis":t.upAxis=o;break;case"UpAxisSign":t.upAxisSign=o;break;case"FrontAxis":t.frontAxis=o;break;case"FrontAxisSign":t.frontAxisSign=o;break;case"CoordAxis":t.coordAxis=o;break;case"CoordAxisSign":t.coordAxisSign=o;break;case"UnitScaleFactor":t.unitScaleFactor=o}}return t}(e),r=[];for(const[e,o]of Array.from(t.objects))"Material"===o.name&&r.push(Be(o,e,t,n));const s=[];for(const[e,n]of Array.from(t.objects))if("Geometry"===n.name){"Mesh"===re(n,2)&&s.push(pe(n,e))}const i=function(e){const t=[];for(const[n,o]of Array.from(e.objects))if("Deformer"===o.name&&"Skin"===re(o,2)){const o=$e(n,0,e);o&&t.push(o)}return t}(t),a=ze(t,i),l=function(e){const t=[];for(const[n,o]of Array.from(e.objects))if("Deformer"===o.name&&"BlendShape"===re(o,2)){const o=wt(n,0,e);o&&t.push(o)}return t}(t),c=function(e){const t=[];for(const[n,o]of Array.from(e.objects))if("AnimationStack"===o.name){const r=at(n,o,e);r&&t.push(r)}return t}(t),u=function(e,t){const n=[],o=Ae(t,"NodeAttribute","FbxCamera")??Ae(t,"NodeAttribute");for(const[t,r]of Array.from(e.objects)){if("NodeAttribute"!==r.name)continue;if("Camera"!==re(r,2))continue;const s=e.parentOf.get(t);if(!s)continue;const i=e.objects.get(s.id);if(!i||"Model"!==i.name)continue;const a=se(re(i,1)??"Camera"),l=Se(r,o,"NearPlane",.1),c=Se(r,o,"FarPlane",1e4),u=$t(r,o),f=1===Se(r,o,"CameraProjectionType",0)||1===Se(r,o,"ProjectionType",0)?"orthographic":"perspective",p=kt(Te(r,o,"FocalLength")),d=kt(Te(r,o,"FilmWidth"))??kt(Te(r,o,"ApertureWidth")),h=kt(Te(r,o,"FilmHeight"))??kt(Te(r,o,"ApertureHeight")),m=kt(Te(r,o,"OrthoZoom")),g=kt(Te(r,o,"Roll")),y=Dt(r,o,u,p,h),b=[];"orthographic"===f&&void 0===m&&b.push("Orthographic camera has no OrthoZoom; runtime orthographic bounds use a fallback."),void 0!==p&&void 0===h&&void 0===Te(r,o,"FieldOfView")&&b.push("FocalLength is present without FilmHeight; default field of view fallback may be used."),n.push({modelId:s.id,name:a,fieldOfView:y,nearPlane:l,farPlane:c,aspectRatio:u,projectionType:f,focalLength:p,filmWidth:d,filmHeight:h,orthoZoom:m,roll:g,unknownProperties:Xt(r,Et),diagnostics:b})}return n}(t,n),f=function(e,t){const n=[],o=Ae(t,"NodeAttribute","FbxLight")??Ae(t,"NodeAttribute");for(const[t,r]of Array.from(e.objects)){if("NodeAttribute"!==r.name)continue;if("Light"!==re(r,2))continue;const s=e.parentOf.get(t);if(!s)continue;const i=e.objects.get(s.id);if(!i||"Model"!==i.name)continue;const a=se(re(i,1)??"Light"),l=Se(r,o,"LightType",0),c=Ce(r,o,"Color",[1,1,1]),u=Se(r,o,"Intensity",100)/100,f=kt(Te(r,o,"OuterAngle"))??kt(Te(r,o,"ConeAngle")),p=kt(Te(r,o,"InnerAngle")),d=f??45,h=Se(r,o,"DecayType",2),m=kt(Te(r,o,"DecayStart")),g=Rt(Te(r,o,"EnableNearAttenuation")),y=Rt(Te(r,o,"EnableFarAttenuation")),b=Rt(Te(r,o,"CastShadow"))??Rt(Te(i,void 0,"CastShadow"))??Rt(Te(i,void 0,"Shadow")),v=[];2!==h&&v.push(`DecayType ${h} is preserved as metadata; Babylon falloff is not remapped in this pass.`),void 0!==m&&v.push("DecayStart is preserved as metadata and is not mapped to Babylon light range."),n.push({modelId:s.id,name:a,lightType:l,color:c,intensity:u,coneAngle:d,decayType:h,innerAngle:p,outerAngle:f,decayStart:m,enableNearAttenuation:g,enableFarAttenuation:y,castShadows:b,unknownProperties:Xt(r,Lt),diagnostics:v})}return n}(t,n),p=function(e){const t=e.diagnostics.map(t=>({type:"connection-graph",message:t.message,objectId:t.childId,subType:t.reason,parentCount:void 0===t.childId?void 0:e.connections.filter(e=>e.childId===t.childId).length}));for(const[n,o]of Array.from(e.objects)){const r=re(o,2)??"";"Constraint"!==o.name?_t.has(o.name)?t.push(Nt(e,n,o,"unsupported-helper",`${o.name} helper data is preserved as diagnostic data but not evaluated at runtime.`)):"LayeredTexture"!==o.name?"Pose"!==o.name||"BindPose"===r?"Deformer"!==o.name||Ot(r)?"NodeAttribute"===o.name&&r&&"Camera"!==r&&"Light"!==r&&t.push(Nt(e,n,o,"unsupported-node-attribute",`NodeAttribute subtype '${r}' is preserved as diagnostic data but not converted to a Babylon object.`)):t.push(Nt(e,n,o,"unsupported-deformer",`Deformer subtype '${r}' is preserved as diagnostic data but not evaluated at runtime.`)):t.push(Nt(e,n,o,"unsupported-pose",`Pose subtype '${r}' is preserved as diagnostic data but not evaluated at runtime.`)):t.push(Nt(e,n,o,"unsupported-layered-texture","LayeredTexture is preserved as diagnostic data; runtime texture layer blending is not implemented.")):t.push(Nt(e,n,o,"unsupported-constraint",`Constraint '${r||se(re(o,1)??"")}' is preserved as diagnostic data but not evaluated at runtime.`))}return t}(t),d=function(e,t,n,o){const r=new Map;for(const e of t)r.set(e.id,e);const s=new Map;for(const e of n)s.set(e.id,e);const i=e.childrenOf.get(0)??[],a=[];for(const{id:t}of i){const n=e.objects.get(t);n&&"Model"===n.name&&a.push(Bt(t,n,e,r,s,o))}return a}(t,s,r,n);return{rootModels:d,geometries:s,materials:r,skins:i,rigs:a,blendShapes:l,animations:c,cameras:u,lights:f,diagnostics:p,...o}}function Bt(e,t,n,o,r,s){const i=se(re(t,1)??"Model"),a=re(t,2)??"Null",l=ie(n,e,"Geometry"),c=l.length>0?o.get(l[0].id):void 0,u=ie(n,e,"Material"),f=[];for(const{id:e}of u){const t=r.get(e);t&&f.push(t)}const p=function(e,t){const n=Ce(e,t,"Lcl Translation",[0,0,0]),o=Ce(e,t,"Lcl Rotation",[0,0,0]),r=Ce(e,t,"Lcl Scaling",[1,1,1]),s=Ce(e,t,"PreRotation",[0,0,0]),i=Ce(e,t,"PostRotation",[0,0,0]),a=Ce(e,t,"RotationPivot",[0,0,0]),l=Ce(e,t,"ScalingPivot",[0,0,0]),c=Ce(e,t,"RotationOffset",[0,0,0]),u=Ce(e,t,"ScalingOffset",[0,0,0]),f=Ce(e,t,"GeometricTranslation",[0,0,0]),p=Ce(e,t,"GeometricRotation",[0,0,0]),d=Ce(e,t,"GeometricScaling",[1,1,1]),h=Se(e,t,"RotationOrder",0),m=Se(e,t,"InheritType",1);return{translation:n,rotation:o,scale:r,preRotation:s,postRotation:i,rotationPivot:a,scalingPivot:l,rotationOffset:c,scalingOffset:u,geometricTranslation:f,geometricRotation:p,geometricScaling:d,rotationOrder:h,inheritType:m,diagnostics:1!==m&&2!==m?[`InheritType ${m} is parsed and preserved; runtime parent-scale inheritance remains gated to avoid changing existing visual behavior without a fixture-specific baseline.`]:[]}}(t,Ae(s,"Model","FbxNode")??Ae(s,"Model")),d=ie(n,e,"Model"),h=[];for(const{id:e,node:t}of d)h.push(Bt(e,t,n,o,r,s));const m=t.children.find(e=>"Culling"===e.name),g=!!m&&"CullingOff"===re(m,0),y=function(e){const t=ne(e,"Properties70");if(!t)return;const n={};let o=!1;for(const e of t.children){if("P"!==e.name)continue;const t=re(e,0);if(!t||Pt.has(t))continue;const r=e.properties[4]?.value;void 0!==r&&(("string"==typeof r||"number"==typeof r||"boolean"==typeof r)&&(n[t]=r,o=!0))}return o?n:void 0}(t);return{id:e,name:i,subType:a,geometry:c,materials:f,children:h,cullingOff:g,customProperties:y,...p}}const Pt=new Set(["Lcl Translation","Lcl Rotation","Lcl Scaling","PreRotation","PostRotation","RotationPivot","ScalingPivot","RotationOffset","ScalingOffset","RotationOrder","GeometricTranslation","GeometricRotation","GeometricScaling","Visibility","InheritType","ScalingMax","DefaultAttributeIndex","currentUVSet","lockInfluenceWeights"]);const Et=new Set(["FieldOfView","FieldOfViewX","FieldOfViewY","NearPlane","FarPlane","AspectWidth","AspectHeight","FilmAspectRatio","FocalLength","FilmWidth","FilmHeight","ApertureWidth","ApertureHeight","CameraProjectionType","ProjectionType","OrthoZoom","Roll","ApertureMode"]),Lt=new Set(["LightType","Color","Intensity","InnerAngle","OuterAngle","ConeAngle","DecayType","DecayStart","EnableNearAttenuation","EnableFarAttenuation","CastShadow","Shadow"]);function kt(e){if("number"==typeof e)return e}function Rt(e){return"boolean"==typeof e?e:"number"==typeof e?0!==e:void 0}function $t(e,t){const n=kt(Te(e,t,"FilmAspectRatio"));if(void 0!==n&&n>0)return n;const o=kt(Te(e,t,"AspectWidth")),r=kt(Te(e,t,"AspectHeight"));return void 0!==o&&void 0!==r&&o>0&&r>0?o/r:0}function Dt(e,t,n,o,r){const s=kt(Te(e,t,"FieldOfViewY"))??kt(Te(e,t,"FieldOfView"));if(void 0!==s)return s;const i=kt(Te(e,t,"FieldOfViewX"));return void 0!==i?n>0?Vt(2*Math.atan(Math.tan(i*Math.PI/180/2)/n)):i:void 0!==o&&o>0&&void 0!==r&&r>0?Vt(2*Math.atan(25.4*r/(2*o))):45}function Xt(e,t){const n=new Set;for(const o of["Properties70","Properties60"]){const r=ne(e,o);for(const e of r?.children??[]){if("P"!==e.name&&"Property"!==e.name)continue;const o=re(e,0);o&&!t.has(o)&&n.add(o)}}return Array.from(n).sort()}function Vt(e){return 180*e/Math.PI}function jt(t,n,o){const r=e.RotationX(t),s=e.RotationY(n),i=e.RotationZ(o);return r.multiply(s).multiply(i)}function Ut(t,n,o,r){const s=e.RotationX(t),i=e.RotationY(n),a=e.RotationZ(o);switch(r){case 0:default:return s.multiply(i).multiply(a);case 1:return s.multiply(a).multiply(i);case 2:return i.multiply(a).multiply(s);case 3:return i.multiply(s).multiply(a);case 4:return a.multiply(s).multiply(i);case 5:return a.multiply(i).multiply(s)}}function Wt(t,n){const o=Math.PI/180,r=e.Scaling(n[0],n[1],n[2]),s=jt(t[0]*o,t[1]*o,t[2]*o);return r.multiply(s)}class Yt{constructor(e={}){this.name=t.name,this.extensions=t.extensions,this._bindRestBones=new WeakSet,this._sourceBonesBySkeleton=new WeakMap,this._scaleCompensationHelpersBySkeleton=new WeakMap,this._options={normalMapCoordinateSystem:e.normalMapCoordinateSystem??"y-up"}}createPlugin(e){return new Yt(e[t.name])}async importMeshAsync(e,t,n,o,r,s){const i=Ft(this._parse(n));return this._buildScene(i,t,o,e)}async loadAsync(e,t,n,o,r){const s=Ft(this._parse(t));this._buildScene(s,e,n,null)}async loadAssetContainerAsync(e,t,n,o,r){const s=Ft(this._parse(t)),i=new S(e),a=this._buildScene(s,e,n,null);for(const e of a.meshes)i.meshes.push(e);for(const e of a.skeletons)i.skeletons.push(e);for(const e of a.animationGroups)i.animationGroups.push(e);for(const e of a.transformNodes)i.transformNodes.push(e);for(const e of a.lights)i.lights.push(e);for(const e of a.cameras)i.cameras.push(e);for(const e of a.materials)this._addMaterialToContainer(e,i);for(const e of a.textures)this._addTextureToContainer(e,i);for(const e of a.meshes)this._addMaterialToContainer(e.material,i);return this._setAssetContainer(i),i.removeAllFromScene(),i}_parse(e){if(e instanceof ArrayBuffer)return this._parseFromArrayBuffer(e);if(ArrayBuffer.isView(e)){const t=e,n=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return this._parseFromArrayBuffer(n)}if("string"==typeof e)return H(e);throw new Error("FBXFileLoader: unsupported data type")}_parseFromArrayBuffer(e){const t=new Uint8Array(e,0,Math.min(21,e.byteLength));if(String.fromCharCode(...t).startsWith("Kaydara FBX Binary"))return function(e){const t=new DataView(e),n=new Uint8Array(e);if("Kaydara FBX Binary \0"!==Z(n,0,21))throw new Error("Not a valid binary FBX file");if(e.byteLength<27)throw new Error("Truncated binary FBX header");const o=t.getUint32(23,!0),r=o>=7500,s=[];let i=27;for(;i<e.byteLength;){const o=U(t,n,i,r,e.byteLength);if(null===o)break;s.push(o.node),i=o.endOffset}return{version:o,nodes:s}}(e);const n=new TextDecoder("utf-8").decode(e);if(n.trimStart().startsWith("; FBX"))return H(n);throw new Error("FBXFileLoader: unrecognized FBX format")}_buildScene(t,o,r,s){const i=this._buildNameFilter(s),a=new Map;for(const e of t.materials){const t=this._createMaterial(e,o,r);a.set(e.id,t)}const l=[],c=new Map,u=new Map,f=new Map,p=new Map,d=new Map;for(const e of t.skins)d.set(e.id,e);for(const e of t.rigs){const t=this._createSkeleton(e.id,e.bones,o);l.push(t),c.set(e.id,t);for(const n of e.skinBindings){const e=d.get(n.skinId);e&&(u.set(n.geometryId,t),f.set(n.geometryId,e),p.set(n.geometryId,n))}}const h=new Map,m=e=>{for(const t of e)h.set(t.id,t),m(t.children)};m(t.rootModels);const g=Yt._collectCullingConflictMaterialIds(t.rootModels),y=new Map,b=new n("__fbx_root__",o);o.useRightHandedSystem||(b.rotation.y=Math.PI,b.scaling.z=-1);const v=[],x=[b];let M=b;const I=Yt._computeFBXAxisConversionMatrix(t);I.equals(e.Identity())||(M=new n("__fbx_axis_conversion__",o),M.parent=b,Yt._applyMatrixToTransform(M,I),x.push(M));const w=new Map,A=e.Identity();for(const e of t.rootModels)this._buildModel(e,o,M,M,A,a,i,v,x,u,f,p,w,g,y);this._linkSkeletonsToTransformNodes(t.rigs,c,w,x,o);for(const n of t.rigs){const t=c.get(n.id);if(!t)continue;const o=v.find(e=>e.skeleton===t)??null,r=o??b,s=new Set;for(const e of t.bones){const t=e.getTransformNode();t&&s.add(t)}for(const i of n.bones){if(!i.isCluster)continue;const n=w.get(i.modelId),a=this._getSourceBone(t,i.index);if(n&&a)for(const i of[...n.getChildren()]){const n=i;if(!s.has(n)){const s=n.computeWorldMatrix(!0).clone(),i=Yt._getBoneReferenceWorldMatrix(t,a,r,o),l=new e;i.invertToRef(l);const c=s.multiply(l);n.parent=null,n.attachToBone(a,r),Yt._applyMatrixToTransform(n,c)}}}}t.blendShapes.length>0&&this._applyBlendShapes(t.blendShapes,v,o);const T=[];for(const e of t.animations){const n=this._createAnimationGroup(e,t.rigs,c,o,w,h,v);n&&T.push(n)}const S=[];for(const e of t.cameras){const t=this._createCamera(e,w,o);t&&S.push(t)}const C=[];for(const e of t.lights){const t=this._createLight(e,w,o);t&&C.push(t)}return{meshes:v,particleSystems:[],skeletons:l,animationGroups:T,transformNodes:x,geometries:[],lights:C,spriteManagers:[],materials:Array.from(a.values()),textures:Array.from(new Set(Array.from(a.values()).flatMap(e=>e.getActiveTextures()))),cameras:S}}_addMaterialToContainer(e,t){if(e){if(e instanceof o){t.multiMaterials.includes(e)||t.multiMaterials.push(e);for(const n of e.subMaterials)this._addMaterialToContainer(n,t)}else t.materials.includes(e)||t.materials.push(e);for(const n of e.getActiveTextures())this._addTextureToContainer(n,t)}}_addTextureToContainer(e,t){t.textures.includes(e)||t.textures.push(e)}_setAssetContainer(e){for(const t of e.meshes)t._parentContainer=e;for(const t of e.transformNodes)t._parentContainer=e;for(const t of e.skeletons)t._parentContainer=e;for(const t of e.animationGroups)t._parentContainer=e;for(const t of e.lights)t._parentContainer=e;for(const t of e.cameras)t._parentContainer=e;for(const t of e.materials)t._parentContainer=e;for(const t of e.multiMaterials)t._parentContainer=e;for(const t of e.textures)t._parentContainer=e}static _computeFBXAxisConversionMatrix(t){const n=[[0,0,0],[0,0,0],[0,0,0]],o=(e,t,o)=>{if(e<0||e>2)return;const r=[0,0,0];r[o]=t>=0?1:-1,n[e]=r};return o(t.coordAxis,t.coordAxisSign,0),o(t.upAxis,t.upAxisSign,1),o(t.frontAxis,t.frontAxisSign,2),n.some(e=>e.every(e=>0===e))?e.Identity():e.FromValues(n[0][0],n[0][1],n[0][2],0,n[1][0],n[1][1],n[1][2],0,n[2][0],n[2][1],n[2][2],0,0,0,0,1)}_buildModel(t,o,r,s,i,a,l,c,u,f,p,d,h,m,g){const y=Yt._computeFBXModelLocalMatrix(t).multiply(i);if(!t.geometry||"Mesh"!==t.subType||l&&!l(t.name)){if(t.geometry&&"Mesh"===t.subType&&l&&!Yt._modelSubtreeMatchesNameFilter(t,l))return;const e=new n(t.name,o);r&&(e.parent=r),Yt._applyFBXTransform(e,t),u.push(e),h.set(t.id,e),Yt._applyModelMetadata(e,t);for(const n of t.children)this._buildModel(n,o,e,s,y,a,l,c,u,f,p,d,h,m,g)}else{const n=f.get(t.geometry.id),i=p.get(t.geometry.id),b=d.get(t.geometry.id);n&&i&&(n.needInitialSkinMatrix=!0);const v=this._createMesh(t,t.geometry,o,n,i,b);if(n&&i){const t=i.meshBindPoseMatrix?e.FromArray(i.meshBindPoseMatrix):y;v.parent=s,Yt._applyMatrixToTransform(v,t),v.computeWorldMatrix(!0),v.updatePoseMatrix(e.Invert(t)),v.alwaysSelectAsActiveMesh=!0}else r&&(v.parent=r),Yt._applyFBXTransform(v,t);if(t.materials.length>1&&t.geometry?.materialIndices)this._applyMultiMaterial(v,t,a,o,m,g);else if(t.materials.length>0){const e=a.get(t.materials[0].id);e&&(v.material=Yt._getModelMaterial(e,t,g,m.has(t.materials[0].id)))}t.geometry?.colors&&this._useUnmodulatedVertexColorMaterials(v,o),this._applyMaterialUVSetCoordinates(v.material,t.geometry),c.push(v),h.set(t.id,v),Yt._applyModelMetadata(v,t);for(const e of t.children)this._buildModel(e,o,v,s,y,a,l,c,u,f,p,d,h,m,g)}}_linkSkeletonsToTransformNodes(e,t,o,r,s){for(const i of e){const e=t.get(i.id);if(e)for(const t of i.bones){const i=this._getSourceBone(e,t.index),a=o.get(t.modelId);if(!i||!a)continue;const l=this._getScaleCompensationHelper(e,t.index);if(l){const e=new n(l.name,s);e.parent=a.parent,a.parent=e,Yt._applyMatrixToTransform(e,l.getLocalMatrix()),Yt._applyMatrixToTransform(a,i.getLocalMatrix()),l.linkTransformNode(e),r.push(e)}else Yt._applyMatrixToTransform(a,i.getLocalMatrix());i.linkTransformNode(a)}}}static _modelSubtreeMatchesNameFilter(e,t){for(const n of e.children){if(n.geometry&&"Mesh"===n.subType&&t(n.name))return!0;if(Yt._modelSubtreeMatchesNameFilter(n,t))return!0}return!1}static _applyModelMetadata(e,t){(t.customProperties||0!==t.diagnostics.length)&&(e.metadata={...e.metadata??{},...t.customProperties?{fbxCustomProperties:t.customProperties}:{},...t.diagnostics.length>0?{fbxDiagnostics:t.diagnostics}:{}})}_createMesh(t,n,o,l,c,u){const f=new r(t.name,o);f.sideOrientation=o.useRightHandedSystem?s.CounterClockWiseSideOrientation:s.ClockWiseSideOrientation;const p=new i,d=Kt(n.positions),h=t.geometricTranslation,m=t.geometricRotation,g=t.geometricScaling,y=Yt._computeFBXGeometricMatrix(h,m,g),b=Yt._computeFBXGeometricDeltaMatrix(m,g),v=Yt._computeFBXGeometricNormalMatrix(m,g),x=!y.equals(e.Identity()),M=!b.equals(e.Identity()),I=!v.equals(e.Identity());if(x)for(let e=0;e<d.length;e+=3){const t=a.TransformCoordinates(new a(d[e],d[e+1],d[e+2]),y);d[e]=t.x,d[e+1]=t.y,d[e+2]=t.z}let w;if(p.positions=d,p.indices=Array.from(n.indices),n.normals){if(w=Kt(n.normals),I)for(let e=0;e<w.length;e+=3){const t=a.TransformNormal(new a(w[e],w[e+1],w[e+2]),v);t.lengthSquared()>0&&t.normalize(),w[e]=t.x,w[e+1]=t.y,w[e+2]=t.z}p.normals=w}if(n.uvs&&(p.uvs=Kt(n.uvs)),n.uvSets.length>1&&(p.uvs2=Kt(n.uvSets[1].data)),n.uvSets.length>2&&(p.uvs3=Kt(n.uvSets[2].data)),n.uvSets.length>3&&(p.uvs4=Kt(n.uvSets[3].data)),n.uvSets.length>4&&(p.uvs5=Kt(n.uvSets[4].data)),n.uvSets.length>5&&(p.uvs6=Kt(n.uvSets[5].data)),n.tangents){const e=Kt(n.tangents);if(I)for(let t=0;t<e.length;t+=4){const n=a.TransformNormal(new a(e[t],e[t+1],e[t+2]),v);n.lengthSquared()>0&&n.normalize(),e[t]=n.x,e[t+1]=n.y,e[t+2]=n.z}!function(e,t){if(1===t)return;for(let n=3;n<e.length;n+=4)e[n]*=t}(e,this._getNormalMapTangentHandednessScale()),p.tangents=e}else w&&p.uvs&&(p.tangents=function(e,t,n,o,r=1,s=null,i=null){const a=e.length/3,l=new Map,c=new Array(a).fill(null);for(let r=0;r+2<o.length;r+=3){const a=i?i[r/3]:0,u=o[r],f=o[r+1],p=o[r+2],d=3*u,h=3*f,m=3*p,g=2*u,y=2*f,b=2*p,v=e[h]-e[d],x=e[m]-e[d],M=e[h+1]-e[d+1],I=e[m+1]-e[d+1],w=e[h+2]-e[d+2],A=e[m+2]-e[d+2],T=n[y]-n[g],S=n[b]-n[g],C=n[y+1]-n[g+1],_=n[b+1]-n[g+1],O=T*_-S*C;if(Math.abs(O)<1e-8)continue;const N=1/O,F=(_*v-C*x)*N,B=(_*M-C*I)*N,P=(_*w-C*A)*N,E=(T*x-S*v)*N,L=(T*I-S*M)*N,k=(T*A-S*w)*N;zt(u,f,p,F,B,P,E,L,k,e,t,n,s,a,l,c),zt(f,p,u,F,B,P,E,L,k,e,t,n,s,a,l,c),zt(p,u,f,F,B,P,E,L,k,e,t,n,s,a,l,c)}const u=new Float32Array(4*a);for(let e=0;e<a;e++){const n=3*e,o=4*e,[s,i,a]=Gt(t[n],t[n+1],t[n+2]),f=c[e]?l.get(c[e]):void 0,p=f?.tx??0,d=f?.ty??0,h=f?.tz??0,m=s*p+i*d+a*h;let g=p-s*m,y=d-i*m,b=h-a*m;const v=Math.hypot(g,y,b);v>1e-8?(g/=v,y/=v,b/=v):[g,y,b]=Ht(s,i,a);const x=f?.bx??0,M=f?.by??0,I=f?.bz??0,w=i*b-a*y,A=a*g-s*b,T=s*y-i*g,S=Math.hypot(x,M,I)>1e-8&&w*x+A*M+T*I<0?-1:1;u[o]=g,u[o+1]=y,u[o+2]=b,u[o+3]=S*r}return u}(d,w,p.uvs,n.indices,this._getNormalMapTangentHandednessScale(),n.controlPointIndices,n.materialIndices));if(n.colors){const e=new Float32Array(n.colors.length);for(let t=0;t<e.length;t+=4)e[t]=n.colors[t],e[t+1]=n.colors[t+1],e[t+2]=n.colors[t+2],e[t+3]=1;p.colors=e,f.hasVertexAlpha=!1}if(l&&c){const{matricesIndices:e,matricesWeights:t,matricesIndicesExtra:o,matricesWeightsExtra:r,numBoneInfluencers:s}=this._buildSkinningData(n,c,u);p.matricesIndices=e,p.matricesWeights=t,o&&r&&(p.matricesIndicesExtra=o,p.matricesWeightsExtra=r),f.numBoneInfluencers=s}return p.applyToMesh(f),f.metadata={...f.metadata??{},fbxGeometryId:n.id,fbxControlPointIndices:n.controlPointIndices,fbxGeometryDeltaMatrix:M?b:null,fbxGeometryNormalMatrix:I?v:null,fbxPreRotMatrix:M?b:null},l&&(f.skeleton=l),f}_applyMultiMaterial(e,t,n,r,s,i){const a=t.geometry.materialIndices,c=e.getIndices();if(!c)return;const u=c.length/3,f=new Map;for(let e=0;e<u;e++){const t=e<a.length?a[e]:0;let n=f.get(t);n||(n=[],f.set(t,n)),n.push(e)}const p=Array.from(f.keys()).sort((e,t)=>e-t),d=[],h=[];for(const e of p){const t=f.get(e),n=d.length;for(const e of t)d.push(c[3*e],c[3*e+1],c[3*e+2]);h.push({start:n,count:3*t.length,matIdx:e})}e.setIndices(d);const m=new o(t.name+"_multi",r);for(const e of h){const o=t.materials[e.matIdx];if(o){const e=n.get(o.id);e?m.subMaterials.push(Yt._getModelMaterial(e,t,i,s.has(o.id))):m.subMaterials.push(null)}else m.subMaterials.push(null)}e.material=m,e.subMeshes=[];const g=e.getTotalVertices();for(let t=0;t<h.length;t++){const n=h[t];new l(t,0,g,n.start,n.count,e)}}static _collectCullingConflictMaterialIds(e){const t=new Map,n=e=>{for(const n of e.materials){const o=t.get(n.id)??{cullingOff:!1,cullingOn:!1};e.cullingOff?o.cullingOff=!0:o.cullingOn=!0,t.set(n.id,o)}for(const t of e.children)n(t)};for(const t of e)n(t);const o=new Set;for(const[e,n]of Array.from(t))n.cullingOff&&n.cullingOn&&o.add(e);return o}static _getModelMaterial(e,t,n,o=!0){if(!t.cullingOff||!e.backFaceCulling)return e;if(!o)return e.backFaceCulling=!1,e;const r=n?.get(e);if(r)return r;const s=e.clone(`${e.name}_CullingOff`);return s.backFaceCulling=!1,n?.set(e,s),s}_applyMaterialUVSetCoordinates(e,t){if(e)if(e instanceof o)for(const n of e.subMaterials)n instanceof y&&this._applyStandardMaterialUVSetCoordinates(n,t);else e instanceof y&&this._applyStandardMaterialUVSetCoordinates(e,t)}_applyStandardMaterialUVSetCoordinates(e,t){for(const n of[e.diffuseTexture,e.bumpTexture,e.emissiveTexture,e.ambientTexture,e.specularTexture,e.opacityTexture,e.reflectionTexture]){if(!n)continue;const e=n.metadata?.fbxUVSetName;if(!e)continue;const o=t.uvSets.findIndex(t=>t.name===e);o>=0&&(n.coordinatesIndex=o)}}_useUnmodulatedVertexColorMaterials(e,t){const n=e.material;if(n)if(n instanceof y){if(!n.diffuseTexture){const t=n.clone(`${n.name}_VertexColor`);t.diffuseColor=new c(1,1,1),e.material=t}}else if(n instanceof o){const r=new o(`${n.name}_VertexColor`,t);r.subMaterials=n.subMaterials.map(e=>{if(e instanceof y&&!e.diffuseTexture){const t=e.clone(`${e.name}_VertexColor`);return t.diffuseColor=new c(1,1,1),t}return e}),e.material=r}}_buildSkinningData(e,t,n){const o=e.positions.length/3,r=new Float32Array(4*o),s=new Float32Array(4*o);let i=null,a=null,l=0;if(e.controlPointIndices){for(let n=0;n<o;n++){const o=e.controlPointIndices[n],r=t.boneIndices[o]??[];l=Math.max(l,Math.min(r.length,8))}l>4&&(i=new Float32Array(4*o),a=new Float32Array(4*o));for(let l=0;l<o;l++){const o=e.controlPointIndices[l],c=t.boneIndices[o]??[],u=t.boneWeights[o]??[];for(let e=0;e<8;e++){const t=e<4?r:i,o=e<4?s:a;if(!t||!o)continue;const f=4*l+e%4;if(e<c.length){const o=c[e],r=n?n.skinBoneIndexToRigBoneIndex[o]:o;if(void 0===r||r<0)throw new Error(`FBXFileLoader: missing rig bone mapping for skin bone index ${o}`);t[f]=r}else t[f]=0;o[f]=e<u.length?u[e]:0}}}return{matricesIndices:r,matricesWeights:s,matricesIndicesExtra:i,matricesWeightsExtra:a,numBoneInfluencers:Math.max(l,1)}}_createMaterial(e,t,n){const o=new y(e.name,t),r=e.properties,i=(...t)=>e.textures.some(e=>t.includes(e.propertyName));if("Lambert"===e.type&&(o.specularColor=c.Black()),r.diffuseColor){const e=i("DiffuseColor","Diffuse")?1:r.diffuseFactor??1;o.diffuseColor=new c(r.diffuseColor[0]*e,r.diffuseColor[1]*e,r.diffuseColor[2]*e)}if(r.ambientColor){const e=i("AmbientColor","Ambient")?1:r.ambientFactor??1;o.ambientColor=new c(r.ambientColor[0]*e,r.ambientColor[1]*e,r.ambientColor[2]*e)}if("Phong"===e.type&&r.specularColor){const e=i("SpecularColor","Specular","Shininess","ShininessExponent")?1:r.specularFactor??1;o.specularColor=new c(r.specularColor[0]*e,r.specularColor[1]*e,r.specularColor[2]*e)}if(r.emissiveColor){const e=i("EmissiveColor","Emissive")?1:r.emissiveFactor??1;o.emissiveColor=new c(r.emissiveColor[0]*e,r.emissiveColor[1]*e,r.emissiveColor[2]*e)}void 0!==r.opacity?o.alpha=r.opacity:void 0!==r.transparencyFactor&&(o.alpha=1-r.transparencyFactor),o.alpha<1&&(o.transparencyMode=s.MATERIAL_ALPHABLEND),void 0!==r.shininess&&(o.specularPower=r.shininess);for(const r of e.textures){if(!Yt._isSupportedMaterialTextureSlot(r.propertyName))continue;const e=Yt._createTexture(r,t,n,Yt._isNormalMapTextureSlot(r.propertyName));if(e){switch(r.propertyName){case"DiffuseColor":o.diffuseTexture=e,o.diffuseColor=new c(1,1,1);break;case"NormalMap":case"NormalMapTexture":case"normalCamera":case"Bump":case"BumpFactor":o.bumpTexture=e,this._configureNormalTexture(e,o);break;case"EmissiveColor":o.emissiveTexture=e;break;case"AmbientColor":o.ambientTexture=e;break;case"SpecularColor":o.specularTexture=e;break;case"TransparencyFactor":case"TransparentColor":o.opacityTexture=e,o.transparencyMode=s.MATERIAL_ALPHATESTANDBLEND;break;case"ReflectionColor":case"ReflectionFactor":o.reflectionTexture=e}r.uvTranslation&&(e.uOffset=r.uvTranslation[0],e.vOffset=r.uvTranslation[1]),r.uvScaling&&(e.uScale=r.uvScaling[0],e.vScale=r.uvScaling[1]),void 0!==r.uvRotation&&(e.wAng=r.uvRotation*(Math.PI/180)),void 0!==r.uvSetIndex&&(e.coordinatesIndex=r.uvSetIndex),r.uvSetName&&(e.metadata={...e.metadata??{},fbxUVSetName:r.uvSetName})}}return o}_configureNormalTexture(e,t){e.gammaSpace=!1,t.invertNormalMapX=!1,t.invertNormalMapY="y-down"===this._options.normalMapCoordinateSystem}_getNormalMapTangentHandednessScale(){return"y-down"===this._options.normalMapCoordinateSystem?-1:1}static _isSupportedMaterialTextureSlot(e){switch(e){case"DiffuseColor":case"NormalMap":case"NormalMapTexture":case"normalCamera":case"Bump":case"BumpFactor":case"EmissiveColor":case"AmbientColor":case"SpecularColor":case"TransparencyFactor":case"TransparentColor":case"ReflectionColor":case"ReflectionFactor":case"DisplacementColor":case"Displacement":case"DisplacementFactor":case"ShininessExponent":case"Shininess":return!0;default:return!1}}static _isNormalMapTextureSlot(e){switch(e){case"NormalMap":case"NormalMapTexture":case"normalCamera":case"Bump":case"BumpFactor":return!0;default:return!1}}static _createTexture(e,t,n,o){const r=Yt._getTextureSourceName(e),s=Yt._getTextureCreationOptions(r,o,e.embeddedData);if(e.embeddedData){const n=new u(null,t,s),o=r??`embeddedTexture_${e.id.toString()}`;return n.updateURL(`data:fbx-embedded-texture/${encodeURIComponent(o)}`,new Uint8Array(e.embeddedData),void 0,s.forcedExtension),n.name=o,n}const i=Yt._getExternalTextureUrls(e,n),a=i.shift();return a?Yt._createExternalTexture(a,i,t,s):null}static _createExternalTexture(e,t,n,o){t.push(...Yt._buildTextureFallbackUrls(e));let r=0;const s=new u(e,n,{...o,onError:()=>{const e=t[r++];e&&s.getScene()&&s.updateURL(e,null,void 0,Yt._getForcedExtension(e))}});return s}static _buildTextureFallbackUrls(e){const t=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\")),n=e.lastIndexOf(".");if(n<=t)return[];const o=e.slice(0,n),r=e.slice(n+1).toLowerCase();return["png","jpg","jpeg","webp","bmp","tga"].filter(e=>e!==r).map(e=>`${o}.${e}`)}static _getTextureCreationOptions(e,t,n){const o=n?e?Yt._getMimeType(e):"image/png":void 0;return{buffer:n?new Uint8Array(n):void 0,forcedExtension:e?Yt._getForcedExtension(e,o):n?".png":void 0,gammaSpace:!t,mimeType:o}}static _getExternalTextureUrls(e,t){const n=[e.relativeFileName,e.fileName].filter(e=>!!e),o=[];for(const e of n){const n=e.replace(/\\/g,"/");Yt._isSafeRelativeTexturePath(n)&&o.push(t+n);const r=Yt._getTextureSourceNameFromPath(n);r&&o.push(t+r)}return Array.from(new Set(o))}static _getTextureSourceName(e){const t=e.relativeFileName||e.fileName;if(!t)return null;const n=t.replace(/\\/g,"/");return Yt._getTextureSourceNameFromPath(n)}static _getTextureSourceNameFromPath(e){return e.split("/").pop()??e}static _isSafeRelativeTexturePath(e){return!(/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e)||e.startsWith("/")||e.startsWith("//"))&&!e.split("/").some(e=>".."===e)}static _getForcedExtension(e,t){const n=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\")),o=e.lastIndexOf(".");if(o>n)return e.slice(o).toLowerCase();switch(t){case"image/png":return".png";case"image/jpeg":return".jpg";case"image/webp":return".webp";case"image/bmp":return".bmp";case"image/gif":return".gif";case"image/x-tga":return".tga";default:return}}static _getMimeType(e){const t=f(e);if(t)return t;switch(Yt._getForcedExtension(e)){case".tga":return"image/x-tga";case".bmp":return"image/bmp";case".gif":return"image/gif";default:return"image/png"}}_applyBlendShapes(e,t,n){for(const o of e){const e=t.find(e=>{const t=e.metadata?.fbxGeometryId;return t===o.geometryId});if(!e)continue;const r=new M(n);r.optimizeInfluencers=!1;const s=e.metadata?.fbxGeometryDeltaMatrix??e.metadata?.fbxPreRotMatrix??null,i=e.metadata?.fbxGeometryNormalMatrix??s;for(const t of o.channels){const o=e.metadata?.fbxControlPointIndices;if(!o)continue;const a=e.getVerticesData("position"),l=e.getVerticesData("normal");if(!a)continue;const c=qt(t.deformPercent,t.fullWeights,t.shapes.length),u=[];for(let e=0;e<t.shapes.length;e++){const f=t.shapes[e];if(!f)continue;const p=Qt(f,o,a,l,s,i);if(!p)continue;const d=t.fullWeights&&t.shapes.length>1?`${t.name}_${t.fullWeights[e]}`:t.name,h=new I(d,c[e]??0,n);h.setPositions(p.positions),p.normals&&h.setNormals(p.normals),u.push(r.numTargets),r.addTarget(h)}0!==u.length&&(e.metadata||(e.metadata={}),e.metadata.fbxBlendShapeChannelIds||(e.metadata.fbxBlendShapeChannelIds=new Map),e.metadata.fbxBlendShapeChannelIds.set(t.id,u[0]),e.metadata.fbxBlendShapeChannelTargets||(e.metadata.fbxBlendShapeChannelTargets=new Map),e.metadata.fbxBlendShapeChannelTargets.set(t.id,{targetIndices:u,fullWeights:t.fullWeights}))}r.numTargets>0&&(r.numMaxInfluencers=r.numTargets,e.morphTargetManager=r)}}_createCamera(t,n,o){const r=n.get(t.modelId),s=r?r.computeWorldMatrix(!0):e.Identity(),i=a.TransformCoordinates(a.Zero(),s),l=new w(t.name,i,o);if(l.fov=t.fieldOfView*(Math.PI/180),l.minZ=t.nearPlane,l.maxZ=t.farPlane,l.metadata={...l.metadata??{},fbxCamera:{projectionType:t.projectionType,focalLength:t.focalLength,filmWidth:t.filmWidth,filmHeight:t.filmHeight,orthoZoom:t.orthoZoom,roll:t.roll,aspectRatio:t.aspectRatio,unknownProperties:t.unknownProperties,diagnostics:t.diagnostics}},"orthographic"===t.projectionType){const e=t.orthoZoom&&t.orthoZoom>0?t.orthoZoom:1,n=t.aspectRatio>0?t.aspectRatio:1;l.mode=p.ORTHOGRAPHIC_CAMERA,l.orthoTop=e/2,l.orthoBottom=-e/2,l.orthoRight=e*n/2,l.orthoLeft=-e*n/2}const c=a.TransformCoordinates(new a(1,0,0),s);return l.setTarget(c),l}_createLight(t,n,o){const r=n.get(t.modelId),s=r?r.computeWorldMatrix(!0):e.Identity(),i=a.TransformCoordinates(a.Zero(),s),l=new c(t.color[0],t.color[1],t.color[2]),u=a.TransformCoordinates(new a(0,0,-1),s).subtract(i).normalize();let f;switch(t.lightType){case 1:f=new d(t.name,u,o),f.diffuse=l,f.intensity=t.intensity;break;case 2:{const e=t.coneAngle*(Math.PI/180);f=new T(t.name,i,u,e,2,o),f.diffuse=l,f.intensity=t.intensity;break}default:f=new A(t.name,i,o),f.diffuse=l,f.intensity=t.intensity}return f.metadata={...f.metadata??{},fbxLight:{lightType:t.lightType,decayType:t.decayType,decayStart:t.decayStart,innerAngle:t.innerAngle,outerAngle:t.outerAngle,enableNearAttenuation:t.enableNearAttenuation,enableFarAttenuation:t.enableFarAttenuation,castShadows:t.castShadows,unknownProperties:t.unknownProperties,diagnostics:t.diagnostics}},f}_createSkeleton(t,n,o){const r=new b("Skeleton",`skeleton_${t}`,o),s=[],i=new Map,a=[],l=[],c=[];for(let e=0;e<n.length;e++){const t=n[e],o=Yt._computeFBXLocalMatrix(t.translation,t.rotation,t.scale,t.preRotation,t.postRotation,t.rotationPivot,t.scalingPivot,t.rotationOffset,t.scalingOffset,t.rotationOrder);a[e]=o,c[e]=Yt._computeFBXRuntimeLocalMatrix(n,o,e)}l.push(...Yt._computeFBXAbsoluteMatrices(n,c));const u=n.map((t,n)=>t.transformLinkMatrix?e.FromArray(t.transformLinkMatrix):t.modelBindPoseMatrix?e.FromArray(t.modelBindPoseMatrix):l[n]),f=u.map((t,o)=>{const r=n[o].parentIndex;if(r<0)return t;const s=new e;return u[r].invertToRef(s),t.multiply(s)}),p=Yt._shouldUseBindMatricesAsRest(n,a,f);for(let t=0;t<n.length;t++){let o=p?f[t]:c[t],l=n[t].parentIndex>=0?s[n[t].parentIndex]:null;if(!p&&2===n[t].inheritType&&n[t].parentIndex>=0&&l){const s=Yt._splitParentScaleCompensatedLocalMatrix(a[t],n[n[t].parentIndex].scale),c=new v(`${n[t].name}__fbx_scaleCompensation`,r,l,s.helperLocalMatrix,s.helperLocalMatrix.clone(),e.Identity(),-1);c.metadata={...c.metadata??{},fbxScaleCompensationForBoneIndex:t,fbxScaleCompensationForBoneName:n[t].name},i.set(t,c),l=c,o=s.boneLocalMatrix}const u=new v(n[t].name,r,l,o,p?o.clone():null,p?o.clone():null,t);p&&n[t].isCluster&&Yt._getMaxScaleRatio(a[t],f[t])>=10&&this._bindRestBones.add(u),s.push(u)}if(this._sourceBonesBySkeleton.set(r,s),this._scaleCompensationHelpersBySkeleton.set(r,i),!p){for(let e=0;e<n.length;e++){s[e].updateMatrix(f[e],!1,!1)}for(const t of Array.from(i.values()))t.updateMatrix(e.Identity(),!1,!1);for(const e of r.bones)e.getParent()||e._updateAbsoluteBindMatrices(void 0,!0)}return r}_getSourceBone(e,t){return this._sourceBonesBySkeleton.get(e)?.[t]??e.bones[t]}_getScaleCompensationHelper(e,t){return this._scaleCompensationHelpersBySkeleton.get(e)?.get(t)}static _computeFBXAbsoluteMatrices(e,t){const n=[];for(let o=0;o<e.length;o++){const r=e[o].parentIndex;r<0?n[o]=t[o].clone():n[o]=t[o].multiply(n[r])}return n}static _computeFBXRuntimeLocalMatrix(e,t,n,o){const r=e[n].parentIndex;if(2!==e[n].inheritType||r<0)return t;const s=o??e[r].scale;return Yt._applyParentScaleCompensation(t,s)}static _applyParentScaleCompensation(e,t){const n=Yt._splitParentScaleCompensatedLocalMatrix(e,t);return n.boneLocalMatrix.multiply(n.helperLocalMatrix)}static _splitParentScaleCompensatedLocalMatrix(t,n){const o=t.getTranslation(),r=t.clone();r.setTranslation(a.Zero());return{boneLocalMatrix:r,helperLocalMatrix:e.Compose(Yt._getInverseScaleVector(n),h.Identity(),o)}}static _safeInverseScale(e){return Math.abs(e)>1e-8?1/e:1}static _getInverseScaleVector(e){return new a(Yt._safeInverseScale(e[0]),Yt._safeInverseScale(e[1]),Yt._safeInverseScale(e[2]))}static _shouldUseBindMatricesAsRest(e,t,n){return e.some((e,o)=>!!e.isCluster&&Yt._getMaxScaleRatio(t[o],n[o])>=10)}static _getMaxScaleRatio(e,t){const n=new a,o=new h,r=new a,s=new a,i=new h,l=new a;return e.decompose(n,o,r),t.decompose(s,i,l),Math.max(Yt._getScaleRatio(n.x,s.x),Yt._getScaleRatio(n.y,s.y),Yt._getScaleRatio(n.z,s.z))}static _getScaleRatio(e,t){const n=Math.abs(e),o=Math.abs(t);return n<1e-6||o<1e-6?n<1e-6&&o<1e-6?1:Number.POSITIVE_INFINITY:Math.max(n/o,o/n)}static _computeFBXGeometricMatrix(t,n,o){return function(t,n,o){const r=e.Translation(t[0],t[1],t[2]);return Wt(n,o).multiply(r)}(t,n,o)}static _computeFBXGeometricDeltaMatrix(e,t){return Wt(e,t)}static _computeFBXGeometricNormalMatrix(t,n){return function(t,n){const o=Math.PI/180,r=e.Scaling(0===n[0]?0:1/n[0],0===n[1]?0:1/n[1],0===n[2]?0:1/n[2]),s=jt(t[0]*o,t[1]*o,t[2]*o);return r.multiply(s)}(t,n)}static _computeFBXLocalMatrix(t,n,o,r,s,i,a,l,c,u=0){return function(t){const{translation:n,rotation:o,scale:r,preRotation:s,postRotation:i,rotationPivot:a,scalingPivot:l,rotationOffset:c,scalingOffset:u,rotationOrder:f}=t,p=Math.PI/180,d=0!==a[0]||0!==a[1]||0!==a[2]||0!==l[0]||0!==l[1]||0!==l[2],h=0!==c[0]||0!==c[1]||0!==c[2]||0!==u[0]||0!==u[1]||0!==u[2],m=0!==i[0]||0!==i[1]||0!==i[2];if(!d&&!h&&!m){const t=jt(s[0]*p,s[1]*p,s[2]*p),i=Ut(o[0]*p,o[1]*p,o[2]*p,f),a=e.Translation(n[0],n[1],n[2]),l=i.multiply(t);return e.Scaling(r[0],r[1],r[2]).multiply(l).multiply(a)}const g=e.Translation(n[0],n[1],n[2]),y=e.Translation(c[0],c[1],c[2]),b=e.Translation(a[0],a[1],a[2]),v=e.Translation(-a[0],-a[1],-a[2]),x=e.Translation(u[0],u[1],u[2]),M=e.Translation(l[0],l[1],l[2]),I=e.Translation(-l[0],-l[1],-l[2]),w=jt(s[0]*p,s[1]*p,s[2]*p),A=Ut(o[0]*p,o[1]*p,o[2]*p,f),T=e.Scaling(r[0],r[1],r[2]);let S;if(m){const t=jt(i[0]*p,i[1]*p,i[2]*p);S=new e,t.invertToRef(S)}else S=e.Identity();let C=I;return C=C.multiply(T),C=C.multiply(M),C=C.multiply(x),C=C.multiply(v),C=C.multiply(S),C=C.multiply(A),C=C.multiply(w),C=C.multiply(b),C=C.multiply(y),C=C.multiply(g),C}({translation:t,rotation:n,scale:o,preRotation:r,postRotation:s,rotationPivot:i,scalingPivot:a,rotationOffset:l,scalingOffset:c,rotationOrder:u})}static _applyFBXTransform(e,t){const n=Yt._computeFBXModelLocalMatrix(t),o=new a,r=new h,s=new a;n.decompose(o,r,s),e.position=s,e.rotationQuaternion=r,e.scaling=o}static _computeFBXModelLocalMatrix(e){return Yt._computeFBXLocalMatrix(e.translation,e.rotation,e.scale,e.preRotation,e.postRotation,e.rotationPivot,e.scalingPivot,e.rotationOffset,e.scalingOffset,e.rotationOrder)}static _getBoneReferenceWorldMatrix(e,t,n,o){return o?e.getTransformMatrices(o):e.prepare(!0),n.computeWorldMatrix(!0),t.getFinalMatrix().multiply(n.getWorldMatrix())}static _applyMatrixToTransform(e,t){const n=new a,o=new h,r=new a;t.decompose(n,o,r),e.position=r,e.rotationQuaternion=o,e.scaling=n}_createAnimationGroup(e,t,n,o,r,s,i){if(0===e.curveNodes.length)return null;const a=new x(e.name,o),l=new Map,c=(e,t)=>{const n=t.getTransformNode()??t;let o=l.get(n);if(o){if(o.has(e.targetProperty))return}else o=new Set,l.set(n,o);o.add(e.targetProperty),a.addTargetedAnimation(e,n)},u=new Map;for(const e of t){const t=n.get(e.id);if(t)for(const n of e.bones){const e=this._getSourceBone(t,n.index);if(!e)continue;const o=u.get(n.modelId);o?o.push(e):u.set(n.modelId,[e])}}const f=new Map,p=new Map,d=[];for(const t of e.curveNodes)"DeformPercent"!==t.type?u.has(t.targetModelId)?(f.has(t.targetModelId)||f.set(t.targetModelId,[]),f.get(t.targetModelId).push(t)):(p.has(t.targetModelId)||p.set(t.targetModelId,[]),p.get(t.targetModelId).push(t)):d.push(t);const h=new Set;for(const o of t){const t=new Set(o.bones.filter(e=>2===e.inheritType).map(e=>e.modelId));if(0===t.size)continue;const r=n.get(o.id);if(r&&!r.bones.some(e=>this._bindRestBones.has(e))){for(const e of Array.from(t))h.add(e);for(const{bone:n,animations:i}of this._buildInheritedRigBoneAnimations(o,r,f,s,t,e.startTime,e.stopTime))for(const e of i)c(e,n)}}for(const[t,n]of Array.from(f)){if(h.has(t))continue;const o=u.get(t),r=s.get(t);if(o&&0!==o.length&&r)for(const t of o){const o=this._buildBoneAnimations(n,t.name,r,e.startTime,e.stopTime,this._bindRestBones.has(t)?t.getBindMatrix():void 0);for(const e of o)c(e,t)}}for(const[t,n]of Array.from(p)){const o=r.get(t);if(!o)continue;const i=s.get(t);if(!i)continue;const l=this._buildNodeAnimations(n,o.name,i,e.startTime,e.stopTime);for(const e of l)a.addTargetedAnimation(e,o)}for(const t of d){const n=t.targetModelId;let o=!1;for(const r of i){if(!r.morphTargetManager||o)continue;const s=r.metadata,i=s?.fbxBlendShapeChannelTargets,l=i?.get(n);if(l&&t.curves.length>0){const n=30;for(let o=0;o<l.targetIndices.length;o++){const s=r.morphTargetManager.getTarget(l.targetIndices[o]);if(!s)continue;const i=new m(`${s.name}_influence`,"influence",n,m.ANIMATIONTYPE_FLOAT,m.ANIMATIONLOOPMODE_CYCLE),c=nn(t.curves[0],n,e.startTime,e.stopTime,e=>qt(e,l.fullWeights,l.targetIndices.length)[o]??0);i.setKeys(c),a.addTargetedAnimation(i,s)}o=!0;continue}const c=s?.fbxBlendShapeChannelIds;if(!c)continue;const u=c.get(n);if(void 0===u)continue;const f=r.morphTargetManager.getTarget(u);if(f&&t.curves.length>0){const n=30,r=new m(`${f.name}_influence`,"influence",n,m.ANIMATIONTYPE_FLOAT,m.ANIMATIONLOOPMODE_CYCLE),s=nn(t.curves[0],n,e.startTime,e.stopTime,e=>e/100);r.setKeys(s),a.addTargetedAnimation(r,f),o=!0}}}return a.targetedAnimations.length>0?(a.normalize(30*e.startTime,30*e.stopTime),a):(a.dispose(),null)}_buildInheritedRigBoneAnimations(t,n,o,r,s,i,a){const l=30,c=new Set;for(let e=0;e<t.bones.length;e++)if(s.has(t.bones[e].modelId))for(let n=e;n>=0;n=t.bones[n].parentIndex)c.add(t.bones[n].modelId);const u=en(t.bones.filter(e=>c.has(e.modelId)).flatMap(e=>o.get(e.modelId)??[]),l,i,a);if(0===u.length)return[];const f=t.bones.map(()=>({posKeys:[],rotKeys:[],sclKeys:[],prevQuat:null})),p=t.bones.map(()=>({posKeys:[],rotKeys:[],sclKeys:[],prevQuat:null})),d=t.bones.map((t,o)=>{const s=this._getSourceBone(n,o),i=r.get(t.modelId);if(!s||!i||!this._bindRestBones.has(s))return null;const a=Yt._computeFBXModelLocalMatrix(i),l=new e;return a.invertToRef(l),l});for(const i of u){const a=t.bones.map((t,s)=>{const a=r.get(t.modelId),l=o.get(t.modelId)??[];let c=a?this._sampleModelLocalMatrix(a,l,i):e.Identity();const u=d[s];if(u){const t=this._getSourceBone(n,s);c=(t?.getBindMatrix()??e.Identity()).multiply(u).multiply(c)}return c}),c=t.bones.map(e=>{const t=r.get(e.modelId),n=o.get(e.modelId)??[];return t?this._sampleModelScale(t,n,i):e.scale}),u=i*l;for(let e=0;e<a.length;e++){if(!s.has(t.bones[e].modelId))continue;const n=t.bones[e].parentIndex,o=n>=0?c[n]:t.bones[e].scale,r=Yt._splitParentScaleCompensatedLocalMatrix(a[e],o);Yt._pushMatrixKeys(f[e],u,r.boneLocalMatrix),Yt._pushMatrixKeys(p[e],u,r.helperLocalMatrix)}}const h=[];for(let e=0;e<t.bones.length;e++){if(!s.has(t.bones[e].modelId))continue;const o=this._getSourceBone(n,e);if(!o)continue;const{posKeys:r,rotKeys:i,sclKeys:a}=f[e],c=[];if(!this._isVector3KeysConstant(r)){const e=new m(`${o.name}_position`,"position",l,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(r),c.push(e)}if(!tn(i)){const e=new m(`${o.name}_rotation`,"rotationQuaternion",l,m.ANIMATIONTYPE_QUATERNION,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(i),c.push(e)}if(!this._isVector3KeysConstant(a)){const e=new m(`${o.name}_scaling`,"scaling",l,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(a),c.push(e)}c.length>0&&h.push({bone:o,animations:c});const u=this._getScaleCompensationHelper(n,e);if(!u)continue;const d=[],{posKeys:g,rotKeys:y,sclKeys:b}=p[e];if(!this._isVector3KeysConstant(g)){const e=new m(`${u.name}_position`,"position",l,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(g),d.push(e)}if(!tn(y)){const e=new m(`${u.name}_rotation`,"rotationQuaternion",l,m.ANIMATIONTYPE_QUATERNION,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(y),d.push(e)}if(!this._isVector3KeysConstant(b)){const e=new m(`${u.name}_scaling`,"scaling",l,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(b),d.push(e)}d.length>0&&h.push({bone:u,animations:d})}return h}static _pushMatrixKeys(e,t,n){const o=new a,r=new h,s=new a;n.decompose(o,r,s),e.prevQuat&&h.Dot(e.prevQuat,r)<0&&r.scaleInPlace(-1),e.prevQuat=r,e.posKeys.push({frame:t,value:s}),e.rotKeys.push({frame:t,value:r}),e.sclKeys.push({frame:t,value:o})}_buildNodeAnimations(e,t,n,o,r){const s=e.find(e=>"T"===e.type),i=e.find(e=>"R"===e.type),l=e.find(e=>"S"===e.type),c=en(e,30,o,r);if(0===c.length)return[];const u=s?.curves.find(e=>"d|X"===e.channel),f=s?.curves.find(e=>"d|Y"===e.channel),p=s?.curves.find(e=>"d|Z"===e.channel),d=i?.curves.find(e=>"d|X"===e.channel),g=i?.curves.find(e=>"d|Y"===e.channel),y=i?.curves.find(e=>"d|Z"===e.channel),b=l?.curves.find(e=>"d|X"===e.channel),v=l?.curves.find(e=>"d|Y"===e.channel),x=l?.curves.find(e=>"d|Z"===e.channel),M=[],I=[],w=[];let A=null;for(const e of c){const t=30*e,o=mt(u,e)??n.translation[0],r=mt(f,e)??n.translation[1],s=mt(p,e)??n.translation[2],i=mt(d,e)??n.rotation[0],l=mt(g,e)??n.rotation[1],c=mt(y,e)??n.rotation[2],m=mt(b,e)??n.scale[0],T=mt(v,e)??n.scale[1],S=mt(x,e)??n.scale[2],C=Yt._computeFBXLocalMatrix([o,r,s],[i,l,c],[m,T,S],n.preRotation,n.postRotation,n.rotationPivot,n.scalingPivot,n.rotationOffset,n.scalingOffset,n.rotationOrder),_=new a,O=new h,N=new a;C.decompose(_,O,N),A&&h.Dot(A,O)<0&&O.scaleInPlace(-1),A=O,M.push({frame:t,value:N}),I.push({frame:t,value:O}),w.push({frame:t,value:_})}const T=[];if(!this._isVector3KeysConstant(M)){const e=new m(`${t}_position`,"position",30,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(M),T.push(e)}if(i){const e=new m(`${t}_rotation`,"rotationQuaternion",30,m.ANIMATIONTYPE_QUATERNION,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(I),T.push(e)}if(!this._isVector3KeysConstant(w)){const e=new m(`${t}_scaling`,"scaling",30,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(w),T.push(e)}return T}_isVector3KeysConstant(e){if(e.length<2)return!0;const t=e[0].value;for(let n=1;n<e.length;n++){const o=e[n].value;if(Math.abs(o.x-t.x)>1e-4||Math.abs(o.y-t.y)>1e-4||Math.abs(o.z-t.z)>1e-4)return!1}return!0}_sampleModelLocalMatrix(e,t,n,o){const r=t.find(e=>"T"===e.type),s=t.find(e=>"R"===e.type),i=t.find(e=>"S"===e.type),a=r?.curves.find(e=>"d|X"===e.channel),l=r?.curves.find(e=>"d|Y"===e.channel),c=r?.curves.find(e=>"d|Z"===e.channel),u=s?.curves.find(e=>"d|X"===e.channel),f=s?.curves.find(e=>"d|Y"===e.channel),p=s?.curves.find(e=>"d|Z"===e.channel),d=i?.curves.find(e=>"d|X"===e.channel),h=i?.curves.find(e=>"d|Y"===e.channel),m=i?.curves.find(e=>"d|Z"===e.channel);return Yt._computeFBXLocalMatrix([mt(a,n)??e.translation[0],mt(l,n)??e.translation[1],mt(c,n)??e.translation[2]],[mt(u,n)??e.rotation[0],mt(f,n)??e.rotation[1],mt(p,n)??e.rotation[2]],o??[mt(d,n)??e.scale[0],mt(h,n)??e.scale[1],mt(m,n)??e.scale[2]],e.preRotation,e.postRotation,e.rotationPivot,e.scalingPivot,e.rotationOffset,e.scalingOffset,e.rotationOrder)}_sampleModelScale(e,t,n){const o=t.find(e=>"S"===e.type),r=o?.curves.find(e=>"d|X"===e.channel),s=o?.curves.find(e=>"d|Y"===e.channel),i=o?.curves.find(e=>"d|Z"===e.channel);return[mt(r,n)??e.scale[0],mt(s,n)??e.scale[1],mt(i,n)??e.scale[2]]}_buildBoneAnimations(t,n,o,r,s,i){const l=t.find(e=>"T"===e.type),c=t.find(e=>"R"===e.type),u=t.find(e=>"S"===e.type),f=en(t,30,r,s);if(0===f.length)return[];const p=l?.curves.find(e=>"d|X"===e.channel),d=l?.curves.find(e=>"d|Y"===e.channel),g=l?.curves.find(e=>"d|Z"===e.channel),y=c?.curves.find(e=>"d|X"===e.channel),b=c?.curves.find(e=>"d|Y"===e.channel),v=c?.curves.find(e=>"d|Z"===e.channel),x=u?.curves.find(e=>"d|X"===e.channel),M=u?.curves.find(e=>"d|Y"===e.channel),I=u?.curves.find(e=>"d|Z"===e.channel),w=[],A=[],T=[];let S=null,C=null;if(i){const t=Yt._computeFBXLocalMatrix(o.translation,o.rotation,o.scale,o.preRotation,o.postRotation,o.rotationPivot,o.scalingPivot,o.rotationOffset,o.scalingOffset,o.rotationOrder);C=new e,t.invertToRef(C)}for(const e of f){const t=30*e,n=mt(p,e)??o.translation[0],r=mt(d,e)??o.translation[1],s=mt(g,e)??o.translation[2],l=mt(y,e)??o.rotation[0],c=mt(b,e)??o.rotation[1],u=mt(v,e)??o.rotation[2],f=mt(x,e)??o.scale[0],m=mt(M,e)??o.scale[1],_=mt(I,e)??o.scale[2],O=Yt._computeFBXLocalMatrix([n,r,s],[l,c,u],[f,m,_],o.preRotation,o.postRotation,o.rotationPivot,o.scalingPivot,o.rotationOffset,o.scalingOffset,o.rotationOrder),N=C&&i?i.multiply(C).multiply(O):O,F=new a,B=new h,P=new a;N.decompose(F,B,P),S&&h.Dot(S,B)<0&&B.scaleInPlace(-1),S=B,w.push({frame:t,value:P}),A.push({frame:t,value:B}),T.push({frame:t,value:F})}const _=[];if(!this._isVector3KeysConstant(w)){const e=new m(`${n}_position`,"position",30,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(w),_.push(e)}if(c){const e=new m(`${n}_rotation`,"rotationQuaternion",30,m.ANIMATIONTYPE_QUATERNION,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(A),_.push(e)}if(!this._isVector3KeysConstant(T)){const e=new m(`${n}_scaling`,"scaling",30,m.ANIMATIONTYPE_VECTOR3,m.ANIMATIONLOOPMODE_CYCLE);e.setKeys(T),_.push(e)}return _}_buildNameFilter(e){if(!e)return null;if("string"==typeof e)return""===e?null:t=>t===e;if(0===e.length)return null;const t=new Set(e);return e=>t.has(e)}}function Kt(e){const t=new Float32Array(e.length);for(let n=0;n<e.length;n++)t[n]=e[n];return t}function zt(e,t,n,o,r,s,i,a,l,c,u,f,p,d,h,m){const g=function(e,t,n,o){const r=3*t,s=3*n,i=3*o,a=e[s]-e[r],l=e[s+1]-e[r+1],c=e[s+2]-e[r+2],u=e[i]-e[r],f=e[i+1]-e[r+1],p=e[i+2]-e[r+2],d=Math.hypot(a,l,c),h=Math.hypot(u,f,p);if(d<=1e-8||h<=1e-8)return 0;const m=(a*u+l*f+c*p)/(d*h);return Math.acos(Math.max(-1,Math.min(1,m)))}(c,e,t,n);if(g<=1e-8)return;const y=function(e,t,n,o,r,s,i,a,l,c,u,f){const p=3*e,d=3*e,h=2*e,[m,g,y]=Gt(l[d],l[d+1],l[d+2]),b=function(e,t,n,o,r,s,i,a,l){const c=t*s-n*r,u=n*o-e*s,f=e*r-t*o;return c*i+u*a+f*l<0?-1:1}(m,g,y,t,n,o,r,s,i),v=u?`cp:${u[e]}`:`p:${Zt(a[p])},${Zt(a[p+1])},${Zt(a[p+2])}`;return[v,Zt(m),Zt(g),Zt(y),Zt(c[h]),Zt(c[h+1]),b,f].join("|")}(e,o,r,s,i,a,l,c,u,f,p,d);let b=h.get(y);b||(b={tx:0,ty:0,tz:0,bx:0,by:0,bz:0},h.set(y,b)),b.tx+=o*g,b.ty+=r*g,b.tz+=s*g,b.bx+=i*g,b.by+=a*g,b.bz+=l*g,m[e]??=y}function Gt(e,t,n){const o=Math.hypot(e,t,n);return o>1e-8?[e/o,t/o,n/o]:[0,0,1]}function Zt(e){const t=Math.round(1e6*e);return Object.is(t,-0)?0:t}function Ht(e,t,n){const o=Math.abs(e)<.9?1:0,r=1===o?0:1,s=e*o+t*r;let i=o-e*s,a=r-t*s,l=-n*s;const c=Math.hypot(i,a,l);return c<=1e-8?[1,0,0]:(i/=c,a/=c,l/=c,[i,a,l])}function Qt(e,t,n,o,r,s){const i=n.length/3,l=new Float32Array(3*i),c=null!==e.normals&&null!==o?new Float32Array(3*i):null;for(let e=0;e<l.length;e++)l[e]=n[e];if(c&&o)for(let e=0;e<c.length;e++)c[e]=o[e];const u=new Map;for(let t=0;t<e.indices.length;t++)u.set(e.indices[t],t);for(let n=0;n<i;n++){const o=t[n],i=u.get(o);if(void 0===i)continue;let f=e.vertices[3*i],p=e.vertices[3*i+1],d=e.vertices[3*i+2];if(r){const e=a.TransformNormal(new a(f,p,d),r);f=e.x,p=e.y,d=e.z}if(l[3*n]+=f,l[3*n+1]+=p,l[3*n+2]+=d,c&&e.normals){let t=e.normals[3*i],o=e.normals[3*i+1],r=e.normals[3*i+2];if(s){const e=a.TransformNormal(new a(t,o,r),s);e.lengthSquared()>0&&e.normalize(),t=e.x,o=e.y,r=e.z}c[3*n]+=t,c[3*n+1]+=o,c[3*n+2]+=r}}return{positions:l,normals:c}}function qt(e,t,n){if(n<=0)return[];if(!t||t.length!==n||1===n){return[Jt(e/(t?.[0]&&0!==t[0]?t[0]:100))]}const o=new Array(n).fill(0);if(e<=t[0])return o[0]=0===t[0]?e<=0?1:0:Jt(e/t[0]),o;for(let n=1;n<t.length;n++){const r=t[n-1],s=t[n];if(e>s)continue;const i=s-r;if(Math.abs(i)<1e-6)return o[n]=1,o;const a=Jt((e-r)/i);return o[n-1]=1-a,o[n]=a,o}return o[n-1]=1,o}function Jt(e){return Math.max(0,Math.min(1,e))}function en(e,t,n,o){let r=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;const i=new Set;for(const t of e)for(const e of t.curves)for(const t of e.keys)r=Math.min(r,t.time),s=Math.max(s,t.time),t.time>=n&&t.time<=o&&i.add(t.time);if(!Number.isFinite(r)||!Number.isFinite(s))return[];const a=o>n?n:r,l=o>n?o:s,c=new Set([a,l,...Array.from(i)]),u=Math.ceil(a*t),f=Math.floor(l*t);for(let e=u;e<=f;e++)c.add(e/t);return Array.from(c).sort((e,t)=>e-t)}function tn(e){if(e.length<2)return!0;const t=e[0].value;for(let n=1;n<e.length;n++){const o=e[n].value;if(Math.abs(o.x-t.x)>1e-4||Math.abs(o.y-t.y)>1e-4||Math.abs(o.z-t.z)>1e-4||Math.abs(o.w-t.w)>1e-4)return!1}return!0}function nn(e,t,n,o,r){const s=function(e,t,n){if(n>t)return{start:t,stop:n};return{start:e.keys[0]?.time??0,stop:e.keys[e.keys.length-1]?.time??0}}(e,n,o),i=e.keys.filter(e=>e.time>=s.start&&e.time<=s.stop).map(e=>({source:e,frame:e.time*t,value:r(e.value)}));i.some(e=>Math.abs(e.source.time-s.start)<1e-6)||i.unshift({source:{time:s.start,value:mt(e,s.start)??0,interpolation:"linear"},frame:s.start*t,value:r(mt(e,s.start)??0)}),i.some(e=>Math.abs(e.source.time-s.stop)<1e-6)||i.push({source:{time:s.stop,value:mt(e,s.stop)??0,interpolation:"linear"},frame:s.stop*t,value:r(mt(e,s.stop)??0)});const a=i.map(e=>({frame:e.frame,value:e.value}));for(let e=0;e<i.length-1;e++){const n=i[e].source,o=a[e+1];if("constant"===n.interpolation){a[e].interpolation=1;continue}if("cubic"!==n.interpolation)continue;const s=i[e+1].source,l=Math.max(s.time-n.time,1e-6),c=(s.value-n.value)/l;a[e].outTangent=on(n.rightSlope??c,r)/t,o.inTangent=on(n.nextLeftSlope??c,r)/t}return a}function on(e,t){return t(e)-t(0)}let rn=!1;function sn(){rn||(rn=!0,g(new Yt))}sn();export{Yt as FBXFileLoader,sn as RegisterFBXFileLoader};
//# sourceMappingURL=fbxFileLoader-BK3LLoYq.esm.min.js.map