@anhldh/gltf-lod-pipeline 0.0.7

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/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # glTF LOD Pipeline
2
+
3
+ Creating optimized glTF, GLB and VRM files for the web.
4
+
5
+ Includes support for generating LOD quality level for textures and meshes.
6
+
7
+ ## Usage
8
+
9
+ In general all files that have been processed by this package are valid glTF/GLB files.
10
+ The glTF Build Pipeline package is meant to be used as a last step before delivery.
11
+ That means:
12
+
13
+ - files are meant to be loaded e.g. in a web runtime like three.js
14
+
15
+ ### Installation
16
+
17
+ ### Commands
18
+
19
+ - `help` - use help to view options
@@ -0,0 +1 @@
1
+ #! /usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
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.
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,`
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:
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:
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
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}
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.
19
+ \u0110\xE3 th\u1EED:
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(`
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:
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(`
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
+ 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});
@@ -0,0 +1 @@
1
+ d8f36fcbb09e79614e96baaed5b1e1cd5d2f5e73
@@ -0,0 +1 @@
1
+ d8f36fcbb09e79614e96baaed5b1e1cd5d2f5e73
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1 @@
1
+ d8f36fcbb09e79614e96baaed5b1e1cd5d2f5e73