@anhldh/gltf-lod-pipeline 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
1
  #! /usr/bin/env node
2
- import{program as ae}from"@donmccurdy/caporal";import Sn from"path";import{existsSync as Dr,readFileSync as Fr,statSync as kr,writeFileSync as Yi}from"fs";import{Logger as Qi,NodeIO as ea,PropertyType as Me,Verbosity as Ct}from"@gltf-transform/core";import{ALL_EXTENSIONS as ta}from"@gltf-transform/extensions";import Gr from"draco3dgltf";import{MeshoptDecoder as na,MeshoptEncoder as ra}from"meshoptimizer";import{dedup as sa,metalRough as oa,prune as ia,resample as aa}from"@gltf-transform/functions";import{PropertyType as j}from"@gltf-transform/core";import{Extension as rs,ExtensionProperty as ss,PropertyType as k,Node as os,TextureChannel as q}from"@gltf-transform/core";import{WriterContext as Yr}from"@gltf-transform/core";function at(t,e){return e===void 0?null:Array.isArray(t)&&t.length>e?t[e]:null}function _n(t,e,n){t!==null&&n&&(t.extensions||(t.extensions={}),t.extensions[e]=n)}function ct(t,e){if(!t.jsonDoc.json.images)return null;let n=de(e);return n!==void 0?t.textures[n]:(console.log("Kh\xF4ng th\u1EC3 t\xECm th\u1EA5y texture",e),null)}function de(t){if(t.source!==void 0)return t.source;if(t.extensions)for(let e of Object.keys(t.extensions)){let n=t.extensions[e];if(n&&n.source!==void 0)return n.source}}function Gt(t,e){let n=t.jsonDoc.json.textures;if(!n)return null;if(t instanceof Yr){let s=t.imageIndexMap.get(e);for(let o of n)if(o.source===s)return o}else{let r=t.textures.indexOf(e);for(let s=0;s<n.length;s++){let o=n[s];if(o.source===r)return o;if(o.extensions)for(let i of Object.keys(o.extensions)){let a=o.extensions[i];if(a&&a.source===r)return o}}}return null}function jt(t){return t%4===0}function Bt(t){return t<=4?4:t%4?t+4-t%4:t}function ue(t){return t.getName()?.startsWith("Lightmap")??!1}function Wt(t){t.setName("Lightmap")}import{Extension as Qr,ExtensionProperty as es,PropertyType as ts}from"@gltf-transform/core";var be="GLTF_progressive_texture_settings",Ne=class extends Qr{static EXTENSION_NAME=be;extensionName=be;read(e){let r=e.jsonDoc.json.textures;if(!r)return this;for(let s=0;s<r.length;s++){let o=r[s];if(o.extensions&&o.extensions[be]){let i=o.extensions[be],a=new zt(this.document.getGraph(),"");Object.assign(a,i);let u=e.textures[s];u&&u.setExtension(be,a)}}return this}write(e){return this}},zt=class extends es{static EXTENSION_NAME=be;extensionName=be;parentTypes=[ts.TEXTURE];propertyType=be;generateLods;maxSize;guid;init(){}get isValid(){return this.maxSize!==void 0&&this.maxSize>0}};var ns=process.env.VITEST==="true",Oe=class extends Error{constructor(e){super(e),this.name="TestAssertionError"}};function re(t,e){if(!t&&ns)throw new Oe(`Assertion failed: ${e}`)}import{existsSync as is,readFileSync as as}from"fs";import{dirname as cs,join as us}from"path";var Mn=[];for(let t in k)Mn.push(k[t]);var Jt="";function z(t,e,n){Array.isArray(e)||(e=[e]);let r=t,s=Mn,o=n?.debug??!1;class i extends rs{extensionName=r;static EXTENSION_NAME=r;prewriteTypes=[k.MATERIAL];jsonPointerHandler;read(c){if(n?.breakpoint===!0)debugger;Jt=c.jsonDoc.json.asset?.generator??"",o&&console.log("READ "+r),this.jsonPointerHandler=new qt(this.document,r),this.jsonPointerHandler.debug=o,this.jsonPointerHandler.breakPoint=n?.breakpoint;for(let l of e)switch(l){case k.ACCESSOR:this.onRead(c,"accessors","accessorIndexMap");break;case k.ANIMATION:this.onRead(c,"animations","animationIndexMap");break;case k.ANIMATION_CHANNEL:r==="KHR_animation_pointer"&&c.jsonDoc.json.animations?.forEach((f,g)=>{let p=c.animations[g],h=p.listChannels();f.channels?.forEach((y,x)=>{let d=y.target,E=d.extensions&&d.extensions[r];if(!E)return;let T=E.pointer;if(T){let M=T.split("/"),O=parseInt(M[2]),b=M[3];(b==="scale"||b==="translation"||b==="rotation")&&(h[x].setTargetNode(c.nodes[O]),h[x].setTargetPath(b))}let L=p.getExtension(r);if(o&&console.log(">>>",r,"animation",g,"channel",x,E),L){A(L);return}let _=this.createExtension();p.setExtension(r,_),A(_);function A(M){M.add(O=>{let b=O.jsonDoc.json.animations;if(!b)return;let P=b[g]?.channels[x];P?(o&&console.log("<<<",r,"animation",g,"channel",x,E),P.target=d):o&&console.log("WARN: ",r,"animation",g,"channel",x,"not found")})}})});break;case k.ANIMATION_SAMPLER:break;case k.BUFFER:this.onRead(c,"buffers","bufferIndexMap");break;case k.CAMERA:this.onRead(c,"cameras","cameraIndexMap");break;case k.MATERIAL:this.onRead(c,"materials","materialIndexMap");break;case k.TEXTURE:c.jsonDoc.json.textures?.forEach((f,g)=>{if(!f.extensions)return;let p=f.extensions[r];if(!p)return;let h=ct(c,f);h||(console.log("WARN: could potentially not find gltf transform texture for "+g),h=c.textures[g]);let y=this.createExtension();this.jsonPointerHandler.read(c,h,p,y),h.setExtension(r,y);let x=new Xt(this.document,f,r,p,o,h);y.add(x);let d=f.source;o&&console.log("Found texture with extension",r,"at index",g,"source image index",d,"name",h.getName()||"<unnamed>")});break;case k.NODE:this.onRead(c,"nodes","nodeIndexMap");break;case k.MESH:this.onRead(c,"meshes","meshIndexMap");break;case k.PRIMITIVE:c.jsonDoc.json.meshes?.forEach((f,g)=>{let p=c.meshes[g],h=p.listPrimitives();f.primitives?.forEach((y,x)=>{if(!y.extensions)return;let d=y.extensions[r];if(!d)return;let E=h[x],T=this.createExtension();this.jsonPointerHandler.read(c,E,d,T),E.setExtension(r,T),T.add(L=>{let _=L.meshIndexMap.get(p),M=L.jsonDoc.json.meshes[_].primitives[x];M.extensions=M.extensions||{},M.extensions[r]=d})})});break;case k.ROOT:{let f=c.jsonDoc.json.extensions;if(!f)continue;let g=f[r];if(g){let p=this.document.getRoot(),h=this.createExtension();this.jsonPointerHandler.read(c,p,g,h),p.setExtension(r,h),this.lightmapWorkaround(c,h,this.document.getLogger()),h.add(y=>{y.jsonDoc.json.extensions=y.jsonDoc.json.extensions||{},y.jsonDoc.json.extensions[r]=g})}break}}return this}lightmapWorkaround(c,l,f){let g=c.jsonDoc.json.textures;if(!g)return;let p=this.document.getRoot().listTextures();for(let h=0;h<p.length;h++){let y=p[h];if(ue(y)&&y.getMimeType()!=="image/exr"){l.setReference("lightmapTexture",y,{channels:q.R|q.G|q.B|q.A});let x=g[h],d=y.getName()||x?.name;f.debug(`Found lightmap texture "${d}" (${y.getMimeType()}) in ${r}`)}}}createExtension(c=""){return new a(this.document.getGraph(),c)}onRead(c,l,f){if(l!==void 0)try{let g=c.jsonDoc.json[l],p=c[l];g?.forEach((h,y)=>{if(!h.extensions||!h.extensions[r])return;let x=h.extensions[r];o&&console.log("READ",y,x);let d=this.createExtension();p[y].setExtension(r,d),this.jsonPointerHandler.read(c,p[y],x,d),d.add(new u(f,l,x))})}catch(g){console.error("ERR: "+g)}}prewrite(c,l){return this.jsonPointerHandler.resolveAndWrite(c,"prewrite"),this}write(c){if(n?.breakpoint===!0)debugger;if(n?.write===!1)return this;o&&console.log("WRITE "+r),this.jsonPointerHandler.resolveAndWrite(c,"write");let l=this.document.getRoot();for(let f of e)switch(f){case k.ACCESSOR:this.onWrite(c,()=>l.listAccessors());break;case k.ANIMATION:this.onWrite(c,()=>l.listAnimations());break;case k.ANIMATION_CHANNEL:case k.ANIMATION_SAMPLER:break;case k.BUFFER:this.onWrite(c,()=>l.listBuffers());break;case k.CAMERA:this.onWrite(c,()=>l.listCameras());break;case k.MATERIAL:this.onWrite(c,()=>l.listMaterials());break;case k.TEXTURE:this.onWrite(c,()=>l.listTextures());break;case k.NODE:this.onWrite(c,()=>l.listNodes());break;case k.MESH:this.onWrite(c,()=>l.listMeshes());break;case k.PRIMITIVE:{let g=l.listMeshes().flatMap(p=>p.listPrimitives());for(let p of g){let h=p.getExtension(r);h instanceof a&&h.onWrite(c,p)}break}case k.ROOT:{let g=l.getExtension(r);g instanceof a?g.onWrite(c,l):o&&console.warn("WARN: no extension found on root",r);break}}return this}onWrite(c,l){let f=l();if(f)for(let g of f){let p=g.getExtension(r);p instanceof a&&p.onWrite(c,g)}}}class a extends ss{static EXTENSION_NAME=r;parentTypes=s;propertyType="GLTF_opaque_property";init(){this.extensionName=r}setReference(c,l,f={modifyChild:!0}){this.setRef(c,l,f)}writers=[];add(c){typeof c=="function"&&(c=new Ut(c)),this.writers.push(c)}onWrite(c,l){for(let f of this.writers)f.write?.call(f,c,l)}getExtensionDefinition(){let c={};for(let l of this.writers)"assignTo"in l&&l.assignTo&&l.assignTo(c);return c}}class u{map;gltfField;ext;constructor(c,l,f){this.map=c,this.gltfField=l,this.ext=f}assignTo(c){Object.assign(c,this.ext)}write(c,l){if(l&&this.gltfField!==void 0){let g=c[this.map].get(l),p=at(c.jsonDoc.json[this.gltfField],g);_n(p,r,this.ext)}}}return i}var Ut=class{fn;constructor(e){this.fn=e}write(e){this.fn(e)}},Xt=class{document;textureDefinition;key;ext;debug;textureRef;constructor(e,n,r,s,o,i){if(this.document=e,this.textureDefinition=n,this.key=r,this.ext=s,this.debug=o,this.textureRef=i,o){let a=this.tryGetSourceIndex(this.textureDefinition);console.log(a,this.textureDefinition)}}assignTo(e){Object.assign(e,this.ext)}write(e){if(this.key==="EXT_texture_exr"&&this.textureRef.getMimeType()!=="image/exr")return;let n=e.imageIndexMap.get(this.textureRef);if(re(n!==void 0||this.key==="EXT_texture_exr",`imageIndexMap missing texture ref for "${this.key}": ${this.textureRef.getName()||"<unnamed>"}`),n===void 0){this.debug&&console.warn("WARN: failed to resolve image index for texture via imageIndexMap:",this.key,this.textureRef.getName()||"<unnamed>");return}let r=!1,s=e.jsonDoc.json.textures||[];for(let o of s){if(r)break;let i=this.tryGetSourceIndex(o);if(n===i&&(r=!0,!o.extensions?.[this.key])){o.extensions=o.extensions||{},this.debug&&console.log("Re-Assign extension:",this.key);let a={...this.ext};a.source!==void 0&&(a.source=n),o.extensions[this.key]=a}}re(r||this.key==="EXT_texture_exr",`failed to match texture for extension "${this.key}", imageIndex=${n}, textures=${s.length}, name=${this.textureRef.getName()||"<unnamed>"}, type=${this.textureRef.getMimeType()}`),!r&&this.debug&&console.warn("WARN: failed to re-assign extension:",this.key,"imageIndex",n,s.length,this.textureRef.getName()||"<unnamed>",this.textureDefinition)}tryGetSourceIndex(e){let n=e.source;if(n!==void 0)return n;if(e.extensions)for(let r of Object.keys(e.extensions)){let s=e.extensions[r];if(s.source!==void 0){n=s.source;break}}return n}},qt=class{debug=!1;breakPoint=!1;extension_name;document;map=new Map;VRM_0_MaterialIndexRegex=/materialProperties\/(?<material_index>\d+)\//g;externalExrTextures=new Map;externalExrPointers=[];constructor(e,n){this.document=e,this.extension_name=n}read(e,n,r,s,o,i){let a=o!==void 0?r[o]:r;if(o!==void 0&&(i??="",i+="/"+o,this.breakPoint==="pointer:read"))debugger;switch(typeof a){case"object":if(a!=null)if(Array.isArray(a))for(let u=0;u<a.length;u++)this.read(e,n,a,s,u.toString(),i);else for(let u of Object.keys(a))this.read(e,n,a,s,u,i);break;case"string":a&&o&&this.readStringPointer(e,n,r,s,o,a,i??"");break;case"number":o&&i&&this.readNumberPointer(e,r,s,o,a,i);break;default:break}}resolveAndWrite(e,n){this.map.forEach(r=>{r.resolve(e,n)&&r.write()});for(let{obj:r,key:s,texture:o}of this.externalExrPointers){let i=o.getURI()||o.getName()||"";if(i){this.debug&&console.log(`< Resolved external EXR: ${r[s]} \u2192 ${i}`),r[s]=i;let a=e.imageIndexMap.get(o);if(a!==void 0){let u=e.jsonDoc.json.images;u&&u[a]&&!u[a].uri&&(u[a].uri=i)}}}}readStringPointer(e,n,r,s,o,i,a){let u="/textures/",m=i.startsWith(u);if(m||(u="textures/",m=i.startsWith(u)),m){this.debug&&console.log("Read pointer",i);let c=this.map.get(i);if(!c){let l=parseInt(i.substring(u.length)),f=i.substring(0,u.length),g=e.jsonDoc.json.textures[l],p=de(g);this.debug&&console.log("Texture index",l,p,e.jsonDoc.json.textures.length,"Textures:"+e.textures.length);let h=at(e.textures,p);if(h){let y=new ut(this.document,h,g);y.debug=this.debug,y.init(e),c=new ve(f,y,i),c.debug=this.debug,this.map.set(i,c);let x=i;s.setReference(x,h,{channels:q.R|q.G|q.B|q.A});let d=this.document.getRoot().listBuffers()[0];d&&s.setReference("buffer",d)}else console.warn("Texture not found",a,i)}c?(this.debug&&console.log("> Register pointer",this.extension_name+"/"+a+" : "+i),c.register(r,o,a)):console.warn("WARN: failed registering pointer",a,i)}if(!m&&i.match(/\.exr$/i)){let c=Ue()?cs(Ue()):"",l=c?us(c,i):"";if(l&&is(l)){let f=this.externalExrTextures.get(i);if(!f){let p=as(l);f=this.document.createTexture(i).setImage(new Uint8Array(p)).setMimeType("image/exr").setURI(i),this.externalExrTextures.set(i,f),this.debug&&console.log(`Injected external EXR "${i}" as Texture`)}s.setReference(`exr_${i}`,f,{channels:q.R|q.G|q.B|q.A});let g=this.document.getRoot().listBuffers()[0];g&&s.setReference(`exr_buffer_${i}`,g),this.externalExrPointers.push({obj:r,key:o,texture:f})}else l&&(this.document.getLogger().error(`GLTF_opaque: External EXR not found: ${l}`),re(!1,`GLTF_opaque: External EXR not found: ${l}`))}if(i.startsWith("/materials/")){this.debug&&console.log("Read pointer",i);let c=parseInt(i.substring(11)),l=e.materials[c];if(l){s&&s.setReference(i,l);let f=this.map.get(i);if(!f){let g=e.jsonDoc.json.materials[c],p=new Kt(this.document,l,g);p.debug=this.debug,p.init(e),f=new ve("/materials/",p,i),f.debug=this.debug,this.map.set(i,f),s.setReference(i,l)}f?.register(r,o,a)}}if(i.startsWith("/animations/")){this.debug&&console.log("Read pointer",i);let c=parseInt(i.substring(12)),l=e.animations[c];if(l){let f=this.map.get(i);f||s.setReference(i,l),f?.register(r,o,a)}}if(i.startsWith("/meshes/")){this.debug&&console.log("Read pointer",i);let c=parseInt(i.substring(8)),l=e.meshes[c];if(l){let f=this.map.get(i);if(!f){let g=e.jsonDoc.json.meshes[c],p=new Vt(this.document,l,g,s);p.debug=this.debug,p.init(e),f=new ve("/meshes/",p,i),f.debug=this.debug,this.map.set(i,f),s.setReference(i,l)}f?.register(r,o,a)}}}readNumberPointer(e,n,r,s,o,i){if(s==="node"||s==="mesh"||i.match(/springs\/\d+\/center/g)){let a=e.nodes[o];if(a){let u=new Ht(this.document,a,e.jsonDoc.json.nodes[o]);u.debug=this.debug,u.init(e);let m=`/${s}/${o}`,c=this.map.get(m);c||(c=new ve(null,u,o)),c.debug=this.debug,c.register(n,s,i),this.map.set(m,c),r.setReference(m,a)}}else if(s==="texture"||i.match(/materialProperties\/(?<material_index>\d+)\/textureProperties/g)||i.match(/meta\/thumbnailImage/g)||i.match(/^\/textures\/\d{1,}$/)){let a=o;if(a<0){console.warn(`WARN: texture index is negative ${a} at ${i}`);return}let u=e.jsonDoc.json.textures?.[a];if(!u){console.warn(`WARN: texture definition with index ${a} not found or does not exist. Set in "${i}"`);return}let m=de(u);this.debug&&console.log("Texture index",a,m,e.jsonDoc.json.textures.length,"Textures:"+e.textures.length);let c=at(e.textures,m);if(c){this.debug&&console.log("Found texture index at "+i+": "+o);let f=new ut(this.document,c,u);f.debug=this.debug,f.init(e);let g=`/textures/${o}`,p=this.map.get(g);p||(p=new ve(null,f,o)),p.debug=this.debug,p.register(n,s,i),this.map.set(g,p),r.setReference(g,c,{channels:q.R|q.G|q.B|q.A})}let l=this.VRM_0_MaterialIndexRegex.exec(i);if(l){let f=parseInt(l.groups.material_index),g=e.materials[f];r.setReference(`/materials/${f}`,g)}}}},ve=class{debug=!1;resolver;pointerBase;oldPointer;_objects=[];_props=[];_debugInfo=[];newPointer=void 0;_didWrite=!1;constructor(e,n,r){this.pointerBase=e,this.resolver=n,this.oldPointer=r}register(e,n,r){this._objects.push(e),this._props.push(n),this._debugInfo.push(r)}resolve(e,n){if(this.newPointer!==void 0)return!0;this.resolver.debug=this.debug;let r=this.resolver.resolve(e);if(r!==void 0)return this.pointerBase!=null?this.newPointer=this.pointerBase+r:this.newPointer=r,!0;if(n==="write"&&(console.log(`ERR: \u{1F9E8} FAILED to resolve pointer "${this.oldPointer}" used by ${this._debugInfo.join(", ")}`),this.debug))debugger;return!1}write(){if(!this._didWrite){this._didWrite=!1;for(let e=0;e<this._objects.length;e++){let n=this._objects[e],r=this._props[e];this.debug&&console.log(`< Resolved pointer ${this._debugInfo[e]}: ${this.oldPointer} \u2192 ${this.newPointer}`),n[r]=this.newPointer}}}},Pe=class{debug=!1;document;inputObject;inputDefinition;property;constructor(e,n,r,s){this.document=e,this.inputObject=n,this.inputDefinition=r,this.property=s}},ut=class extends Pe{_debugName="";_samplerDef;init(e){this._debugName=this.inputDefinition.name??this.inputDefinition.source?.toString()??"unknown";let n=this.inputDefinition.sampler;n!==void 0&&(this._samplerDef=e.jsonDoc.json.samplers?.[n]),this.debug&&console.log(this._debugName,this._samplerDef)}resolve(e){let n=e.imageIndexMap.get(this.inputObject);if(n===void 0)return re(!1,`imageIndexMap missing texture: ${this.inputObject.getName()||"<unnamed>"}`),console.error("ERR: image is missing"),-1;e.jsonDoc.json.textures=e.jsonDoc.json.textures||[];for(let i=0;i<e.jsonDoc.json.textures.length;i++){let a=e.jsonDoc.json.textures[i];if(de(a)===n)return a.sampler===void 0&&(a.sampler=this.findOrCreateSampler(e.jsonDoc.json)),this.debug&&console.log("Found texture def at "+i,"using image",n,a),i}this.debug&&console.log("Could not find texture, creating a new one: "+this._debugName);let r=this.inputDefinition.extensions?{...this.inputDefinition.extensions}:void 0;r&&(delete r[Ne.EXTENSION_NAME],r.EXT_texture_exr&&this.inputObject.getMimeType()!=="image/exr"&&delete r.EXT_texture_exr,Object.keys(r).length===0&&(r=void 0));let o={source:r&&Object.keys(r).some(i=>r[i]?.source!==void 0)?void 0:n,sampler:this.findOrCreateSampler(e.jsonDoc.json),extensions:r,extras:this.inputDefinition.extras};return e.jsonDoc.json.textures.push(o),e.jsonDoc.json.textures.length-1}findOrCreateSampler(e){if(e.samplers=e.samplers||[],this._samplerDef===void 0)console.log("WARN: Creating default sampler",this._debugName),this._samplerDef={magFilter:9729,minFilter:9729,wrapS:33648,wrapT:33648};else for(let n=0;n<e.samplers.length;n++){let r=e.samplers[n];if(r.minFilter===this._samplerDef.minFilter&&r.magFilter===this._samplerDef.magFilter&&r.wrapS===this._samplerDef.wrapS&&r.wrapT===this._samplerDef.wrapT)return n}return e.samplers.push(this._samplerDef),e.samplers.length-1}},Kt=class extends Pe{init(e){}resolve(e){return e.materialIndexMap.get(this.inputObject)}},Ht=class extends Pe{init(e){}resolve(e){return e.nodeIndexMap.get(this.inputObject)}},Vt=class extends Pe{init(e){}resolve(e){let n=e.meshIndexMap.get(this.inputObject);if(n!==void 0&&n>=0)return n;let r=null;if(this.inputObject.isDisposed()){let s=this.property?.listParents()??[];for(let o of s)if(o instanceof os&&(r=o.getMesh(),r)){this.document.getLogger().info(`INFO: resolved mesh "${this.inputObject.getName()}" from parent node "${o.getName()}"`);break}r?.isDisposed()&&console.warn("WARN: mesh is disposed",this.inputObject.getName())}if(r)return e.meshIndexMap.get(r)}};var K={debug:process.argv.includes("debug")},mt=[z("KHR_animation_pointer",[j.ANIMATION,j.ANIMATION_CHANNEL],{...K}),z("GLTF_techniques_webgl",[j.NODE,j.MATERIAL,j.ROOT],{...K}),z("GLTF_gameobject_data",j.NODE,{...K}),z("GLTF_components",j.NODE,{...K}),z("GLTF_persistent_assets",j.ROOT,{...K}),z("GLTF_lighting_settings",j.ROOT,{...K}),z("GLTF_render_objects",j.ROOT,{...K}),z("GLTF_progressive",[j.TEXTURE,j.MATERIAL,j.MESH],{...K}),z("EXT_texture_exr",[j.TEXTURE],{...K}),z("GLTF_editor",[j.NODE,j.MATERIAL],{...K}),z("GLTF_gltf_dependencies",[j.ROOT],{...K}),z("GLTF_materials_mtlx",[j.ROOT,j.MATERIAL],{...K}),z("VRM",[j.ROOT],{...K}),z("VRMC_vrm",[j.ROOT],{...K}),z("VRMC_springBone",[j.ROOT],{...K}),z("VRMC_node_constraint",[j.NODE],{...K})];import{Extension as ms,ExtensionProperty as ls,PropertyType as Zt}from"@gltf-transform/core";var X="GLTF_mesh_compression",An=!1,Te=class{compression;constructor(e){this.compression=e}};var lt=class extends ls{static EXTENSION_NAME=X;extensionName=X;parentTypes=[Zt.ROOT,Zt.PRIMITIVE,Zt.MESH];propertyType=X;model;init(){}copy(e,n){return this.model={...e.model},super.copy(e,n)}},se=class extends ms{static EXTENSION_NAME=X;extensionName=X;create(e){let n=new lt(this.document.getGraph(),"");return n.model=e,n}read(e){An&&console.log("READ "+X);let n=e.jsonDoc.json.extensions?.[X];return n&&this.document.getRoot().setExtension(X,this.create(n)),e.jsonDoc.json.meshes&&e.meshes?.forEach((r,s)=>{let o=e.jsonDoc.json.meshes[s];if(!o)return;let i=r.listPrimitives();for(let a=0;a<i.length;a++){let u=o.primitives[a];if(u.extensions&&u.extensions[X]){let m=u.extensions[X];i[a].setExtension(X,this.create(m))}}}),this}write(e){An&&console.log("WRITE "+X);let n=this.document.getRoot(),r=n.getExtension(X);r&&(e.jsonDoc.json.extensions=e.jsonDoc.json.extensions||{},e.jsonDoc.json.extensions[X]=r.model);for(let s of n.listMeshes()){let o=e.meshIndexMap.get(s);if(o===void 0)continue;let i=e.jsonDoc.json.meshes[o],a=s.listPrimitives();for(let u=0;u<a.length;u++){let c=a[u].getExtension(X);if(c){let l=i.primitives[u];l&&(l.extensions=l.extensions||{},l.extensions[X]=c.model)}}}return this}};import{Extension as fs,ExtensionProperty as gs,PropertyType as Ln}from"@gltf-transform/core";var H="GLTF_compression_texture",Nn=!1,Xe=class extends gs{static EXTENSION_NAME=H;extensionName=H;parentTypes=[Ln.TEXTURE];propertyType=H;model;init(){this.extensionName=H,this.parentTypes=[Ln.TEXTURE],this.propertyType=H}},ne=class extends fs{static EXTENSION_NAME=H;extensionName=H;create(e){let n=new Xe(this.document.getGraph(),"");return n.model=e,n}read(e){return Nn&&console.log("READ "+H),e.jsonDoc.json.textures?(e.textures?.forEach(n=>{let r=Gt(e,n);if(r?.extensions&&r.extensions[H]){let s=new Xe(this.document.getGraph(),H);s.model=r.extensions[H],n.setExtension(H,s)}}),this):this}write(e){Nn&&console.log("WRITE "+H);let r=this.document.getRoot().listTextures();for(let s of r){let o=s.getExtension(H);if(o){let i=Gt(e,s);i&&(i.extensions=i.extensions||{},i.extensions[H]=o.model)}}return this}};import{Extension as ps,ExtensionProperty as ds,PropertyType as On}from"@gltf-transform/core";var Y="GLTF_progressive",ft=class extends ds{static EXTENSION_NAME=Y;extensionName=Y;parentTypes=[On.TEXTURE,On.MESH];propertyType="progressive_texture";model;init(){}},me=class extends ps{static EXTENSION_NAME=Y;extensionName=Y;createTexture(e){let n=new ft(this.document.getGraph());return n.model=e,n}createMesh(e){let n=new ft(this.document.getGraph());return n.model=e,n}read(e){return this}write(e){let n=this.document.getRoot(),r=e.jsonDoc.json,s=r.textures;if(s?.length){let i=n.listTextures(),a=e.imageIndexMap;for(let u of i){let m=u.getExtension(Y);if(m&&m.model){let c=a.get(u);for(let l of s)l.source===c&&(l.extensions=l.extensions||{},l.extensions[Y]=m.model)}}}let o=r.meshes;if(o?.length){let i=e.meshIndexMap,a=n.listMeshes();for(let u=0;u<a.length;u++){let m=a[u],c=i.get(m);if(c===void 0)continue;let l=m.getExtension(Y);if(l&&l.model){let f=o[c];f&&(f.extensions=f.extensions||{},f.extensions[Y]=l.model)}}}return this}};import{Extension as hs,ExtensionProperty as xs,PropertyType as ys}from"@gltf-transform/core";var Ee="GLTF_progressive_mesh_settings",Yt=class extends xs{static EXTENSION_NAME=Ee;extensionName=Ee;parentTypes=[ys.MESH];propertyType=Ee;generateLods;guid;init(){}},qe=class extends hs{static EXTENSION_NAME=Ee;extensionName=Ee;read(e){let n=e.jsonDoc.json.meshes;if(!n)return this;let s=this.document.getRoot().listMeshes();for(let o=0;o<n.length;o++){let i=n[o];if(i.extensions&&i.extensions[Ee]){let a=i.extensions[Ee],u=new Yt(this.document.getGraph(),"");Object.assign(u,a);let c=s[o];c?c.setExtension(Ee,u):console.warn(`WARN: Progressive mesh at index ${o} was not found in the glTF file. This might result in falsely loaded textures for ${a.guid} / name "${i.name}"`)}}return this}write(e){return this}};import{Extension as bs}from"@gltf-transform/core";var Ce="GLTF_pmrem",Se=class extends bs{static EXTENSION_NAME=Ce;extensionName=Ce;pmremTextures=new Set;addTexture(e){this.pmremTextures.add(e)}preread(e,n){let r=e.jsonDoc.json;for(let s of r.textures??[]){let o=s.extensions?.[Ce];o?.source!==void 0&&s.source===void 0&&(s.source=o.source)}for(let s of r.textures??[]){let o=s.extensions?.[Ce];if(o?.source!==void 0){let i=r.images?.[o.source];i&&!i.mimeType&&(i.mimeType="image/ktx2")}}return this}read(e){let r=e.jsonDoc.json.textures??[],s=this.document.getRoot().listTextures();for(let o=0;o<r.length;o++){if(r[o].extensions?.[Ce]?.source===void 0)continue;let u=s[o];u&&(u.setMimeType("image/ktx2"),this.pmremTextures.add(u))}return this}write(e){let n=e.jsonDoc;for(let s of this.pmremTextures){let o=e.imageIndexMap.get(s);if(o!==void 0)for(let i of n.json.textures??[])(i.source??i.extensions?.KHR_texture_basisu?.source)===o&&(i.extensions=i.extensions||{},i.extensions[Ce]={source:o},i.extensions.KHR_texture_basisu&&delete i.extensions.KHR_texture_basisu)}if(!(n.json.textures??[]).some(s=>s.extensions?.KHR_texture_basisu)){let s=o=>{if(!o)return;let i=o.indexOf("KHR_texture_basisu");i>=0&&o.splice(i,1)};s(n.json.extensionsUsed),s(n.json.extensionsRequired)}return this}};import{Extension as Ts,ExtensionProperty as Es,PropertyType as Qt,TextureChannel as we}from"@gltf-transform/core";import{existsSync as Ss,readFileSync as ws}from"fs";import{join as Is,dirname as _s}from"path";var Ie="GLTF_lightmaps",en=class extends Es{static EXTENSION_NAME=Ie;parentTypes=[Qt.ROOT];init(){this.extensionName=Ie,this.propertyType="LightmapProperty"}getDefaults(){return Object.assign(super.getDefaults(),{})}setReference(e,n,r){this.setRef(e,n,r)}},De=class extends Ts{static EXTENSION_NAME=Ie;extensionName=Ie;prereadTypes=[Qt.TEXTURE];prewriteTypes=[Qt.MATERIAL];extensionData=null;resolved=[];injectedImageIndices=new Map;lightmapProp=null;preread(e,n){let r=e.jsonDoc.json,s=r.extensions?.[Ie];if(!s?.textures)return this;let o=Ue(),i=o?_s(o):"";for(let a of s.textures){if(a.pointer.startsWith("/")||a.pointer.startsWith("textures/")||!a.pointer.match(/\.exr$/i))continue;let u=i?Is(i,a.pointer):"";if(!u||!Ss(u)){this.document.getLogger().error(`GLTF_lightmaps: Kh\xF4ng t\xECm th\u1EA5y file EXR b\xEAn ngo\xE0i: ${u||a.pointer}`),re(!1,`GLTF_lightmaps: Kh\xF4ng t\xECm th\u1EA5y file EXR b\xEAn ngo\xE0i: ${u||a.pointer}`);continue}let m=ws(u);r.images=r.images||[],r.textures=r.textures||[];let c=r.images.length;r.images.push({uri:a.pointer,mimeType:"image/exr",name:a.pointer}),r.textures.push({source:c,name:a.pointer}),e.jsonDoc.resources[a.pointer]=new Uint8Array(m),this.injectedImageIndices.set(a.pointer,c),this.document.getLogger().info(`GLTF_lightmaps: \u0110\xE3 \u0111\u0103ng k\xFD file EXR b\xEAn ngo\xE0i "${a.pointer}" d\u01B0\u1EDBi d\u1EA1ng image[${c}]`)}return this}read(e){let n=e.jsonDoc.json,r=n.extensions?.[Ie];if(!r?.textures)return this;this.extensionData=r;let s=this.document.getRoot();this.lightmapProp=new en(this.document.getGraph()),s.setExtension(Ie,this.lightmapProp);let o=n.textures||[],i=this.document.getLogger();for(let u of r.textures){let m=null,c;if(u.pointer.startsWith("/textures/")||u.pointer.startsWith("textures/")){let l=u.pointer.startsWith("/")?"/textures/":"textures/",f=parseInt(u.pointer.substring(l.length),10),g=o[f];g&&(c=g,m=ct(e,g)??null)}else if(u.pointer.match(/\.exr$/i)){let l=this.injectedImageIndices.get(u.pointer);l!==void 0&&(m=e.textures[l]??null,c=o.find(f=>de(f)===l))}else if(!u.pointer.startsWith("/")){let l=n.images??[];for(let f=0;f<l.length;f++)if(l[f].uri===u.pointer){m=e.textures[f]??null,c=o.find(g=>de(g)===f);break}}if(m){this.resolved.push({entry:u,texture:m,inputTextureDef:c});let l=`lightmapTexture_${u.pointer}`,f=we.R|we.G|we.B|we.A;this.lightmapProp.setReference(l,m,{channels:f});let g=this.document.getRoot().listBuffers()[0];g&&this.lightmapProp.setReference("buffer",g)}else this.document.getLogger().error(`GLTF_lightmaps: Kh\xF4ng th\u1EC3 gi\u1EA3i quy\u1EBFt (resolve) texture cho con tr\u1ECF "${u.pointer}"`),re(!1,`GLTF_lightmaps: Kh\xF4ng th\u1EC3 gi\u1EA3i quy\u1EBFt texture cho con tr\u1ECF "${u.pointer}"`)}let a=this.document.getRoot().listTextures();for(let u of a)if(ue(u)&&u.getMimeType()!=="image/exr"){let m=`lightmapTexture_${u.getName()}`,c=we.R|we.G|we.B|we.A;this.lightmapProp.setReference(m,u,{channels:c}),this.document.getLogger().debug(`[GLTF_lightmaps] T\xECm th\u1EA5y texture lightmap "${u.getName()}" (${u.getMimeType()})`)}return this}prewrite(e,n){return this.resolvePointers(e),this}write(e){if(!this.extensionData)return this;this.resolvePointers(e);let n=e.jsonDoc.json;return n.extensions=n.extensions||{},n.extensions[Ie]=this.extensionData,this}pointersResolved=!1;resolvePointers(e){if(!this.pointersResolved){this.pointersResolved=!0;for(let{entry:n,texture:r,inputTextureDef:s}of this.resolved)if(n.pointer.startsWith("/textures/")||n.pointer.startsWith("textures/")){let o=this.findOrCreateTextureIndex(e,r,s);o!==void 0&&(n.pointer=`/textures/${o}`)}else{let o=r.getURI();if(o){n.pointer=o;let i=e.imageIndexMap.get(r);if(i!==void 0){let a=e.jsonDoc.json.images;a&&a[i]&&(a[i].uri=o)}}}}}findOrCreateTextureIndex(e,n,r){let s=e.imageIndexMap.get(n);if(s===void 0)return;let o=e.jsonDoc.json.textures=e.jsonDoc.json.textures||[];for(let m=0;m<o.length;m++)if(de(o[m])===s)return m;let i=r?.extensions?{...r.extensions}:void 0;i&&(delete i.GLTF_progressive_texture_settings,i.EXT_texture_exr&&n.getMimeType()!=="image/exr"&&delete i.EXT_texture_exr,Object.keys(i).length===0&&(i=void 0));let u={source:i&&Object.values(i).some(m=>m?.source!==void 0)?void 0:s,extensions:i};return o.push(u),o.length-1}};import{ALL_EXTENSIONS as Ms}from"@gltf-transform/extensions";var vn="";function gt(t){vn=t}function Ue(){return vn}function Rn(t){t.registerExtensions(Ms),t.registerExtensions(mt),t.registerExtensions([me,Se,De])}import{createTransform as Yo}from"@gltf-transform/functions";function tn(t){return t.includes("normalTexture")||t.includes("metallicRoughnessTexture")?"UASTC":"ETC1S"}import{existsSync as le,statSync as $n,readdirSync as As,readFileSync as Ls,mkdirSync as Pn,rmSync as Ns}from"fs";import{setTimeout as Os}from"timers/promises";import{dirname as vs,isAbsolute as Rs,join as $s}from"path";function pt(t,e,n){if(!e)return t;if(!Fe(e))return e;let r=nn(t);return n?.create!==!1&&!le(e)&&Pn(e,{recursive:!0}),$s(e,r)}function nn(t){let e=t.replaceAll("\\","/").split("/");return e[e.length-1]}async function He(t,e){let n=process.env.INIT_CWD,r={baseDirectory:n,files:[]};if(Array.isArray(t))for(let s of t)await Ke(s,r);else typeof t=="string"&&await Ke(t,r);if(r.files.length<=0&&r.baseDirectory){let s=r.baseDirectory+"/gltf.config.json";if(le(s)){let i=JSON.parse(Ls(s,"utf8")).buildDirectory;if(i?.length)if(le(i))console.log("INFO: \u0110ang s\u1EED d\u1EE5ng th\u01B0 m\u1EE5c build t\u1EEB gltf.config.json: "+i),await Ke(i,r);else{let a=r.baseDirectory+"/"+i;le(a)&&(console.log("INFO: \u0110ang s\u1EED d\u1EE5ng th\u01B0 m\u1EE5c build t\u1EEB gltf.config.json: "+a),await Ke(a,r))}}}if(r.files.length<=0)console.log(`WARN: Kh\xF4ng t\xECm th\u1EA5y file glTF n\xE0o. H\xE3y \u0111\u1EA3m b\u1EA3o b\u1EA1n g\u1ECDi l\u1EC7nh v\u1EDBi \u0111\u01B0\u1EDDng d\u1EABn h\u1EE3p l\u1EC7 tr\u1ECF t\u1EDBi m\u1ED9t file glTF ho\u1EB7c m\u1ED9t th\u01B0 m\u1EE5c.
2
+ import{program as ae}from"@donmccurdy/caporal";import pn from"path";import{existsSync as Sr,readFileSync as wr,statSync as Ir,writeFileSync as No}from"fs";import{Logger as Ro,NodeIO as Ao,PropertyType as Me,Verbosity as At}from"@gltf-transform/core";import{ALL_EXTENSIONS as vo}from"@gltf-transform/extensions";import _r from"draco3dgltf";import{MeshoptDecoder as Oo,MeshoptEncoder as $o}from"meshoptimizer";import{dedup as Co,metalRough as Po,prune as Do,resample as Fo}from"@gltf-transform/functions";import{PropertyType as j}from"@gltf-transform/core";import{Extension as zr,ExtensionProperty as Ur,PropertyType as P,Node as Xr,TextureChannel as q}from"@gltf-transform/core";import{WriterContext as kr}from"@gltf-transform/core";function rt(t,e){return e===void 0?null:Array.isArray(t)&&t.length>e?t[e]:null}function xn(t,e,n){t!==null&&n&&(t.extensions||(t.extensions={}),t.extensions[e]=n)}function st(t,e){if(!t.jsonDoc.json.images)return null;let n=he(e);return n!==void 0?t.textures[n]:(console.log("Kh\xF4ng th\u1EC3 t\xECm th\u1EA5y texture",e),null)}function he(t){if(t.source!==void 0)return t.source;if(t.extensions)for(let e of Object.keys(t.extensions)){let n=t.extensions[e];if(n&&n.source!==void 0)return n.source}}function Ct(t,e){let n=t.jsonDoc.json.textures;if(!n)return null;if(t instanceof kr){let s=t.imageIndexMap.get(e);for(let i of n)if(i.source===s)return i}else{let r=t.textures.indexOf(e);for(let s=0;s<n.length;s++){let i=n[s];if(i.source===r)return i;if(i.extensions)for(let o of Object.keys(i.extensions)){let a=i.extensions[o];if(a&&a.source===r)return i}}}return null}function Pt(t){return t%4===0}function Dt(t){return t<=4?4:t%4?t+4-t%4:t}function ue(t){return t.getName()?.startsWith("Lightmap")??!1}function Ft(t){t.setName("Lightmap")}import{Extension as Gr,ExtensionProperty as jr,PropertyType as Br}from"@gltf-transform/core";var be="GLTF_progressive_texture_settings",Re=class extends Gr{static EXTENSION_NAME=be;extensionName=be;read(e){let r=e.jsonDoc.json.textures;if(!r)return this;for(let s=0;s<r.length;s++){let i=r[s];if(i.extensions&&i.extensions[be]){let o=i.extensions[be],a=new kt(this.document.getGraph(),"");Object.assign(a,o);let u=e.textures[s];u&&u.setExtension(be,a)}}return this}write(e){return this}},kt=class extends jr{static EXTENSION_NAME=be;extensionName=be;parentTypes=[Br.TEXTURE];propertyType=be;generateLods;maxSize;guid;init(){}get isValid(){return this.maxSize!==void 0&&this.maxSize>0}};var Wr=process.env.VITEST==="true",Ae=class extends Error{constructor(e){super(e),this.name="TestAssertionError"}};function re(t,e){if(!t&&Wr)throw new Ae(`Assertion failed: ${e}`)}import{existsSync as qr,readFileSync as Kr}from"fs";import{dirname as Hr,join as Vr}from"path";var yn=[];for(let t in P)yn.push(P[t]);var Xt="";function z(t,e,n){Array.isArray(e)||(e=[e]);let r=t,s=yn,i=n?.debug??!1;class o extends zr{extensionName=r;static EXTENSION_NAME=r;prewriteTypes=[P.MATERIAL];jsonPointerHandler;read(c){if(n?.breakpoint===!0)debugger;Xt=c.jsonDoc.json.asset?.generator??"",i&&console.log("READ "+r),this.jsonPointerHandler=new Bt(this.document,r),this.jsonPointerHandler.debug=i,this.jsonPointerHandler.breakPoint=n?.breakpoint;for(let l of e)switch(l){case P.ACCESSOR:this.onRead(c,"accessors","accessorIndexMap");break;case P.ANIMATION:this.onRead(c,"animations","animationIndexMap");break;case P.ANIMATION_CHANNEL:r==="KHR_animation_pointer"&&c.jsonDoc.json.animations?.forEach((f,g)=>{let p=c.animations[g],d=p.listChannels();f.channels?.forEach((y,x)=>{let h=y.target,M=h.extensions&&h.extensions[r];if(!M)return;let w=M.pointer;if(w){let v=w.split("/"),O=parseInt(v[2]),b=v[3];(b==="scale"||b==="translation"||b==="rotation")&&(d[x].setTargetNode(c.nodes[O]),d[x].setTargetPath(b))}let A=p.getExtension(r);if(i&&console.log(">>>",r,"animation",g,"channel",x,M),A){L(A);return}let I=this.createExtension();p.setExtension(r,I),L(I);function L(v){v.add(O=>{let b=O.jsonDoc.json.animations;if(!b)return;let D=b[g]?.channels[x];D?(i&&console.log("<<<",r,"animation",g,"channel",x,M),D.target=h):i&&console.log("WARN: ",r,"animation",g,"channel",x,"not found")})}})});break;case P.ANIMATION_SAMPLER:break;case P.BUFFER:this.onRead(c,"buffers","bufferIndexMap");break;case P.CAMERA:this.onRead(c,"cameras","cameraIndexMap");break;case P.MATERIAL:this.onRead(c,"materials","materialIndexMap");break;case P.TEXTURE:c.jsonDoc.json.textures?.forEach((f,g)=>{if(!f.extensions)return;let p=f.extensions[r];if(!p)return;let d=st(c,f);d||(console.log("WARN: could potentially not find gltf transform texture for "+g),d=c.textures[g]);let y=this.createExtension();this.jsonPointerHandler.read(c,d,p,y),d.setExtension(r,y);let x=new jt(this.document,f,r,p,i,d);y.add(x);let h=f.source;i&&console.log("Found texture with extension",r,"at index",g,"source image index",h,"name",d.getName()||"<unnamed>")});break;case P.NODE:this.onRead(c,"nodes","nodeIndexMap");break;case P.MESH:this.onRead(c,"meshes","meshIndexMap");break;case P.PRIMITIVE:c.jsonDoc.json.meshes?.forEach((f,g)=>{let p=c.meshes[g],d=p.listPrimitives();f.primitives?.forEach((y,x)=>{if(!y.extensions)return;let h=y.extensions[r];if(!h)return;let M=d[x],w=this.createExtension();this.jsonPointerHandler.read(c,M,h,w),M.setExtension(r,w),w.add(A=>{let I=A.meshIndexMap.get(p),v=A.jsonDoc.json.meshes[I].primitives[x];v.extensions=v.extensions||{},v.extensions[r]=h})})});break;case P.ROOT:{let f=c.jsonDoc.json.extensions;if(!f)continue;let g=f[r];if(g){let p=this.document.getRoot(),d=this.createExtension();this.jsonPointerHandler.read(c,p,g,d),p.setExtension(r,d),this.lightmapWorkaround(c,d,this.document.getLogger()),d.add(y=>{y.jsonDoc.json.extensions=y.jsonDoc.json.extensions||{},y.jsonDoc.json.extensions[r]=g})}break}}return this}lightmapWorkaround(c,l,f){let g=c.jsonDoc.json.textures;if(!g)return;let p=this.document.getRoot().listTextures();for(let d=0;d<p.length;d++){let y=p[d];if(ue(y)&&y.getMimeType()!=="image/exr"){l.setReference("lightmapTexture",y,{channels:q.R|q.G|q.B|q.A});let x=g[d],h=y.getName()||x?.name;f.debug(`Found lightmap texture "${h}" (${y.getMimeType()}) in ${r}`)}}}createExtension(c=""){return new a(this.document.getGraph(),c)}onRead(c,l,f){if(l!==void 0)try{let g=c.jsonDoc.json[l],p=c[l];g?.forEach((d,y)=>{if(!d.extensions||!d.extensions[r])return;let x=d.extensions[r];i&&console.log("READ",y,x);let h=this.createExtension();p[y].setExtension(r,h),this.jsonPointerHandler.read(c,p[y],x,h),h.add(new u(f,l,x))})}catch(g){console.error("ERR: "+g)}}prewrite(c,l){return this.jsonPointerHandler.resolveAndWrite(c,"prewrite"),this}write(c){if(n?.breakpoint===!0)debugger;if(n?.write===!1)return this;i&&console.log("WRITE "+r),this.jsonPointerHandler.resolveAndWrite(c,"write");let l=this.document.getRoot();for(let f of e)switch(f){case P.ACCESSOR:this.onWrite(c,()=>l.listAccessors());break;case P.ANIMATION:this.onWrite(c,()=>l.listAnimations());break;case P.ANIMATION_CHANNEL:case P.ANIMATION_SAMPLER:break;case P.BUFFER:this.onWrite(c,()=>l.listBuffers());break;case P.CAMERA:this.onWrite(c,()=>l.listCameras());break;case P.MATERIAL:this.onWrite(c,()=>l.listMaterials());break;case P.TEXTURE:this.onWrite(c,()=>l.listTextures());break;case P.NODE:this.onWrite(c,()=>l.listNodes());break;case P.MESH:this.onWrite(c,()=>l.listMeshes());break;case P.PRIMITIVE:{let g=l.listMeshes().flatMap(p=>p.listPrimitives());for(let p of g){let d=p.getExtension(r);d instanceof a&&d.onWrite(c,p)}break}case P.ROOT:{let g=l.getExtension(r);g instanceof a?g.onWrite(c,l):i&&console.warn("WARN: no extension found on root",r);break}}return this}onWrite(c,l){let f=l();if(f)for(let g of f){let p=g.getExtension(r);p instanceof a&&p.onWrite(c,g)}}}class a extends Ur{static EXTENSION_NAME=r;parentTypes=s;propertyType="GLTF_opaque_property";init(){this.extensionName=r}setReference(c,l,f={modifyChild:!0}){this.setRef(c,l,f)}writers=[];add(c){typeof c=="function"&&(c=new Gt(c)),this.writers.push(c)}onWrite(c,l){for(let f of this.writers)f.write?.call(f,c,l)}getExtensionDefinition(){let c={};for(let l of this.writers)"assignTo"in l&&l.assignTo&&l.assignTo(c);return c}}class u{map;gltfField;ext;constructor(c,l,f){this.map=c,this.gltfField=l,this.ext=f}assignTo(c){Object.assign(c,this.ext)}write(c,l){if(l&&this.gltfField!==void 0){let g=c[this.map].get(l),p=rt(c.jsonDoc.json[this.gltfField],g);xn(p,r,this.ext)}}}return o}var Gt=class{fn;constructor(e){this.fn=e}write(e){this.fn(e)}},jt=class{document;textureDefinition;key;ext;debug;textureRef;constructor(e,n,r,s,i,o){if(this.document=e,this.textureDefinition=n,this.key=r,this.ext=s,this.debug=i,this.textureRef=o,i){let a=this.tryGetSourceIndex(this.textureDefinition);console.log(a,this.textureDefinition)}}assignTo(e){Object.assign(e,this.ext)}write(e){if(this.key==="EXT_texture_exr"&&this.textureRef.getMimeType()!=="image/exr")return;let n=e.imageIndexMap.get(this.textureRef);if(re(n!==void 0||this.key==="EXT_texture_exr",`imageIndexMap missing texture ref for "${this.key}": ${this.textureRef.getName()||"<unnamed>"}`),n===void 0){this.debug&&console.warn("WARN: failed to resolve image index for texture via imageIndexMap:",this.key,this.textureRef.getName()||"<unnamed>");return}let r=!1,s=e.jsonDoc.json.textures||[];for(let i of s){if(r)break;let o=this.tryGetSourceIndex(i);if(n===o&&(r=!0,!i.extensions?.[this.key])){i.extensions=i.extensions||{},this.debug&&console.log("Re-Assign extension:",this.key);let a={...this.ext};a.source!==void 0&&(a.source=n),i.extensions[this.key]=a}}re(r||this.key==="EXT_texture_exr",`failed to match texture for extension "${this.key}", imageIndex=${n}, textures=${s.length}, name=${this.textureRef.getName()||"<unnamed>"}, type=${this.textureRef.getMimeType()}`),!r&&this.debug&&console.warn("WARN: failed to re-assign extension:",this.key,"imageIndex",n,s.length,this.textureRef.getName()||"<unnamed>",this.textureDefinition)}tryGetSourceIndex(e){let n=e.source;if(n!==void 0)return n;if(e.extensions)for(let r of Object.keys(e.extensions)){let s=e.extensions[r];if(s.source!==void 0){n=s.source;break}}return n}},Bt=class{debug=!1;breakPoint=!1;extension_name;document;map=new Map;VRM_0_MaterialIndexRegex=/materialProperties\/(?<material_index>\d+)\//g;externalExrTextures=new Map;externalExrPointers=[];constructor(e,n){this.document=e,this.extension_name=n}read(e,n,r,s,i,o){let a=i!==void 0?r[i]:r;if(i!==void 0&&(o??="",o+="/"+i,this.breakPoint==="pointer:read"))debugger;switch(typeof a){case"object":if(a!=null)if(Array.isArray(a))for(let u=0;u<a.length;u++)this.read(e,n,a,s,u.toString(),o);else for(let u of Object.keys(a))this.read(e,n,a,s,u,o);break;case"string":a&&i&&this.readStringPointer(e,n,r,s,i,a,o??"");break;case"number":i&&o&&this.readNumberPointer(e,r,s,i,a,o);break;default:break}}resolveAndWrite(e,n){this.map.forEach(r=>{r.resolve(e,n)&&r.write()});for(let{obj:r,key:s,texture:i}of this.externalExrPointers){let o=i.getURI()||i.getName()||"";if(o){this.debug&&console.log(`< Resolved external EXR: ${r[s]} \u2192 ${o}`),r[s]=o;let a=e.imageIndexMap.get(i);if(a!==void 0){let u=e.jsonDoc.json.images;u&&u[a]&&!u[a].uri&&(u[a].uri=o)}}}}readStringPointer(e,n,r,s,i,o,a){let u="/textures/",m=o.startsWith(u);if(m||(u="textures/",m=o.startsWith(u)),m){this.debug&&console.log("Read pointer",o);let c=this.map.get(o);if(!c){let l=parseInt(o.substring(u.length)),f=o.substring(0,u.length),g=e.jsonDoc.json.textures[l],p=he(g);this.debug&&console.log("Texture index",l,p,e.jsonDoc.json.textures.length,"Textures:"+e.textures.length);let d=rt(e.textures,p);if(d){let y=new it(this.document,d,g);y.debug=this.debug,y.init(e),c=new ve(f,y,o),c.debug=this.debug,this.map.set(o,c);let x=o;s.setReference(x,d,{channels:q.R|q.G|q.B|q.A});let h=this.document.getRoot().listBuffers()[0];h&&s.setReference("buffer",h)}else console.warn("Texture not found",a,o)}c?(this.debug&&console.log("> Register pointer",this.extension_name+"/"+a+" : "+o),c.register(r,i,a)):console.warn("WARN: failed registering pointer",a,o)}if(!m&&o.match(/\.exr$/i)){let c=ze()?Hr(ze()):"",l=c?Vr(c,o):"";if(l&&qr(l)){let f=this.externalExrTextures.get(o);if(!f){let p=Kr(l);f=this.document.createTexture(o).setImage(new Uint8Array(p)).setMimeType("image/exr").setURI(o),this.externalExrTextures.set(o,f),this.debug&&console.log(`Injected external EXR "${o}" as Texture`)}s.setReference(`exr_${o}`,f,{channels:q.R|q.G|q.B|q.A});let g=this.document.getRoot().listBuffers()[0];g&&s.setReference(`exr_buffer_${o}`,g),this.externalExrPointers.push({obj:r,key:i,texture:f})}else l&&(this.document.getLogger().error(`GLTF_opaque: External EXR not found: ${l}`),re(!1,`GLTF_opaque: External EXR not found: ${l}`))}if(o.startsWith("/materials/")){this.debug&&console.log("Read pointer",o);let c=parseInt(o.substring(11)),l=e.materials[c];if(l){s&&s.setReference(o,l);let f=this.map.get(o);if(!f){let g=e.jsonDoc.json.materials[c],p=new Wt(this.document,l,g);p.debug=this.debug,p.init(e),f=new ve("/materials/",p,o),f.debug=this.debug,this.map.set(o,f),s.setReference(o,l)}f?.register(r,i,a)}}if(o.startsWith("/animations/")){this.debug&&console.log("Read pointer",o);let c=parseInt(o.substring(12)),l=e.animations[c];if(l){let f=this.map.get(o);f||s.setReference(o,l),f?.register(r,i,a)}}if(o.startsWith("/meshes/")){this.debug&&console.log("Read pointer",o);let c=parseInt(o.substring(8)),l=e.meshes[c];if(l){let f=this.map.get(o);if(!f){let g=e.jsonDoc.json.meshes[c],p=new Ut(this.document,l,g,s);p.debug=this.debug,p.init(e),f=new ve("/meshes/",p,o),f.debug=this.debug,this.map.set(o,f),s.setReference(o,l)}f?.register(r,i,a)}}}readNumberPointer(e,n,r,s,i,o){if(s==="node"||s==="mesh"||o.match(/springs\/\d+\/center/g)){let a=e.nodes[i];if(a){let u=new zt(this.document,a,e.jsonDoc.json.nodes[i]);u.debug=this.debug,u.init(e);let m=`/${s}/${i}`,c=this.map.get(m);c||(c=new ve(null,u,i)),c.debug=this.debug,c.register(n,s,o),this.map.set(m,c),r.setReference(m,a)}}else if(s==="texture"||o.match(/materialProperties\/(?<material_index>\d+)\/textureProperties/g)||o.match(/meta\/thumbnailImage/g)||o.match(/^\/textures\/\d{1,}$/)){let a=i;if(a<0){console.warn(`WARN: texture index is negative ${a} at ${o}`);return}let u=e.jsonDoc.json.textures?.[a];if(!u){console.warn(`WARN: texture definition with index ${a} not found or does not exist. Set in "${o}"`);return}let m=he(u);this.debug&&console.log("Texture index",a,m,e.jsonDoc.json.textures.length,"Textures:"+e.textures.length);let c=rt(e.textures,m);if(c){this.debug&&console.log("Found texture index at "+o+": "+i);let f=new it(this.document,c,u);f.debug=this.debug,f.init(e);let g=`/textures/${i}`,p=this.map.get(g);p||(p=new ve(null,f,i)),p.debug=this.debug,p.register(n,s,o),this.map.set(g,p),r.setReference(g,c,{channels:q.R|q.G|q.B|q.A})}let l=this.VRM_0_MaterialIndexRegex.exec(o);if(l){let f=parseInt(l.groups.material_index),g=e.materials[f];r.setReference(`/materials/${f}`,g)}}}},ve=class{debug=!1;resolver;pointerBase;oldPointer;_objects=[];_props=[];_debugInfo=[];newPointer=void 0;_didWrite=!1;constructor(e,n,r){this.pointerBase=e,this.resolver=n,this.oldPointer=r}register(e,n,r){this._objects.push(e),this._props.push(n),this._debugInfo.push(r)}resolve(e,n){if(this.newPointer!==void 0)return!0;this.resolver.debug=this.debug;let r=this.resolver.resolve(e);if(r!==void 0)return this.pointerBase!=null?this.newPointer=this.pointerBase+r:this.newPointer=r,!0;if(n==="write"&&(console.log(`ERR: \u{1F9E8} FAILED to resolve pointer "${this.oldPointer}" used by ${this._debugInfo.join(", ")}`),this.debug))debugger;return!1}write(){if(!this._didWrite){this._didWrite=!1;for(let e=0;e<this._objects.length;e++){let n=this._objects[e],r=this._props[e];this.debug&&console.log(`< Resolved pointer ${this._debugInfo[e]}: ${this.oldPointer} \u2192 ${this.newPointer}`),n[r]=this.newPointer}}}},Ce=class{debug=!1;document;inputObject;inputDefinition;property;constructor(e,n,r,s){this.document=e,this.inputObject=n,this.inputDefinition=r,this.property=s}},it=class extends Ce{_debugName="";_samplerDef;init(e){this._debugName=this.inputDefinition.name??this.inputDefinition.source?.toString()??"unknown";let n=this.inputDefinition.sampler;n!==void 0&&(this._samplerDef=e.jsonDoc.json.samplers?.[n]),this.debug&&console.log(this._debugName,this._samplerDef)}resolve(e){let n=e.imageIndexMap.get(this.inputObject);if(n===void 0)return re(!1,`imageIndexMap missing texture: ${this.inputObject.getName()||"<unnamed>"}`),console.error("ERR: image is missing"),-1;e.jsonDoc.json.textures=e.jsonDoc.json.textures||[];for(let o=0;o<e.jsonDoc.json.textures.length;o++){let a=e.jsonDoc.json.textures[o];if(he(a)===n)return a.sampler===void 0&&(a.sampler=this.findOrCreateSampler(e.jsonDoc.json)),this.debug&&console.log("Found texture def at "+o,"using image",n,a),o}this.debug&&console.log("Could not find texture, creating a new one: "+this._debugName);let r=this.inputDefinition.extensions?{...this.inputDefinition.extensions}:void 0;r&&(delete r[Re.EXTENSION_NAME],r.EXT_texture_exr&&this.inputObject.getMimeType()!=="image/exr"&&delete r.EXT_texture_exr,Object.keys(r).length===0&&(r=void 0));let i={source:r&&Object.keys(r).some(o=>r[o]?.source!==void 0)?void 0:n,sampler:this.findOrCreateSampler(e.jsonDoc.json),extensions:r,extras:this.inputDefinition.extras};return e.jsonDoc.json.textures.push(i),e.jsonDoc.json.textures.length-1}findOrCreateSampler(e){if(e.samplers=e.samplers||[],this._samplerDef===void 0)console.log("WARN: Creating default sampler",this._debugName),this._samplerDef={magFilter:9729,minFilter:9729,wrapS:33648,wrapT:33648};else for(let n=0;n<e.samplers.length;n++){let r=e.samplers[n];if(r.minFilter===this._samplerDef.minFilter&&r.magFilter===this._samplerDef.magFilter&&r.wrapS===this._samplerDef.wrapS&&r.wrapT===this._samplerDef.wrapT)return n}return e.samplers.push(this._samplerDef),e.samplers.length-1}},Wt=class extends Ce{init(e){}resolve(e){return e.materialIndexMap.get(this.inputObject)}},zt=class extends Ce{init(e){}resolve(e){return e.nodeIndexMap.get(this.inputObject)}},Ut=class extends Ce{init(e){}resolve(e){let n=e.meshIndexMap.get(this.inputObject);if(n!==void 0&&n>=0)return n;let r=null;if(this.inputObject.isDisposed()){let s=this.property?.listParents()??[];for(let i of s)if(i instanceof Xr&&(r=i.getMesh(),r)){this.document.getLogger().info(`INFO: resolved mesh "${this.inputObject.getName()}" from parent node "${i.getName()}"`);break}r?.isDisposed()&&console.warn("WARN: mesh is disposed",this.inputObject.getName())}if(r)return e.meshIndexMap.get(r)}};var K={debug:process.argv.includes("debug")},ot=[z("KHR_animation_pointer",[j.ANIMATION,j.ANIMATION_CHANNEL],{...K}),z("GLTF_techniques_webgl",[j.NODE,j.MATERIAL,j.ROOT],{...K}),z("GLTF_gameobject_data",j.NODE,{...K}),z("GLTF_components",j.NODE,{...K}),z("GLTF_persistent_assets",j.ROOT,{...K}),z("GLTF_lighting_settings",j.ROOT,{...K}),z("GLTF_render_objects",j.ROOT,{...K}),z("GLTF_progressive",[j.TEXTURE,j.MATERIAL,j.MESH],{...K}),z("EXT_texture_exr",[j.TEXTURE],{...K}),z("GLTF_editor",[j.NODE,j.MATERIAL],{...K}),z("GLTF_gltf_dependencies",[j.ROOT],{...K}),z("GLTF_materials_mtlx",[j.ROOT,j.MATERIAL],{...K}),z("VRM",[j.ROOT],{...K}),z("VRMC_vrm",[j.ROOT],{...K}),z("VRMC_springBone",[j.ROOT],{...K}),z("VRMC_node_constraint",[j.NODE],{...K})];import{Extension as Jr,ExtensionProperty as Zr,PropertyType as qt}from"@gltf-transform/core";var X="GLTF_mesh_compression",bn=!1,Te=class{compression;constructor(e){this.compression=e}};var at=class extends Zr{static EXTENSION_NAME=X;extensionName=X;parentTypes=[qt.ROOT,qt.PRIMITIVE,qt.MESH];propertyType=X;model;init(){}copy(e,n){return this.model={...e.model},super.copy(e,n)}},se=class extends Jr{static EXTENSION_NAME=X;extensionName=X;create(e){let n=new at(this.document.getGraph(),"");return n.model=e,n}read(e){bn&&console.log("READ "+X);let n=e.jsonDoc.json.extensions?.[X];return n&&this.document.getRoot().setExtension(X,this.create(n)),e.jsonDoc.json.meshes&&e.meshes?.forEach((r,s)=>{let i=e.jsonDoc.json.meshes[s];if(!i)return;let o=r.listPrimitives();for(let a=0;a<o.length;a++){let u=i.primitives[a];if(u.extensions&&u.extensions[X]){let m=u.extensions[X];o[a].setExtension(X,this.create(m))}}}),this}write(e){bn&&console.log("WRITE "+X);let n=this.document.getRoot(),r=n.getExtension(X);r&&(e.jsonDoc.json.extensions=e.jsonDoc.json.extensions||{},e.jsonDoc.json.extensions[X]=r.model);for(let s of n.listMeshes()){let i=e.meshIndexMap.get(s);if(i===void 0)continue;let o=e.jsonDoc.json.meshes[i],a=s.listPrimitives();for(let u=0;u<a.length;u++){let c=a[u].getExtension(X);if(c){let l=o.primitives[u];l&&(l.extensions=l.extensions||{},l.extensions[X]=c.model)}}}return this}};import{Extension as Yr,ExtensionProperty as Qr,PropertyType as Tn}from"@gltf-transform/core";var H="GLTF_compression_texture",En=!1,Ue=class extends Qr{static EXTENSION_NAME=H;extensionName=H;parentTypes=[Tn.TEXTURE];propertyType=H;model;init(){this.extensionName=H,this.parentTypes=[Tn.TEXTURE],this.propertyType=H}},te=class extends Yr{static EXTENSION_NAME=H;extensionName=H;create(e){let n=new Ue(this.document.getGraph(),"");return n.model=e,n}read(e){return En&&console.log("READ "+H),e.jsonDoc.json.textures?(e.textures?.forEach(n=>{let r=Ct(e,n);if(r?.extensions&&r.extensions[H]){let s=new Ue(this.document.getGraph(),H);s.model=r.extensions[H],n.setExtension(H,s)}}),this):this}write(e){En&&console.log("WRITE "+H);let r=this.document.getRoot().listTextures();for(let s of r){let i=s.getExtension(H);if(i){let o=Ct(e,s);o&&(o.extensions=o.extensions||{},o.extensions[H]=i.model)}}return this}};import{Extension as es,ExtensionProperty as ts,PropertyType as Sn}from"@gltf-transform/core";var Z="GLTF_progressive",ct=class extends ts{static EXTENSION_NAME=Z;extensionName=Z;parentTypes=[Sn.TEXTURE,Sn.MESH];propertyType="progressive_texture";model;init(){}},me=class extends es{static EXTENSION_NAME=Z;extensionName=Z;createTexture(e){let n=new ct(this.document.getGraph());return n.model=e,n}createMesh(e){let n=new ct(this.document.getGraph());return n.model=e,n}read(e){return this}write(e){let n=this.document.getRoot(),r=e.jsonDoc.json,s=r.textures;if(s?.length){let o=n.listTextures(),a=e.imageIndexMap;for(let u of o){let m=u.getExtension(Z);if(m&&m.model){let c=a.get(u);for(let l of s)l.source===c&&(l.extensions=l.extensions||{},l.extensions[Z]=m.model)}}}let i=r.meshes;if(i?.length){let o=e.meshIndexMap,a=n.listMeshes();for(let u=0;u<a.length;u++){let m=a[u],c=o.get(m);if(c===void 0)continue;let l=m.getExtension(Z);if(l&&l.model){let f=i[c];f&&(f.extensions=f.extensions||{},f.extensions[Z]=l.model)}}}return this}};import{Extension as ns,ExtensionProperty as rs,PropertyType as ss}from"@gltf-transform/core";var Ee="GLTF_progressive_mesh_settings",Kt=class extends rs{static EXTENSION_NAME=Ee;extensionName=Ee;parentTypes=[ss.MESH];propertyType=Ee;generateLods;guid;init(){}},Xe=class extends ns{static EXTENSION_NAME=Ee;extensionName=Ee;read(e){let n=e.jsonDoc.json.meshes;if(!n)return this;let s=this.document.getRoot().listMeshes();for(let i=0;i<n.length;i++){let o=n[i];if(o.extensions&&o.extensions[Ee]){let a=o.extensions[Ee],u=new Kt(this.document.getGraph(),"");Object.assign(u,a);let c=s[i];c?c.setExtension(Ee,u):console.warn(`WARN: Progressive mesh at index ${i} was not found in the glTF file. This might result in falsely loaded textures for ${a.guid} / name "${o.name}"`)}}return this}write(e){return this}};import{Extension as is}from"@gltf-transform/core";var Pe="GLTF_pmrem",Se=class extends is{static EXTENSION_NAME=Pe;extensionName=Pe;pmremTextures=new Set;addTexture(e){this.pmremTextures.add(e)}preread(e,n){let r=e.jsonDoc.json;for(let s of r.textures??[]){let i=s.extensions?.[Pe];i?.source!==void 0&&s.source===void 0&&(s.source=i.source)}for(let s of r.textures??[]){let i=s.extensions?.[Pe];if(i?.source!==void 0){let o=r.images?.[i.source];o&&!o.mimeType&&(o.mimeType="image/ktx2")}}return this}read(e){let r=e.jsonDoc.json.textures??[],s=this.document.getRoot().listTextures();for(let i=0;i<r.length;i++){if(r[i].extensions?.[Pe]?.source===void 0)continue;let u=s[i];u&&(u.setMimeType("image/ktx2"),this.pmremTextures.add(u))}return this}write(e){let n=e.jsonDoc;for(let s of this.pmremTextures){let i=e.imageIndexMap.get(s);if(i!==void 0)for(let o of n.json.textures??[])(o.source??o.extensions?.KHR_texture_basisu?.source)===i&&(o.extensions=o.extensions||{},o.extensions[Pe]={source:i},o.extensions.KHR_texture_basisu&&delete o.extensions.KHR_texture_basisu)}if(!(n.json.textures??[]).some(s=>s.extensions?.KHR_texture_basisu)){let s=i=>{if(!i)return;let o=i.indexOf("KHR_texture_basisu");o>=0&&i.splice(o,1)};s(n.json.extensionsUsed),s(n.json.extensionsRequired)}return this}};import{Extension as os,ExtensionProperty as as,PropertyType as Ht,TextureChannel as we}from"@gltf-transform/core";import{existsSync as cs,readFileSync as us}from"fs";import{join as ms,dirname as ls}from"path";var Ie="GLTF_lightmaps",Vt=class extends as{static EXTENSION_NAME=Ie;parentTypes=[Ht.ROOT];init(){this.extensionName=Ie,this.propertyType="LightmapProperty"}getDefaults(){return Object.assign(super.getDefaults(),{})}setReference(e,n,r){this.setRef(e,n,r)}},De=class extends os{static EXTENSION_NAME=Ie;extensionName=Ie;prereadTypes=[Ht.TEXTURE];prewriteTypes=[Ht.MATERIAL];extensionData=null;resolved=[];injectedImageIndices=new Map;lightmapProp=null;preread(e,n){let r=e.jsonDoc.json,s=r.extensions?.[Ie];if(!s?.textures)return this;let i=ze(),o=i?ls(i):"";for(let a of s.textures){if(a.pointer.startsWith("/")||a.pointer.startsWith("textures/")||!a.pointer.match(/\.exr$/i))continue;let u=o?ms(o,a.pointer):"";if(!u||!cs(u)){this.document.getLogger().error(`GLTF_lightmaps: Kh\xF4ng t\xECm th\u1EA5y file EXR b\xEAn ngo\xE0i: ${u||a.pointer}`),re(!1,`GLTF_lightmaps: Kh\xF4ng t\xECm th\u1EA5y file EXR b\xEAn ngo\xE0i: ${u||a.pointer}`);continue}let m=us(u);r.images=r.images||[],r.textures=r.textures||[];let c=r.images.length;r.images.push({uri:a.pointer,mimeType:"image/exr",name:a.pointer}),r.textures.push({source:c,name:a.pointer}),e.jsonDoc.resources[a.pointer]=new Uint8Array(m),this.injectedImageIndices.set(a.pointer,c),this.document.getLogger().info(`GLTF_lightmaps: \u0110\xE3 \u0111\u0103ng k\xFD file EXR b\xEAn ngo\xE0i "${a.pointer}" d\u01B0\u1EDBi d\u1EA1ng image[${c}]`)}return this}read(e){let n=e.jsonDoc.json,r=n.extensions?.[Ie];if(!r?.textures)return this;this.extensionData=r;let s=this.document.getRoot();this.lightmapProp=new Vt(this.document.getGraph()),s.setExtension(Ie,this.lightmapProp);let i=n.textures||[],o=this.document.getLogger();for(let u of r.textures){let m=null,c;if(u.pointer.startsWith("/textures/")||u.pointer.startsWith("textures/")){let l=u.pointer.startsWith("/")?"/textures/":"textures/",f=parseInt(u.pointer.substring(l.length),10),g=i[f];g&&(c=g,m=st(e,g)??null)}else if(u.pointer.match(/\.exr$/i)){let l=this.injectedImageIndices.get(u.pointer);l!==void 0&&(m=e.textures[l]??null,c=i.find(f=>he(f)===l))}else if(!u.pointer.startsWith("/")){let l=n.images??[];for(let f=0;f<l.length;f++)if(l[f].uri===u.pointer){m=e.textures[f]??null,c=i.find(g=>he(g)===f);break}}if(m){this.resolved.push({entry:u,texture:m,inputTextureDef:c});let l=`lightmapTexture_${u.pointer}`,f=we.R|we.G|we.B|we.A;this.lightmapProp.setReference(l,m,{channels:f});let g=this.document.getRoot().listBuffers()[0];g&&this.lightmapProp.setReference("buffer",g)}else this.document.getLogger().error(`GLTF_lightmaps: Kh\xF4ng th\u1EC3 gi\u1EA3i quy\u1EBFt (resolve) texture cho con tr\u1ECF "${u.pointer}"`),re(!1,`GLTF_lightmaps: Kh\xF4ng th\u1EC3 gi\u1EA3i quy\u1EBFt texture cho con tr\u1ECF "${u.pointer}"`)}let a=this.document.getRoot().listTextures();for(let u of a)if(ue(u)&&u.getMimeType()!=="image/exr"){let m=`lightmapTexture_${u.getName()}`,c=we.R|we.G|we.B|we.A;this.lightmapProp.setReference(m,u,{channels:c}),this.document.getLogger().debug(`[GLTF_lightmaps] T\xECm th\u1EA5y texture lightmap "${u.getName()}" (${u.getMimeType()})`)}return this}prewrite(e,n){return this.resolvePointers(e),this}write(e){if(!this.extensionData)return this;this.resolvePointers(e);let n=e.jsonDoc.json;return n.extensions=n.extensions||{},n.extensions[Ie]=this.extensionData,this}pointersResolved=!1;resolvePointers(e){if(!this.pointersResolved){this.pointersResolved=!0;for(let{entry:n,texture:r,inputTextureDef:s}of this.resolved)if(n.pointer.startsWith("/textures/")||n.pointer.startsWith("textures/")){let i=this.findOrCreateTextureIndex(e,r,s);i!==void 0&&(n.pointer=`/textures/${i}`)}else{let i=r.getURI();if(i){n.pointer=i;let o=e.imageIndexMap.get(r);if(o!==void 0){let a=e.jsonDoc.json.images;a&&a[o]&&(a[o].uri=i)}}}}}findOrCreateTextureIndex(e,n,r){let s=e.imageIndexMap.get(n);if(s===void 0)return;let i=e.jsonDoc.json.textures=e.jsonDoc.json.textures||[];for(let m=0;m<i.length;m++)if(he(i[m])===s)return m;let o=r?.extensions?{...r.extensions}:void 0;o&&(delete o.GLTF_progressive_texture_settings,o.EXT_texture_exr&&n.getMimeType()!=="image/exr"&&delete o.EXT_texture_exr,Object.keys(o).length===0&&(o=void 0));let u={source:o&&Object.values(o).some(m=>m?.source!==void 0)?void 0:s,extensions:o};return i.push(u),i.length-1}};import{ALL_EXTENSIONS as fs}from"@gltf-transform/extensions";var wn="";function ut(t){wn=t}function ze(){return wn}function In(t){t.registerExtensions(fs),t.registerExtensions(ot),t.registerExtensions([me,Se,De])}import{createTransform as Li}from"@gltf-transform/functions";function Jt(t){return t.includes("normalTexture")||t.includes("metallicRoughnessTexture")?"UASTC":"ETC1S"}import{existsSync as le,statSync as _n,readdirSync as gs,readFileSync as ps,mkdirSync as Mn,rmSync as hs}from"fs";import{setTimeout as ds}from"timers/promises";import{dirname as xs,isAbsolute as ys,join as bs}from"path";function mt(t,e,n){if(!e)return t;if(!Fe(e))return e;let r=Zt(t);return n?.create!==!1&&!le(e)&&Mn(e,{recursive:!0}),bs(e,r)}function Zt(t){let e=t.replaceAll("\\","/").split("/");return e[e.length-1]}async function Ke(t,e){let n=process.env.INIT_CWD,r={baseDirectory:n,files:[]};if(Array.isArray(t))for(let s of t)await qe(s,r);else typeof t=="string"&&await qe(t,r);if(r.files.length<=0&&r.baseDirectory){let s=r.baseDirectory+"/gltf.config.json";if(le(s)){let o=JSON.parse(ps(s,"utf8")).buildDirectory;if(o?.length)if(le(o))console.log("INFO: \u0110ang s\u1EED d\u1EE5ng th\u01B0 m\u1EE5c build t\u1EEB gltf.config.json: "+o),await qe(o,r);else{let a=r.baseDirectory+"/"+o;le(a)&&(console.log("INFO: \u0110ang s\u1EED d\u1EE5ng th\u01B0 m\u1EE5c build t\u1EEB gltf.config.json: "+a),await qe(a,r))}}}if(r.files.length<=0)console.log(`WARN: Kh\xF4ng t\xECm th\u1EA5y file glTF n\xE0o. H\xE3y \u0111\u1EA3m b\u1EA3o b\u1EA1n g\u1ECDi l\u1EC7nh v\u1EDBi \u0111\u01B0\u1EDDng d\u1EABn h\u1EE3p l\u1EC7 tr\u1ECF t\u1EDBi m\u1ED9t file glTF ho\u1EB7c m\u1ED9t th\u01B0 m\u1EE5c.
3
3
  Th\u01B0 m\u1EE5c g\u1ED1c (Base Directory): ${r.baseDirectory}
4
- C\xE1c \u0111\u01B0\u1EDDng d\u1EABn c\xF3 th\u1EC3 \u0111\u01B0\u1EE3c vi\u1EBFt t\u01B0\u01A1ng \u0111\u1ED1i so v\u1EDBi "${n}"`);else for(let s of r.files)await e(s)}async function Ke(t,e){if(t.startsWith("--"))return!1;if((t==="."||t==="./")&&e.baseDirectory&&(t=e.baseDirectory),le(t)===!1){if(e.baseDirectory===void 0)return console.log("WARN: \u0110\u01B0\u1EDDng d\u1EABn kh\xF4ng t\u1ED3n t\u1EA1i: "+t),!1;let n=e.baseDirectory+"/"+t;if(le(n)===!1)return console.log(`INFO: Gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn th\u1EA5t b\u1EA1i: "${t}" -> ${n} (kh\xF4ng t\u1ED3n t\u1EA1i ho\u1EB7c \u0111ang b\u1ECB kh\xF3a b\u1EDFi ti\u1EBFn tr\xECnh kh\xE1c)`),!1;console.log(`INFO: \u0110\xE3 gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn: ${t} -> ${n}`),t=n}else if(!Rs(t)&&e.baseDirectory){let r=e.baseDirectory+"/"+t;if(console.log(`INFO: \u0110\xE3 gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn: ${t} -> ${r}`),t=r,!le(t))return!1}if(t.endsWith(".glb")||t.endsWith(".gltf")||t.endsWith(".vrm"))e.files.push(t);else if($n(t).isDirectory()){if(t.endsWith("node_modules"))return!1;let r=As(t);for(let s of r)await Ke(t+"/"+s,e)}}function Cn(t,e){let n=t.split(".");return n.pop(),n.join(".")+"."+e}function Fe(t){return t?le(t)?$n(t).isDirectory():!t.replaceAll("\\","/").split("/").pop()?.includes("."):!1}function Ve(t){return Fe(t)||(t=vs(t)),le(t)||Pn(t,{recursive:!0}),t}async function dt(t,e=3,n=150){for(let r=0;r<=e;r++)try{le(t)&&Ns(t,{recursive:!0});return}catch(s){if(!(s?.code==="EBUSY"||s?.code==="EPERM")||r===e)return;await Os(n)}}var Dn="0.0.7";function Q(t=!0){return Dn}import{Mesh as Ps}from"@gltf-transform/core";function Je(t){let e=0,n=0,r=0;return t instanceof Ps?(r=t.listPrimitives().reduce((s,o)=>{let i=o.getIndices()?.getCount()||0;n+=i;let a=o.getAttribute("POSITION")?.getCount()||0;return e=Math.max(e,a),s+a},0),{maxVertexCount:e,totalVertexCount:r,totalIndexCount:n}):(t.getRoot().listMeshes().forEach(s=>{let o=Je(s);e=Math.max(e,o.maxVertexCount),r+=o.totalVertexCount,n+=o.totalIndexCount}),{maxVertexCount:e,totalVertexCount:r,totalIndexCount:n})}function Ze(t){let e={min:[1/0,1/0,1/0],max:[-1/0,-1/0,-1/0]},n=t.getAttribute("POSITION");if(!n)return-1;let r=[0,0,0];function s(a,u){for(let m=0;m<3;m++)u.min[m]=Math.min(a[m],u.min[m]),u.max[m]=Math.max(a[m],u.max[m])}for(let a=0;a<n.getCount();a++)r=n.getElement(a,r),s(r,e);let o=t.getIndices(),i=0;if(o){let a=o.getCount(),u=o.getArray(),m=[0,0,0],c=[0,0,0],l=[0,0,0],f=[0,0,0],g=[0,0,0],p=e.max[0]-e.min[0],h=e.max[1]-e.min[1],y=e.max[2]-e.min[2],x=Math.max(p,h,y);for(let T=0;T<a;T+=3){let L=u[T+0],_=u[T+1],A=u[T+2];n.getElement(L,m),n.getElement(_,c),n.getElement(A,l),f[0]=c[0]-m[0],f[1]=c[1]-m[1],f[2]=c[2]-m[2],g[0]=l[0]-m[0],g[1]=l[1]-m[1],g[2]=l[2]-m[2],f[0]/=x,f[1]/=x,f[2]/=x,g[0]/=x,g[1]/=x,g[2]/=x;let M=[f[1]*g[2]-f[2]*g[1],f[2]*g[0]-f[0]*g[2],f[0]*g[1]-f[1]*g[0]];i+=Math.sqrt(M[0]*M[0]+M[1]*M[1]+M[2]*M[2])/2}return o.getCount()/3/i}else{let a=n.getCount(),u=[0,0,0];u[0]=e.max[0]-e.min[0],u[1]=e.max[1]-e.min[1],u[2]=e.max[2]-e.min[2];let m=u[0]*u[1]*u[2];return a/m}}import{v5 as Cs}from"uuid";var Ds="0c147764-f63f-4508-81fb-3704b1175de2";function ht(t){return Cs(t,Ds)}import{cpSync as Fn,existsSync as Ye,mkdirSync as Fs}from"fs";import{writeFile as ks}from"fs/promises";import he from"path";import Gs from"sharp";async function xt(t,e,n){let r=he.dirname(e);if(Ye(r)||Fs(r),e.endsWith(".vrm")){let s=await t.writeBinary(n);await ks(e,s)}else await t.write(e,n);return e}var js=/open '(?<path>.+?)'/,kn=new Set;async function Qe(t,e,n=0){let r=await t.read(e).catch(s=>s);if(r instanceof Error){let s=r;if(n<100&&s.message?.includes("ENOENT"))try{let o=s.message.match(js);if(o?.groups?.path){let i=o.groups.path;if(i.startsWith("http")||kn.has(i))throw s;kn.add(i),console.warn(`\u0110ang t\u1EA1o m\u1ED9t file r\u1ED7ng \u0111\u1EC3 thay th\u1EBF cho t\xE0i nguy\xEAn b\u1ECB thi\u1EBFu: ${i}`);let a=i.split(".").pop();if(!a)throw console.warn(`Kh\xF4ng th\u1EC3 x\xE1c \u0111\u1ECBnh \u0111\u01B0\u1EE3c \u0111u\xF4i m\u1EDF r\u1ED9ng (extension) cho ${i}`),s;let u=a.toLowerCase(),m=!1;switch(u){case"jpeg":case"jpg":case"png":case"webp":case"tiff":case"gif":await Gs({create:{width:64,height:64,channels:4,background:{r:255,g:255,b:255,alpha:1}}}).toFormat(a).toFile(i),m=!0}if(m)return console.warn(`\u0110\xE3 t\u1EA1o th\xE0nh c\xF4ng file r\u1ED7ng cho t\xE0i nguy\xEAn b\u1ECB thi\u1EBFu: ${i}`),Qe(t,e,n+1)}}catch(o){console.warn(o)}throw s}return r}function yt(t,e,n){let r=he.resolve(he.dirname(e)),s=he.resolve(he.dirname(n));if(r!==s){for(let o of t.getRoot().listTextures()){let i=o.getURI();if(!i||i.startsWith("data:"))continue;let a=he.join(r,i),u=he.join(s,i);!Ye(u)&&Ye(a)&&Fn(a,u)}for(let o of t.getRoot().listBuffers()){let i=o.getURI();if(!i||i.startsWith("data:"))continue;let a=he.join(r,i),u=he.join(s,i);!Ye(u)&&Ye(a)&&Fn(a,u)}}}import{Document as Wo,ImageUtils as zo}from"@gltf-transform/core";import{inspect as Uo}from"@gltf-transform/functions";import{statSync as Xo,writeFileSync as qo}from"fs";import{Document as sr,NodeIO as fn,PropertyType as xo,TextureChannel as yo,Verbosity as er}from"@gltf-transform/core";import{SIMPLIFY_DEFAULTS as bo,WELD_DEFAULTS as To,listTextureChannels as Eo,listTextureSlots as So,metalRough as tr,sparse as or}from"@gltf-transform/functions";import{KHRMaterialsSpecular as St}from"@gltf-transform/extensions";import nr from"draco3dgltf";import Re,{basename as wo,resolve as Io}from"path";import{existsSync as wt,mkdirSync as _o,readFileSync as Mo,rmSync as Ao,statSync as Lo,writeFileSync as No}from"fs";import{ExtensibleProperty as Bs,Texture as Gn,Primitive as Ws,Accessor as zs,Mesh as Us}from"@gltf-transform/core";import Xs from"tmp";import ee,{statSync as qs}from"fs";import Ks from"path";import Hs from"xxhash-wasm";var rn=null;Hs().then(t=>{rn=t}).catch(()=>{});var jn=Q(!1),Bn=process.argv.includes("--debug");function Wn(t){let e=Ge(!0);ee.rmSync(e,{recursive:!0}),t?t.info(`\u0110\xE3 x\xF3a b\u1ED9 nh\u1EDB cache t\u1EA1i ${e}`):console.log(`\u0110\xE3 x\xF3a b\u1ED9 nh\u1EDB cache t\u1EA1i ${e}`)}var sn=1024*5;function zn(t=sn){let e=Ge(!0);console.log(`Gi\u1EDBi h\u1EA1n k\xEDch th\u01B0\u1EDBc cache \u1EDF m\u1EE9c ${t.toFixed(2)} MB t\u1EA1i ${e}`);let n=0,r=[];function s(u){ee.readdirSync(u).forEach(m=>{let c=`${u}/${m}`,l=qs(c);l.isDirectory()?s(c):(n+=l.size,r.push({path:c,size:l.size}))})}s(e);let o=t*1024*1024;if(console.log(`K\xEDch th\u01B0\u1EDBc cache hi\u1EC7n t\u1EA1i l\xE0 ${(n/(1024*1024)).toFixed(1)} MB`),n<o)return;r.sort((u,m)=>{let c=ee.statSync(u.path).mtimeMs,l=ee.statSync(m.path).mtimeMs;return c-l});let i=o*.9,a=0;for(;n>i;){let u=r.shift();if(!u)break;ee.statSync(u.path).isDirectory()||(a++,ee.rmSync(u.path),n-=u.size)}console.log(`K\xEDch th\u01B0\u1EDBc cache \u0111\xE3 gi\u1EA3m xu\u1ED1ng c\xF2n ${(n/(1024*1024)).toFixed(1)} MB (\u0110\xE3 x\xF3a ${a} file)`)}function fe(t,e){let r=`${Ge()}/${t}.bin`;Bn&&console.log(`\u0110\xE3 th\xEAm ${(e.byteLength/1024).toFixed(1)} KB v\xE0o cache t\u1EA1i "${r}"`),e instanceof Buffer&&(e=new Uint8Array(e)),ee.writeFileSync(r,e)}function xe(t){let n=`${Ge()}/${t}.bin`;if(ee.existsSync(n)){let r=ee.readFileSync(n);return r instanceof Buffer?new Uint8Array(r):r}return null}function Un(t,e){let r=`${Ge()}/${t}.meta`;e["gltf-lod-pipeline:version"]=jn,ee.writeFileSync(r,JSON.stringify(e))}function Xn(t,e=!1){try{let r=`${Ge()}/${t}.meta`;if(ee.existsSync(r)){let s=ee.readFileSync(r);if(s?.length>0){let o=s.toString("utf-8");if(o){let i=JSON.parse(o);if(e||i["gltf-lod-pipeline:version"]===jn)return i}}}return null}catch(n){return console.error(`L\u1ED7i khi \u0111\u1ECDc meta t\u1EEB cache: ${n.message}`),null}}function Tt(t){let e="prop";t instanceof Gn&&(e="image");let n=oe(t);return`${e}-${n}`}function oe(t,e=0){let r=0;if(t instanceof Bs){let s=t.listExtensions(),o=t.getExtras();if(r+=et({extensions:s,extras:o}),t instanceof Gn){let i=t.getImage(),a=i?.buffer;a&&(r+=bt(a,i.byteOffset,i.byteLength))}else if(t instanceof Us){let i=t.getWeights();r+=et(i);let a=t.listPrimitives();for(let u of a)r+=ke(oe(u,e+1))}else if(t instanceof Ws){let i=t.getIndices(),a=t.listAttributes(),u=t.listTargets(),m=t.listSemantics(),c=m.map(l=>({name:l}));if(r+=et({indices:i,attributes:a,targets:u,semantics:c}),i){let l=i.getArray();l&&(r+=bt(l.buffer,l.byteOffset,l.byteLength))}for(let l of m){let f=t.getAttribute(l)?.getArray();f&&(r+=bt(f.buffer,f.byteOffset,f.byteLength))}}}else r+=et(t);return""+r}var Vs=Q(!1).replace(/[^a-zA-Z0-9]/g,"_");function Ge(t){let e=Ks.join(Xs.tmpdir,"GLTF","lod-pipeline-cache",t?"":Vs);return ee.existsSync(e)||ee.mkdirSync(e,{recursive:!0}),e}function et(t,e=0){if(t instanceof zs){let n=t.getArray();return bt(n.buffer)}else if(t==null)return 0;if(typeof t!="object")return ke(String(t));try{let n=new WeakSet,r=JSON.stringify(t,(s,o)=>{if(typeof o=="object"&&o!==null){if(n.has(o))return;n.add(o)}if(typeof o!="function")return o});return ke(r)}catch(n){if(console.warn(`WARN: [Cache] G\u1EB7p l\u1ED7i trong qu\xE1 tr\xECnh b\u0103m (hashing) \u0111\u1ED1i t\u01B0\u1EE3ng:
5
- `+n),Bn)debugger;let r=0;if(typeof t=="object"&&t!==null){for(let s in t)if(Object.prototype.hasOwnProperty.call(t,s)){let o=t[s];r+=ke(s),typeof o=="object"&&o!==null?e>10?r+=ke("[object]"):r+=et(o,e+1):r+=ke(String(o))}}return r}}function bt(t,e,n){if(rn){let o=new Uint8Array(t,e,n);return rn.h32Raw(o)}let r=0,s=new Uint8Array(t,e,n);for(let o=0;o<s.length;o++)r=(r<<5)-r+s[o],r|=0;return r}function ke(t){let e=0;for(let n=0;n<t.length;n++)e=(e<<5)-e+t.charCodeAt(n),e|=0;return e}import Oo from"sharp";import{MeshoptDecoder as vo,MeshoptEncoder as Ro,MeshoptSimplifier as ir}from"meshoptimizer";import{Primitive as ao}from"@gltf-transform/core";import{meshopt as co,simplifyPrimitive as uo,SIMPLIFY_DEFAULTS as mo,WELD_DEFAULTS as lo,draco as Yn}from"@gltf-transform/functions";import{MeshoptEncoder as fo,MeshoptSimplifier as go}from"meshoptimizer";import{Accessor as Js,Document as Zs,Primitive as qn,PropertyType as Bu}from"@gltf-transform/core";import{createTransform as zu,prune as Uu,dedup as Xu}from"@gltf-transform/functions";var Et="weld",je={DEFAULT:1e-4,TEXCOORD:1e-4,COLOR:.01,NORMAL:.05,JOINTS:0,WEIGHTS:.01},an={tolerance:je.DEFAULT,toleranceNormal:je.NORMAL,overwrite:!0,exhaustive:!1};function tt(t,e=t){let n=e<=65534?new Uint16Array(t):new Uint32Array(t);for(let r=0;r<n.length;r++)n[r]=r;return n}function Kn(t){return t.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")}function Ys(t,e,n=2){return(t>e?"\u2013":"+")+(Math.abs(t-e)/t*100).toFixed(n)+"%"}function Qs(t,e){return`${Kn(t)} \u2192 ${Kn(e)} (${Ys(t,e)})`}function eo(t){let e=t.getIndices();if(!e)return;let n=[],r=-1/0;for(let o=0,i=e.getCount();o<i;o+=3){let a=e.getScalar(o),u=e.getScalar(o+1),m=e.getScalar(o+2);a===u||a===m||u===m||(n.push(a,u,m),r=Math.max(r,a,u,m))}let s=tt(n.length,r);s.set(n),e.setArray(s)}function Zn(t,e=an,n=an){let r,s,o;if(t instanceof qn){let i=t.getGraph();r=Zs.fromGraph(i),s=t,o=Jn(e)}else r=t,s=e,o=Jn(n);s.getIndices()&&!o.overwrite||s.getMode()!==qn.Mode.POINTS&&(o.tolerance===0?to(r,s):no(r,s,o))}function to(t,e){if(e.getIndices())return;let n=e.listAttributes()[0],r=n.getCount(),s=n.getBuffer(),o=t.createAccessor().setBuffer(s).setType(Js.Type.SCALAR).setArray(tt(r));e.setIndices(o)}function no(t,e,n){let r=t.getLogger(),s=e.getAttribute("POSITION"),o=e.getIndices()||t.createAccessor().setArray(tt(s.getCount())),i=new Uint32Array(new Set(o.getArray())).sort(),a={};for(let E of e.listSemantics()){let T=e.getAttribute(E);a[E]=so(E,T,n)}r.debug(`${Et}: Tolerance thresholds: ${oo(a)}`);let u=[0,0,0],m=[0,0,0],c={},l=a.POSITION;for(let E=0;E<i.length;E++){s.getElement(i[E],u);let T=cn(u,l);c[T]=c[T]||[],c[T].push(i[E])}let f=i[i.length-1],g=tt(f+1),p=new Array(i.length).fill(-1),h=s.getCount(),y=0;for(let E=0;E<i.length;E++){let T=i[E];s.getElement(T,u);let L=n.exhaustive?io(u,l):[cn(u,l)];e:for(let _ of L){if(!c[_])continue e;t:for(let A of c[_]){let M=g[A];if(T<=M)continue t;s.getElement(M,m);let O=e.listSemantics().every($=>{let P=e.getAttribute($),F=a[$];return Vn(P,T,M,F,$)}),b=e.listTargets().every($=>$.listSemantics().every(P=>{let F=$.getAttribute(P),Z=a[P];return Vn(F,T,M,Z,P)}));if(O&&b){g[T]=M;break e}}}g[T]===T?p[T]=y++:p[T]=p[g[T]]}r.debug(`${Et}: ${Qs(h,y)} vertices.`);let x=o.getCount(),d=tt(x,i.length);for(let E=0;E<x;E++)d[E]=p[o.getScalar(E)];e.setIndices(o.clone().setArray(d)),o.listParents().length===1&&o.dispose();for(let E of e.listAttributes())Hn(e,E,p,y);for(let E of e.listTargets())for(let T of E.listAttributes())Hn(E,T,p,y);eo(e)}function ro(t,e){let n=t.constructor;return new n(e)}function Hn(t,e,n,r){let s=ro(e.getArray(),r*e.getElementSize()),o=e.clone().setArray(s),i=new Uint8Array(r);for(let a=0,u=[];a<n.length;a++)i[n[a]]||(o.setElement(n[a],e.getElement(a,u)),i[n[a]]=1);t.swap(e,o),e.listParents().length===1&&e.dispose()}var nt=[],rt=[];function so(t,e,n){if(t==="NORMAL"||t==="TANGENT")return n.toleranceNormal;if(t.startsWith("COLOR_"))return je.COLOR;if(t.startsWith("TEXCOORD_"))return je.TEXCOORD;if(t.startsWith("JOINTS_"))return je.JOINTS;if(t.startsWith("WEIGHTS_"))return je.WEIGHTS;nt.length=rt.length=0,e.getMinNormalized(nt),e.getMaxNormalized(rt);let r=rt.map((o,i)=>o-nt[i]),s=Math.max(...r);return n.tolerance*s}function Vn(t,e,n,r,s){t.getElement(e,nt),t.getElement(n,rt);for(let o=0,i=t.getElementSize();o<i;o++)if(Math.abs(nt[o]-rt[o])>r)return!1;return!0}function oo(t){return Object.entries(t).map(([e,n])=>`${e}=${n}`).join(", ")}var on=[0,-1,1];function io(t,e){let n=[],r=[0,0,0];for(let s of on)for(let o of on)for(let i of on)r[0]=t[0]+s*e,r[1]=t[1]+o*e,r[2]=t[2]+i*e,n.push(cn(r,e));return n}function cn(t,e){let n=Math.round(t[0]/e),r=Math.round(t[1]/e),s=Math.round(t[2]/e);return n+":"+r+":"+s}function Jn(t){let e={...an,...t};if(e.tolerance<0||e.tolerance>.1)throw new Error(`${Et}: Requires 0 <= tolerance <= 0.1`);if(e.toleranceNormal<0||e.toleranceNormal>Math.PI/2)throw new Error(`${Et}: Requires 0 <= toleranceNormal <= ${(Math.PI/2).toFixed(2)}`);return e.tolerance>0&&(e.tolerance=Math.max(e.tolerance,Number.EPSILON),e.toleranceNormal=Math.max(e.toleranceNormal,Number.EPSILON)),e}var ye="gltf_mesh_transform";function un(t,e){let n=t.getRoot().getExtension(se.EXTENSION_NAME);if(n){let o=n.model;if(o){if(!o.compression)throw new Error(`[${ye}]: Thi\u1EBFu c\u1EA5u h\xECnh n\xE9n l\u01B0\u1EDBi \u1EDF node g\u1ED1c c\u1EE7a file ${e}`);return o}}if(e?.toLowerCase().endsWith(".vrm")&&t.getRoot().listMeshes().some(i=>i.listPrimitives().some(a=>a.listTargets().length>0)))return new Te("meshopt");let r=0,s=0;for(let o of t.getRoot().listMeshes())for(let i of o.listPrimitives()){for(let u of i.listTargets()){let m=u.getAttribute("POSITION");m&&(r+=m.getArray().length)}let a=i.getAttribute("POSITION");a&&(s+=a.getArray().length)}return r>0?(s>0?r/s:1)<.01?new Te("draco"):(t.getLogger().debug(`[${ye}]: S\u1EBD \xE1p d\u1EE5ng n\xE9n l\u01B0\u1EDBi "meshopt" v\xEC m\xF4 h\xECnh c\xF3 ch\u1EE9a blendshapes (morph targets)`),new Te("meshopt")):new Te("draco")}var Qn=function(t){return async(e,n)=>{await ho(e,n,t),await po(e,n,t)}};async function po(t,e,n){let r=Be(n.file),s=un(t,n.file);if(s&&s.compression){if(s.compression==="none"){t.getLogger().debug(`[${ye}]: NONE \u2192 B\u1ECF qua, kh\xF4ng \xE1p d\u1EE5ng n\xE9n l\u01B0\u1EDBi`);return}if(t.getLogger().debug(`[${ye}]: ${s.compression.toUpperCase()} \u2192 S\u1EBD \xE1p d\u1EE5ng n\xE9n b\u1EB1ng ${s.compression}`),s.compression==="draco"){await Yn({encodeSpeed:8,decodeSpeed:8,quantizationVolume:r?"scene":void 0})(t,e);return}else if(s.compression==="meshopt"){await co({encoder:fo})(t,e);return}}t.getLogger().debug(`[${ye}]: \u2192 S\u1EBD \xE1p d\u1EE5ng n\xE9n b\u1EB1ng draco (chu\u1EA9n m\u1EB7c \u0111\u1ECBnh)`),await Yn({encodeSpeed:8,decodeSpeed:8,quantizationVolume:r?"scene":void 0})(t,e)}async function ho(t,e,n){let r=go;if(!r)return t.getLogger().warn(`WARN: [${ye}] \u0110ang thi\u1EBFu dependency cho vi\u1EC7c t\u1ED1i gi\u1EA3n l\u01B0\u1EDBi \u2014 h\xE3y c\xE0i \u0111\u1EB7t "meshoptimizer".`),!1;let s=t.getLogger(),o=n.file?.toLowerCase().endsWith(".vrm"),i={...mo,simplifier:r,ratio:.75,error:5e-4},a={...lo,overwrite:!0};for(let u of t.getRoot().listMeshes()){let m=0;for(let c of u.listPrimitives()){let l=m++,f=c.getExtension(se.EXTENSION_NAME),g=f?.model,p={...i};if(o){let h=Ze(c);if(h>0){let x=1/h*2e3;p.ratio=Math.min(Math.max(.1,x),.95),p.error=15/h,p.lockBorder=!0}else p.ratio=.8,p.error=.001,p.lockBorder=!0;s.info(`${u.getName()}: M\u1EADt \u0111\u1ED9 (Density): ${h.toFixed(2)}, T\u1EF7 l\u1EC7 (Ratio): ${p.ratio.toFixed(2)}, Sai s\u1ED1 (Error): ${p.error}`)}if(!(!f&&!o)){if(g){if(g.useSimplifier===!1){s.debug(`[${ye}]: B\u1ECF qua primitive c\u1EE7a mesh "${u.getName()}": C\u1EDD useSimplifier \u0111ang b\u1ECB t\u1EAFt.`);continue}g.error>=0&&(p.error=g.error),g.ratio>=0&&(p.ratio=g.ratio),g.lockBorder!==void 0&&(p.lockBorder=g.lockBorder)}if(c.getMode()!==ao.Mode.TRIANGLES){s.warn(`[${ye}]: B\u1ECF qua primitive c\u1EE7a mesh "${u.getName()}": Y\xEAu c\u1EA7u ch\u1EBF \u0111\u1ED9 v\u1EBD l\u01B0\u1EDBi (draw mode) l\xE0 TRIANGLES.`);continue}await mn(t,u,c,l,a,p)}}}return!0}async function mn(t,e,n,r,s,o){let i=t.getLogger();if(i.debug(`\u0110ang h\xE0n \u0111\u1EC9nh (weld): primitive[${r}] thu\u1ED9c mesh "${e.getName()}"`),Zn(n,s),!(o.simplifier&&o.simplifier?.ready instanceof Promise&&!await o.simplifier?.ready.then(()=>!0).catch(u=>(console.error(`[${ye}]: B\u1ED9 t\u1ED1i gi\u1EA3n (Simplifier) t\u1EA3i l\xEAn th\u1EA5t b\u1EA1i...
6
- ${u}`),!1))))return i.debug(`\u0110ang \u0111\u01A1n gi\u1EA3n h\xF3a (simplify): primitive[${r}] thu\u1ED9c mesh "${e.getName()}" \u2192 ratio: ${o.ratio}, error: ${o.error}, lockBorder: ${o.lockBorder}, regularize: ${o.regularize}, normalWeight: ${o.normalWeight}, colorWeight: ${o.colorWeight}, textureWeight: ${o.textureWeight}`),uo(n,o)}async function ar(t){let e=t.path,n=!0;if(await He(e,async r=>{if(!n)return;if(Be(r)||lr(r)){t.logger.info(`[Progressive Transform]: B\u1ECF qua t\u1EC7p LOD \u0111\xE3 t\u1ED3n t\u1EA1i t\u1EA1i ${r}`);return}await $o(r,t)||(n=!1)}),n){let r=t.results.length;for(let o=t.results.length-1;o>=0;o--)wt(t.results[o])||t.results.splice(o,1);let s=r!==t.results.length;t.debug&&console.log(`[Progressive Transform]: \u0110\xE3 x\u1EED l\xFD ${t.results.length} t\u1EC7p. ${s?"M\u1ED9t s\u1ED1 k\u1EBFt qu\u1EA3 \u0111\xE3 b\u1ECB lo\u1EA1i b\u1ECF":""}`)}return n}function gn(t){Rn(t),t.registerExtensions([me,Ne,qe,se,z(ne.EXTENSION_NAME,xo.TEXTURE)])}async function $o(t,e){if(!t.endsWith(".glb")&&!t.endsWith(".gltf")&&!t.endsWith(".vrm"))return console.log("L\u1ED6I: t\u1EC7p kh\xF4ng ph\u1EA3i glTF/GLB"),!1;if(!wt(t))return console.log("L\u1ED6I: t\u1EC7p kh\xF4ng t\u1ED3n t\u1EA1i: "+t),!1;try{let n=new fn;gn(n),n.registerDependencies({"meshopt.decoder":vo,"meshopt.encoder":Ro,"draco3d.decoder":await nr.createDecoderModule(),"draco3d.encoder":await nr.createEncoderModule()}),gt(t);let r=await Qe(n,t);if(r){e.logger?r.setLogger(e.logger):r.getLogger().verbosity=e.debug||e.verbose?er.DEBUG:er.WARN;let s=e.logger||r.getLogger();e.outpath&&yt(r,t,Re.join(e.outpath,Re.basename(t)));let o=128;e.config.usecase==="product"&&(o=512);let i=[_t()];(await n.readAsJSON(t)).json.extensionsUsed?.includes("KHR_materials_pbrSpecularGlossiness")&&(s.warn("\u0110ang chuy\u1EC3n \u0111\u1ED5i KHR_materials_pbrSpecularGlossiness sang quy tr\xECnh metal/rough..."),await r.transform(tr())),e.config?.textures?.lods!==!1&&i.push(Po(t,{size:[o,o]},e));let u=t.toLowerCase().endsWith(".vrm");!u&&e.config?.meshes?.lods!==!1?i.push(ko(t,{},e)):u&&s.warn("C\u1EA2NH B\xC1O: Progressive mesh ch\u01B0a \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 cho t\u1EC7p VRM"),i.push(tr()),i.push(or()),s.info("\u2192 \u0110ang bi\u1EBFn \u0111\u1ED5i: "+t),await r.transform(...i);let m=pt(t,e.outpath);await xt(n,m,r),e.results.push(m),s.info("\u2190 Bi\u1EBFn \u0111\u1ED5i ho\xE0n t\u1EA5t: "+m)}}catch(n){if(n instanceof Oe)throw n;return console.log('L\u1ED6I: kh\xF4ng th\u1EC3 x\u1EED l\xFD t\u1EC7p "'+t+'", L\xFD do: '+n.message,`
4
+ C\xE1c \u0111\u01B0\u1EDDng d\u1EABn c\xF3 th\u1EC3 \u0111\u01B0\u1EE3c vi\u1EBFt t\u01B0\u01A1ng \u0111\u1ED1i so v\u1EDBi "${n}"`);else for(let s of r.files)await e(s)}async function qe(t,e){if(t.startsWith("--"))return!1;if((t==="."||t==="./")&&e.baseDirectory&&(t=e.baseDirectory),le(t)===!1){if(e.baseDirectory===void 0)return console.log("WARN: \u0110\u01B0\u1EDDng d\u1EABn kh\xF4ng t\u1ED3n t\u1EA1i: "+t),!1;let n=e.baseDirectory+"/"+t;if(le(n)===!1)return console.log(`INFO: Gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn th\u1EA5t b\u1EA1i: "${t}" -> ${n} (kh\xF4ng t\u1ED3n t\u1EA1i ho\u1EB7c \u0111ang b\u1ECB kh\xF3a b\u1EDFi ti\u1EBFn tr\xECnh kh\xE1c)`),!1;console.log(`INFO: \u0110\xE3 gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn: ${t} -> ${n}`),t=n}else if(!ys(t)&&e.baseDirectory){let r=e.baseDirectory+"/"+t;if(console.log(`INFO: \u0110\xE3 gi\u1EA3i quy\u1EBFt \u0111\u01B0\u1EDDng d\u1EABn: ${t} -> ${r}`),t=r,!le(t))return!1}if(t.endsWith(".glb")||t.endsWith(".gltf")||t.endsWith(".vrm"))e.files.push(t);else if(_n(t).isDirectory()){if(t.endsWith("node_modules"))return!1;let r=gs(t);for(let s of r)await qe(t+"/"+s,e)}}function Ln(t,e){let n=t.split(".");return n.pop(),n.join(".")+"."+e}function Fe(t){return t?le(t)?_n(t).isDirectory():!t.replaceAll("\\","/").split("/").pop()?.includes("."):!1}function He(t){return Fe(t)||(t=xs(t)),le(t)||Mn(t,{recursive:!0}),t}async function lt(t,e=3,n=150){for(let r=0;r<=e;r++)try{le(t)&&hs(t,{recursive:!0});return}catch(s){if(!(s?.code==="EBUSY"||s?.code==="EPERM")||r===e)return;await ds(n)}}var Nn="0.0.7";function Y(t=!0){return Nn}import{Mesh as Ts}from"@gltf-transform/core";function Ve(t){let e=0,n=0,r=0;return t instanceof Ts?(r=t.listPrimitives().reduce((s,i)=>{let o=i.getIndices()?.getCount()||0;n+=o;let a=i.getAttribute("POSITION")?.getCount()||0;return e=Math.max(e,a),s+a},0),{maxVertexCount:e,totalVertexCount:r,totalIndexCount:n}):(t.getRoot().listMeshes().forEach(s=>{let i=Ve(s);e=Math.max(e,i.maxVertexCount),r+=i.totalVertexCount,n+=i.totalIndexCount}),{maxVertexCount:e,totalVertexCount:r,totalIndexCount:n})}function Je(t){let e={min:[1/0,1/0,1/0],max:[-1/0,-1/0,-1/0]},n=t.getAttribute("POSITION");if(!n)return-1;let r=[0,0,0];function s(a,u){for(let m=0;m<3;m++)u.min[m]=Math.min(a[m],u.min[m]),u.max[m]=Math.max(a[m],u.max[m])}for(let a=0;a<n.getCount();a++)r=n.getElement(a,r),s(r,e);let i=t.getIndices(),o=0;if(i){let a=i.getCount(),u=i.getArray(),m=[0,0,0],c=[0,0,0],l=[0,0,0],f=[0,0,0],g=[0,0,0],p=e.max[0]-e.min[0],d=e.max[1]-e.min[1],y=e.max[2]-e.min[2],x=Math.max(p,d,y);for(let w=0;w<a;w+=3){let A=u[w+0],I=u[w+1],L=u[w+2];n.getElement(A,m),n.getElement(I,c),n.getElement(L,l),f[0]=c[0]-m[0],f[1]=c[1]-m[1],f[2]=c[2]-m[2],g[0]=l[0]-m[0],g[1]=l[1]-m[1],g[2]=l[2]-m[2],f[0]/=x,f[1]/=x,f[2]/=x,g[0]/=x,g[1]/=x,g[2]/=x;let v=[f[1]*g[2]-f[2]*g[1],f[2]*g[0]-f[0]*g[2],f[0]*g[1]-f[1]*g[0]];o+=Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])/2}return i.getCount()/3/o}else{let a=n.getCount(),u=[0,0,0];u[0]=e.max[0]-e.min[0],u[1]=e.max[1]-e.min[1],u[2]=e.max[2]-e.min[2];let m=u[0]*u[1]*u[2];return a/m}}import{v5 as Es}from"uuid";var Ss="0c147764-f63f-4508-81fb-3704b1175de2";function ft(t){return Es(t,Ss)}import{cpSync as Rn,existsSync as Ze,mkdirSync as ws}from"fs";import{writeFile as Is}from"fs/promises";import de from"path";import _s from"sharp";async function gt(t,e,n){let r=de.dirname(e);if(Ze(r)||ws(r),e.endsWith(".vrm")){let s=await t.writeBinary(n);await Is(e,s)}else await t.write(e,n);return e}var Ms=/open '(?<path>.+?)'/,An=new Set;async function Ye(t,e,n=0){let r=await t.read(e).catch(s=>s);if(r instanceof Error){let s=r;if(n<100&&s.message?.includes("ENOENT"))try{let i=s.message.match(Ms);if(i?.groups?.path){let o=i.groups.path;if(o.startsWith("http")||An.has(o))throw s;An.add(o),console.warn(`\u0110ang t\u1EA1o m\u1ED9t file r\u1ED7ng \u0111\u1EC3 thay th\u1EBF cho t\xE0i nguy\xEAn b\u1ECB thi\u1EBFu: ${o}`);let a=o.split(".").pop();if(!a)throw console.warn(`Kh\xF4ng th\u1EC3 x\xE1c \u0111\u1ECBnh \u0111\u01B0\u1EE3c \u0111u\xF4i m\u1EDF r\u1ED9ng (extension) cho ${o}`),s;let u=a.toLowerCase(),m=!1;switch(u){case"jpeg":case"jpg":case"png":case"webp":case"tiff":case"gif":await _s({create:{width:64,height:64,channels:4,background:{r:255,g:255,b:255,alpha:1}}}).toFormat(a).toFile(o),m=!0}if(m)return console.warn(`\u0110\xE3 t\u1EA1o th\xE0nh c\xF4ng file r\u1ED7ng cho t\xE0i nguy\xEAn b\u1ECB thi\u1EBFu: ${o}`),Ye(t,e,n+1)}}catch(i){console.warn(i)}throw s}return r}function pt(t,e,n){let r=de.resolve(de.dirname(e)),s=de.resolve(de.dirname(n));if(r!==s){for(let i of t.getRoot().listTextures()){let o=i.getURI();if(!o||o.startsWith("data:"))continue;let a=de.join(r,o),u=de.join(s,o);!Ze(u)&&Ze(a)&&Rn(a,u)}for(let i of t.getRoot().listBuffers()){let o=i.getURI();if(!o||o.startsWith("data:"))continue;let a=de.join(r,o),u=de.join(s,o);!Ze(u)&&Ze(a)&&Rn(a,u)}}}import{Document as xi,ImageUtils as yi}from"@gltf-transform/core";import{inspect as bi}from"@gltf-transform/functions";import{statSync as Ti,writeFileSync as Ei}from"fs";import{Document as Un,NodeIO as rn,PropertyType as qs,TextureChannel as Ks,Verbosity as jn}from"@gltf-transform/core";import{SIMPLIFY_DEFAULTS as Hs,WELD_DEFAULTS as Vs,listTextureChannels as Js,listTextureSlots as Zs,metalRough as Bn,sparse as Xn}from"@gltf-transform/functions";import{KHRMaterialsSpecular as xt}from"@gltf-transform/extensions";import Wn from"draco3dgltf";import Oe,{basename as Ys,resolve as Qs}from"path";import{existsSync as yt,mkdirSync as ei,readFileSync as ti,rmSync as ni,statSync as ri,writeFileSync as si}from"fs";import{ExtensibleProperty as Ls,Texture as vn,Primitive as Ns,Accessor as Rs,Mesh as As}from"@gltf-transform/core";import vs from"tmp";import Q,{statSync as Os}from"fs";import $s from"path";import Cs from"xxhash-wasm";var Yt=null;Cs().then(t=>{Yt=t}).catch(()=>{});var On=Y(!1),$n=process.argv.includes("--debug");function Cn(t){let e=Ge(!0);Q.rmSync(e,{recursive:!0}),t?t.info(`\u0110\xE3 x\xF3a b\u1ED9 nh\u1EDB cache t\u1EA1i ${e}`):console.log(`\u0110\xE3 x\xF3a b\u1ED9 nh\u1EDB cache t\u1EA1i ${e}`)}var Qt=1024*5;function Pn(t=Qt){let e=Ge(!0);console.log(`Gi\u1EDBi h\u1EA1n k\xEDch th\u01B0\u1EDBc cache \u1EDF m\u1EE9c ${t.toFixed(2)} MB t\u1EA1i ${e}`);let n=0,r=[];function s(u){Q.readdirSync(u).forEach(m=>{let c=`${u}/${m}`,l=Os(c);l.isDirectory()?s(c):(n+=l.size,r.push({path:c,size:l.size}))})}s(e);let i=t*1024*1024;if(console.log(`K\xEDch th\u01B0\u1EDBc cache hi\u1EC7n t\u1EA1i l\xE0 ${(n/(1024*1024)).toFixed(1)} MB`),n<i)return;r.sort((u,m)=>{let c=Q.statSync(u.path).mtimeMs,l=Q.statSync(m.path).mtimeMs;return c-l});let o=i*.9,a=0;for(;n>o;){let u=r.shift();if(!u)break;Q.statSync(u.path).isDirectory()||(a++,Q.rmSync(u.path),n-=u.size)}console.log(`K\xEDch th\u01B0\u1EDBc cache \u0111\xE3 gi\u1EA3m xu\u1ED1ng c\xF2n ${(n/(1024*1024)).toFixed(1)} MB (\u0110\xE3 x\xF3a ${a} file)`)}function fe(t,e){let r=`${Ge()}/${t}.bin`;$n&&console.log(`\u0110\xE3 th\xEAm ${(e.byteLength/1024).toFixed(1)} KB v\xE0o cache t\u1EA1i "${r}"`),e instanceof Buffer&&(e=new Uint8Array(e)),Q.writeFileSync(r,e)}function xe(t){let n=`${Ge()}/${t}.bin`;if(Q.existsSync(n)){let r=Q.readFileSync(n);return r instanceof Buffer?new Uint8Array(r):r}return null}function Dn(t,e){let r=`${Ge()}/${t}.meta`;e["gltf-lod-pipeline:version"]=On,Q.writeFileSync(r,JSON.stringify(e))}function Fn(t,e=!1){try{let r=`${Ge()}/${t}.meta`;if(Q.existsSync(r)){let s=Q.readFileSync(r);if(s?.length>0){let i=s.toString("utf-8");if(i){let o=JSON.parse(i);if(e||o["gltf-lod-pipeline:version"]===On)return o}}}return null}catch(n){return console.error(`L\u1ED7i khi \u0111\u1ECDc meta t\u1EEB cache: ${n.message}`),null}}function dt(t){let e="prop";t instanceof vn&&(e="image");let n=ie(t);return`${e}-${n}`}function ie(t,e=0){let r=0;if(t instanceof Ls){let s=t.listExtensions(),i=t.getExtras();if(r+=Qe({extensions:s,extras:i}),t instanceof vn){let o=t.getImage(),a=o?.buffer;a&&(r+=ht(a,o.byteOffset,o.byteLength))}else if(t instanceof As){let o=t.getWeights();r+=Qe(o);let a=t.listPrimitives();for(let u of a)r+=ke(ie(u,e+1))}else if(t instanceof Ns){let o=t.getIndices(),a=t.listAttributes(),u=t.listTargets(),m=t.listSemantics(),c=m.map(l=>({name:l}));if(r+=Qe({indices:o,attributes:a,targets:u,semantics:c}),o){let l=o.getArray();l&&(r+=ht(l.buffer,l.byteOffset,l.byteLength))}for(let l of m){let f=t.getAttribute(l)?.getArray();f&&(r+=ht(f.buffer,f.byteOffset,f.byteLength))}}}else r+=Qe(t);return""+r}var Ps=Y(!1).replace(/[^a-zA-Z0-9]/g,"_");function Ge(t){let e=$s.join(vs.tmpdir,"GLTF","lod-pipeline-cache",t?"":Ps);return Q.existsSync(e)||Q.mkdirSync(e,{recursive:!0}),e}function Qe(t,e=0){if(t instanceof Rs){let n=t.getArray();return ht(n.buffer)}else if(t==null)return 0;if(typeof t!="object")return ke(String(t));try{let n=new WeakSet,r=JSON.stringify(t,(s,i)=>{if(typeof i=="object"&&i!==null){if(n.has(i))return;n.add(i)}if(typeof i!="function")return i});return ke(r)}catch(n){if(console.warn(`WARN: [Cache] G\u1EB7p l\u1ED7i trong qu\xE1 tr\xECnh b\u0103m (hashing) \u0111\u1ED1i t\u01B0\u1EE3ng:
5
+ `+n),$n)debugger;let r=0;if(typeof t=="object"&&t!==null){for(let s in t)if(Object.prototype.hasOwnProperty.call(t,s)){let i=t[s];r+=ke(s),typeof i=="object"&&i!==null?e>10?r+=ke("[object]"):r+=Qe(i,e+1):r+=ke(String(i))}}return r}}function ht(t,e,n){if(Yt){let i=new Uint8Array(t,e,n);return Yt.h32Raw(i)}let r=0,s=new Uint8Array(t,e,n);for(let i=0;i<s.length;i++)r=(r<<5)-r+s[i],r|=0;return r}function ke(t){let e=0;for(let n=0;n<t.length;n++)e=(e<<5)-e+t.charCodeAt(n),e|=0;return e}import ii from"sharp";import{MeshoptDecoder as oi,MeshoptEncoder as ai,MeshoptSimplifier as qn}from"meshoptimizer";import{Primitive as Ds}from"@gltf-transform/core";import{meshopt as Fs,simplifyPrimitive as ks,SIMPLIFY_DEFAULTS as Gs,WELD_DEFAULTS as js,weldPrimitive as Bs,draco as kn}from"@gltf-transform/functions";import{MeshoptEncoder as Ws,MeshoptSimplifier as zs}from"meshoptimizer";var ye="gltf_mesh_transform";function en(t,e){let n=t.getRoot().getExtension(se.EXTENSION_NAME);if(n){let i=n.model;if(i){if(!i.compression)throw new Error(`[${ye}]: Thi\u1EBFu c\u1EA5u h\xECnh n\xE9n l\u01B0\u1EDBi \u1EDF node g\u1ED1c c\u1EE7a file ${e}`);return i}}if(e?.toLowerCase().endsWith(".vrm")&&t.getRoot().listMeshes().some(o=>o.listPrimitives().some(a=>a.listTargets().length>0)))return new Te("meshopt");let r=0,s=0;for(let i of t.getRoot().listMeshes())for(let o of i.listPrimitives()){for(let u of o.listTargets()){let m=u.getAttribute("POSITION");m&&(r+=m.getArray().length)}let a=o.getAttribute("POSITION");a&&(s+=a.getArray().length)}return r>0?(s>0?r/s:1)<.01?new Te("draco"):(t.getLogger().debug(`[${ye}]: S\u1EBD \xE1p d\u1EE5ng n\xE9n l\u01B0\u1EDBi "meshopt" v\xEC m\xF4 h\xECnh c\xF3 ch\u1EE9a blendshapes (morph targets)`),new Te("meshopt")):new Te("draco")}var Gn=function(t){return async(e,n)=>{await Xs(e,n,t),await Us(e,n,t)}};async function Us(t,e,n){let r=je(n.file),s=en(t,n.file);if(s&&s.compression){if(s.compression==="none"){t.getLogger().debug(`[${ye}]: NONE \u2192 B\u1ECF qua, kh\xF4ng \xE1p d\u1EE5ng n\xE9n l\u01B0\u1EDBi`);return}if(t.getLogger().debug(`[${ye}]: ${s.compression.toUpperCase()} \u2192 S\u1EBD \xE1p d\u1EE5ng n\xE9n b\u1EB1ng ${s.compression}`),s.compression==="draco"){await kn({encodeSpeed:8,decodeSpeed:8,quantizationVolume:r?"scene":void 0})(t,e);return}else if(s.compression==="meshopt"){await Fs({encoder:Ws})(t,e);return}}t.getLogger().debug(`[${ye}]: \u2192 S\u1EBD \xE1p d\u1EE5ng n\xE9n b\u1EB1ng draco (chu\u1EA9n m\u1EB7c \u0111\u1ECBnh)`),await kn({encodeSpeed:8,decodeSpeed:8,quantizationVolume:r?"scene":void 0})(t,e)}async function Xs(t,e,n){let r=zs;if(!r)return t.getLogger().warn(`WARN: [${ye}] \u0110ang thi\u1EBFu dependency cho vi\u1EC7c t\u1ED1i gi\u1EA3n l\u01B0\u1EDBi \u2014 h\xE3y c\xE0i \u0111\u1EB7t "meshoptimizer".`),!1;let s=t.getLogger(),i=n.file?.toLowerCase().endsWith(".vrm"),o={...Gs,simplifier:r,ratio:.75,error:5e-4},a={...js,overwrite:!0};for(let u of t.getRoot().listMeshes()){let m=0;for(let c of u.listPrimitives()){let l=m++,f=c.getExtension(se.EXTENSION_NAME),g=f?.model,p={...o};if(i){let d=Je(c);if(d>0){let x=1/d*2e3;p.ratio=Math.min(Math.max(.1,x),.95),p.error=15/d,p.lockBorder=!0}else p.ratio=.8,p.error=.001,p.lockBorder=!0;s.info(`${u.getName()}: M\u1EADt \u0111\u1ED9 (Density): ${d.toFixed(2)}, T\u1EF7 l\u1EC7 (Ratio): ${p.ratio.toFixed(2)}, Sai s\u1ED1 (Error): ${p.error}`)}if(!(!f&&!i)){if(g){if(g.useSimplifier===!1){s.debug(`[${ye}]: B\u1ECF qua primitive c\u1EE7a mesh "${u.getName()}": C\u1EDD useSimplifier \u0111ang b\u1ECB t\u1EAFt.`);continue}g.error>=0&&(p.error=g.error),g.ratio>=0&&(p.ratio=g.ratio),g.lockBorder!==void 0&&(p.lockBorder=g.lockBorder)}if(c.getMode()!==Ds.Mode.TRIANGLES){s.warn(`[${ye}]: B\u1ECF qua primitive c\u1EE7a mesh "${u.getName()}": Y\xEAu c\u1EA7u ch\u1EBF \u0111\u1ED9 v\u1EBD l\u01B0\u1EDBi (draw mode) l\xE0 TRIANGLES.`);continue}await tn(t,u,c,l,a,p)}}}return!0}async function tn(t,e,n,r,s,i){let o=t.getLogger();if(o.debug(`\u0110ang h\xE0n \u0111\u1EC9nh (weld): primitive[${r}] thu\u1ED9c mesh "${e.getName()}"`),Bs(n,s),!(i.simplifier&&i.simplifier?.ready instanceof Promise&&!await i.simplifier?.ready.then(()=>!0).catch(u=>(console.error(`[${ye}]: B\u1ED9 t\u1ED1i gi\u1EA3n (Simplifier) t\u1EA3i l\xEAn th\u1EA5t b\u1EA1i...
6
+ ${u}`),!1))))return o.debug(`\u0110ang \u0111\u01A1n gi\u1EA3n h\xF3a (simplify): primitive[${r}] thu\u1ED9c mesh "${e.getName()}" \u2192 ratio: ${i.ratio}, error: ${i.error}, lockBorder: ${i.lockBorder}, regularize: ${i.regularize}, normalWeight: ${i.normalWeight}, colorWeight: ${i.colorWeight}, textureWeight: ${i.textureWeight}`),ks(n,i)}async function Kn(t){let e=t.path,n=!0;if(await Ke(e,async r=>{if(!n)return;if(je(r)||Zn(r)){t.logger.info(`[Progressive Transform]: B\u1ECF qua t\u1EC7p LOD \u0111\xE3 t\u1ED3n t\u1EA1i t\u1EA1i ${r}`);return}await ci(r,t)||(n=!1)}),n){let r=t.results.length;for(let i=t.results.length-1;i>=0;i--)yt(t.results[i])||t.results.splice(i,1);let s=r!==t.results.length;t.debug&&console.log(`[Progressive Transform]: \u0110\xE3 x\u1EED l\xFD ${t.results.length} t\u1EC7p. ${s?"M\u1ED9t s\u1ED1 k\u1EBFt qu\u1EA3 \u0111\xE3 b\u1ECB lo\u1EA1i b\u1ECF":""}`)}return n}function sn(t){In(t),t.registerExtensions([me,Re,Xe,se,z(te.EXTENSION_NAME,qs.TEXTURE)])}async function ci(t,e){if(!t.endsWith(".glb")&&!t.endsWith(".gltf")&&!t.endsWith(".vrm"))return console.log("L\u1ED6I: t\u1EC7p kh\xF4ng ph\u1EA3i glTF/GLB"),!1;if(!yt(t))return console.log("L\u1ED6I: t\u1EC7p kh\xF4ng t\u1ED3n t\u1EA1i: "+t),!1;try{let n=new rn;sn(n),n.registerDependencies({"meshopt.decoder":oi,"meshopt.encoder":ai,"draco3d.decoder":await Wn.createDecoderModule(),"draco3d.encoder":await Wn.createEncoderModule()}),ut(t);let r=await Ye(n,t);if(r){e.logger?r.setLogger(e.logger):r.getLogger().verbosity=e.debug||e.verbose?jn.DEBUG:jn.WARN;let s=e.logger||r.getLogger();e.outpath&&pt(r,t,Oe.join(e.outpath,Oe.basename(t)));let i=128;e.config.usecase==="product"&&(i=512);let o=[Tt()];(await n.readAsJSON(t)).json.extensionsUsed?.includes("KHR_materials_pbrSpecularGlossiness")&&(s.warn("\u0110ang chuy\u1EC3n \u0111\u1ED5i KHR_materials_pbrSpecularGlossiness sang quy tr\xECnh metal/rough..."),await r.transform(Bn())),e.config?.textures?.lods!==!1&&o.push(ui(t,{size:[i,i]},e));let u=t.toLowerCase().endsWith(".vrm");!u&&e.config?.meshes?.lods!==!1?o.push(gi(t,{},e)):u&&s.warn("C\u1EA2NH B\xC1O: Progressive mesh ch\u01B0a \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 cho t\u1EC7p VRM"),o.push(Bn()),o.push(Xn()),s.info("\u2192 \u0110ang bi\u1EBFn \u0111\u1ED5i: "+t),await r.transform(...o);let m=mt(t,e.outpath);await gt(n,m,r),e.results.push(m),s.info("\u2190 Bi\u1EBFn \u0111\u1ED5i ho\xE0n t\u1EA5t: "+m)}}catch(n){if(n instanceof Ae)throw n;return console.log('L\u1ED6I: kh\xF4ng th\u1EC3 x\u1EED l\xFD t\u1EC7p "'+t+'", L\xFD do: '+n.message,`
7
7
  Stack:
8
- `+n.stack),!1}return!0}function cr(t,e){return Object.defineProperty(e,"name",{value:t}),e}var S="GLTF_progressive";function Po(t,e=ln,n){let r=Date.now(),s=wo(t),o={...ln,...e},i=Re.dirname(t);n.outpath&&(i=Ve(n.outpath));let a=i+"/";return cr(S,async u=>{let m=u.getLogger();if(ge(t))return m.info("Bi\u1EBFn \u0111\u1ED5i \u1EA3nh Progressive: b\u1ECF qua LOD t\u1EA1i "+t),Promise.resolve();let c=0,l=new Map;for(let f of u.getRoot().listTextures()){let g=c++,p=f.getName(),h=f.getURI();if(!(!o.pattern||o.pattern.test(p)||o.pattern.test(h))){m.debug(`[${S}] B\u1ECF qua, lo\u1EA1i tr\u1EEB b\u1EDFi tham s\u1ED1 "pattern". ${g}`);continue}if(f.getMimeType()!=="image/png"&&f.getMimeType()!=="image/jpeg"){m.warn(`[${S}] B\u1ECF qua, lo\u1EA1i texture kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 "${f.getMimeType()} t\u1EA1i ${g}".`);continue}let x=So(f);if(o.slots&&!x.some(G=>o.slots?.test(G))){m.debug(`[${S}] B\u1ECF qua, [${x.join(", ")}] lo\u1EA1i tr\u1EEB b\u1EDFi tham s\u1ED1 "slots". ${g}`);continue}let d=f.getExtension(Ne.EXTENSION_NAME);if(d){if(d.generateLods===!1){m.debug(`[${S}] B\u1ECF qua texture[${g}]: progressive texture \u0111\xE3 b\u1ECB t\u1EAFt`);continue}}else{let G=f.getSize();if(G?.length>=2&&G[0]<=o.size[0]&&G[1]<=o.size[1]){m.warn(`[${S}] B\u1ECF qua texture[${g}], kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t v\xE0 texture \u0111\xE3 <= ${G[0]}x${G[1]}`);continue}else l.has(f)||l.set(f,oe(f)),d={guid:ht(l.get(f)),maxSize:e.size[0]},m.debug(`[${S}] Kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t cho texture[${c}] - s\u1EBD d\xF9ng c\xE0i \u0111\u1EB7t m\u1EB7c \u0111\u1ECBnh (maxSize: ${d.maxSize}, guid: ${d.guid})`)}if(d.maxSize==null||d.maxSize<=0){m.warn(`[${S}] B\u1ECF qua texture[${g}], c\xE0i \u0111\u1EB7t kh\xF4ng h\u1EE3p l\u1EC7 (maxSize: ${d.maxSize})`);continue}let E=f.getExtension(Y);if(E!=null){m.debug(`[${S}] B\u1ECF qua, texture \u0111\xE3 l\xE0 progressive ${g}`);continue}let T=u.createExtension(me);if(!T||!T.createTexture){m.debug(`[${S}] B\u1ECF qua v\xEC extension progressive kh\xF4ng kh\u1EA3 d\u1EE5ng. ${g}`);continue}let L=st(f.getMimeType(),f.getImage(),m);L?.error&&(m.warn(`[${S}] Texture[${c}] c\xF3 mime type kh\xF4ng h\u1EE3p l\u1EC7! B\xE1o c\xE1o "${f.getMimeType()}" nh\u01B0ng th\u1EF1c t\u1EBF l\xE0 "${L.mimeType}": t\u1EF1 \u0111\u1ED9ng s\u1EEDa`),f.setMimeType(L.mimeType));let _=Math.min(...f.getSize());if(_<=d.maxSize){m.debug(`[${S}] B\u1ECF qua, texture[${g}] \u0111\xE3 nh\u1ECF h\u01A1n k\xEDch th\u01B0\u1EDBc y\xEAu c\u1EA7u: ${_}px <= ${d.maxSize}px`);continue}if(!d.guid?.length){l.has(f)||l.set(f,oe(f));let G=l.get(f);d.guid=ht(G)}let A=d.guid,M=d.maxSize,O=[];O.push({size:_});let b=!0,$=x.includes("lightmapTexture")||ue(f);if(b&&!$){let C=_;for(let v=1;v<6;v++){let U=C*.5;if(U<=M)break;C=Math.round(U),O.push({size:U})}}let P=[];for(let G=0;G<O.length;G++){let C=O[G],v=await Co({doc:u,inputFilepath:t,inputFilename:s,basePath:a,level:G,texture:f,slots:x,guid:A,textureIndex:g,maxSize:C.size},n);if(!v)continue;let[U,ce]=v.texture.getSize(),D=v.outpath,N=Re.relative(i,D);P.push({path:N,hash:v.hash,width:U,height:ce}),n.results.push(D)}let F=Tt(f),Z={guid:A,lods:P};if(f.setExtension(Y,T.createTexture(Z)),n.useCache){let G=xe(F);if(G){m.debug(`\u1EA2nh progressive ${c}: d\xF9ng phi\xEAn b\u1EA3n xem tr\u01B0\u1EDBc t\u1EEB b\u1ED9 nh\u1EDB \u0111\u1EC7m (k\xEDch th\u01B0\u1EDBc: ${o.size}))`),f.setImage(G);continue}}P?.length&&(o.size[0]=d.maxSize,o.size[1]=d.maxSize,m.debug(`[${S}] Thu nh\u1ECF texture nh\xFAng[${c}] v\u1EC1 ${o.size[0]}x${o.size[1]}`),await pn(o,f,m,h||p,x),n?.useCache===!1||fe(F,f.getImage()))}m.debug(`Bi\u1EBFn \u0111\u1ED5i progressive ho\xE0n th\xE0nh trong ${((Date.now()-r)/1e3).toFixed(1)} gi\xE2y.`)})}async function Co(t,e){let{doc:n,inputFilepath:r,basePath:s,level:o,texture:i,guid:a,textureIndex:u}=t,m=t.slots,c=n.getLogger(),l=new sr;It(l,{source:{filename:t.inputFilename}});let f=l.createScene(),g=l.createBuffer(),p=l.createTexture(),h=i.getImage();if(p.setImage(h),p.setURI(i.getURI()),p.setMimeType(i.getMimeType()),p.setName(i.getName()||"LOD_"+u),t.maxSize&&t.maxSize>=16){let O=p.getSize();O[0]>t.maxSize&&O[1]>t.maxSize&&await pn({size:[t.maxSize,t.maxSize]},p,c,i.getURI(),m)}m?.length||(c.warn(`C\u1EA2NH B\xC1O: Kh\xF4ng t\xECm th\u1EA5y slot material cho texture t\u1EA1i index ${u} (t\xEAn: "${i.getName()}") \u2192 s\u1EBD gi\u1EA3 \u0111\u1ECBnh slot "baseColorTexture"`),m=["baseColorTexture"]);let y=0;for(let O of m){let b=l.createMaterial(p.getName());switch(Eo(i).includes(yo.A)&&b.setAlphaMode("BLEND"),O){case"baseColorTexture":b.setBaseColorTexture(p);break;case"metallicRoughnessTexture":b.setMetallicRoughnessTexture(p);break;case"normalTexture":b.setNormalTexture(p);break;case"occlusionTexture":b.setOcclusionTexture(p);break;case"emissiveTexture":b.setEmissiveTexture(p);break;case"lightmapTexture":b.setBaseColorTexture(p),Wt(p);break;default:if(O.startsWith("lightmapTexture_")||O.startsWith("lightmap_")){b.setBaseColorTexture(p),Wt(p);break}if(O.startsWith("/textures/")){b.setAlphaMode("BLEND"),b.setBaseColorTexture(p);break}if(O==="specularColorTexture"){c.info("Chuy\u1EC3n ti\u1EBFp KHR_materials_pbrSpecularGlossiness specularColorTexture");let F=l.createExtension(St).createSpecular();F.setSpecularColorTexture(p),b.setExtension(St.EXTENSION_NAME,F);break}else if(O==="specularTexture"){c.info("Chuy\u1EC3n ti\u1EBFp KHR_materials_specular specularTexture");let F=l.createExtension(St).createSpecular();F.setSpecularTexture(p),b.setExtension(St.EXTENSION_NAME,F);break}return c.warn(`C\u1EA2NH B\xC1O: Slot texture kh\xF4ng x\xE1c \u0111\u1ECBnh: ${O} cho texture ${u} \u2192 kh\xF4ng th\u1EC3 t\u1EA3i progressive (t\u1EA5t c\u1EA3 slot: ${m.join(", ")})`),null}Do(l,b,y++)}let x=i.getExtension(ne.EXTENSION_NAME);if(x!=null&&x.getExtensionDefinition){c.debug("> Truy\u1EC1n extension n\xE9n sang texture m\u1EDBi");let O=l.createExtension(ne),b=x.getExtensionDefinition();if(!(b?.mode==="none"||b?.mode==="webp"||b?.mode==="UASTC"||b?.mode==="ETC1S"))switch(e.config.usecase){case"world":b.mode="ETC1S";break;case"product":b.mode=tn(m),b.quality=100;break;default:b.mode=tn(m);break}b.slot=m[0];let $=O.create(b);p.setExtension(ne.EXTENSION_NAME,$)}let d=l.createExtension(me);p.setExtension(Y,d.createTexture({guid:a}));let E=new fn;gn(E);let _="image_"+o+"_"+a+".glb",A=Re.join(s,_);wt(s)||_o(s,{recursive:!0}),c.info(`[${S}] Ghi texture LOD ${o} v\xE0o "${_}"`),E.write(A,l),c.info(`[${S}] T\u1EA1o hash cho texture LOD ${o}`);let M=oe(p);return{outpath:A,texture:p,hash:M}}function Do(t,e,n){let r=t.getRoot().listBuffers()[0],s=t.getRoot().listScenes()[0],o=t.createNode(),i=t.createMesh(),a=t.createPrimitive(),u=t.createAccessor();u.setType("VEC3"),u.setArray(new Float32Array([-.5,-.5,0,.5,-.5,0,-.5,.5,0,.5,.5,0])),u.setBuffer(r),a.setAttribute("POSITION",u);let m=t.createAccessor();m.setType("SCALAR"),m.setArray(new Uint32Array([0,1,2,2,1,3])),m.setBuffer(r),a.setIndices(m);let c=t.createAccessor();c.setType("VEC2"),c.setArray(new Float32Array([0,0,1,0,0,1,1,1])),c.setBuffer(r),a.setAttribute("TEXCOORD_0",c),a.setMaterial(e),i.addPrimitive(a),o.setMesh(i),s.addChild(o),o.setName(`Quad_${n}`);let l=[n,0,0];return o.setTranslation(l),{node:o,mesh:i,prim:a}}var Fo={LANCZOS3:"lanczos3",LANCZOS2:"lanczos2"},ln={size:[2048,2048],filter:Fo.LANCZOS3,pattern:null,slots:null};async function ur(t,e,n){let r={...ln};r.size=[e,e],await pn(r,t,n)}async function pn(t,e,n,r,s){let o=st(e.getMimeType(),e.getImage(),n);o?.error&&(n.warn(`[${S}] Texture[${r}] c\xF3 mime type kh\xF4ng h\u1EE3p l\u1EC7: ${o.error}: t\u1EF1 \u0111\u1ED9ng s\u1EEDa`),e.setMimeType(o.mimeType));let[i,a]=t.size,[u,m]=e.getSize();if(u<=i&&m<=a){n.debug(`[${S}] B\u1ECF qua, texture \u0111\xE3 th\u1ECFa m\xE3n k\xEDch th\u01B0\u1EDBc t\u1ED1i \u0111a ${i}x${a}}`);return}if(i<=0||a<=0){n.debug(`${r}: B\u1ECF qua, kho\u1EA3ng k\xEDch th\u01B0\u1EDBc kh\xF4ng h\u1EE3p l\u1EC7: ${i}x${a}`);return}let c=u,l=m;c>i&&(l=Math.floor(l*(i/c)),c=i),l>a&&(c=Math.floor(c*(a/l)),l=a),c=Math.floor(c),l=Math.floor(l),n.info(`\u2192 Thu nh\u1ECF texture (${r||e.getName()||s?.join(", ")}) t\u1EEB ${u}x${m} v\u1EC1 ${c}x${l}px`);let f=await Oo(e.getImage()).resize(c,l,{fit:"inside",kernel:"lanczos3",withoutEnlargement:!0}).toBuffer();return e.setImage(new Uint8Array(f.buffer,f.byteOffset,f.byteLength)),{width:c,height:l}}function ko(t,e,n){let r=Re.dirname(t);n.outpath&&(r=Ve(n.outpath));let s=r+"/";return cr("PROGRESSIVE_MESHES",async(o,i)=>{let a=o.getLogger();if(Jt=="Needle Engine"){a.warn("C\u1EA2NH B\xC1O: B\u1ECF qua t\u1EA1o LOD mesh - Ph\xE1t hi\u1EC7n generator kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3... Vui l\xF2ng c\u1EADp nh\u1EADt t\xEDch h\u1EE3p editor");return}if(ge(t))return a.info("Bi\u1EBFn \u0111\u1ED5i Mesh Progressive: b\u1ECF qua LOD t\u1EA1i "+t),Promise.resolve();await ir.ready;let u=Re.basename(t);a.info(`[${S}]: B\u1EAFt \u0111\u1EA7u t\u1EA1o progressive mesh cho "${u}"`);let m=0,c=6;n.config.usecase==="product"&&(c=3);let l={ratio:1,error:0,lockBorder:!0,normalWeight:2,colorWeight:1,textureWeight:1},f=[0,.003,.005,.01,.02],g=[l];for(let d=0;d<c;d++){let E=d/(c-1),L=g[g.length-1].ratio*.5,_=f[Math.min(f.length-1,d)];n.config.usecase==="product"&&(_*=.5);let A=l.normalWeight,M=Math.max(.2,Math.min(1,l.colorWeight*(1-E))),O=Math.max(.2,Math.min(10,l.textureWeight*(1-E*2))),b=d>1&&d<c-2;g.push({ratio:L,error:_,lockBorder:!0,regularize:b,normalWeight:A,colorWeight:M,textureWeight:O})}a.debug(`[${S}]: \u0110ang t\u1EA1o c\xE1c LOD mesh:
9
- ${JSON.stringify(g,void 0,2)}`);let p=new Map,y=o.getRoot().listMeshes();for(let d of y)await x(d,{filename:u});a.info(`[${S}]: Ho\xE0n th\xE0nh t\u1EA1o progressive mesh cho "${u}"`);async function x(d,E){let T=Je(d),{totalVertexCount:L,maxVertexCount:_}=T,A=d.getExtension(qe.EXTENSION_NAME);if(A){if(A.generateLods===!1){a.debug(`[${S}] Progressive mesh b\u1ECB t\u1EAFt cho mesh t\u1EA1i index ${m++}`);return}}else if(_<32){a.debug(`[${S}] B\u1ECF qua, kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t v\xE0 kh\xF4ng c\xF3 primitive n\xE0o c\xF3 h\u01A1n 32 \u0111\u1EC9nh. mesh[${m}] c\xF3 ${L} \u0111\u1EC9nh (t\u1ED1i \u0111a: ${_})`);return}else A={guid:ht(E.filename+"_mesh_"+m.toString()),generateLods:!0},a.debug(`[${S}] Kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t cho mesh[${m}] v\u1EDBi ${L} \u0111\u1EC9nh (t\u1ED1i \u0111a: ${_}) - s\u1EBD d\xF9ng c\xE0i \u0111\u1EB7t m\u1EB7c \u0111\u1ECBnh (guid: ${A.guid})`);let M=o.createExtension(me);if(!M||!M.createMesh){a.debug(`[${S}] B\u1ECF qua v\xEC extension progressive kh\xF4ng kh\u1EA3 d\u1EE5ng. ${m++}`);return}let O=!0,b=[];if(p.has(A.guid)){a.debug(`[${S}] Mesh \u0111\xE3 \u0111\u01B0\u1EE3c x\u1EED l\xFD ${m} - s\u1EBD d\xF9ng c\xE1c LOD \u0111\xE3 t\u1EA1o tr\u01B0\u1EDBc \u0111\xF3`),O=!1;let D=p.get(A.guid);b.push(...D.infos)}let $=[];if(O){a.info(`[${S}] B\u1EAFt \u0111\u1EA7u t\u1EA1o LOD mesh cho "${d.getName()}"`);for(let D=0;D<g.length-1;D++){let N=g[D],R=A.guid,W=Bo(u,o,s,D,d,T,R,N,n);W.then(B=>{B?.success&&(b[D]=B)}),$.push(W)}await Promise.all($),$.length=0}let P=-1/0;for(let D=0;D<b.length;D++){let N=b[D];if(!N){console.log(`[${S}] LOD ${D} kh\xF4ng t\u1ED3n t\u1EA1i`);continue}let R=s+N.path;if(wt(R)){let W=P,B=Lo(R).size,ie=W-B,V=N.level,te=!1;if(B<=0)a.info(`[${S}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: k\xEDch th\u01B0\u1EDBc tr\xEAn \u0111\u0129a l\xE0 0 \u2192 c\u1EA5p s\u1EBD b\u1ECB b\u1ECF qua. "${d.getName()}" t\u1EA1i "${N.path}"`),te=!0;else if(ie==0)a.info(`[${S}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: k\xEDch th\u01B0\u1EDBc tr\xEAn \u0111\u0129a kh\xF4ng thay \u0111\u1ED5i so v\u1EDBi c\u1EA5p tr\u01B0\u1EDBc \u2192 c\u1EA5p s\u1EBD b\u1ECB b\u1ECF qua. "${d.getName()}" t\u1EA1i "${N.path}"`),te=!0;else if(!te){let Ft=N.lodMeshInfo,it=b[D-1]?.lodMeshInfo;if(Ft&&it){let ze=it.totalVertexCount-Ft.totalVertexCount,kt=ze/it.totalVertexCount;ze<0?(a.info(`[${S}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: s\u1ED1 \u0111\u1EC9nh t\u0103ng l\xEAn (${-ze.toFixed(0)} \u0111\u1EC9nh, ${(-kt*100).toFixed(4)}%) \u2192 LOD ${V} s\u1EBD b\u1ECB b\u1ECF qua. "${d.getName()}" t\u1EA1i "${N.path}" ${JSON.stringify(it)} \u2192 ${JSON.stringify(Ft)}`),te=!0):(ze<32||kt<.05)&&(a.info(`[${S}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: ch\xEAnh l\u1EC7ch s\u1ED1 \u0111\u1EC9nh d\u01B0\u1EDBi ng\u01B0\u1EE1ng (lo\u1EA1i b\u1ECF ${ze.toFixed(0)} \u0111\u1EC9nh, ${(-kt*100).toFixed(4)}%) \u2192 LOD ${V} s\u1EBD b\u1ECB b\u1ECF qua. "${d.getName()}" t\u1EA1i "${N.path}"`),te=!0)}te&&n.useCache!=!1&&N.cacheKey!=null&&fe(N.cacheKey,new Uint8Array(0))}te?(a.debug(`[${S}] B\u1ECF qua LOD ${V} cho "${d.getName()}" t\u1EA1i "${N.path}"`),b.splice(D,1),rr(R,n),D--):P=B}}let F=0,Z=0,G=b.length,C={primitives:[],weights:[...d.getWeights()]};d.listPrimitives().forEach((D,N)=>{let R=Go(D,a);R!=null&&C.primitives.push(R),a.info(`[${S}] \u0110\u01A1n gi\u1EA3n h\xF3a mesh[${m}] primitive[${Z}] (nh\xFAng)`);let W=g[G],B=Ze(D);F=Math.max(F,B);let ie=mr(o,d,D,Z++,W);$.push(ie)}),await Promise.all($),$.length=0;let{totalVertexCount:v}=Je(d),U=L-v,ce=U/L;if(v<=0)a.error(`L\u1ED6I: [${S}]: Mesh[${m}] kh\xF4ng c\xF2n \u0111\u1EC9nh n\xE0o sau khi \u0111\u01A1n gi\u1EA3n h\xF3a: ${d.getName()}`);else if(U<32||ce<=.05){a.info(`[${S}]: \u0110\xE1nh d\u1EA5u mesh LOD ${b.length} (nh\xFAng): ch\xEAnh l\u1EC7ch s\u1ED1 \u0111\u1EC9nh d\u01B0\u1EDBi ng\u01B0\u1EE1ng (lo\u1EA1i b\u1ECF ${U} \u0111\u1EC9nh, ${(-ce*100).toFixed(2)} %) \u2192 s\u1EBD x\xF3a t\u1EA5t c\u1EA3 LOD. "${d.getName()}"`);try{for(let N of b)rr(s+"/"+N.path,n)}catch{a.error(`L\u1ED6I: [${S}] Kh\xF4ng th\u1EC3 x\xF3a c\xE1c t\u1EC7p LOD cho "${d.getName()}"`)}let D=d.listPrimitives();if(C.primitives.length==D.length){C.weights?.length>0&&d.setWeights(C.weights);for(let N=0;N<D.length;N++){let R=C.primitives[N];R&&jo(D[N],R)}}return}if(b.length>0){let D=M.createMesh({guid:A.guid,lods:b.map(N=>(n.results.push(Io(s,N.path)),{path:N.path,hash:N.content_hash.toString(),density:N.density,densities:N.densities,vertexCount:N.lodMeshInfo?.totalVertexCount,indexCount:N.lodMeshInfo?.totalIndexCount}))});d.setExtension(Y,D),m++,p.has(A.guid)||p.set(A.guid,{model:D,infos:b})}}})}function rr(t,e){Ao(t)}function Go(t,e){let n=t.listSemantics();if(n.some(i=>i.includes("JOINTS")))return null;let r=t.getIndices(),s=r?r.getArray().slice():new Uint32Array,o={};for(let i of n){e.info(`[${S}] Sao ch\xE9p thu\u1ED9c t\xEDnh ${i}`);let a=t.getAttribute(i);a&&(o[i]=a.getArray().slice())}return{indices:s,attributes:o}}function jo(t,e){let n=t.getIndices();n&&n.setArray(e.indices);for(let r of t.listSemantics()){let s=t.getAttribute(r);s&&s.setArray(e.attributes[r])}}async function Bo(t,e,n,r,s,o,i,a,u){let m=e.getLogger(),f="mesh_lod_"+r+"_"+i+".glb",g=n+f,p=s.listPrimitives(),h,y=s["gltf:mesh-hash"];if(y===void 0&&(m.info(`[${S}] \u0110ang t\u1EA1o hash cho mesh "${s.getName()}"`),y=oe(s),s["gltf:mesh-hash"]=y),y+=oe({lodLevel:a,guid:i,config:u.config}),u.useCache!==!1){h=`mesh_lod_${r}_${y}`;let C=xe(h),v=Xn(h);if(C&&v)return m.info(`[${S}] LOD ${r} \u0111\u01B0\u1EE3c t\u1EA3i t\u1EEB b\u1ED9 nh\u1EDB \u0111\u1EC7m cho "${s.getName()}"`),No(g,C),{level:r,path:f,success:!0,cacheKey:h,content_hash:y,lodMeshInfo:v.meshInfo,density:v.density,densities:v.densities}}let x=new sr;It(x,{source:{filename:t}});let d=x.createScene();x.createBuffer();let E=x.createNode();d.addChild(E),E.setName("LOD "+r+"_"+i),E.setTranslation([0,0,0]);let T=x.createMesh();T.setName((s.getName()||"Kh\xF4ng t\xEAn")+" LOD "+r),E.setMesh(T);let L=x.createMaterial(),_=s.getWeights();_&&T.setWeights(_);let A=[],M=new Map;for(let C of p){let v=x.createPrimitive();T.addPrimitive(v),v.setName(C.getName()),v.setMode(C.getMode()),v.setMaterial(L);let U=C.getIndices();if(U){let R=x.createAccessor();R.setArray(U.getArray()),R.setType(U.getType()),R.setSparse(U.getSparse()),R.setNormalized(U.getNormalized()),v.setIndices(R)}let ce=C.listSemantics();for(let R=0;R<ce.length;R++){let W=C.getAttribute(ce[R]);if(W)if(M.has(W)){let B=M.get(W);v.setAttribute(ce[R],B)}else{let B=x.createAccessor();B.setArray(W.getArray()),B.setType(W.getType()),B.setSparse(W.getSparse()),B.setNormalized(W.getNormalized()),v.setAttribute(ce[R],B),M.set(W,B)}else m.warn(`[${S}] Thi\u1EBFu thu\u1ED9c t\xEDnh ${ce[R]} trong mesh LOD ${r}`)}let D=C.listTargets();for(let R of D){let W=x.createPrimitiveTarget(R.getName());v.addTarget(W);let B=R.listSemantics();for(let ie of B){let V=R.getAttribute(ie);if(V){let te=x.createAccessor();te.setArray(V.getArray()),te.setType(V.getType()),te.setSparse(V.getSparse()),te.setNormalized(V.getNormalized()),W.setAttribute(ie,te)}else console.error(`[${S}] Thi\u1EBFu thu\u1ED9c t\xEDnh target ${ie} trong mesh LOD ${r}`)}}let N=C.listExtensions();for(let R of N){let W=R.constructor,B=new W(x.getGraph());try{let ie=B.copy(R),V=R.extensionName;v.setExtension(V,ie)}catch(ie){m.error(`[${S}] Kh\xF4ng th\u1EC3 sao ch\xE9p extension ${R.extensionName} cho mesh LOD ${r} \u2192 ${ie}`)}}}let O=0;if((a.error!=null||a.ratio!=null)&&(a.error>0||a.ratio<1))for(let C of T.listPrimitives()){let v=mr(x,T,C,O++,a);A.push(v)}await Promise.all(A),A.length=0;let b=Je(T);if(b.totalVertexCount<4)return m.error(`[${S}] mesh LOD ${r} c\xF3 \xEDt h\u01A1n 4 \u0111\u1EC9nh \u2192 b\u1ECF qua`),{level:r,path:f,success:!1,cacheKey:h,content_hash:y,lodMeshInfo:null,density:null,densities:null};let $=0,P=new Array(T.listPrimitives().length);T.listPrimitives().forEach((C,v)=>{let U=Ze(C);$=Math.max($,U),P[v]=U});let F=x.createExtension(me);if(!F||!F.createMesh){m.error("Kh\xF4ng th\u1EC3 t\u1EA1o extension progressive");return}T.setExtension(Y,F.createMesh({guid:i}));let Z=un(e,f);if(Z){let v=x.createExtension(se).create(Z);m.info(`[${S}] Truy\u1EC1n \u0111\u1ECBnh d\u1EA1ng n\xE9n sang mesh LOD ${r} \u2192 ${JSON.stringify(Z)}`),x.getRoot().setExtension(se.EXTENSION_NAME,v)}await x.transform(or());let G=new fn;if(gn(G),m.info(`[${S}] Ghi mesh LOD ${r} v\xE0o "${f}"`),await G.write(g,x),h!=null){let C=Mo(g),v=(C.byteLength/1024/1024).toFixed(2);m.info(`[${S}] Th\xEAm LOD ${r} v\xE0o b\u1ED9 nh\u1EDB \u0111\u1EC7m (${v} MB) cho "${s.getName()}" v\u1EDBi key ${h}`),fe(h,C),Un(h,{meshInfo:b,density:$,densities:P})}return{level:r,path:f,success:!0,lodMeshInfo:b,cacheKey:h,content_hash:y,density:$,densities:P}}async function mr(t,e,n,r,s){let o={...To,overwrite:!0,cleanup:!1,tolerance:1e-11,...s},i={...bo,...s,simplifier:ir};await mn(t,e,n,r,o,i)}function Be(t){return t.includes("mesh_lod_")}function lr(t){return t.includes("image_")}function ge(t){return Be(t)||lr(t)}function fr(t,e,n){let s=(Date.now()-t.startTime)/1e3/60,o=`[GLTF LOD Pipeline] v${Q()} \u2014 \u0110\xE3 ho\xE0n t\u1EA5t qu\xE1 tr\xECnh n\xE9n "${n?.usecase}" cho ${t.totalFilesProcessed} file trong ${s.toFixed(1)} ph\xFAt; t\u1ED5ng dung l\u01B0\u1EE3ng ${t.totalFileSizeInMBBefore.toFixed(1)} MB \u2192 ${t.totalFileSizeInMB.toFixed(1)} MB, t\u1ED5ng b\u1ED9 nh\u1EDB GPU (VRAM): ${t.totalGPUMemoryInMB.toFixed(1)} MB`;console.log(`info: ${o}`)}var Mt=class t{size;asset;json;nodes;materials;meshes;textures;animations;constructor(e,n,r){let s=e.getRoot(),o=s.getAsset();this.asset={generator:o.generator,version:o.version,copyright:o.copyright,extras:o.extras};let i=null;try{i=Uo(e)}catch{}this.size=r,this.json=Jo(n),this.nodes=s.listNodes().length,this.materials=s.listMaterials().length,this.meshes=Ko(e,i),this.textures=Ho(e,i),this.animations=Vo(e)}static combine(e,n){let r=new t(new Wo,null,0),s=!1;for(let o of e){if(n!==void 0){let i=o.filename;if(i){if(ge(i)){if(n==="main")continue}else if(n==="lods")continue}}s=!0,r.size+=o.size,r.json.addFrom(o.json),r.nodes+=o.nodes,r.materials+=o.materials,r.meshes.addFrom(o.meshes),r.textures.addFrom(o.textures),r.animations.addFrom(o.animations)}return s?r:null}},dn=class extends Mt{filename;isLOD;constructor(e,n,r){super(n,r,Xo(e).size),this.filename=nn(e),this.isLOD=ge(this.filename)}},hn=class{count=0;primitives=0;vertices=0;triangles=0;memory=0;formats=[];errors=[];warnings=[];addFrom(e){this.count+=e.count,this.primitives+=e.primitives,this.vertices+=e.vertices,this.triangles+=e.triangles,this.memory+=e.memory,this.formats=Array.from(new Set([...this.formats,...e.formats])),this.errors=Array.from(new Set([...this.errors||[],...e.errors||[]])),this.warnings=Array.from(new Set([...this.warnings||[],...e.warnings||[]]))}},xn=class{count=0;memory=0;gpu_memory=0;formats=[];errors=[];warnings=[];addFrom(e){this.count+=e.count,this.memory+=e.memory,this.gpu_memory+=e.gpu_memory,this.formats=Array.from(new Set([...this.formats,...e.formats])),this.errors=Array.from(new Set([...this.errors||[],...e.errors||[]])),this.warnings=Array.from(new Set([...this.warnings||[],...e.warnings||[]]))}},yn=class{count=0;size=0;channels=0;addFrom(e){this.count+=e.count,this.size+=e.size,this.channels+=e.channels}},bn=class{size=0;addFrom(e){this.size+=e.size}};function gr(t,e,n){return new dn(t,e,n)}function pr(t,e){if(e===void 0)return console.error("Kh\xF4ng c\xF3 \u0111\u01B0\u1EDDng d\u1EABn \u0111\u1EA7u ra (output path) n\xE0o \u0111\u01B0\u1EE3c cung c\u1EA5p cho file stats"),null;let n={sum:Mt.combine(t),files:t},r=JSON.stringify(n);return qo(e,r),r}function Ko(t,e){let n=t.getRoot(),r=n.listMeshes(),s=new hn;s.count=r.length,s.errors=e?.meshes?.errors||[],s.warnings=e?.meshes?.warnings||[];for(let i of r){let a=i.listPrimitives();s.primitives+=a.length;for(let u of a){let m=u.getAttribute("POSITION"),c=u.getIndices();m&&(s.vertices+=m.getCount()),c?s.triangles+=c.getCount()/3:m&&(s.triangles+=m.getCount()/3);let l=u.listSemantics();for(let f of l){let g=u.getAttribute(f);if(g){let p=g.getByteLength();s.memory+=p}}}}let o=n.listExtensionsUsed();for(let i of o)i.extensionName.startsWith("EXT_meshopt_compression")?s.formats.push("meshopt"):i.extensionName.startsWith("KHR_draco_mesh_compression")&&s.formats.push("draco");return s.formats=Array.from(new Set(s.formats)),s}function Ho(t,e){let r=t.getRoot().listTextures(),s=new xn;s.count=r.length,s.formats=r.map(o=>o.getMimeType()||"unknown"),s.errors=e?.textures?.errors||[],s.warnings=e?.textures?.warnings||[],s.gpu_memory=0,s.memory=0;for(let o of r){let i=o.getImage(),a=o.getMimeType();if(i&&a){try{s.gpu_memory+=zo.getVRAMByteLength(i,a)}catch{}s.memory+=i.byteLength}}return s.formats=Array.from(new Set(s.formats)),s}function Vo(t){let e=t.getRoot().listAnimations(),n=new yn;n.count=e.length,n.channels=0,n.size=0;for(let r of e){let s=r.listChannels();n.channels+=s.length;for(let o of s){let i=o.getSampler();if(!i)continue;let a=i.getInput(),u=i.getOutput();a&&(n.size+=a.getArray()?.byteLength??0),u&&(n.size+=u.getArray()?.byteLength??0)}}return n}function Jo(t){let e=new bn;return t&&t.json&&(e.size=JSON.stringify(t.json).length),e}import{ImageUtils as Zo}from"@gltf-transform/core";function st(t,e,n){let r=Zo.getMimeType(e);if(r!=null&&r!==t){let s=`Image reported wrong mime type "${t}" but is actually "${r}"`;return n.warn(s),{error:!0,message:s,mimeType:r}}else r===null&&n.debug(`Could not validate image type for "${t}"`);return null}var dr="Gltf Build Pipeline";function It(t,e){let r=t.getRoot().getAsset();if(r){r.extras=Qo(r.extras),e&&(r.extras=Object.assign(r.extras||{},e));let s=Q();r.generator=dr,s?.length>0&&(r.generator+=" "+s)}}function _t(){return Yo("gltf_asset_transform",t=>{It(t)})}function Qo(t){if(t||(t={}),typeof t=="object"&&!t.gltf){let e=dr,n=Q();n?.length>0&&(e+=" "+n);let r=new Date().toISOString();t.gltf={generator:e,created:r,updated:r,revision:0}}else{let e=t.gltf;e&&(e.updated=new Date().toISOString(),e.revision=e.revision+1)}return t}import ii from"micromatch";import ai from"os";import ot from"semver";import ci from"tmp";import{TextureChannel as ui}from"@gltf-transform/core";import{TextureResizeFilter as mi,getTextureColorSpace as li}from"@gltf-transform/functions";import{spawn as ei}from"child_process";import il from"command-exists";var hr={nocase:!0,contains:!0},At=ei;var Lt=ti;async function ti(t){let e="";if(t.stdout)for await(let s of t.stdout)e+=s;let n="";if(t.stderr)for await(let s of t.stderr)n+=s;return[await new Promise(s=>{t.on("close",s)}),e,n]}function Tn(t,e=2){if(t===0)return"0 Bytes";let n=1e3,r=e<0?0:e,s=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],o=Math.floor(Math.log(t)/Math.log(n));return parseFloat((t/Math.pow(n,o)).toFixed(r))+" "+s[o]}import ni from"os";import{TextureResizeFilter as ri}from"@gltf-transform/functions";var si=ni.cpus().length||1;var oi={BOX:"box",TENT:"tent",BELL:"bell",BSPLINE:"b-spline",MITCHELL:"mitchell",LANCZOS3:"lanczos3",LANCZOS4:"lanczos4",LANCZOS6:"lanczos6",LANCZOS12:"lanczos12",BLACKMAN:"blackman",KAISER:"kaiser",GAUSSIAN:"gaussian",CATMULLROM:"catmullrom",QUADRATIC_INTERP:"quadratic_interp",QUADRATIC_APPROX:"quadratic_approx",QUADRATIC_MIX:"quadratic_mix"},xr={resizeFilter:ri.LANCZOS3,filter:oi.LANCZOS4,filterScale:1,pattern:null,slots:null,jobs:2*si,cleanup:!0,limitInputPixels:!0},_e={quality:128,compression:1,rdo:!0,rdoThreshold:1.25,maxSelectors:0,maxEndpoints:0,...xr},$e={level:2,rdo:!1,rdoLambda:1,rdoDictionarySize:32768,rdoBlockScale:10,rdoStdDev:18,rdoMultithreading:!0,zstd:18,...xr};ci.setGracefulCleanup();var En=ai.cpus().length||1,Nt="4.3.0",{R:yr,G:br,A:fi}=ui,gi={BOX:"box",TENT:"tent",BELL:"bell",BSPLINE:"b-spline",MITCHELL:"mitchell",LANCZOS3:"lanczos3",LANCZOS4:"lanczos4",LANCZOS6:"lanczos6",LANCZOS12:"lanczos12",BLACKMAN:"blackman",KAISER:"kaiser",GAUSSIAN:"gaussian",CATMULLROM:"catmullrom",QUADRATIC_INTERP:"quadratic_interp",QUADRATIC_APPROX:"quadratic_approx",QUADRATIC_MIX:"quadratic_mix"},Tr={resizeFilter:mi.LANCZOS3,filter:gi.LANCZOS4,filterScale:1,pattern:null,slots:null,jobs:2*En,cleanup:!0,limitInputPixels:!0},pe={ETC1S:"etc1s",UASTC:"uastc"};function Sr(t,e,n,r,s,o,i){let a=li(t),u=["--generate-mipmap"];i.filter!==Tr.filter&&u.push("--mipmap-filter",i.filter),i.filterScale!==Tr.filterScale&&u.push("--mipmap-filter-scale",i.filterScale);let m=e.find(c=>ii.isMatch(c,"*normal*",hr));if(i.mode===pe.UASTC){let c=i;u.push("--encode","uastc"),u.push("--uastc-quality",c.level),c.rdo&&!m&&(u.push("--uastc-rdo"),c.rdoLambda!==$e.rdoLambda&&u.push("--uastc-rdo-l",c.rdoLambda),c.rdoDictionarySize!==$e.rdoDictionarySize&&u.push("--uastc-rdo-d",c.rdoDictionarySize),c.rdoBlockScale!==$e.rdoBlockScale&&u.push("--uastc-rdo-b",c.rdoBlockScale),c.rdoStdDev!==$e.rdoStdDev&&u.push("--uastc-rdo-s",c.rdoStdDev),c.rdoMultithreading||u.push("--uastc-rdo-m")),c.zstd&&c.zstd>0&&u.push("--zstd",c.zstd)}else{let c=i;u.push("--encode","basis-lz"),c.quality!==_e.quality&&u.push("--qlevel",c.quality),c.compression!==_e.compression&&u.push("--clevel",c.compression),c.rdo&&!m?(c.maxEndpoints!==_e.maxEndpoints&&u.push("--max-endpoints",c.maxEndpoints),c.maxSelectors!==_e.maxSelectors&&u.push("--max-selectors",c.maxSelectors),c.rdoThreshold!==_e.rdoThreshold&&(u.push("--endpoint-rdo-threshold",c.rdoThreshold),u.push("--selector-rdo-threshold",c.rdoThreshold))):u.push("--no-endpoint-rdo","--no-selector-rdo")}if(a==="srgb"?u.push("--assign-oetf","srgb","--assign-primaries","bt709"):a==="srgb-linear"?u.push("--assign-oetf","linear","--assign-primaries","bt709"):e.length&&!a&&u.push("--assign-oetf","linear","--assign-primaries","none"),n===yr?u.push("--format","R8_UNORM"):n===br||n===(yr|br)?u.push("--format","R8G8_UNORM"):n&fi?u.push("--format",a==="srgb"?"R8G8B8A8_SRGB":"R8G8B8A8_UNORM"):u.push("--format",a==="srgb"?"R8G8B8_SRGB":"R8G8B8_UNORM"),i.jobs&&i.jobs>1&&o>1){let c=Math.max(2,Math.min(En,Math.round(3*En/o)));u.push("--threads",c)}return u}var Er=!1;async function wr(t,e){let n=!1,r=At("toktx",["--version"],{env:e});r.on("error",u=>{u.message.endsWith("ENOENT")&&(n=!0)});let[s,o,i]=await Lt(r);if(n)return console.log('WARN: Unable to find "toktx". Confirm KTX-Software is installed from: https://github.com/KhronosGroup/KTX-Software.'),null;let a=(o||i).replace(/toktx\s+/,"").replace(/~\d+/,"").trim();if(s!==0||!ot.valid(ot.clean(a)))throw new Error(`Unable to find "toktx" version. Confirm KTX-Software is installed from:
8
+ `+n.stack),!1}return!0}function Hn(t,e){return Object.defineProperty(e,"name",{value:t}),e}var T="GLTF_progressive";function ui(t,e=nn,n){let r=Date.now(),s=Ys(t),i={...nn,...e},o=Oe.dirname(t);n.outpath&&(o=He(n.outpath));let a=o+"/";return Hn(T,async u=>{let m=u.getLogger();if(ge(t))return m.info("Bi\u1EBFn \u0111\u1ED5i \u1EA3nh Progressive: b\u1ECF qua LOD t\u1EA1i "+t),Promise.resolve();let c=0,l=new Map;for(let f of u.getRoot().listTextures()){let g=c++,p=f.getName(),d=f.getURI();if(!(!i.pattern||i.pattern.test(p)||i.pattern.test(d))){m.debug(`[${T}] B\u1ECF qua, lo\u1EA1i tr\u1EEB b\u1EDFi tham s\u1ED1 "pattern". ${g}`);continue}if(f.getMimeType()!=="image/png"&&f.getMimeType()!=="image/jpeg"){m.warn(`[${T}] B\u1ECF qua, lo\u1EA1i texture kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 "${f.getMimeType()} t\u1EA1i ${g}".`);continue}let x=Zs(f);if(i.slots&&!x.some(k=>i.slots?.test(k))){m.debug(`[${T}] B\u1ECF qua, [${x.join(", ")}] lo\u1EA1i tr\u1EEB b\u1EDFi tham s\u1ED1 "slots". ${g}`);continue}let h=f.getExtension(Re.EXTENSION_NAME);if(h){if(h.generateLods===!1){m.debug(`[${T}] B\u1ECF qua texture[${g}]: progressive texture \u0111\xE3 b\u1ECB t\u1EAFt`);continue}}else{let k=f.getSize();if(k?.length>=2&&k[0]<=i.size[0]&&k[1]<=i.size[1]){m.warn(`[${T}] B\u1ECF qua texture[${g}], kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t v\xE0 texture \u0111\xE3 <= ${k[0]}x${k[1]}`);continue}else l.has(f)||l.set(f,ie(f)),h={guid:ft(l.get(f)),maxSize:e.size[0]},m.debug(`[${T}] Kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t cho texture[${c}] - s\u1EBD d\xF9ng c\xE0i \u0111\u1EB7t m\u1EB7c \u0111\u1ECBnh (maxSize: ${h.maxSize}, guid: ${h.guid})`)}if(h.maxSize==null||h.maxSize<=0){m.warn(`[${T}] B\u1ECF qua texture[${g}], c\xE0i \u0111\u1EB7t kh\xF4ng h\u1EE3p l\u1EC7 (maxSize: ${h.maxSize})`);continue}let M=f.getExtension(Z);if(M!=null){m.debug(`[${T}] B\u1ECF qua, texture \u0111\xE3 l\xE0 progressive ${g}`);continue}let w=u.createExtension(me);if(!w||!w.createTexture){m.debug(`[${T}] B\u1ECF qua v\xEC extension progressive kh\xF4ng kh\u1EA3 d\u1EE5ng. ${g}`);continue}let A=et(f.getMimeType(),f.getImage(),m);A?.error&&(m.warn(`[${T}] Texture[${c}] c\xF3 mime type kh\xF4ng h\u1EE3p l\u1EC7! B\xE1o c\xE1o "${f.getMimeType()}" nh\u01B0ng th\u1EF1c t\u1EBF l\xE0 "${A.mimeType}": t\u1EF1 \u0111\u1ED9ng s\u1EEDa`),f.setMimeType(A.mimeType));let I=Math.min(...f.getSize());if(I<=h.maxSize){m.debug(`[${T}] B\u1ECF qua, texture[${g}] \u0111\xE3 nh\u1ECF h\u01A1n k\xEDch th\u01B0\u1EDBc y\xEAu c\u1EA7u: ${I}px <= ${h.maxSize}px`);continue}if(!h.guid?.length){l.has(f)||l.set(f,ie(f));let k=l.get(f);h.guid=ft(k)}let L=h.guid,v=h.maxSize,O=[];O.push({size:I});let b=!0,G=x.includes("lightmapTexture")||ue(f);if(b&&!G){let $=I;for(let N=1;N<6;N++){let U=$*.5;if(U<=v)break;$=Math.round(U),O.push({size:U})}}let D=[];for(let k=0;k<O.length;k++){let $=O[k],N=await mi({doc:u,inputFilepath:t,inputFilename:s,basePath:a,level:k,texture:f,slots:x,guid:L,textureIndex:g,maxSize:$.size},n);if(!N)continue;let[U,ce]=N.texture.getSize(),C=N.outpath,_=Oe.relative(o,C);D.push({path:_,hash:N.hash,width:U,height:ce}),n.results.push(C)}let F=dt(f),ne={guid:L,lods:D};if(f.setExtension(Z,w.createTexture(ne)),n.useCache){let k=xe(F);if(k){m.debug(`\u1EA2nh progressive ${c}: d\xF9ng phi\xEAn b\u1EA3n xem tr\u01B0\u1EDBc t\u1EEB b\u1ED9 nh\u1EDB \u0111\u1EC7m (k\xEDch th\u01B0\u1EDBc: ${i.size}))`),f.setImage(k);continue}}D?.length&&(i.size[0]=h.maxSize,i.size[1]=h.maxSize,m.debug(`[${T}] Thu nh\u1ECF texture nh\xFAng[${c}] v\u1EC1 ${i.size[0]}x${i.size[1]}`),await on(i,f,m,d||p,x),n?.useCache===!1||fe(F,f.getImage()))}m.debug(`Bi\u1EBFn \u0111\u1ED5i progressive ho\xE0n th\xE0nh trong ${((Date.now()-r)/1e3).toFixed(1)} gi\xE2y.`)})}async function mi(t,e){let{doc:n,inputFilepath:r,basePath:s,level:i,texture:o,guid:a,textureIndex:u}=t,m=t.slots,c=n.getLogger(),l=new Un;bt(l,{source:{filename:t.inputFilename}});let f=l.createScene(),g=l.createBuffer(),p=l.createTexture(),d=o.getImage();if(p.setImage(d),p.setURI(o.getURI()),p.setMimeType(o.getMimeType()),p.setName(o.getName()||"LOD_"+u),t.maxSize&&t.maxSize>=16){let O=p.getSize();O[0]>t.maxSize&&O[1]>t.maxSize&&await on({size:[t.maxSize,t.maxSize]},p,c,o.getURI(),m)}m?.length||(c.warn(`C\u1EA2NH B\xC1O: Kh\xF4ng t\xECm th\u1EA5y slot material cho texture t\u1EA1i index ${u} (t\xEAn: "${o.getName()}") \u2192 s\u1EBD gi\u1EA3 \u0111\u1ECBnh slot "baseColorTexture"`),m=["baseColorTexture"]);let y=0;for(let O of m){let b=l.createMaterial(p.getName());switch(Js(o).includes(Ks.A)&&b.setAlphaMode("BLEND"),O){case"baseColorTexture":b.setBaseColorTexture(p);break;case"metallicRoughnessTexture":b.setMetallicRoughnessTexture(p);break;case"normalTexture":b.setNormalTexture(p);break;case"occlusionTexture":b.setOcclusionTexture(p);break;case"emissiveTexture":b.setEmissiveTexture(p);break;case"lightmapTexture":b.setBaseColorTexture(p),Ft(p);break;default:if(O.startsWith("lightmapTexture_")||O.startsWith("lightmap_")){b.setBaseColorTexture(p),Ft(p);break}if(O.startsWith("/textures/")){b.setAlphaMode("BLEND"),b.setBaseColorTexture(p);break}if(O==="specularColorTexture"){c.info("Chuy\u1EC3n ti\u1EBFp KHR_materials_pbrSpecularGlossiness specularColorTexture");let F=l.createExtension(xt).createSpecular();F.setSpecularColorTexture(p),b.setExtension(xt.EXTENSION_NAME,F);break}else if(O==="specularTexture"){c.info("Chuy\u1EC3n ti\u1EBFp KHR_materials_specular specularTexture");let F=l.createExtension(xt).createSpecular();F.setSpecularTexture(p),b.setExtension(xt.EXTENSION_NAME,F);break}return c.warn(`C\u1EA2NH B\xC1O: Slot texture kh\xF4ng x\xE1c \u0111\u1ECBnh: ${O} cho texture ${u} \u2192 kh\xF4ng th\u1EC3 t\u1EA3i progressive (t\u1EA5t c\u1EA3 slot: ${m.join(", ")})`),null}li(l,b,y++)}let x=o.getExtension(te.EXTENSION_NAME);if(x!=null&&x.getExtensionDefinition){c.debug("> Truy\u1EC1n extension n\xE9n sang texture m\u1EDBi");let O=l.createExtension(te),b=x.getExtensionDefinition();if(!(b?.mode==="none"||b?.mode==="webp"||b?.mode==="UASTC"||b?.mode==="ETC1S"))switch(e.config.usecase){case"world":b.mode="ETC1S";break;case"product":b.mode=Jt(m),b.quality=100;break;default:b.mode=Jt(m);break}b.slot=m[0];let G=O.create(b);p.setExtension(te.EXTENSION_NAME,G)}let h=l.createExtension(me);p.setExtension(Z,h.createTexture({guid:a}));let M=new rn;sn(M);let I="image_"+i+"_"+a+".glb",L=Oe.join(s,I);yt(s)||ei(s,{recursive:!0}),c.info(`[${T}] Ghi texture LOD ${i} v\xE0o "${I}"`),M.write(L,l),c.info(`[${T}] T\u1EA1o hash cho texture LOD ${i}`);let v=ie(p);return{outpath:L,texture:p,hash:v}}function li(t,e,n){let r=t.getRoot().listBuffers()[0],s=t.getRoot().listScenes()[0],i=t.createNode(),o=t.createMesh(),a=t.createPrimitive(),u=t.createAccessor();u.setType("VEC3"),u.setArray(new Float32Array([-.5,-.5,0,.5,-.5,0,-.5,.5,0,.5,.5,0])),u.setBuffer(r),a.setAttribute("POSITION",u);let m=t.createAccessor();m.setType("SCALAR"),m.setArray(new Uint32Array([0,1,2,2,1,3])),m.setBuffer(r),a.setIndices(m);let c=t.createAccessor();c.setType("VEC2"),c.setArray(new Float32Array([0,0,1,0,0,1,1,1])),c.setBuffer(r),a.setAttribute("TEXCOORD_0",c),a.setMaterial(e),o.addPrimitive(a),i.setMesh(o),s.addChild(i),i.setName(`Quad_${n}`);let l=[n,0,0];return i.setTranslation(l),{node:i,mesh:o,prim:a}}var fi={LANCZOS3:"lanczos3",LANCZOS2:"lanczos2"},nn={size:[2048,2048],filter:fi.LANCZOS3,pattern:null,slots:null};async function Vn(t,e,n){let r={...nn};r.size=[e,e],await on(r,t,n)}async function on(t,e,n,r,s){let i=et(e.getMimeType(),e.getImage(),n);i?.error&&(n.warn(`[${T}] Texture[${r}] c\xF3 mime type kh\xF4ng h\u1EE3p l\u1EC7: ${i.error}: t\u1EF1 \u0111\u1ED9ng s\u1EEDa`),e.setMimeType(i.mimeType));let[o,a]=t.size,[u,m]=e.getSize();if(u<=o&&m<=a){n.debug(`[${T}] B\u1ECF qua, texture \u0111\xE3 th\u1ECFa m\xE3n k\xEDch th\u01B0\u1EDBc t\u1ED1i \u0111a ${o}x${a}}`);return}if(o<=0||a<=0){n.debug(`${r}: B\u1ECF qua, kho\u1EA3ng k\xEDch th\u01B0\u1EDBc kh\xF4ng h\u1EE3p l\u1EC7: ${o}x${a}`);return}let c=u,l=m;c>o&&(l=Math.floor(l*(o/c)),c=o),l>a&&(c=Math.floor(c*(a/l)),l=a),c=Math.floor(c),l=Math.floor(l),n.info(`\u2192 Thu nh\u1ECF texture (${r||e.getName()||s?.join(", ")}) t\u1EEB ${u}x${m} v\u1EC1 ${c}x${l}px`);let f=await ii(e.getImage()).resize(c,l,{fit:"inside",kernel:"lanczos3",withoutEnlargement:!0}).toBuffer();return e.setImage(new Uint8Array(f.buffer,f.byteOffset,f.byteLength)),{width:c,height:l}}function gi(t,e,n){let r=Oe.dirname(t);n.outpath&&(r=He(n.outpath));let s=r+"/";return Hn("PROGRESSIVE_MESHES",async(i,o)=>{let a=i.getLogger();if(Xt=="Needle Engine"){a.warn("C\u1EA2NH B\xC1O: B\u1ECF qua t\u1EA1o LOD mesh - Ph\xE1t hi\u1EC7n generator kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3... Vui l\xF2ng c\u1EADp nh\u1EADt t\xEDch h\u1EE3p editor");return}if(ge(t))return a.info("Bi\u1EBFn \u0111\u1ED5i Mesh Progressive: b\u1ECF qua LOD t\u1EA1i "+t),Promise.resolve();await qn.ready;let u=Oe.basename(t);a.info(`[${T}]: B\u1EAFt \u0111\u1EA7u t\u1EA1o progressive mesh cho "${u}"`);let m=0,c=6;n.config.usecase==="product"&&(c=3);let l={ratio:1,error:0,lockBorder:!0,normalWeight:2,colorWeight:1,textureWeight:1},f=[0,.003,.005,.01,.02],g=[l];for(let h=0;h<c;h++){let M=h/(c-1),A=g[g.length-1].ratio*.5,I=f[Math.min(f.length-1,h)];n.config.usecase==="product"&&(I*=.5);let L=l.normalWeight,v=Math.max(.2,Math.min(1,l.colorWeight*(1-M))),O=Math.max(.2,Math.min(10,l.textureWeight*(1-M*2))),b=h>1&&h<c-2;g.push({ratio:A,error:I,lockBorder:!0,regularize:b,normalWeight:L,colorWeight:v,textureWeight:O})}a.debug(`[${T}]: \u0110ang t\u1EA1o c\xE1c LOD mesh:
9
+ ${JSON.stringify(g,void 0,2)}`);let p=new Map,y=i.getRoot().listMeshes();for(let h of y)await x(h,{filename:u});a.info(`[${T}]: Ho\xE0n th\xE0nh t\u1EA1o progressive mesh cho "${u}"`);async function x(h,M){let w=Ve(h),{totalVertexCount:A,maxVertexCount:I}=w,L=h.getExtension(Xe.EXTENSION_NAME);if(L){if(L.generateLods===!1){a.debug(`[${T}] Progressive mesh b\u1ECB t\u1EAFt cho mesh t\u1EA1i index ${m++}`);return}}else if(I<32){a.debug(`[${T}] B\u1ECF qua, kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t v\xE0 kh\xF4ng c\xF3 primitive n\xE0o c\xF3 h\u01A1n 32 \u0111\u1EC9nh. mesh[${m}] c\xF3 ${A} \u0111\u1EC9nh (t\u1ED1i \u0111a: ${I})`);return}else L={guid:ft(M.filename+"_mesh_"+m.toString()),generateLods:!0},a.debug(`[${T}] Kh\xF4ng t\xECm th\u1EA5y c\xE0i \u0111\u1EB7t cho mesh[${m}] v\u1EDBi ${A} \u0111\u1EC9nh (t\u1ED1i \u0111a: ${I}) - s\u1EBD d\xF9ng c\xE0i \u0111\u1EB7t m\u1EB7c \u0111\u1ECBnh (guid: ${L.guid})`);let v=i.createExtension(me);if(!v||!v.createMesh){a.debug(`[${T}] B\u1ECF qua v\xEC extension progressive kh\xF4ng kh\u1EA3 d\u1EE5ng. ${m++}`);return}let O=!0,b=[];if(p.has(L.guid)){a.debug(`[${T}] Mesh \u0111\xE3 \u0111\u01B0\u1EE3c x\u1EED l\xFD ${m} - s\u1EBD d\xF9ng c\xE1c LOD \u0111\xE3 t\u1EA1o tr\u01B0\u1EDBc \u0111\xF3`),O=!1;let C=p.get(L.guid);b.push(...C.infos)}let G=[];if(O){a.info(`[${T}] B\u1EAFt \u0111\u1EA7u t\u1EA1o LOD mesh cho "${h.getName()}"`);for(let C=0;C<g.length-1;C++){let _=g[C],R=L.guid,W=di(u,i,s,C,h,w,R,_,n);W.then(B=>{B?.success&&(b[C]=B)}),G.push(W)}await Promise.all(G),G.length=0}let D=-1/0;for(let C=0;C<b.length;C++){let _=b[C];if(!_){console.log(`[${T}] LOD ${C} kh\xF4ng t\u1ED3n t\u1EA1i`);continue}let R=s+_.path;if(yt(R)){let W=D,B=ri(R).size,oe=W-B,V=_.level,ee=!1;if(B<=0)a.info(`[${T}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: k\xEDch th\u01B0\u1EDBc tr\xEAn \u0111\u0129a l\xE0 0 \u2192 c\u1EA5p s\u1EBD b\u1ECB b\u1ECF qua. "${h.getName()}" t\u1EA1i "${_.path}"`),ee=!0;else if(oe==0)a.info(`[${T}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: k\xEDch th\u01B0\u1EDBc tr\xEAn \u0111\u0129a kh\xF4ng thay \u0111\u1ED5i so v\u1EDBi c\u1EA5p tr\u01B0\u1EDBc \u2192 c\u1EA5p s\u1EBD b\u1ECB b\u1ECF qua. "${h.getName()}" t\u1EA1i "${_.path}"`),ee=!0;else if(!ee){let Ot=_.lodMeshInfo,nt=b[C-1]?.lodMeshInfo;if(Ot&&nt){let We=nt.totalVertexCount-Ot.totalVertexCount,$t=We/nt.totalVertexCount;We<0?(a.info(`[${T}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: s\u1ED1 \u0111\u1EC9nh t\u0103ng l\xEAn (${-We.toFixed(0)} \u0111\u1EC9nh, ${(-$t*100).toFixed(4)}%) \u2192 LOD ${V} s\u1EBD b\u1ECB b\u1ECF qua. "${h.getName()}" t\u1EA1i "${_.path}" ${JSON.stringify(nt)} \u2192 ${JSON.stringify(Ot)}`),ee=!0):(We<32||$t<.05)&&(a.info(`[${T}] \u0110\xE1nh d\u1EA5u mesh LOD ${V}: ch\xEAnh l\u1EC7ch s\u1ED1 \u0111\u1EC9nh d\u01B0\u1EDBi ng\u01B0\u1EE1ng (lo\u1EA1i b\u1ECF ${We.toFixed(0)} \u0111\u1EC9nh, ${(-$t*100).toFixed(4)}%) \u2192 LOD ${V} s\u1EBD b\u1ECB b\u1ECF qua. "${h.getName()}" t\u1EA1i "${_.path}"`),ee=!0)}ee&&n.useCache!=!1&&_.cacheKey!=null&&fe(_.cacheKey,new Uint8Array(0))}ee?(a.debug(`[${T}] B\u1ECF qua LOD ${V} cho "${h.getName()}" t\u1EA1i "${_.path}"`),b.splice(C,1),zn(R,n),C--):D=B}}let F=0,ne=0,k=b.length,$={primitives:[],weights:[...h.getWeights()]};h.listPrimitives().forEach((C,_)=>{let R=pi(C,a);R!=null&&$.primitives.push(R),a.info(`[${T}] \u0110\u01A1n gi\u1EA3n h\xF3a mesh[${m}] primitive[${ne}] (nh\xFAng)`);let W=g[k],B=Je(C);F=Math.max(F,B);let oe=Jn(i,h,C,ne++,W);G.push(oe)}),await Promise.all(G),G.length=0;let{totalVertexCount:N}=Ve(h),U=A-N,ce=U/A;if(N<=0)a.error(`L\u1ED6I: [${T}]: Mesh[${m}] kh\xF4ng c\xF2n \u0111\u1EC9nh n\xE0o sau khi \u0111\u01A1n gi\u1EA3n h\xF3a: ${h.getName()}`);else if(U<32||ce<=.05){a.info(`[${T}]: \u0110\xE1nh d\u1EA5u mesh LOD ${b.length} (nh\xFAng): ch\xEAnh l\u1EC7ch s\u1ED1 \u0111\u1EC9nh d\u01B0\u1EDBi ng\u01B0\u1EE1ng (lo\u1EA1i b\u1ECF ${U} \u0111\u1EC9nh, ${(-ce*100).toFixed(2)} %) \u2192 s\u1EBD x\xF3a t\u1EA5t c\u1EA3 LOD. "${h.getName()}"`);try{for(let _ of b)zn(s+"/"+_.path,n)}catch{a.error(`L\u1ED6I: [${T}] Kh\xF4ng th\u1EC3 x\xF3a c\xE1c t\u1EC7p LOD cho "${h.getName()}"`)}let C=h.listPrimitives();if($.primitives.length==C.length){$.weights?.length>0&&h.setWeights($.weights);for(let _=0;_<C.length;_++){let R=$.primitives[_];R&&hi(C[_],R)}}return}if(b.length>0){let C=v.createMesh({guid:L.guid,lods:b.map(_=>(n.results.push(Qs(s,_.path)),{path:_.path,hash:_.content_hash.toString(),density:_.density,densities:_.densities,vertexCount:_.lodMeshInfo?.totalVertexCount,indexCount:_.lodMeshInfo?.totalIndexCount}))});h.setExtension(Z,C),m++,p.has(L.guid)||p.set(L.guid,{model:C,infos:b})}}})}function zn(t,e){ni(t)}function pi(t,e){let n=t.listSemantics();if(n.some(o=>o.includes("JOINTS")))return null;let r=t.getIndices(),s=r?r.getArray().slice():new Uint32Array,i={};for(let o of n){e.info(`[${T}] Sao ch\xE9p thu\u1ED9c t\xEDnh ${o}`);let a=t.getAttribute(o);a&&(i[o]=a.getArray().slice())}return{indices:s,attributes:i}}function hi(t,e){let n=t.getIndices();n&&n.setArray(e.indices);for(let r of t.listSemantics()){let s=t.getAttribute(r);s&&s.setArray(e.attributes[r])}}async function di(t,e,n,r,s,i,o,a,u){let m=e.getLogger(),f="mesh_lod_"+r+"_"+o+".glb",g=n+f,p=s.listPrimitives(),d,y=s["gltf:mesh-hash"];if(y===void 0&&(m.info(`[${T}] \u0110ang t\u1EA1o hash cho mesh "${s.getName()}"`),y=ie(s),s["gltf:mesh-hash"]=y),y+=ie({lodLevel:a,guid:o,config:u.config}),u.useCache!==!1){d=`mesh_lod_${r}_${y}`;let $=xe(d),N=Fn(d);if($&&N)return m.info(`[${T}] LOD ${r} \u0111\u01B0\u1EE3c t\u1EA3i t\u1EEB b\u1ED9 nh\u1EDB \u0111\u1EC7m cho "${s.getName()}"`),si(g,$),{level:r,path:f,success:!0,cacheKey:d,content_hash:y,lodMeshInfo:N.meshInfo,density:N.density,densities:N.densities}}let x=new Un;bt(x,{source:{filename:t}});let h=x.createScene();x.createBuffer();let M=x.createNode();h.addChild(M),M.setName("LOD "+r+"_"+o),M.setTranslation([0,0,0]);let w=x.createMesh();w.setName((s.getName()||"Kh\xF4ng t\xEAn")+" LOD "+r),M.setMesh(w);let A=x.createMaterial(),I=s.getWeights();I&&w.setWeights(I);let L=[],v=new Map;for(let $ of p){let N=x.createPrimitive();w.addPrimitive(N),N.setName($.getName()),N.setMode($.getMode()),N.setMaterial(A);let U=$.getIndices();if(U){let R=x.createAccessor();R.setArray(U.getArray()),R.setType(U.getType()),R.setSparse(U.getSparse()),R.setNormalized(U.getNormalized()),N.setIndices(R)}let ce=$.listSemantics();for(let R=0;R<ce.length;R++){let W=$.getAttribute(ce[R]);if(W)if(v.has(W)){let B=v.get(W);N.setAttribute(ce[R],B)}else{let B=x.createAccessor();B.setArray(W.getArray()),B.setType(W.getType()),B.setSparse(W.getSparse()),B.setNormalized(W.getNormalized()),N.setAttribute(ce[R],B),v.set(W,B)}else m.warn(`[${T}] Thi\u1EBFu thu\u1ED9c t\xEDnh ${ce[R]} trong mesh LOD ${r}`)}let C=$.listTargets();for(let R of C){let W=x.createPrimitiveTarget(R.getName());N.addTarget(W);let B=R.listSemantics();for(let oe of B){let V=R.getAttribute(oe);if(V){let ee=x.createAccessor();ee.setArray(V.getArray()),ee.setType(V.getType()),ee.setSparse(V.getSparse()),ee.setNormalized(V.getNormalized()),W.setAttribute(oe,ee)}else console.error(`[${T}] Thi\u1EBFu thu\u1ED9c t\xEDnh target ${oe} trong mesh LOD ${r}`)}}let _=$.listExtensions();for(let R of _){let W=R.constructor,B=new W(x.getGraph());try{let oe=B.copy(R),V=R.extensionName;N.setExtension(V,oe)}catch(oe){m.error(`[${T}] Kh\xF4ng th\u1EC3 sao ch\xE9p extension ${R.extensionName} cho mesh LOD ${r} \u2192 ${oe}`)}}}let O=0;if((a.error!=null||a.ratio!=null)&&(a.error>0||a.ratio<1))for(let $ of w.listPrimitives()){let N=Jn(x,w,$,O++,a);L.push(N)}await Promise.all(L),L.length=0;let b=Ve(w);if(b.totalVertexCount<4)return m.error(`[${T}] mesh LOD ${r} c\xF3 \xEDt h\u01A1n 4 \u0111\u1EC9nh \u2192 b\u1ECF qua`),{level:r,path:f,success:!1,cacheKey:d,content_hash:y,lodMeshInfo:null,density:null,densities:null};let G=0,D=new Array(w.listPrimitives().length);w.listPrimitives().forEach(($,N)=>{let U=Je($);G=Math.max(G,U),D[N]=U});let F=x.createExtension(me);if(!F||!F.createMesh){m.error("Kh\xF4ng th\u1EC3 t\u1EA1o extension progressive");return}w.setExtension(Z,F.createMesh({guid:o}));let ne=en(e,f);if(ne){let N=x.createExtension(se).create(ne);m.info(`[${T}] Truy\u1EC1n \u0111\u1ECBnh d\u1EA1ng n\xE9n sang mesh LOD ${r} \u2192 ${JSON.stringify(ne)}`),x.getRoot().setExtension(se.EXTENSION_NAME,N)}await x.transform(Xn());let k=new rn;if(sn(k),m.info(`[${T}] Ghi mesh LOD ${r} v\xE0o "${f}"`),await k.write(g,x),d!=null){let $=ti(g),N=($.byteLength/1024/1024).toFixed(2);m.info(`[${T}] Th\xEAm LOD ${r} v\xE0o b\u1ED9 nh\u1EDB \u0111\u1EC7m (${N} MB) cho "${s.getName()}" v\u1EDBi key ${d}`),fe(d,$),Dn(d,{meshInfo:b,density:G,densities:D})}return{level:r,path:f,success:!0,lodMeshInfo:b,cacheKey:d,content_hash:y,density:G,densities:D}}async function Jn(t,e,n,r,s){let i={...Vs,overwrite:!0,cleanup:!1,tolerance:1e-11,...s},o={...Hs,...s,simplifier:qn};await tn(t,e,n,r,i,o)}function je(t){return t.includes("mesh_lod_")}function Zn(t){return t.includes("image_")}function ge(t){return je(t)||Zn(t)}function Yn(t,e,n){let s=(Date.now()-t.startTime)/1e3/60,i=`[GLTF LOD Pipeline] v${Y()} \u2014 \u0110\xE3 ho\xE0n t\u1EA5t qu\xE1 tr\xECnh n\xE9n "${n?.usecase}" cho ${t.totalFilesProcessed} file trong ${s.toFixed(1)} ph\xFAt; t\u1ED5ng dung l\u01B0\u1EE3ng ${t.totalFileSizeInMBBefore.toFixed(1)} MB \u2192 ${t.totalFileSizeInMB.toFixed(1)} MB, t\u1ED5ng b\u1ED9 nh\u1EDB GPU (VRAM): ${t.totalGPUMemoryInMB.toFixed(1)} MB`;console.log(`info: ${i}`)}var Et=class t{size;asset;json;nodes;materials;meshes;textures;animations;constructor(e,n,r){let s=e.getRoot(),i=s.getAsset();this.asset={generator:i.generator,version:i.version,copyright:i.copyright,extras:i.extras};let o=null;try{o=bi(e)}catch{}this.size=r,this.json=_i(n),this.nodes=s.listNodes().length,this.materials=s.listMaterials().length,this.meshes=Si(e,o),this.textures=wi(e,o),this.animations=Ii(e)}static combine(e,n){let r=new t(new xi,null,0),s=!1;for(let i of e){if(n!==void 0){let o=i.filename;if(o){if(ge(o)){if(n==="main")continue}else if(n==="lods")continue}}s=!0,r.size+=i.size,r.json.addFrom(i.json),r.nodes+=i.nodes,r.materials+=i.materials,r.meshes.addFrom(i.meshes),r.textures.addFrom(i.textures),r.animations.addFrom(i.animations)}return s?r:null}},an=class extends Et{filename;isLOD;constructor(e,n,r){super(n,r,Ti(e).size),this.filename=Zt(e),this.isLOD=ge(this.filename)}},cn=class{count=0;primitives=0;vertices=0;triangles=0;memory=0;formats=[];errors=[];warnings=[];addFrom(e){this.count+=e.count,this.primitives+=e.primitives,this.vertices+=e.vertices,this.triangles+=e.triangles,this.memory+=e.memory,this.formats=Array.from(new Set([...this.formats,...e.formats])),this.errors=Array.from(new Set([...this.errors||[],...e.errors||[]])),this.warnings=Array.from(new Set([...this.warnings||[],...e.warnings||[]]))}},un=class{count=0;memory=0;gpu_memory=0;formats=[];errors=[];warnings=[];addFrom(e){this.count+=e.count,this.memory+=e.memory,this.gpu_memory+=e.gpu_memory,this.formats=Array.from(new Set([...this.formats,...e.formats])),this.errors=Array.from(new Set([...this.errors||[],...e.errors||[]])),this.warnings=Array.from(new Set([...this.warnings||[],...e.warnings||[]]))}},mn=class{count=0;size=0;channels=0;addFrom(e){this.count+=e.count,this.size+=e.size,this.channels+=e.channels}},ln=class{size=0;addFrom(e){this.size+=e.size}};function Qn(t,e,n){return new an(t,e,n)}function er(t,e){if(e===void 0)return console.error("Kh\xF4ng c\xF3 \u0111\u01B0\u1EDDng d\u1EABn \u0111\u1EA7u ra (output path) n\xE0o \u0111\u01B0\u1EE3c cung c\u1EA5p cho file stats"),null;let n={sum:Et.combine(t),files:t},r=JSON.stringify(n);return Ei(e,r),r}function Si(t,e){let n=t.getRoot(),r=n.listMeshes(),s=new cn;s.count=r.length,s.errors=e?.meshes?.errors||[],s.warnings=e?.meshes?.warnings||[];for(let o of r){let a=o.listPrimitives();s.primitives+=a.length;for(let u of a){let m=u.getAttribute("POSITION"),c=u.getIndices();m&&(s.vertices+=m.getCount()),c?s.triangles+=c.getCount()/3:m&&(s.triangles+=m.getCount()/3);let l=u.listSemantics();for(let f of l){let g=u.getAttribute(f);if(g){let p=g.getByteLength();s.memory+=p}}}}let i=n.listExtensionsUsed();for(let o of i)o.extensionName.startsWith("EXT_meshopt_compression")?s.formats.push("meshopt"):o.extensionName.startsWith("KHR_draco_mesh_compression")&&s.formats.push("draco");return s.formats=Array.from(new Set(s.formats)),s}function wi(t,e){let r=t.getRoot().listTextures(),s=new un;s.count=r.length,s.formats=r.map(i=>i.getMimeType()||"unknown"),s.errors=e?.textures?.errors||[],s.warnings=e?.textures?.warnings||[],s.gpu_memory=0,s.memory=0;for(let i of r){let o=i.getImage(),a=i.getMimeType();if(o&&a){try{s.gpu_memory+=yi.getVRAMByteLength(o,a)}catch{}s.memory+=o.byteLength}}return s.formats=Array.from(new Set(s.formats)),s}function Ii(t){let e=t.getRoot().listAnimations(),n=new mn;n.count=e.length,n.channels=0,n.size=0;for(let r of e){let s=r.listChannels();n.channels+=s.length;for(let i of s){let o=i.getSampler();if(!o)continue;let a=o.getInput(),u=o.getOutput();a&&(n.size+=a.getArray()?.byteLength??0),u&&(n.size+=u.getArray()?.byteLength??0)}}return n}function _i(t){let e=new ln;return t&&t.json&&(e.size=JSON.stringify(t.json).length),e}import{ImageUtils as Mi}from"@gltf-transform/core";function et(t,e,n){let r=Mi.getMimeType(e);if(r!=null&&r!==t){let s=`Image reported wrong mime type "${t}" but is actually "${r}"`;return n.warn(s),{error:!0,message:s,mimeType:r}}else r===null&&n.debug(`Could not validate image type for "${t}"`);return null}var tr="Gltf Build Pipeline";function bt(t,e){let r=t.getRoot().getAsset();if(r){r.extras=Ni(r.extras),e&&(r.extras=Object.assign(r.extras||{},e));let s=Y();r.generator=tr,s?.length>0&&(r.generator+=" "+s)}}function Tt(){return Li("gltf_asset_transform",t=>{bt(t)})}function Ni(t){if(t||(t={}),typeof t=="object"&&!t.gltf){let e=tr,n=Y();n?.length>0&&(e+=" "+n);let r=new Date().toISOString();t.gltf={generator:e,created:r,updated:r,revision:0}}else{let e=t.gltf;e&&(e.updated=new Date().toISOString(),e.revision=e.revision+1)}return t}import Pi from"micromatch";import Di from"os";import tt from"semver";import Fi from"tmp";import{TextureChannel as ki}from"@gltf-transform/core";import{TextureResizeFilter as Gi,getTextureColorSpace as ji}from"@gltf-transform/functions";import{spawn as Ri}from"child_process";import Lm from"command-exists";var nr={nocase:!0,contains:!0},St=Ri;var wt=Ai;async function Ai(t){let e="";if(t.stdout)for await(let s of t.stdout)e+=s;let n="";if(t.stderr)for await(let s of t.stderr)n+=s;return[await new Promise(s=>{t.on("close",s)}),e,n]}function fn(t,e=2){if(t===0)return"0 Bytes";let n=1e3,r=e<0?0:e,s=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],i=Math.floor(Math.log(t)/Math.log(n));return parseFloat((t/Math.pow(n,i)).toFixed(r))+" "+s[i]}import vi from"os";import{TextureResizeFilter as Oi}from"@gltf-transform/functions";var $i=vi.cpus().length||1;var Ci={BOX:"box",TENT:"tent",BELL:"bell",BSPLINE:"b-spline",MITCHELL:"mitchell",LANCZOS3:"lanczos3",LANCZOS4:"lanczos4",LANCZOS6:"lanczos6",LANCZOS12:"lanczos12",BLACKMAN:"blackman",KAISER:"kaiser",GAUSSIAN:"gaussian",CATMULLROM:"catmullrom",QUADRATIC_INTERP:"quadratic_interp",QUADRATIC_APPROX:"quadratic_approx",QUADRATIC_MIX:"quadratic_mix"},rr={resizeFilter:Oi.LANCZOS3,filter:Ci.LANCZOS4,filterScale:1,pattern:null,slots:null,jobs:2*$i,cleanup:!0,limitInputPixels:!0},_e={quality:128,compression:1,rdo:!0,rdoThreshold:1.25,maxSelectors:0,maxEndpoints:0,...rr},$e={level:2,rdo:!1,rdoLambda:1,rdoDictionarySize:32768,rdoBlockScale:10,rdoStdDev:18,rdoMultithreading:!0,zstd:18,...rr};Fi.setGracefulCleanup();var gn=Di.cpus().length||1,It="4.3.0",{R:sr,G:ir,A:Bi}=ki,Wi={BOX:"box",TENT:"tent",BELL:"bell",BSPLINE:"b-spline",MITCHELL:"mitchell",LANCZOS3:"lanczos3",LANCZOS4:"lanczos4",LANCZOS6:"lanczos6",LANCZOS12:"lanczos12",BLACKMAN:"blackman",KAISER:"kaiser",GAUSSIAN:"gaussian",CATMULLROM:"catmullrom",QUADRATIC_INTERP:"quadratic_interp",QUADRATIC_APPROX:"quadratic_approx",QUADRATIC_MIX:"quadratic_mix"},or={resizeFilter:Gi.LANCZOS3,filter:Wi.LANCZOS4,filterScale:1,pattern:null,slots:null,jobs:2*gn,cleanup:!0,limitInputPixels:!0},pe={ETC1S:"etc1s",UASTC:"uastc"};function cr(t,e,n,r,s,i,o){let a=ji(t),u=["--generate-mipmap"];o.filter!==or.filter&&u.push("--mipmap-filter",o.filter),o.filterScale!==or.filterScale&&u.push("--mipmap-filter-scale",o.filterScale);let m=e.find(c=>Pi.isMatch(c,"*normal*",nr));if(o.mode===pe.UASTC){let c=o;u.push("--encode","uastc"),u.push("--uastc-quality",c.level),c.rdo&&!m&&(u.push("--uastc-rdo"),c.rdoLambda!==$e.rdoLambda&&u.push("--uastc-rdo-l",c.rdoLambda),c.rdoDictionarySize!==$e.rdoDictionarySize&&u.push("--uastc-rdo-d",c.rdoDictionarySize),c.rdoBlockScale!==$e.rdoBlockScale&&u.push("--uastc-rdo-b",c.rdoBlockScale),c.rdoStdDev!==$e.rdoStdDev&&u.push("--uastc-rdo-s",c.rdoStdDev),c.rdoMultithreading||u.push("--uastc-rdo-m")),c.zstd&&c.zstd>0&&u.push("--zstd",c.zstd)}else{let c=o;u.push("--encode","basis-lz"),c.quality!==_e.quality&&u.push("--qlevel",c.quality),c.compression!==_e.compression&&u.push("--clevel",c.compression),c.rdo&&!m?(c.maxEndpoints!==_e.maxEndpoints&&u.push("--max-endpoints",c.maxEndpoints),c.maxSelectors!==_e.maxSelectors&&u.push("--max-selectors",c.maxSelectors),c.rdoThreshold!==_e.rdoThreshold&&(u.push("--endpoint-rdo-threshold",c.rdoThreshold),u.push("--selector-rdo-threshold",c.rdoThreshold))):u.push("--no-endpoint-rdo","--no-selector-rdo")}if(a==="srgb"?u.push("--assign-oetf","srgb","--assign-primaries","bt709"):a==="srgb-linear"?u.push("--assign-oetf","linear","--assign-primaries","bt709"):e.length&&!a&&u.push("--assign-oetf","linear","--assign-primaries","none"),n===sr?u.push("--format","R8_UNORM"):n===ir||n===(sr|ir)?u.push("--format","R8G8_UNORM"):n&Bi?u.push("--format",a==="srgb"?"R8G8B8A8_SRGB":"R8G8B8A8_UNORM"):u.push("--format",a==="srgb"?"R8G8B8_SRGB":"R8G8B8_UNORM"),o.jobs&&o.jobs>1&&i>1){let c=Math.max(2,Math.min(gn,Math.round(3*gn/i)));u.push("--threads",c)}return u}var ar=!1;async function ur(t,e){let n=!1,r=St("toktx",["--version"],{env:e});r.on("error",u=>{u.message.endsWith("ENOENT")&&(n=!0)});let[s,i,o]=await wt(r);if(n)return console.log('WARN: Unable to find "toktx". Confirm KTX-Software is installed from: https://github.com/KhronosGroup/KTX-Software.'),null;let a=(i||o).replace(/toktx\s+/,"").replace(/~\d+/,"").trim();if(s!==0||!tt.valid(tt.clean(a)))throw new Error(`Unable to find "toktx" version. Confirm KTX-Software is installed from:
10
10
 
11
- https://github.com/KhronosGroup/KTX-Software.`);return ot.lt(ot.clean(a),Nt)?(t.warn(`toktx: Expected KTX-Software >= v${Nt}, found ${a}.`),null):(Er||t.debug(`toktx: Found KTX-Software ${a}.`),Er=!0,ot.clean(a))}import pi from"sharp";import{BufferUtils as di,HTTPUtils as hi}from"@gltf-transform/core";import{EXTTextureWebP as xi}from"@gltf-transform/extensions";var Ot=class{options;logger;compressed=0;constructor(e){this.options=e}async prepare(e){this.compressed=0,this.logger=e.getLogger()}async process(e,n,r,s){let o=n.getSize();if(!o)return this.logger.warn(`webp:texture[${e}] ${n.getName()}: Could not determine size. Skipping.`),!1;let i=!1;(o[0]<64||o[1]<64)&&(i=!0);let a={lossless:i,...r};r.quality!==void 0&&r.quality>=0&&(a.quality=Math.round(r.quality*100)),a.quality!==void 0&&a.quality<0&&(a.quality=void 0),this.logger.info(`webp:texture[${e}] ${n.getName()}: Slots \u2192 [${r.slot}] with quality '${a.quality===void 0?"default":a.quality}'`);let u=n.getImage();if(!u)return this.logger.warn(`webp:texture[${e}] ${n.getName()}: No image data found.`),!1;let m=await pi(u).toFormat("webp",a).toBuffer();return n.setMimeType("image/webp").setImage(di.toView(new Uint8Array(m))).setURI(hi.basename(n.getURI())+".webp"),this.compressed+=1,!0}async finalize(e){this.compressed>0&&e.createExtension(xi).setRequired(!0)}};import{ImageUtils as Wi}from"@gltf-transform/core";import{createTransform as zi,listTextureSlots as Ui}from"@gltf-transform/functions";import{dirname as vr}from"path";import{existsSync as Xi,rmSync as qi}from"fs";import{BufferUtils as yi,FileUtils as bi,ImageUtils as Ir,uuid as _r}from"@gltf-transform/core";import{listTextureSlots as Ti,getTextureChannelMask as Ei,fitPowerOfTwo as Si,TextureResizeFilter as wi}from"@gltf-transform/functions";import{KHRTextureBasisu as Ii}from"@gltf-transform/extensions";import{existsSync as vt,mkdirSync as _i}from"fs";import Mr from"fs/promises";import Mi from"os";import Ai from"tmp";import Li from"p-limit";import Ni from"sharp";var Oi=Mi.cpus().length||1;var Rt=class{limit;basisuExtension;version;cacheDirectory;tmpPathBase;document;env;numTextures=0;_prepareFailed=!1;constructor(e){this.limit=Li(e.jobs||Oi);let n=process.platform==="win32";if(this.env={PATH:process.env.PATH??""},e?.toktxPath?.length&&this.env&&(this.env.PATH=`${e.toktxPath};${this.env.PATH}`),process.env.GLTF_TOKTX?.length&&(vt(process.env.GLTF_TOKTX)?(e.debug&&console.log('INFO: \u0110ang th\xEAm GLTF_TOKTX v\xE0o bi\u1EBFn m\xF4i tr\u01B0\u1EDDng PATH: "'+process.env.GLTF_TOKTX+'"'),this.env.PATH=`${process.env.GLTF_TOKTX};${this.env.PATH}`):e.debug&&console.log('WARN: GLTF_TOKTX \u0111\u01B0\u1EE3c \u0111\u1EB7t th\xE0nh m\u1ED9t \u0111\u01B0\u1EDDng d\u1EABn kh\xF4ng t\u1ED3n t\u1EA1i: "'+process.env.GLTF_TOKTX+'"')),n){let s="C:\\Program Files\\KTX-Software\\bin";vt(s)&&(this.env.PATH=`${this.env.PATH};${s}`)}else{let s="/usr/local/bin";vt(s)&&(this.env.PATH=`${this.env.PATH}:${s}`)}n&&process.env.Path?.length&&(this.env.PATH=`${this.env.PATH};${process.env.Path}`);let r=this.env.PATH.split(";").filter(s=>s.toLocaleLowerCase().includes("ktx"));e.debug&&console.log(`INFO: T\xECm th\u1EA5y c\xE1c \u0111\u01B0\u1EDDng d\u1EABn sau c\xF3 ch\u1EE9a ktx:
11
+ https://github.com/KhronosGroup/KTX-Software.`);return tt.lt(tt.clean(a),It)?(t.warn(`toktx: Expected KTX-Software >= v${It}, found ${a}.`),null):(ar||t.debug(`toktx: Found KTX-Software ${a}.`),ar=!0,tt.clean(a))}import zi from"sharp";import{BufferUtils as Ui,HTTPUtils as Xi}from"@gltf-transform/core";import{EXTTextureWebP as qi}from"@gltf-transform/extensions";var _t=class{options;logger;compressed=0;constructor(e){this.options=e}async prepare(e){this.compressed=0,this.logger=e.getLogger()}async process(e,n,r,s){let i=n.getSize();if(!i)return this.logger.warn(`webp:texture[${e}] ${n.getName()}: Could not determine size. Skipping.`),!1;let o=!1;(i[0]<64||i[1]<64)&&(o=!0);let a={lossless:o,...r};r.quality!==void 0&&r.quality>=0&&(a.quality=Math.round(r.quality*100)),a.quality!==void 0&&a.quality<0&&(a.quality=void 0),this.logger.info(`webp:texture[${e}] ${n.getName()}: Slots \u2192 [${r.slot}] with quality '${a.quality===void 0?"default":a.quality}'`);let u=n.getImage();if(!u)return this.logger.warn(`webp:texture[${e}] ${n.getName()}: No image data found.`),!1;let m=await zi(u).toFormat("webp",a).toBuffer();return n.setMimeType("image/webp").setImage(Ui.toView(new Uint8Array(m))).setURI(Xi.basename(n.getURI())+".webp"),this.compressed+=1,!0}async finalize(e){this.compressed>0&&e.createExtension(qi).setRequired(!0)}};import{ImageUtils as yo}from"@gltf-transform/core";import{createTransform as bo,listTextureSlots as To}from"@gltf-transform/functions";import{dirname as xr}from"path";import{existsSync as Eo,rmSync as So}from"fs";import{BufferUtils as Ki,FileUtils as Hi,ImageUtils as mr,uuid as lr}from"@gltf-transform/core";import{listTextureSlots as Vi,getTextureChannelMask as Ji,fitPowerOfTwo as Zi,TextureResizeFilter as Yi}from"@gltf-transform/functions";import{KHRTextureBasisu as Qi}from"@gltf-transform/extensions";import{existsSync as Mt,mkdirSync as eo}from"fs";import fr from"fs/promises";import to from"os";import no from"tmp";import ro from"p-limit";import so from"sharp";var io=to.cpus().length||1;var Lt=class{limit;basisuExtension;version;cacheDirectory;tmpPathBase;document;env;numTextures=0;_prepareFailed=!1;constructor(e){this.limit=ro(e.jobs||io);let n=process.platform==="win32";if(this.env={PATH:process.env.PATH??""},e?.toktxPath?.length&&this.env&&(this.env.PATH=`${e.toktxPath};${this.env.PATH}`),process.env.GLTF_TOKTX?.length&&(Mt(process.env.GLTF_TOKTX)?(e.debug&&console.log('INFO: \u0110ang th\xEAm GLTF_TOKTX v\xE0o bi\u1EBFn m\xF4i tr\u01B0\u1EDDng PATH: "'+process.env.GLTF_TOKTX+'"'),this.env.PATH=`${process.env.GLTF_TOKTX};${this.env.PATH}`):e.debug&&console.log('WARN: GLTF_TOKTX \u0111\u01B0\u1EE3c \u0111\u1EB7t th\xE0nh m\u1ED9t \u0111\u01B0\u1EDDng d\u1EABn kh\xF4ng t\u1ED3n t\u1EA1i: "'+process.env.GLTF_TOKTX+'"')),n){let s="C:\\Program Files\\KTX-Software\\bin";Mt(s)&&(this.env.PATH=`${this.env.PATH};${s}`)}else{let s="/usr/local/bin";Mt(s)&&(this.env.PATH=`${this.env.PATH}:${s}`)}n&&process.env.Path?.length&&(this.env.PATH=`${this.env.PATH};${process.env.Path}`);let r=this.env.PATH.split(";").filter(s=>s.toLocaleLowerCase().includes("ktx"));e.debug&&console.log(`INFO: T\xECm th\u1EA5y c\xE1c \u0111\u01B0\u1EDDng d\u1EABn sau c\xF3 ch\u1EE9a ktx:
12
12
  `+r.join(`
13
- `))}async prepare(e){try{this.document=e;let n=e.getLogger();if(this.version=await wr(n,this.env),this.version===null)return n.warn(`WARN: Kh\xF4ng t\xECm th\u1EA5y toktx, b\u1ECF qua n\xE9n texture KTX2. Vui l\xF2ng c\xE0i \u0111\u1EB7t KTX-Software >= ${Nt}. B\u1EA1n c\xF3 th\u1EC3 \u0111\u1EB7t bi\u1EBFn m\xF4i tr\u01B0\u1EDDng 'GLTF_TOKTX' \u0111\u1EC3 ch\u1EC9 \u0111\u1ECBnh th\u01B0 m\u1EE5c c\xE0i \u0111\u1EB7t toktx (path/to/bin)`),this._prepareFailed=!0,!1;this.basisuExtension=e.createExtension(Ii).setRequired(!0);let r=`${Ai.tmpdir}/gltf-transform/${_r()}`;this.cacheDirectory=r,_i(r,{recursive:!0}),this.tmpPathBase=r+"/"+_r(),this.numTextures=e.getRoot().listTextures().length}catch(n){return console.error("ERR: Chu\u1EA9n b\u1ECB transform toktx th\u1EA5t b\u1EA1i: "+n),this._prepareFailed=!0,!1}return!0}async process(e,n,r,s){let o=async()=>{if(this._prepareFailed||!this.document)return!1;let a=this.document.getLogger(),u=Ti(n),m=Ei(n),c=`toktx:texture[${e}] ${n.getName()}`,l=n.getMimeType();if(l==="image/ktx2")return a.debug(`${c}: B\u1ECF qua, \u0111\xE3 l\xE0 \u0111\u1ECBnh d\u1EA1ng KTX2.`),!0;if(l!=="image/png"&&l!=="image/jpeg")return a.warn(`${c}: B\u1ECF qua, lo\u1EA1i texture kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 "${n.getMimeType()}".`),!1;u.length>0?a.debug(`${c}: C\xE1c slot (khe v\u1EADt li\u1EC7u) \u2192 [${u.join(", ")}]`):a.debug(`${c}: Kh\xF4ng c\xF3 slot n\xE0o, gi\u1EA3 \u0111\u1ECBnh \u0111\xE2y l\xE0 texture m\u1EB7c \u0111\u1ECBnh.`);let f=n.getImage(),g=n.getURI()?bi.extension(n.getURI()):Ir.mimeTypeToExtension(n.getMimeType()),p=n.getSize(),h=f?f.byteLength:null;if(!f||!p||!h)return a.warn(`${c}: B\u1ECF qua, kh\xF4ng th\u1EC3 \u0111\u1ECDc d\u1EEF li\u1EC7u texture.`),!1;if(!jt(p[0])||!jt(p[1])){let $=Ni(f,{limitInputPixels:!0}).toFormat("png"),P=Ir.getSize(f,l),F=Si(P,"nearest-pot");F[0]=Bt(F[0]),F[1]=Bt(F[1]),a.warn(`${c}: \u0110ang thay \u0111\u1ED5i k\xEDch th\u01B0\u1EDBc ${P.join("x")} \u2192 ${F.join("x")}px`),$.resize(F[0],F[1],{fit:"fill",kernel:wi.LANCZOS3});let Z=await $.toBuffer();f=yi.toView(new Uint8Array(Z)),g="png",l="image/png"}let y=this.tmpPathBase+"_"+e,x=y+"."+g,d=y+".ktx2",E=Buffer.from(f);await Mr.writeFile(x,E);let T=pe.ETC1S,L=128,_=1;if(r)if(r.mode==="auto"){let b=u.includes("normalTexture")||u.includes("metallicRoughnessTexture");T=b?pe.UASTC:pe.ETC1S,L=b?255:128,_=b?4:1}else T=r.mode==="ETC1S"?pe.ETC1S:pe.UASTC;else if(u){let b=u.includes("normalTexture"),$=u.includes("metallicRoughnessTexture"),P=b||$;T=pe.ETC1S,L=P?255:128,_=P?4:1,s.config?.usecase==="product"?(P&&(T=pe.UASTC),L=255,_=4):(u.includes("lightmapTexture")||ue(n))&&(L=255,_=4)}let A=T===pe.ETC1S?_e:$e,O=["create",...Sr(n,u,m,p,a,this.numTextures,{...A,mode:T,quality:L,compression:_}).map(String),x,d];a.debug(`${c}: \u0110ang ch\u1EA1y (Spawning) CLI \u2192 ktx ${O.join(" ")}`);try{let[b,$,P]=await Lt(At("ktx",O,{env:this.env}));if(b!==0)a.error(`${c}: ktx create th\u1EA5t b\u1EA1i (m\xE3 tho\xE1t ${b}) \u2192
13
+ `))}async prepare(e){try{this.document=e;let n=e.getLogger();if(this.version=await ur(n,this.env),this.version===null)return n.warn(`WARN: Kh\xF4ng t\xECm th\u1EA5y toktx, b\u1ECF qua n\xE9n texture KTX2. Vui l\xF2ng c\xE0i \u0111\u1EB7t KTX-Software >= ${It}. B\u1EA1n c\xF3 th\u1EC3 \u0111\u1EB7t bi\u1EBFn m\xF4i tr\u01B0\u1EDDng 'GLTF_TOKTX' \u0111\u1EC3 ch\u1EC9 \u0111\u1ECBnh th\u01B0 m\u1EE5c c\xE0i \u0111\u1EB7t toktx (path/to/bin)`),this._prepareFailed=!0,!1;this.basisuExtension=e.createExtension(Qi).setRequired(!0);let r=`${no.tmpdir}/gltf-transform/${lr()}`;this.cacheDirectory=r,eo(r,{recursive:!0}),this.tmpPathBase=r+"/"+lr(),this.numTextures=e.getRoot().listTextures().length}catch(n){return console.error("ERR: Chu\u1EA9n b\u1ECB transform toktx th\u1EA5t b\u1EA1i: "+n),this._prepareFailed=!0,!1}return!0}async process(e,n,r,s){let i=async()=>{if(this._prepareFailed||!this.document)return!1;let a=this.document.getLogger(),u=Vi(n),m=Ji(n),c=`toktx:texture[${e}] ${n.getName()}`,l=n.getMimeType();if(l==="image/ktx2")return a.debug(`${c}: B\u1ECF qua, \u0111\xE3 l\xE0 \u0111\u1ECBnh d\u1EA1ng KTX2.`),!0;if(l!=="image/png"&&l!=="image/jpeg")return a.warn(`${c}: B\u1ECF qua, lo\u1EA1i texture kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3 "${n.getMimeType()}".`),!1;u.length>0?a.debug(`${c}: C\xE1c slot (khe v\u1EADt li\u1EC7u) \u2192 [${u.join(", ")}]`):a.debug(`${c}: Kh\xF4ng c\xF3 slot n\xE0o, gi\u1EA3 \u0111\u1ECBnh \u0111\xE2y l\xE0 texture m\u1EB7c \u0111\u1ECBnh.`);let f=n.getImage(),g=n.getURI()?Hi.extension(n.getURI()):mr.mimeTypeToExtension(n.getMimeType()),p=n.getSize(),d=f?f.byteLength:null;if(!f||!p||!d)return a.warn(`${c}: B\u1ECF qua, kh\xF4ng th\u1EC3 \u0111\u1ECDc d\u1EEF li\u1EC7u texture.`),!1;if(!Pt(p[0])||!Pt(p[1])){let G=so(f,{limitInputPixels:!0}).toFormat("png"),D=mr.getSize(f,l),F=Zi(D,"nearest-pot");F[0]=Dt(F[0]),F[1]=Dt(F[1]),a.warn(`${c}: \u0110ang thay \u0111\u1ED5i k\xEDch th\u01B0\u1EDBc ${D.join("x")} \u2192 ${F.join("x")}px`),G.resize(F[0],F[1],{fit:"fill",kernel:Yi.LANCZOS3});let ne=await G.toBuffer();f=Ki.toView(new Uint8Array(ne)),g="png",l="image/png"}let y=this.tmpPathBase+"_"+e,x=y+"."+g,h=y+".ktx2",M=Buffer.from(f);await fr.writeFile(x,M);let w=pe.ETC1S,A=128,I=1;if(r)if(r.mode==="auto"){let b=u.includes("normalTexture")||u.includes("metallicRoughnessTexture");w=b?pe.UASTC:pe.ETC1S,A=b?255:128,I=b?4:1}else w=r.mode==="ETC1S"?pe.ETC1S:pe.UASTC;else if(u){let b=u.includes("normalTexture"),G=u.includes("metallicRoughnessTexture"),D=b||G;w=pe.ETC1S,A=D?255:128,I=D?4:1,s.config?.usecase==="product"?(D&&(w=pe.UASTC),A=255,I=4):(u.includes("lightmapTexture")||ue(n))&&(A=255,I=4)}let L=w===pe.ETC1S?_e:$e,O=["create",...cr(n,u,m,p,a,this.numTextures,{...L,mode:w,quality:A,compression:I}).map(String),x,h];a.debug(`${c}: \u0110ang ch\u1EA1y (Spawning) CLI \u2192 ktx ${O.join(" ")}`);try{let[b,G,D]=await wt(St("ktx",O,{env:this.env}));if(b!==0)a.error(`${c}: ktx create th\u1EA5t b\u1EA1i (m\xE3 tho\xE1t ${b}) \u2192
14
14
 
15
- ${P.toString()}`);else if(!vt(d))a.error(`${c}: ktx create b\xE1o c\xE1o th\xE0nh c\xF4ng nh\u01B0ng thi\u1EBFu file \u0111\u1EA7u ra: ${d}
15
+ ${D.toString()}`);else if(!Mt(h))a.error(`${c}: ktx create b\xE1o c\xE1o th\xE0nh c\xF4ng nh\u01B0ng thi\u1EBFu file \u0111\u1EA7u ra: ${h}
16
16
 
17
- stdout: ${$}
18
- stderr: ${P}`);else{let F=await Mr.readFile(d);if(n.setImage(new Uint8Array(F)).setMimeType("image/ktx2"),n.getURI()){let G=n.getURI(),C=Cn(G,"ktx2");n.setURI(C)}let Z=n.getImage().byteLength;return a.debug(`${c}: ${Tn(h)} \u2192 ${Tn(Z)}`),!0}}catch(b){a.error(`${c}: Ch\u1EA1y l\u1EC7nh toktx th\u1EA5t b\u1EA1i \u2192 ${b}`)}return!1};return this.limit(o)}async finalize(e){e.getRoot().listTextures().some(r=>r.getMimeType()==="image/ktx2")||this.basisuExtension?.dispose(),this.cacheDirectory&&await dt(this.cacheDirectory)}};import{existsSync as We,readFileSync as Ar,writeFileSync as Lr,mkdirSync as vi,rmSync as Ri,chmodSync as $i}from"fs";import{join as J,dirname as Or}from"path";import{fileURLToPath as Pi,pathToFileURL as Ci}from"url";import{execFile as Di}from"child_process";import{v4 as Nr}from"uuid";import{createHash as Fi}from"crypto";import ki from"tmp";function Gi(){let t=Or(Pi(import.meta.url)),e=[J(t,"tools","pmrem"),J(t,"..","tools","pmrem"),J(t,"..","..","tools","pmrem"),J(process.cwd(),"tools","pmrem")];for(let n of e)if(We(n))return n;throw new Error(`Kh\xF4ng t\xECm th\u1EA5y tools/pmrem.
17
+ stdout: ${G}
18
+ stderr: ${D}`);else{let F=await fr.readFile(h);if(n.setImage(new Uint8Array(F)).setMimeType("image/ktx2"),n.getURI()){let k=n.getURI(),$=Ln(k,"ktx2");n.setURI($)}let ne=n.getImage().byteLength;return a.debug(`${c}: ${fn(d)} \u2192 ${fn(ne)}`),!0}}catch(b){a.error(`${c}: Ch\u1EA1y l\u1EC7nh toktx th\u1EA5t b\u1EA1i \u2192 ${b}`)}return!1};return this.limit(i)}async finalize(e){e.getRoot().listTextures().some(r=>r.getMimeType()==="image/ktx2")||this.basisuExtension?.dispose(),this.cacheDirectory&&await lt(this.cacheDirectory)}};import{existsSync as Be,readFileSync as gr,writeFileSync as pr,mkdirSync as oo,rmSync as ao,chmodSync as co}from"fs";import{join as J,dirname as dr}from"path";import{fileURLToPath as uo,pathToFileURL as mo}from"url";import{execFile as lo}from"child_process";import{v4 as hr}from"uuid";import{createHash as fo}from"crypto";import go from"tmp";function po(){let t=dr(uo(import.meta.url)),e=[J(t,"tools","pmrem"),J(t,"..","tools","pmrem"),J(t,"..","..","tools","pmrem"),J(process.cwd(),"tools","pmrem")];for(let n of e)if(Be(n))return n;throw new Error(`Kh\xF4ng t\xECm th\u1EA5y tools/pmrem.
19
19
  \u0110\xE3 th\u1EED:
20
20
  ${e.join(`
21
- `)}`)}function ji(t){let e=process.platform,n=J(t,"basis");return e==="win32"?J(n,"win","basisu.exe"):e==="darwin"?J(n,"osx","basisu"):J(n,"linux","basisu")}function Bi(t,e,n,r,s){return new Promise((o,i)=>{let a=[];a.push(r==="hdr6x6"?"-hdr_6x6":"-hdr_4x4"),s&&a.push("-mipmap"),a.push("-file",e,"-output_file",n,"-y_flip"),Di(t,a,{windowsHide:!0,encoding:"utf8"},(u,m,c)=>{if(u){let l=[c,m,u.message].filter(Boolean).join(`
22
- `);i(new Error(`basisu th\u1EA5t b\u1EA1i (m\xE3 tho\xE1t ${u.code}):
23
- ${l}`));return}o()})})}var $t=class{wasmModule=null;pmremDir="";basisuExe="";tmpDir="";processed=0;available=!1;logger;convertedTextures=[];processingPromises=new Map;async prepare(e){this.logger=e.getLogger(),this.processed=0,this.pmremDir=Gi();let n=J(this.pmremDir,"pkg","pmrem_wasm.js"),r=J(this.pmremDir,"pkg","pmrem_wasm_bg.wasm");if(!We(n)||!We(r))return this.logger.warn("pmrem: Kh\xF4ng t\xECm th\u1EA5y WASM \u2014 c\xE1c texture EXR s\u1EBD kh\xF4ng \u0111\u01B0\u1EE3c x\u1EED l\xFD"),re(!1,"Thi\u1EBFu c\xE1c file pmrem WASM. Vui l\xF2ng ch\u1EA1y `npm run build:pmrem` \u0111\u1EC3 build module WASM trong tools/pmrem/."),!1;if(this.basisuExe=ji(this.pmremDir),!We(this.basisuExe))return this.logger.warn(`pmrem: Kh\xF4ng t\xECm th\u1EA5y file ch\u1EA1y basisu t\u1EA1i ${this.basisuExe} \u2014 c\xE1c texture EXR s\u1EBD kh\xF4ng \u0111\u01B0\u1EE3c x\u1EED l\xFD`),re(!1,`Thi\u1EBFu file th\u1EF1c thi basisu cho n\u1EC1n t\u1EA3ng ${process.platform}. Vui l\xF2ng ch\u1EA1y \`npm run build:pmrem\` \u0111\u1EC3 build binary trong tools/pmrem/.`),!1;if(process.platform!=="win32")try{$i(this.basisuExe,493)}catch{}try{let s=await import(Ci(n).href),o=Ar(r);await s.default({module_or_path:o}),this.wasmModule=s}catch(s){return this.logger.warn(`pmrem: N\u1EA1p WASM th\u1EA5t b\u1EA1i \u2014 ${s.message}`),re(!1,`N\u1EA1p pmrem WASM module th\u1EA5t b\u1EA1i: ${s.message}`),!1}return this.tmpDir=J(ki.tmpdir,"gltf-pmrem",Nr()),vi(this.tmpDir,{recursive:!0}),this.available=!0,this.logger.debug("pmrem: \u0110\xE3 s\u1EB5n s\xE0ng (WASM + basisu \u0111\xE3 \u0111\u01B0\u1EE3c n\u1EA1p)"),!0}async process(e,n,r,s){if(!this.available||n.getMimeType()!=="image/exr")return!1;let o=n.getImage();if(!o)return!1;let i=n.getName()||`texture_${e}`,a=!!n.getURI(),u=new Uint8Array(o.buffer,o.byteOffset,o.byteLength),c=`pmrem-${Fi("md5").update(u).digest("hex")}`,l=this.processingPromises.has(c),f=await this.getOrProcessExr(c,u,e,i,s.useCache),g=n.getExtension("EXT_texture_exr");if(g&&(n.setExtension("EXT_texture_exr",null),g.dispose()),n.setMimeType("image/ktx2"),a){let p=n.getURI(),h=p.replace(/\.exr$/i,".pmrem.ktx2"),y=h!==p?h:p+".pmrem.ktx2",x=Or(s.outfile);Lr(J(x,y),f);let d=J(x,p);We(d)&&Ri(d),n.setURI(y),n.setName(y),n.setImage(null),this.logger.debug(`GLTF_pmrem[${e}] ${i}: external (b\xEAn ngo\xE0i) \u2192 ${y}`)}else n.setImage(new Uint8Array(f));if(l)this.logger.debug(`GLTF_pmrem[${e}] ${i}: \u0110\xE3 t\xE1i s\u1EED d\u1EE5ng (n\u1ED9i dung gi\u1ED1ng h\u1EC7t nhau) \u2192 ${n.getURI()||n.getName()||i}`);else{let p=o.byteLength<102400?`${(o.byteLength/1024).toFixed(0)} KB`:`${(o.byteLength/1048576).toFixed(2)} MB`,h=f.length<100*1024?`${(f.length/1024).toFixed(0)} KB`:`${(f.length/(1024*1024)).toFixed(2)} MB`;this.logger.info(`GLTF_pmrem[${e}] ${i}: ${p} EXR \u2192 ${h} KTX2 (${n.getURI()||n.getName()||i})`)}return this.convertedTextures.push(n),this.processed++,!0}getOrProcessExr(e,n,r,s,o){let i=this.processingPromises.get(e);if(i)return this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang t\xE1i s\u1EED d\u1EE5ng k\u1EBFt qu\u1EA3 \u0111ang \u0111\u01B0\u1EE3c x\u1EED l\xFD (n\u1ED9i dung gi\u1ED1ng h\u1EC7t nhau)`),i;let a=this.processExrToKtx2(e,n,r,s,o);return this.processingPromises.set(e,a),a}async processExrToKtx2(e,n,r,s,o){if(o){let h=xe(e);if(h&&h.length>0)return this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110\xE3 load t\u1EEB b\u1ED9 nh\u1EDB cache`),new Uint8Array(h)}let i=n.byteLength<100*1024?`${(n.byteLength/1024).toFixed(0)} KB`:`${(n.byteLength/(1024*1024)).toFixed(2)} MB`;this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang ch\u1EA1y PMREM WASM (${i} EXR) \u2014 qu\xE1 tr\xECnh n\xE0y c\xF3 th\u1EC3 m\u1EA5t m\u1ED9t l\xFAc...`),await new Promise(h=>setTimeout(h,0));let a=Date.now(),u=this.wasmModule.pmrem_exr(n),m=((Date.now()-a)/1e3).toFixed(1);this.logger.debug(`GLTF_pmrem[${r}] ${s}: Ho\xE0n t\u1EA5t PMREM trong ${m}s (${(u.byteLength/1024/1024).toFixed(1)} MB)`);let c=Nr(),l=J(this.tmpDir,`${c}.pmrem.exr`),f=J(this.tmpDir,`${c}.ktx2`);if(Lr(l,Buffer.from(u)),this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang m\xE3 h\xF3a KTX2 HDR...`),await Bi(this.basisuExe,l,f,"hdr4x4",!0),!We(f))throw new Error(`GLTF_pmrem[${r}] ${s}: basisu kh\xF4ng t\u1EA1o ra \u0111\u01B0\u1EE3c file \u0111\u1EA7u ra`);let p=Ar(f);return o&&fe(e,p),new Uint8Array(p)}async finalize(e){if(this.processed>0){let n=e.createExtension(Se);for(let s of this.convertedTextures)n.addTexture(s);if(!e.getRoot().listTextures().some(s=>s.getMimeType()==="image/exr")){let s=e.getRoot().listExtensionsUsed().find(o=>o.extensionName==="EXT_texture_exr");s&&s.dispose()}}this.tmpDir&&await dt(this.tmpDir)}};async function Pt(t){let e=t.getExtension(ne.EXTENSION_NAME);if(e?.model){let n=t.getMimeType();if(n==="image/jpeg"||n==="image/png"){let s=e.model,o=t.getSize();o&&s.maxSize>4&&(o[0]>s.maxSize||o[1]>s.maxSize)&&(console.log(`> S\u1EBD thay \u0111\u1ED5i k\xEDch th\u01B0\u1EDBc texture ${t.getName()} t\u1EEB ${o[0]}x${o[1]} xu\u1ED1ng ${s.maxSize}x${s.maxSize}`),await ur(t,s.maxSize,console))}}}var Rr=function(t){let e=new Ot({}),n=new Rt({jobs:void 0,debug:t.debug}),r=new $t,s={config:t.config,...t,webPContext:e,toktxContext:n,pmremContext:r};return zi("gltf_texture_transform",async o=>{await e.prepare(o),s.noToktx!==!0&&(await n.prepare(o)||(s.noToktx=!0)),await r.prepare(o);try{let i=o.getLogger(),a=o.getRoot().listTextures(),u=0;if(await Promise.all(a.map((m,c)=>Ki(m,c,o,i,s).then(()=>{try{let l=Wi.getVRAMByteLength(m.getImage(),m.getMimeType());u+=l}catch{}}))),u>0){let m=u/1024/1024;s.reportGPUMemory?s.reportGPUMemory(u):console.log(`> T\u1ED5ng b\u1ED9 nh\u1EDB GPU \u01B0\u1EDBc t\xEDnh: ${m.toFixed(2)} MB c\u1EE7a ${a.length} textures`),m>1e3&&console.log("WARN: T\u1ED5ng b\u1ED9 nh\u1EDB GPU \u01B0\u1EDBc t\xEDnh l\xE0 r\u1EA5t l\u1EDBn - \u0111i\u1EC1u n\xE0y c\xF3 th\u1EC3 g\xE2y ra s\u1EF1 c\u1ED1 tr\xEAn m\u1ED9t s\u1ED1 thi\u1EBFt b\u1ECB y\u1EBFu. H\xE3y c\xE2n nh\u1EAFc thay \u0111\u1ED5i c\xE0i \u0111\u1EB7t n\xE9n ho\u1EB7c gi\u1EA3m k\xEDch th\u01B0\u1EDBc texture.")}}finally{await e.finalize(o),s.noToktx!==!0&&await n.finalize(o),await r.finalize(o)}})};async function Ki(t,e,n,r,s){let o=st(t.getMimeType(),t.getImage(),r);o?.error&&(r.warn(`WARN: Texture ${t.getName()} [${e}] c\xF3 mime type kh\xF4ng ch\xEDnh x\xE1c "${t.getMimeType()}" \u2192 t\u1EF1 \u0111\u1ED9ng s\u1EEDa th\xE0nh ${o.mimeType}`),t.setMimeType(o.mimeType));let i=t.getMimeType();if(i==="image/exr"){await s.pmremContext.process(e,t,null,s);return}if(!(i==="image/jpeg"||i==="image/png"||i==="image/webp"))return;let m=t.getExtension(ne.EXTENSION_NAME)?.model;if(m?.mode==="none"){r.info(`\u2192 B\u1ECF qua qu\xE1 tr\xECnh n\xE9n \u0111\u1ED1i v\u1EDBi texture ${t.getName()} [${e}] theo nh\u01B0 c\u1EA5u h\xECnh trong texture extension`);return}let c=s.useCache?Tt(t)+oe(s.config):void 0,l=s.useCache&&c?xe(c):void 0;l&&(l.length<=0?(r.warn(`WARN: Cache c\u1EE7a texture ${t.getName()} [${e}] b\u1ECB tr\u1ED1ng. S\u1EBD ti\u1EBFn h\xE0nh x\u1EED l\xFD l\u1EA1i.`),l=void 0):r.info(`\u2192 S\u1EED d\u1EE5ng cache cho texture ${t.getName()} [${e}] \u2013 ${(l.length/1024).toFixed(0)} KB`));let f=!1,g=!0,p=s.noToktx!==!0,h=t.getURI();if(m&&m.mode!=="auto"){switch(m.mode){case"world":m.mode="ETC1S";break;case"product":switch(m.slot){default:m.mode="ETC1S";break;case"normalTexture":m.mode="UASTC";break;case"baseColorTexture":case"metallicRoughnessTexture":case"lightmapTexture":m.mode="webp",m.quality=.8;break}break}switch(m.mode){case"webp":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/webp");return}await Pt(t),g=!1,f=await s.webPContext.process(e,t,m,s);break;case"ETC1S":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/ktx2");return}await Pt(t),g=!1,f=await s.toktxContext.process(e,t,m,s);break;case"UASTC":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/ktx2");return}await Pt(t),g=!1,f=await s.toktxContext.process(e,t,m,s);break}}if(g){let y="image/ktx2",d=Ui(t),E=t.getSize()||[0,0],T=s.file?.toLowerCase().endsWith(".vrm"),L={};if((d.includes("lightmapTexture")||ue(t)||E[0]<=32||E[1]<=32||s.config?.usecase==="product"&&(d.includes("normalTexture")||d.includes("metallicRoughnessTexture")))&&(y="image/webp"),l){t.setImage(new Uint8Array(l)).setMimeType(y);return}if(await Pt(t),y==="image/webp")f=await s.webPContext.process(e,t,{...L,quality:.95,slot:d.join(",")},s);else if(p){let _=null;T&&(_={mode:"ETC1S"}),f=await s.toktxContext.process(e,t,_,s)}else r.warn("Kh\xF4ng t\xECm th\u1EA5y Toktx: \u0110ang b\u1ECF qua qu\xE1 tr\xECnh n\xE9n \u0111\u1ED1i v\u1EDBi texture: "+i)}if(s.useCache&&f&&c){let y=t.getImage();y&&fe(c,y)}if(f){let y=t.getURI();if(h&&h!==y&&s.file&&s.outfile){let x=vr(s.file),d=vr(s.outfile),E=x+"/"+h;x===d&&Xi(E)&&(r.info(`\u0110ang x\xF3a file texture c\u0169 "${h}" \u2192 "${y}"`),qi(E))}}}var $r=function(t){return(e,n)=>{}};import{NodeIO as Hi}from"@gltf-transform/core";import{readFileSync as Pr}from"fs";import{extname as Vi}from"path";async function Cr(t,e){let n=await Ji(t,e);return Zi(n)}async function Ji(t,e){if(Vi(t).toLowerCase()===".gltf")return JSON.parse(Pr(t,"utf8"));let n=e??new Hi,r=new Uint8Array(Pr(t)),{json:s}=await n.binaryToJSON(r);return s}function Zi(t){for(let e of t.animations??[])for(let n of e.channels??[])if(n?.target?.extensions?.KHR_animation_pointer?.pointer?.startsWith("/materials/"))return!0;return!1}async function wn(t,e,n){n.logger||(n.logger=new Qi(Ct.INFO));let{debug:r,stats:s,packedFiles:o,useCache:i,logger:a}=n;if(!Dr(t))return a.error(`WARN: Kh\xF4ng th\u1EC3 \u0111\xF3ng g\xF3i (pack), file kh\xF4ng t\u1ED3n t\u1EA1i: "${t}"`),!1;let u;if(i&&Be(t)){let m=Fr(t);u="packed-"+oe(m);let l=xe(u);if(l)return a.info(`\u2192 \u0110\xE3 t\u1EA3i file n\xE9n t\u1EEB b\u1ED9 nh\u1EDB cache: "${Sn.basename(t)}"`),Yi(t,Buffer.from(l)),!0}if(o){if(o.has(t))return!0;o.add(t)}try{let m=n.config;e?e=pt(t,e):e=t;let c=kr(t).size/1024/1024;a.debug(`\u2192 B\u1EAFt \u0111\u1EA7u n\xE9n ${c.toFixed(1)} MB: ${t}`);let l=Date.now(),f=new ea().registerExtensions([...ta]).registerExtensions(mt).registerExtensions([ne,se,Se,De]).registerDependencies({"draco3d.decoder":await Gr.createDecoderModule(),"draco3d.encoder":await Gr.createEncoderModule(),"meshopt.decoder":na,"meshopt.encoder":ra}),g=n.sourceFile??t;gt(g);let p=await Qe(f,t),y=await Cr(t,f)?[Me.MESH]:[Me.MESH,Me.MATERIAL];n.logger?p.setLogger(n.logger):p.getLogger().verbosity=n.verbose?Ct.DEBUG:n.debug?Ct.INFO:Ct.WARN,yt(p,g,e);let x=0,d=[_t(),oa(),Rr({file:t,outfile:e,useCache:i,noToktx:!1,debug:r,reportGPUMemory:M=>{x+=M},config:m}),Qn({file:t,config:m}),$r({}),aa({tolerance:1e-6}),sa({propertyTypes:y})];ge(t)||d.push(ia({propertyTypes:[Me.MESH,Me.MATERIAL,Me.TEXTURE,Me.ACCESSOR,Me.BUFFER],keepAttributes:!0,keepIndices:!0,keepExtras:!0,keepSolidTextures:!0})),await p.transform(...d),a.debug(`\u2190 \u0110ang ghi ra file: ${e}`),await xt(f,e,p),i&&u!=null&&Dr(e)&&fe(u,Fr(e));let T=Date.now()-l,L=kr(e).size/1024/1024,_=Sn.basename(e),A=x/1024/1024;return a.info(`\u2190 N\xE9n th\xE0nh c\xF4ng '${_}' ${c.toFixed(1)} MB \u2192 ${L.toFixed(1)} MB (L\u01B0\u1EE3ng VRAM GPU \u0103n: ${A.toFixed(1)} MB textures) trong th\u1EDDi gian ${(T/1e3).toFixed(1)} gi\xE2y`),s&&(s.totalFilesProcessed++,s.totalFileSizeInMB+=L,s.totalFileSizeInMBBefore+=c,s.totalGPUMemoryInMB+=A),!0}catch(m){if(m instanceof Oe)throw m;let c=m instanceof Error&&m.stack?m.stack.split(`
21
+ `)}`)}function ho(t){let e=process.platform,n=J(t,"basis");return e==="win32"?J(n,"win","basisu.exe"):e==="darwin"?J(n,"osx","basisu"):J(n,"linux","basisu")}function xo(t,e,n,r,s){return new Promise((i,o)=>{let a=[];a.push(r==="hdr6x6"?"-hdr_6x6":"-hdr_4x4"),s&&a.push("-mipmap"),a.push("-file",e,"-output_file",n,"-y_flip"),lo(t,a,{windowsHide:!0,encoding:"utf8"},(u,m,c)=>{if(u){let l=[c,m,u.message].filter(Boolean).join(`
22
+ `);o(new Error(`basisu th\u1EA5t b\u1EA1i (m\xE3 tho\xE1t ${u.code}):
23
+ ${l}`));return}i()})})}var Nt=class{wasmModule=null;pmremDir="";basisuExe="";tmpDir="";processed=0;available=!1;logger;convertedTextures=[];processingPromises=new Map;async prepare(e){this.logger=e.getLogger(),this.processed=0,this.pmremDir=po();let n=J(this.pmremDir,"pkg","pmrem_wasm.js"),r=J(this.pmremDir,"pkg","pmrem_wasm_bg.wasm");if(!Be(n)||!Be(r))return this.logger.warn("pmrem: Kh\xF4ng t\xECm th\u1EA5y WASM \u2014 c\xE1c texture EXR s\u1EBD kh\xF4ng \u0111\u01B0\u1EE3c x\u1EED l\xFD"),re(!1,"Thi\u1EBFu c\xE1c file pmrem WASM. Vui l\xF2ng ch\u1EA1y `npm run build:pmrem` \u0111\u1EC3 build module WASM trong tools/pmrem/."),!1;if(this.basisuExe=ho(this.pmremDir),!Be(this.basisuExe))return this.logger.warn(`pmrem: Kh\xF4ng t\xECm th\u1EA5y file ch\u1EA1y basisu t\u1EA1i ${this.basisuExe} \u2014 c\xE1c texture EXR s\u1EBD kh\xF4ng \u0111\u01B0\u1EE3c x\u1EED l\xFD`),re(!1,`Thi\u1EBFu file th\u1EF1c thi basisu cho n\u1EC1n t\u1EA3ng ${process.platform}. Vui l\xF2ng ch\u1EA1y \`npm run build:pmrem\` \u0111\u1EC3 build binary trong tools/pmrem/.`),!1;if(process.platform!=="win32")try{co(this.basisuExe,493)}catch{}try{let s=await import(mo(n).href),i=gr(r);await s.default({module_or_path:i}),this.wasmModule=s}catch(s){return this.logger.warn(`pmrem: N\u1EA1p WASM th\u1EA5t b\u1EA1i \u2014 ${s.message}`),re(!1,`N\u1EA1p pmrem WASM module th\u1EA5t b\u1EA1i: ${s.message}`),!1}return this.tmpDir=J(go.tmpdir,"gltf-pmrem",hr()),oo(this.tmpDir,{recursive:!0}),this.available=!0,this.logger.debug("pmrem: \u0110\xE3 s\u1EB5n s\xE0ng (WASM + basisu \u0111\xE3 \u0111\u01B0\u1EE3c n\u1EA1p)"),!0}async process(e,n,r,s){if(!this.available||n.getMimeType()!=="image/exr")return!1;let i=n.getImage();if(!i)return!1;let o=n.getName()||`texture_${e}`,a=!!n.getURI(),u=new Uint8Array(i.buffer,i.byteOffset,i.byteLength),c=`pmrem-${fo("md5").update(u).digest("hex")}`,l=this.processingPromises.has(c),f=await this.getOrProcessExr(c,u,e,o,s.useCache),g=n.getExtension("EXT_texture_exr");if(g&&(n.setExtension("EXT_texture_exr",null),g.dispose()),n.setMimeType("image/ktx2"),a){let p=n.getURI(),d=p.replace(/\.exr$/i,".pmrem.ktx2"),y=d!==p?d:p+".pmrem.ktx2",x=dr(s.outfile);pr(J(x,y),f);let h=J(x,p);Be(h)&&ao(h),n.setURI(y),n.setName(y),n.setImage(null),this.logger.debug(`GLTF_pmrem[${e}] ${o}: external (b\xEAn ngo\xE0i) \u2192 ${y}`)}else n.setImage(new Uint8Array(f));if(l)this.logger.debug(`GLTF_pmrem[${e}] ${o}: \u0110\xE3 t\xE1i s\u1EED d\u1EE5ng (n\u1ED9i dung gi\u1ED1ng h\u1EC7t nhau) \u2192 ${n.getURI()||n.getName()||o}`);else{let p=i.byteLength<102400?`${(i.byteLength/1024).toFixed(0)} KB`:`${(i.byteLength/1048576).toFixed(2)} MB`,d=f.length<100*1024?`${(f.length/1024).toFixed(0)} KB`:`${(f.length/(1024*1024)).toFixed(2)} MB`;this.logger.info(`GLTF_pmrem[${e}] ${o}: ${p} EXR \u2192 ${d} KTX2 (${n.getURI()||n.getName()||o})`)}return this.convertedTextures.push(n),this.processed++,!0}getOrProcessExr(e,n,r,s,i){let o=this.processingPromises.get(e);if(o)return this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang t\xE1i s\u1EED d\u1EE5ng k\u1EBFt qu\u1EA3 \u0111ang \u0111\u01B0\u1EE3c x\u1EED l\xFD (n\u1ED9i dung gi\u1ED1ng h\u1EC7t nhau)`),o;let a=this.processExrToKtx2(e,n,r,s,i);return this.processingPromises.set(e,a),a}async processExrToKtx2(e,n,r,s,i){if(i){let d=xe(e);if(d&&d.length>0)return this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110\xE3 load t\u1EEB b\u1ED9 nh\u1EDB cache`),new Uint8Array(d)}let o=n.byteLength<100*1024?`${(n.byteLength/1024).toFixed(0)} KB`:`${(n.byteLength/(1024*1024)).toFixed(2)} MB`;this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang ch\u1EA1y PMREM WASM (${o} EXR) \u2014 qu\xE1 tr\xECnh n\xE0y c\xF3 th\u1EC3 m\u1EA5t m\u1ED9t l\xFAc...`),await new Promise(d=>setTimeout(d,0));let a=Date.now(),u=this.wasmModule.pmrem_exr(n),m=((Date.now()-a)/1e3).toFixed(1);this.logger.debug(`GLTF_pmrem[${r}] ${s}: Ho\xE0n t\u1EA5t PMREM trong ${m}s (${(u.byteLength/1024/1024).toFixed(1)} MB)`);let c=hr(),l=J(this.tmpDir,`${c}.pmrem.exr`),f=J(this.tmpDir,`${c}.ktx2`);if(pr(l,Buffer.from(u)),this.logger.debug(`GLTF_pmrem[${r}] ${s}: \u0110ang m\xE3 h\xF3a KTX2 HDR...`),await xo(this.basisuExe,l,f,"hdr4x4",!0),!Be(f))throw new Error(`GLTF_pmrem[${r}] ${s}: basisu kh\xF4ng t\u1EA1o ra \u0111\u01B0\u1EE3c file \u0111\u1EA7u ra`);let p=gr(f);return i&&fe(e,p),new Uint8Array(p)}async finalize(e){if(this.processed>0){let n=e.createExtension(Se);for(let s of this.convertedTextures)n.addTexture(s);if(!e.getRoot().listTextures().some(s=>s.getMimeType()==="image/exr")){let s=e.getRoot().listExtensionsUsed().find(i=>i.extensionName==="EXT_texture_exr");s&&s.dispose()}}this.tmpDir&&await lt(this.tmpDir)}};async function Rt(t){let e=t.getExtension(te.EXTENSION_NAME);if(e?.model){let n=t.getMimeType();if(n==="image/jpeg"||n==="image/png"){let s=e.model,i=t.getSize();i&&s.maxSize>4&&(i[0]>s.maxSize||i[1]>s.maxSize)&&(console.log(`> S\u1EBD thay \u0111\u1ED5i k\xEDch th\u01B0\u1EDBc texture ${t.getName()} t\u1EEB ${i[0]}x${i[1]} xu\u1ED1ng ${s.maxSize}x${s.maxSize}`),await Vn(t,s.maxSize,console))}}}var yr=function(t){let e=new _t({}),n=new Lt({jobs:void 0,debug:t.debug}),r=new Nt,s={config:t.config,...t,webPContext:e,toktxContext:n,pmremContext:r};return bo("gltf_texture_transform",async i=>{await e.prepare(i),s.noToktx!==!0&&(await n.prepare(i)||(s.noToktx=!0)),await r.prepare(i);try{let o=i.getLogger(),a=i.getRoot().listTextures(),u=0;if(await Promise.all(a.map((m,c)=>wo(m,c,i,o,s).then(()=>{try{let l=yo.getVRAMByteLength(m.getImage(),m.getMimeType());u+=l}catch{}}))),u>0){let m=u/1024/1024;s.reportGPUMemory?s.reportGPUMemory(u):console.log(`> T\u1ED5ng b\u1ED9 nh\u1EDB GPU \u01B0\u1EDBc t\xEDnh: ${m.toFixed(2)} MB c\u1EE7a ${a.length} textures`),m>1e3&&console.log("WARN: T\u1ED5ng b\u1ED9 nh\u1EDB GPU \u01B0\u1EDBc t\xEDnh l\xE0 r\u1EA5t l\u1EDBn - \u0111i\u1EC1u n\xE0y c\xF3 th\u1EC3 g\xE2y ra s\u1EF1 c\u1ED1 tr\xEAn m\u1ED9t s\u1ED1 thi\u1EBFt b\u1ECB y\u1EBFu. H\xE3y c\xE2n nh\u1EAFc thay \u0111\u1ED5i c\xE0i \u0111\u1EB7t n\xE9n ho\u1EB7c gi\u1EA3m k\xEDch th\u01B0\u1EDBc texture.")}}finally{await e.finalize(i),s.noToktx!==!0&&await n.finalize(i),await r.finalize(i)}})};async function wo(t,e,n,r,s){let i=et(t.getMimeType(),t.getImage(),r);i?.error&&(r.warn(`WARN: Texture ${t.getName()} [${e}] c\xF3 mime type kh\xF4ng ch\xEDnh x\xE1c "${t.getMimeType()}" \u2192 t\u1EF1 \u0111\u1ED9ng s\u1EEDa th\xE0nh ${i.mimeType}`),t.setMimeType(i.mimeType));let o=t.getMimeType();if(o==="image/exr"){await s.pmremContext.process(e,t,null,s);return}if(!(o==="image/jpeg"||o==="image/png"||o==="image/webp"))return;let m=t.getExtension(te.EXTENSION_NAME)?.model;if(m?.mode==="none"){r.info(`\u2192 B\u1ECF qua qu\xE1 tr\xECnh n\xE9n \u0111\u1ED1i v\u1EDBi texture ${t.getName()} [${e}] theo nh\u01B0 c\u1EA5u h\xECnh trong texture extension`);return}let c=s.useCache?dt(t)+ie(s.config):void 0,l=s.useCache&&c?xe(c):void 0;l&&(l.length<=0?(r.warn(`WARN: Cache c\u1EE7a texture ${t.getName()} [${e}] b\u1ECB tr\u1ED1ng. S\u1EBD ti\u1EBFn h\xE0nh x\u1EED l\xFD l\u1EA1i.`),l=void 0):r.info(`\u2192 S\u1EED d\u1EE5ng cache cho texture ${t.getName()} [${e}] \u2013 ${(l.length/1024).toFixed(0)} KB`));let f=!1,g=!0,p=s.noToktx!==!0,d=t.getURI();if(m&&m.mode!=="auto"){switch(m.mode){case"world":m.mode="ETC1S";break;case"product":switch(m.slot){default:m.mode="ETC1S";break;case"normalTexture":m.mode="UASTC";break;case"baseColorTexture":case"metallicRoughnessTexture":case"lightmapTexture":m.mode="webp",m.quality=.8;break}break}switch(m.mode){case"webp":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/webp");return}await Rt(t),g=!1,f=await s.webPContext.process(e,t,m,s);break;case"ETC1S":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/ktx2");return}await Rt(t),g=!1,f=await s.toktxContext.process(e,t,m,s);break;case"UASTC":if(l){t.setImage(new Uint8Array(l)).setMimeType("image/ktx2");return}await Rt(t),g=!1,f=await s.toktxContext.process(e,t,m,s);break}}if(g){let y="image/ktx2",h=To(t),M=t.getSize()||[0,0],w=s.file?.toLowerCase().endsWith(".vrm"),A={};if((h.includes("lightmapTexture")||ue(t)||M[0]<=32||M[1]<=32||s.config?.usecase==="product"&&(h.includes("normalTexture")||h.includes("metallicRoughnessTexture")))&&(y="image/webp"),l){t.setImage(new Uint8Array(l)).setMimeType(y);return}if(await Rt(t),y==="image/webp")f=await s.webPContext.process(e,t,{...A,quality:.95,slot:h.join(",")},s);else if(p){let I=null;w&&(I={mode:"ETC1S"}),f=await s.toktxContext.process(e,t,I,s)}else r.warn("Kh\xF4ng t\xECm th\u1EA5y Toktx: \u0110ang b\u1ECF qua qu\xE1 tr\xECnh n\xE9n \u0111\u1ED1i v\u1EDBi texture: "+o)}if(s.useCache&&f&&c){let y=t.getImage();y&&fe(c,y)}if(f){let y=t.getURI();if(d&&d!==y&&s.file&&s.outfile){let x=xr(s.file),h=xr(s.outfile),M=x+"/"+d;x===h&&Eo(M)&&(r.info(`\u0110ang x\xF3a file texture c\u0169 "${d}" \u2192 "${y}"`),So(M))}}}var br=function(t){return(e,n)=>{}};import{NodeIO as Io}from"@gltf-transform/core";import{readFileSync as Tr}from"fs";import{extname as _o}from"path";async function Er(t,e){let n=await Mo(t,e);return Lo(n)}async function Mo(t,e){if(_o(t).toLowerCase()===".gltf")return JSON.parse(Tr(t,"utf8"));let n=e??new Io,r=new Uint8Array(Tr(t)),{json:s}=await n.binaryToJSON(r);return s}function Lo(t){for(let e of t.animations??[])for(let n of e.channels??[])if(n?.target?.extensions?.KHR_animation_pointer?.pointer?.startsWith("/materials/"))return!0;return!1}async function hn(t,e,n){n.logger||(n.logger=new Ro(At.INFO));let{debug:r,stats:s,packedFiles:i,useCache:o,logger:a}=n;if(!Sr(t))return a.error(`WARN: Kh\xF4ng th\u1EC3 \u0111\xF3ng g\xF3i (pack), file kh\xF4ng t\u1ED3n t\u1EA1i: "${t}"`),!1;let u;if(o&&je(t)){let m=wr(t);u="packed-"+ie(m);let l=xe(u);if(l)return a.info(`\u2192 \u0110\xE3 t\u1EA3i file n\xE9n t\u1EEB b\u1ED9 nh\u1EDB cache: "${pn.basename(t)}"`),No(t,Buffer.from(l)),!0}if(i){if(i.has(t))return!0;i.add(t)}try{let m=n.config;e?e=mt(t,e):e=t;let c=Ir(t).size/1024/1024;a.debug(`\u2192 B\u1EAFt \u0111\u1EA7u n\xE9n ${c.toFixed(1)} MB: ${t}`);let l=Date.now(),f=new Ao().registerExtensions([...vo]).registerExtensions(ot).registerExtensions([te,se,Se,De]).registerDependencies({"draco3d.decoder":await _r.createDecoderModule(),"draco3d.encoder":await _r.createEncoderModule(),"meshopt.decoder":Oo,"meshopt.encoder":$o}),g=n.sourceFile??t;ut(g);let p=await Ye(f,t),y=await Er(t,f)?[Me.MESH]:[Me.MESH,Me.MATERIAL];n.logger?p.setLogger(n.logger):p.getLogger().verbosity=n.verbose?At.DEBUG:n.debug?At.INFO:At.WARN,pt(p,g,e);let x=0,h=[Tt(),Po(),yr({file:t,outfile:e,useCache:o,noToktx:!1,debug:r,reportGPUMemory:v=>{x+=v},config:m}),Gn({file:t,config:m}),br({}),Fo({tolerance:1e-6}),Co({propertyTypes:y})];ge(t)||h.push(Do({propertyTypes:[Me.MESH,Me.MATERIAL,Me.TEXTURE,Me.ACCESSOR,Me.BUFFER],keepAttributes:!0,keepIndices:!0,keepExtras:!0,keepSolidTextures:!0})),await p.transform(...h),a.debug(`\u2190 \u0110ang ghi ra file: ${e}`),await gt(f,e,p),o&&u!=null&&Sr(e)&&fe(u,wr(e));let w=Date.now()-l,A=Ir(e).size/1024/1024,I=pn.basename(e),L=x/1024/1024;return a.info(`\u2190 N\xE9n th\xE0nh c\xF4ng '${I}' ${c.toFixed(1)} MB \u2192 ${A.toFixed(1)} MB (L\u01B0\u1EE3ng VRAM GPU \u0103n: ${L.toFixed(1)} MB textures) trong th\u1EDDi gian ${(w/1e3).toFixed(1)} gi\xE2y`),s&&(s.totalFilesProcessed++,s.totalFileSizeInMB+=A,s.totalFileSizeInMBBefore+=c,s.totalGPUMemoryInMB+=L),!0}catch(m){if(m instanceof Ae)throw m;let c=m instanceof Error&&m.stack?m.stack.split(`
24
24
  `).slice(0,2).join(`
25
- `):"";if(a.error(`\u0110\xF3ng g\xF3i file "${Sn.basename(t)}" b\u1EB1ng phi\xEAn b\u1EA3n pipeline ${Q()} th\u1EA5t b\u1EA1i v\u1EDBi l\u1ED7i sau:
25
+ `):"";if(a.error(`\u0110\xF3ng g\xF3i file "${pn.basename(t)}" b\u1EB1ng phi\xEAn b\u1EA3n pipeline ${Y()} th\u1EA5t b\u1EA1i v\u1EDBi l\u1ED7i sau:
26
26
  ${m instanceof Error?m.message:String(m)}
27
- ${c}`),r)throw m;return!1}}import{Logger as ca,NodeIO as ua,Verbosity as jr}from"@gltf-transform/core";import{ALL_EXTENSIONS as ma}from"@gltf-transform/extensions";import Br from"draco3dgltf";import{MeshoptDecoder as la,MeshoptEncoder as fa}from"meshoptimizer";async function Wr(t,e){let n=new ua().setLogger(new ca(e?.verbose?jr.DEBUG:jr.ERROR)).registerExtensions(ma).registerDependencies({"draco3d.decoder":await Br.createDecoderModule(),"draco3d.encoder":await Br.createEncoderModule(),"meshopt.decoder":la,"meshopt.encoder":fa}),r=await n.read(t),s=await n.readAsJSON(t);return gr(t,r,s)}import{Logger as ga,Verbosity as pa}from"@gltf-transform/core";import{existsSync as qr,readFileSync as Kr,statSync as Hr}from"fs";import da,{dirname as ha,resolve as xa}from"path";var Dt=["product","world"],zr={usecase:"default"},Ae,Ur=new Set;function In(t){if(!Dt.includes(t)&&t!=="default")throw new Error(`Invalid usecase: "${t}". Valid usecases: ${Dt.join(", ")}`);return{usecase:t}}function Vr(t,e,n){let r=n?.logger||new ga(pa.WARN);if(t!=null){if(t=xa(process.cwd(),t),!qr(t))throw new Error(`No config found at "${t}"`);if(Hr(t).isDirectory()){let i=Xr(t,r);if(i)return i;throw new Error(`No config found in directory "${t}"`)}let o=Jr(t,Kr(t,"utf8"),r);if(o)return o;throw new Error(`Failed parsing config at "${t}"`)}if(Ae!==void 0)return Ae;if(e){let s=Xr(e,r);if(s)return Ae={...zr,...s},r.info(`Using config with usecase: ${Ae.usecase}`),Ae}return Ae||(r.debug("No config found. Using default config."),Ae=zr),Ae}function Xr(t,e){for(Hr(t).isFile()&&(t=ha(t)),t=t.replaceAll("\\","/");t.length>0;){let n=da.join(t,"gltf.config.json");if(qr(n)){let s=Kr(n,"utf8"),o=Jr(n,s,e);if(o)return o}let r=t.lastIndexOf("/");if(r<0)break;t=t.slice(0,r)}return null}function Jr(t,e,n){if(t.endsWith("gltf.config.json"))try{let r=JSON.parse(e);return r.gltf?(n.info(`Found "gltf" config at "${t.replaceAll("\\","/")}".`),typeof r.gltf=="string"?In(r.gltf):r.gltf):(Ur.has(t)||(n.debug(`No "gltf" config found in gltf.config.json at "${t.replaceAll("\\","/")}". You may add a "gltf" field to the config with the optimization config. Example: { "gltf": { "usecase": "product" } }. Using default config for glTF optimization now.`),Ur.add(t)),null)}catch(r){n.error(`Failed parsing config "${r.message}" at ${t.replaceAll("\\","/")}`)}else if(e.trimStart().startsWith("{"))try{return JSON.parse(e)}catch(r){r instanceof Error?n.error(`Failed parsing config "${r.message}" at ${t.replaceAll("\\","/")}`):n.error(`Failed parsing config "${r}" at ${t.replaceAll("\\","/")}`)}else n.error("Invalid config file format. Expected JSON object at "+t.replaceAll("\\","/"))}import{existsSync as ya}from"fs";import Zr,{resolve as ba}from"path";var Le={UNKNOWN_ERROR:1,PACKING_FAILED:2,PROGRESSIVE_FAILED:3,INVALID_ARGS:4,LOST_FILE:5};ae.command("version","In ra phi\xEAn b\u1EA3n hi\u1EC7n t\u1EA1i").action(async({logger:t})=>{t.info(Q())}).command("clear-caches","X\xF3a to\xE0n b\u1ED9 b\u1ED9 nh\u1EDB \u0111\u1EC7m (caches)").help(`X\xF3a t\u1EA5t c\u1EA3 c\xE1c file \u0111\xE3 \u0111\u01B0\u1EE3c l\u01B0u trong cache.
28
- Theo m\u1EB7c \u0111\u1ECBnh, dung l\u01B0\u1EE3ng cache \u0111\u01B0\u1EE3c gi\u1EDBi h\u1EA1n \u1EDF m\u1EE9c ${sn} MB tr\xEAn \u1ED5 \u0111\u0129a.
29
- `).action(async({logger:t})=>{t.info("\u0110ang x\xF3a c\xE1c b\u1ED9 nh\u1EDB \u0111\u1EC7m..."),Wn(t)}).command("stats","T\xEDnh to\xE1n s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA c\u1EE7a glTF").help("T\xEDnh to\xE1n v\xE0 xu\u1EA5t ra c\xE1c s\u1ED1 li\u1EC7u nh\u01B0 s\u1ED1 l\u01B0\u1EE3ng tam gi\xE1c, dung l\u01B0\u1EE3ng texture, v.v.").argument("<input>","\u0110\u01B0\u1EDDng d\u1EABn t\u1EDBi m\u1ED9t file glTF, GLB, VRM HO\u1EB6C m\u1ED9t th\u01B0 m\u1EE5c").argument("<output>","\u0110\u01B0\u1EDDng d\u1EABn \u0111\u1EA7u ra cho file th\u1ED1ng k\xEA",{default:null,validator:ae.STRING}).option("--verbose","B\u1EADt ch\u1EBF \u0111\u1ED9 xu\u1EA5t log chi ti\u1EBFt (verbose)",{validator:ae.BOOLEAN,default:!1}).action(async({logger:t,args:e,options:n})=>{t.level=n.verbose?"debug":"info",t.info('\u0110ang t\xEDnh to\xE1n s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA cho "'+e.input+'"');let r=e.input.toString(),s=[];await He(r,async i=>{let a=await Wr(i,{verbose:!!n.verbose});s.push(a)});let o=e.output==="null"?void 0:e.output?.toString();o||(Fe(r)?o=Zr.join(r,"stats.gltf.json"):o=r+".gltf.stats.json"),t.info("\u0110ang ghi s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA ra file: "+o),pr(s,o)}).command("transform","Bi\u1EBFn \u0111\u1ED5i (t\u1EA3i l\u0169y ti\u1EBFn - progressive loading) v\xE0 n\xE9n c\xE1c file glTF, GLB ho\u1EB7c VRM").help(`
27
+ ${c}`),r)throw m;return!1}}import{Logger as ko,NodeIO as Go,Verbosity as Mr}from"@gltf-transform/core";import{ALL_EXTENSIONS as jo}from"@gltf-transform/extensions";import Lr from"draco3dgltf";import{MeshoptDecoder as Bo,MeshoptEncoder as Wo}from"meshoptimizer";async function Nr(t,e){let n=new Go().setLogger(new ko(e?.verbose?Mr.DEBUG:Mr.ERROR)).registerExtensions(jo).registerDependencies({"draco3d.decoder":await Lr.createDecoderModule(),"draco3d.encoder":await Lr.createEncoderModule(),"meshopt.decoder":Bo,"meshopt.encoder":Wo}),r=await n.read(t),s=await n.readAsJSON(t);return Qn(t,r,s)}import{Logger as zo,Verbosity as Uo}from"@gltf-transform/core";import{existsSync as Or,readFileSync as $r,statSync as Cr}from"fs";import Xo,{dirname as qo,resolve as Ko}from"path";var vt=["product","world"],Rr={usecase:"default"},Le,Ar=new Set;function dn(t){if(!vt.includes(t)&&t!=="default")throw new Error(`Invalid usecase: "${t}". Valid usecases: ${vt.join(", ")}`);return{usecase:t}}function Pr(t,e,n){let r=n?.logger||new zo(Uo.WARN);if(t!=null){if(t=Ko(process.cwd(),t),!Or(t))throw new Error(`No config found at "${t}"`);if(Cr(t).isDirectory()){let o=vr(t,r);if(o)return o;throw new Error(`No config found in directory "${t}"`)}let i=Dr(t,$r(t,"utf8"),r);if(i)return i;throw new Error(`Failed parsing config at "${t}"`)}if(Le!==void 0)return Le;if(e){let s=vr(e,r);if(s)return Le={...Rr,...s},r.info(`Using config with usecase: ${Le.usecase}`),Le}return Le||(r.debug("No config found. Using default config."),Le=Rr),Le}function vr(t,e){for(Cr(t).isFile()&&(t=qo(t)),t=t.replaceAll("\\","/");t.length>0;){let n=Xo.join(t,"gltf.config.json");if(Or(n)){let s=$r(n,"utf8"),i=Dr(n,s,e);if(i)return i}let r=t.lastIndexOf("/");if(r<0)break;t=t.slice(0,r)}return null}function Dr(t,e,n){if(t.endsWith("gltf.config.json"))try{let r=JSON.parse(e);return r.gltf?(n.info(`Found "gltf" config at "${t.replaceAll("\\","/")}".`),typeof r.gltf=="string"?dn(r.gltf):r.gltf):(Ar.has(t)||(n.debug(`No "gltf" config found in gltf.config.json at "${t.replaceAll("\\","/")}". You may add a "gltf" field to the config with the optimization config. Example: { "gltf": { "usecase": "product" } }. Using default config for glTF optimization now.`),Ar.add(t)),null)}catch(r){n.error(`Failed parsing config "${r.message}" at ${t.replaceAll("\\","/")}`)}else if(e.trimStart().startsWith("{"))try{return JSON.parse(e)}catch(r){r instanceof Error?n.error(`Failed parsing config "${r.message}" at ${t.replaceAll("\\","/")}`):n.error(`Failed parsing config "${r}" at ${t.replaceAll("\\","/")}`)}else n.error("Invalid config file format. Expected JSON object at "+t.replaceAll("\\","/"))}import{existsSync as Ho}from"fs";import Fr,{resolve as Vo}from"path";var Ne={UNKNOWN_ERROR:1,PACKING_FAILED:2,PROGRESSIVE_FAILED:3,INVALID_ARGS:4,LOST_FILE:5};ae.command("version","In ra phi\xEAn b\u1EA3n hi\u1EC7n t\u1EA1i").action(async({logger:t})=>{t.info(Y())}).command("clear-caches","X\xF3a to\xE0n b\u1ED9 b\u1ED9 nh\u1EDB \u0111\u1EC7m (caches)").help(`X\xF3a t\u1EA5t c\u1EA3 c\xE1c file \u0111\xE3 \u0111\u01B0\u1EE3c l\u01B0u trong cache.
28
+ Theo m\u1EB7c \u0111\u1ECBnh, dung l\u01B0\u1EE3ng cache \u0111\u01B0\u1EE3c gi\u1EDBi h\u1EA1n \u1EDF m\u1EE9c ${Qt} MB tr\xEAn \u1ED5 \u0111\u0129a.
29
+ `).action(async({logger:t})=>{t.info("\u0110ang x\xF3a c\xE1c b\u1ED9 nh\u1EDB \u0111\u1EC7m..."),Cn(t)}).command("stats","T\xEDnh to\xE1n s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA c\u1EE7a glTF").help("T\xEDnh to\xE1n v\xE0 xu\u1EA5t ra c\xE1c s\u1ED1 li\u1EC7u nh\u01B0 s\u1ED1 l\u01B0\u1EE3ng tam gi\xE1c, dung l\u01B0\u1EE3ng texture, v.v.").argument("<input>","\u0110\u01B0\u1EDDng d\u1EABn t\u1EDBi m\u1ED9t file glTF, GLB, VRM HO\u1EB6C m\u1ED9t th\u01B0 m\u1EE5c").argument("<output>","\u0110\u01B0\u1EDDng d\u1EABn \u0111\u1EA7u ra cho file th\u1ED1ng k\xEA",{default:null,validator:ae.STRING}).option("--verbose","B\u1EADt ch\u1EBF \u0111\u1ED9 xu\u1EA5t log chi ti\u1EBFt (verbose)",{validator:ae.BOOLEAN,default:!1}).action(async({logger:t,args:e,options:n})=>{t.level=n.verbose?"debug":"info",t.info('\u0110ang t\xEDnh to\xE1n s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA cho "'+e.input+'"');let r=e.input.toString(),s=[];await Ke(r,async o=>{let a=await Nr(o,{verbose:!!n.verbose});s.push(a)});let i=e.output==="null"?void 0:e.output?.toString();i||(Fe(r)?i=Fr.join(r,"stats.gltf.json"):i=r+".gltf.stats.json"),t.info("\u0110ang ghi s\u1ED1 li\u1EC7u th\u1ED1ng k\xEA ra file: "+i),er(s,i)}).command("transform","Bi\u1EBFn \u0111\u1ED5i (t\u1EA3i l\u0169y ti\u1EBFn - progressive loading) v\xE0 n\xE9n c\xE1c file glTF, GLB ho\u1EB7c VRM").help(`
30
30
  L\u1EC7nh n\xE0y s\u1EBD t\u1EA1o ra nhi\u1EC1u phi\xEAn b\u1EA3n c\u1EE7a file \u0111\u1EA7u v\xE0o, m\u1ED7i phi\xEAn b\u1EA3n c\xF3 m\u1ED9t m\u1EE9c \u0111\u1ED9 t\u1ED1i \u01B0u h\xF3a kh\xE1c nhau.
31
31
  M\u1ED7i phi\xEAn b\u1EA3n s\u1EBD \u0111\u01B0\u1EE3c n\xE9n v\xE0 ghi v\xE0o th\u01B0 m\u1EE5c \u0111\u1EA7u ra.
32
- `).argument("<input>","File glTF, GLB ho\u1EB7c VRM \u0111\u1EA7u v\xE0o c\u1EA7n \u0111\u01B0\u1EE3c n\xE9n HO\u1EB6C m\u1ED9t th\u01B0 m\u1EE5c ch\u1EE9a c\xE1c file c\u1EA7n n\xE9n").argument("<output>","File ho\u1EB7c th\u01B0 m\u1EE5c \u0111\u1EA7u ra. N\xF3 c\xF3 th\u1EC3 l\xE0 m\u1ED9t \u0111\u01B0\u1EDDng d\u1EABn tuy\u1EC7t \u0111\u1ED1i ho\u1EB7c \u0111\u01B0\u1EDDng d\u1EABn t\u01B0\u01A1ng \u0111\u1ED1i so v\u1EDBi file \u0111\u1EA7u v\xE0o. N\u1EBFu kh\xF4ng \u0111\u01B0\u1EE3c cung c\u1EA5p, file \u0111\u1EA7u v\xE0o s\u1EBD b\u1ECB ghi \u0111\xE8.",{default:null}).option("--compress","Khi \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file s\u1EBD \u0111\u01B0\u1EE3c n\xE9n l\u1EA1i",{validator:ae.BOOLEAN,default:!0}).option("--progressive","Khi \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file s\u1EBD \u0111\u01B0\u1EE3c x\u1EED l\xFD \u0111\u1EC3 h\u1ED7 tr\u1EE3 t\u1EA3i l\u0169y ti\u1EBFn (progressive loading)",{validator:ae.BOOLEAN,default:!0}).option("--usecase <usecase>",`M\u1EE5c \u0111\xEDch s\u1EED d\u1EE5ng (usecase) cho vi\u1EC7c n\xE9n. \u0110i\u1EC1u n\xE0y s\u1EBD thi\u1EBFt l\u1EADp c\xE1c c\u1EA5u h\xECnh n\xE9n t\u01B0\u01A1ng \u1EE9ng. C\xE1c t\xF9y ch\u1ECDn kh\u1EA3 thi: [${Dt.join(", ")}]`,{validator:ae.STRING}).option("--config <config>",'\u0110\u01B0\u1EDDng d\u1EABn t\u1EDBi file JSON ch\u1EE9a c\u1EA5u h\xECnh n\xE9n. \u0110\xE2y c\u0169ng c\xF3 th\u1EC3 l\xE0 file gltf.config.json v\u1EDBi object "compression" ho\u1EB7c chu\u1ED7i usecase.',{validator:ae.STRING}).option("--cache",`S\u1EED d\u1EE5ng "--cache False" \u0111\u1EC3 t\u1EAFt b\u1ED9 nh\u1EDB \u0111\u1EC7m.
33
- Khi b\u1ED9 nh\u1EDB \u0111\u1EC7m \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file \u0111\xE3 \u0111\u01B0\u1EE3c x\u1EED l\xFD tr\u01B0\u1EDBc \u0111\xF3 s\u1EBD \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n v\xE0 t\u1EA3i t\u1EEB cache \u1ED5 \u0111\u0129a thay v\xEC ph\u1EA3i x\u1EED l\xFD l\u1EA1i n\u1EBFu c\xE1c thi\u1EBFt l\u1EADp ho\u1EB7c n\u1ED9i dung file kh\xF4ng thay \u0111\u1ED5i.`,{validator:ae.BOOLEAN,default:!0}).option("--debug",'B\u1EADt t\xEDnh n\u0103ng n\xE0y \u0111\u1EC3 xu\u1EA5t ra nhi\u1EC1u log h\u01A1n b\u1EB1ng c\xE1ch d\xF9ng "--debug True"',{validator:ae.BOOLEAN,default:!1}).option("--verbose",'B\u1EADt t\xEDnh n\u0103ng n\xE0y \u0111\u1EC3 xu\u1EA5t ra c\u1EF1c k\u1EF3 chi ti\u1EBFt b\u1EB1ng c\xE1ch d\xF9ng "--verbose True"',{validator:ae.BOOLEAN,default:!1}).action(async({logger:t,args:e,options:n})=>{t.level=n.debug||n.verbose?"debug":"info",n.compress===!1&&n.progressive===!1&&(t.error(`[Gltf LOD Pipeline] v${Q()} B\u1EA1n c\u1EA7n ph\u1EA3i b\u1EADt \xEDt nh\u1EA5t m\u1ED9t trong hai t\xF9y ch\u1ECDn: --compress ho\u1EB7c --progressive`),process.exit(Le.INVALID_ARGS)),console.log(`info: [Gltf LOD Pipeline] v${Q()} \u2014 \u0110ang x\u1EED l\xFD bi\u1EBFn \u0111\u1ED5i (Transform) '${e.input}'`);let r={startTime:Date.now(),totalGPUMemoryInMB:0,totalFilesProcessed:0,totalFileSizeInMB:0,totalFileSizeInMBBefore:0},s=e.input.toString(),o=Vr(n.config?.toString(),s,{logger:t});n.usecase&&(t.info("\u0110ang s\u1EED d\u1EE5ng usecase: "+n.usecase),o={...In(n.usecase.toString()),...o},o.usecase!=="default"&&o.usecase!==n.usecase.toString()?t.warn(`Xung \u0111\u1ED9t usecase. C\u1EA5u h\xECnh c\u1EE5 th\u1EC3 c\u1EE7a b\u1EA1n t\u1EA1i "${n.config}" c\xF3 m\u1ED9t usecase kh\xE1c v\u1EDBi usecase \u0111\u01B0\u1EE3c cung c\u1EA5p qua CLI: "${n.usecase}". S\u1EBD \u01B0u ti\xEAn s\u1EED d\u1EE5ng usecase t\u1EEB file c\u1EA5u h\xECnh.`):o.usecase=n.usecase.toString());let i=Fe(s),a=e.output?.toString();!i&&!a&&(a=s);let u=a&&Fe(a);if(i&&a&&!u&&(t.error("Khi <input> l\xE0 m\u1ED9t th\u01B0 m\u1EE5c th\xEC <output> c\u0169ng b\u1EAFt bu\u1ED9c ph\u1EA3i l\xE0 m\u1ED9t th\u01B0 m\u1EE5c"),process.exit(Le.INVALID_ARGS)),a&&Zr.isAbsolute(a)===!1){let g=Ve(s);a=ba(g,a)}let m=new Set,c=n.cache!==!1,l=n.debug===!0,f=n.verbose===!0;await He(s,async g=>{if(ya(g)){if(g!==s&&n.progressive===!0&&ge(g)){t.debug(`\u2192 B\u1ECF qua file LOD hi\u1EC7n c\xF3 t\u1EA1i ${g}`);return}}else if(ge(g)){t.warn(`WARN: \u0110ang b\u1ECF qua file \u0111\xE3 t\xECm th\u1EA5y tr\u01B0\u1EDBc \u0111\xF3 nh\u01B0ng hi\u1EC7n kh\xF4ng c\xF2n t\u1ED3n t\u1EA1i: "${g}"`);return}else t.error(`ERR: File \u0111\xE3 t\xECm th\u1EA5y tr\u01B0\u1EDBc \u0111\xF3 hi\u1EC7n \u0111ang b\u1ECB thi\u1EBFu m\u1EA5t: "${g}"`),process.exit(Le.LOST_FILE);t.info(`\u2192 \u0110ang bi\u1EBFn \u0111\u1ED5i (Transform) ${g}`);let p=new Array;if(n.progressive===!0&&(await ar({path:g,outpath:a,results:p,config:o,debug:l,verbose:f,useCache:c,logger:t}).catch(h=>{t.error(h),process.exit(Le.PROGRESSIVE_FAILED)})===!1&&process.exit(Le.PROGRESSIVE_FAILED),f&&console.log(`K\u1EBFt qu\u1EA3 t\u1EA3i l\u0169y ti\u1EBFn (Progressive results):
34
- `,p)),n.compress===!0){let h={config:o,stats:r,packedFiles:m,debug:l,verbose:f,useCache:c,logger:t,sourceFile:p.length>0?g:void 0};if(p.length>0)for(let y of p)await wn(y,y,h)===!1&&process.exit(Le.PACKING_FAILED);else await wn(g,a,h)===!1&&process.exit(Le.PACKING_FAILED)}}),fr(r,t,o),c&&zn()});ae.run().catch(t=>{if(!(t.message.includes("Unknown command")&&!t.message.includes("Did you mean")))throw t});
32
+ `).argument("<input>","File glTF, GLB ho\u1EB7c VRM \u0111\u1EA7u v\xE0o c\u1EA7n \u0111\u01B0\u1EE3c n\xE9n HO\u1EB6C m\u1ED9t th\u01B0 m\u1EE5c ch\u1EE9a c\xE1c file c\u1EA7n n\xE9n").argument("<output>","File ho\u1EB7c th\u01B0 m\u1EE5c \u0111\u1EA7u ra. N\xF3 c\xF3 th\u1EC3 l\xE0 m\u1ED9t \u0111\u01B0\u1EDDng d\u1EABn tuy\u1EC7t \u0111\u1ED1i ho\u1EB7c \u0111\u01B0\u1EDDng d\u1EABn t\u01B0\u01A1ng \u0111\u1ED1i so v\u1EDBi file \u0111\u1EA7u v\xE0o. N\u1EBFu kh\xF4ng \u0111\u01B0\u1EE3c cung c\u1EA5p, file \u0111\u1EA7u v\xE0o s\u1EBD b\u1ECB ghi \u0111\xE8.",{default:null}).option("--compress","Khi \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file s\u1EBD \u0111\u01B0\u1EE3c n\xE9n l\u1EA1i",{validator:ae.BOOLEAN,default:!0}).option("--progressive","Khi \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file s\u1EBD \u0111\u01B0\u1EE3c x\u1EED l\xFD \u0111\u1EC3 h\u1ED7 tr\u1EE3 t\u1EA3i l\u0169y ti\u1EBFn (progressive loading)",{validator:ae.BOOLEAN,default:!0}).option("--usecase <usecase>",`M\u1EE5c \u0111\xEDch s\u1EED d\u1EE5ng (usecase) cho vi\u1EC7c n\xE9n. \u0110i\u1EC1u n\xE0y s\u1EBD thi\u1EBFt l\u1EADp c\xE1c c\u1EA5u h\xECnh n\xE9n t\u01B0\u01A1ng \u1EE9ng. C\xE1c t\xF9y ch\u1ECDn kh\u1EA3 thi: [${vt.join(", ")}]`,{validator:ae.STRING}).option("--config <config>",'\u0110\u01B0\u1EDDng d\u1EABn t\u1EDBi file JSON ch\u1EE9a c\u1EA5u h\xECnh n\xE9n. \u0110\xE2y c\u0169ng c\xF3 th\u1EC3 l\xE0 file gltf.config.json v\u1EDBi object "compression" ho\u1EB7c chu\u1ED7i usecase.',{validator:ae.STRING}).option("--cache",`S\u1EED d\u1EE5ng "--cache False" \u0111\u1EC3 t\u1EAFt b\u1ED9 nh\u1EDB \u0111\u1EC7m.
33
+ Khi b\u1ED9 nh\u1EDB \u0111\u1EC7m \u0111\u01B0\u1EE3c b\u1EADt, c\xE1c file \u0111\xE3 \u0111\u01B0\u1EE3c x\u1EED l\xFD tr\u01B0\u1EDBc \u0111\xF3 s\u1EBD \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n v\xE0 t\u1EA3i t\u1EEB cache \u1ED5 \u0111\u0129a thay v\xEC ph\u1EA3i x\u1EED l\xFD l\u1EA1i n\u1EBFu c\xE1c thi\u1EBFt l\u1EADp ho\u1EB7c n\u1ED9i dung file kh\xF4ng thay \u0111\u1ED5i.`,{validator:ae.BOOLEAN,default:!0}).option("--debug",'B\u1EADt t\xEDnh n\u0103ng n\xE0y \u0111\u1EC3 xu\u1EA5t ra nhi\u1EC1u log h\u01A1n b\u1EB1ng c\xE1ch d\xF9ng "--debug True"',{validator:ae.BOOLEAN,default:!1}).option("--verbose",'B\u1EADt t\xEDnh n\u0103ng n\xE0y \u0111\u1EC3 xu\u1EA5t ra c\u1EF1c k\u1EF3 chi ti\u1EBFt b\u1EB1ng c\xE1ch d\xF9ng "--verbose True"',{validator:ae.BOOLEAN,default:!1}).action(async({logger:t,args:e,options:n})=>{t.level=n.debug||n.verbose?"debug":"info",n.compress===!1&&n.progressive===!1&&(t.error(`[Gltf LOD Pipeline] v${Y()} B\u1EA1n c\u1EA7n ph\u1EA3i b\u1EADt \xEDt nh\u1EA5t m\u1ED9t trong hai t\xF9y ch\u1ECDn: --compress ho\u1EB7c --progressive`),process.exit(Ne.INVALID_ARGS)),console.log(`info: [Gltf LOD Pipeline] v${Y()} \u2014 \u0110ang x\u1EED l\xFD bi\u1EBFn \u0111\u1ED5i (Transform) '${e.input}'`);let r={startTime:Date.now(),totalGPUMemoryInMB:0,totalFilesProcessed:0,totalFileSizeInMB:0,totalFileSizeInMBBefore:0},s=e.input.toString(),i=Pr(n.config?.toString(),s,{logger:t});n.usecase&&(t.info("\u0110ang s\u1EED d\u1EE5ng usecase: "+n.usecase),i={...dn(n.usecase.toString()),...i},i.usecase!=="default"&&i.usecase!==n.usecase.toString()?t.warn(`Xung \u0111\u1ED9t usecase. C\u1EA5u h\xECnh c\u1EE5 th\u1EC3 c\u1EE7a b\u1EA1n t\u1EA1i "${n.config}" c\xF3 m\u1ED9t usecase kh\xE1c v\u1EDBi usecase \u0111\u01B0\u1EE3c cung c\u1EA5p qua CLI: "${n.usecase}". S\u1EBD \u01B0u ti\xEAn s\u1EED d\u1EE5ng usecase t\u1EEB file c\u1EA5u h\xECnh.`):i.usecase=n.usecase.toString());let o=Fe(s),a=e.output?.toString();!o&&!a&&(a=s);let u=a&&Fe(a);if(o&&a&&!u&&(t.error("Khi <input> l\xE0 m\u1ED9t th\u01B0 m\u1EE5c th\xEC <output> c\u0169ng b\u1EAFt bu\u1ED9c ph\u1EA3i l\xE0 m\u1ED9t th\u01B0 m\u1EE5c"),process.exit(Ne.INVALID_ARGS)),a&&Fr.isAbsolute(a)===!1){let g=He(s);a=Vo(g,a)}let m=new Set,c=n.cache!==!1,l=n.debug===!0,f=n.verbose===!0;await Ke(s,async g=>{if(Ho(g)){if(g!==s&&n.progressive===!0&&ge(g)){t.debug(`\u2192 B\u1ECF qua file LOD hi\u1EC7n c\xF3 t\u1EA1i ${g}`);return}}else if(ge(g)){t.warn(`WARN: \u0110ang b\u1ECF qua file \u0111\xE3 t\xECm th\u1EA5y tr\u01B0\u1EDBc \u0111\xF3 nh\u01B0ng hi\u1EC7n kh\xF4ng c\xF2n t\u1ED3n t\u1EA1i: "${g}"`);return}else t.error(`ERR: File \u0111\xE3 t\xECm th\u1EA5y tr\u01B0\u1EDBc \u0111\xF3 hi\u1EC7n \u0111ang b\u1ECB thi\u1EBFu m\u1EA5t: "${g}"`),process.exit(Ne.LOST_FILE);t.info(`\u2192 \u0110ang bi\u1EBFn \u0111\u1ED5i (Transform) ${g}`);let p=new Array;if(n.progressive===!0&&(await Kn({path:g,outpath:a,results:p,config:i,debug:l,verbose:f,useCache:c,logger:t}).catch(d=>{t.error(d),process.exit(Ne.PROGRESSIVE_FAILED)})===!1&&process.exit(Ne.PROGRESSIVE_FAILED),f&&console.log(`K\u1EBFt qu\u1EA3 t\u1EA3i l\u0169y ti\u1EBFn (Progressive results):
34
+ `,p)),n.compress===!0){let d={config:i,stats:r,packedFiles:m,debug:l,verbose:f,useCache:c,logger:t,sourceFile:p.length>0?g:void 0};if(p.length>0)for(let y of p)await hn(y,y,d)===!1&&process.exit(Ne.PACKING_FAILED);else await hn(g,a,d)===!1&&process.exit(Ne.PACKING_FAILED)}}),Yn(r,t,i),c&&Pn()});ae.run().catch(t=>{if(!(t.message.includes("Unknown command")&&!t.message.includes("Did you mean")))throw t});
@@ -0,0 +1,68 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export function pmrem_exr(input: Uint8Array): Uint8Array;
5
+
6
+ /**
7
+ * Generate PMREM EXR bytes from input EXR, after downscaling the equirectangular source to target width.
8
+ * If `target_width` is >= source width, no resizing is performed.
9
+ */
10
+ export function pmrem_exr_resized(input: Uint8Array, target_width: number): Uint8Array;
11
+
12
+ /**
13
+ * PMREM with optional downscale and filter selection ("lanczos"|"bicubic"|"bilinear").
14
+ */
15
+ export function pmrem_exr_resized_with_filter(input: Uint8Array, target_width: number, filter: string): Uint8Array;
16
+
17
+ /**
18
+ * Resize equirectangular EXR to target width (maintain aspect), returning EXR bytes.
19
+ */
20
+ export function resize_equirect_exr(input: Uint8Array, target_width: number): Uint8Array;
21
+
22
+ /**
23
+ * Resize equirectangular EXR to target width with chosen filter ("lanczos"|"bicubic"|"bilinear").
24
+ */
25
+ export function resize_equirect_exr_with_filter(input: Uint8Array, target_width: number, filter: string): Uint8Array;
26
+
27
+ /**
28
+ * Split a PMREM CubeUV EXR buffer into cube face EXR images per mip level, packaged as a ZIP.
29
+ */
30
+ export function split_pmrem_exr_to_zip(input: Uint8Array): Uint8Array;
31
+
32
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
33
+
34
+ export interface InitOutput {
35
+ readonly memory: WebAssembly.Memory;
36
+ readonly pmrem_exr: (a: number, b: number, c: number) => void;
37
+ readonly pmrem_exr_resized: (a: number, b: number, c: number, d: number) => void;
38
+ readonly pmrem_exr_resized_with_filter: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
39
+ readonly resize_equirect_exr: (a: number, b: number, c: number, d: number) => void;
40
+ readonly resize_equirect_exr_with_filter: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
41
+ readonly split_pmrem_exr_to_zip: (a: number, b: number, c: number) => void;
42
+ readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
43
+ readonly __wbindgen_export: (a: number, b: number) => number;
44
+ readonly __wbindgen_export2: (a: number, b: number, c: number) => void;
45
+ readonly __wbindgen_export3: (a: number, b: number, c: number, d: number) => number;
46
+ }
47
+
48
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
49
+
50
+ /**
51
+ * Instantiates the given `module`, which can either be bytes or
52
+ * a precompiled `WebAssembly.Module`.
53
+ *
54
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
55
+ *
56
+ * @returns {InitOutput}
57
+ */
58
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
59
+
60
+ /**
61
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
62
+ * for everything else, calls `WebAssembly.instantiate` directly.
63
+ *
64
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
65
+ *
66
+ * @returns {Promise<InitOutput>}
67
+ */
68
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anhldh/gltf-lod-pipeline",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "CLI pipeline for generating glTF LOD variants with texture, mesh, and geometry optimizations.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,23 +31,18 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@donmccurdy/caporal": "^0.0.10",
34
- "@gltf-transform/core": "^4.3.0",
35
- "@gltf-transform/extensions": "^4.3.0",
36
- "@gltf-transform/functions": "^4.3.0",
34
+ "@gltf-transform/core": "^4.4.0",
35
+ "@gltf-transform/extensions": "^4.4.0",
36
+ "@gltf-transform/functions": "^4.4.0",
37
37
  "command-exists": "^1.2.9",
38
- "command-line-args": "^6.0.2",
39
38
  "draco3dgltf": "^1.5.7",
40
- "glob": "^13.0.6",
41
- "meshoptimizer": "^1.1.0",
39
+ "meshoptimizer": "^1.1.1",
42
40
  "micromatch": "^4.0.8",
43
- "ndarray": "^1.0.19",
44
- "ndarray-lanczos": "^0.3.0",
45
- "ndarray-pixels": "^5.0.1",
46
41
  "p-limit": "^7.3.0",
47
42
  "semver": "^7.7.4",
48
- "sharp": "^0.34.5",
49
- "tmp": "^0.2.5",
50
- "uuid": "^13.0.0",
43
+ "sharp": "0.34.5",
44
+ "tmp": "^0.2.7",
45
+ "uuid": "^14.0.0",
51
46
  "xxhash-wasm": "^1.1.0"
52
47
  },
53
48
  "devDependencies": {
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- #! /usr/bin/env node