@vctrl/hooks 0.5.0 → 0.7.0

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 CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ## Overview
10
10
 
11
- `@vctrl/hooks` is a React hooks package designed to simplify 3D model loading, optimization, and exporting within React applications. It's part of the vectreal-core ecosystem and is primarily used in the `@vctrl/viewer` React component and the official website application.
11
+ `@vctrl/hooks` is a React hooks package designed to simplify 3D model loading, optimization, and exporting within React applications. It's part of the [vectreal-core](https://github.com/vectreal/vectreal-core) ecosystem and is primarily used in the [`@vctrl/viewer`](https://www.npmjs.com/package/@vctrl/viewer?activeTab=readme) React component and the [official website application](https://core.vectreal.com).
12
12
 
13
13
  The package provides powerful hooks for:
14
14
 
@@ -177,11 +177,12 @@ function ModelLoader() {
177
177
  }
178
178
  ```
179
179
 
180
- The `optimize` object includes:
180
+ The `optimize` object includes quick access optimization:
181
181
 
182
- - `simplifyOptimization()`: Simplifies the model using mesh simplification.
183
- - `dedupOptimization()`: Removes duplicate vertices and meshes.
184
- - `quantizeOptimization()`: Reduces the precision of vertex attributes.
182
+ - `simplifyOptimization(options)`: Simplifies the model using mesh simplification.
183
+ - `dedupOptimization(options)`: Removes duplicate vertices and meshes.
184
+ - `quantizeOptimization(options)`: Reduces the precision of vertex attributes.
185
+ - `texturesCompressionOptimization(options)`: Compresses the relevant textures in the model file using texture compression.
185
186
 
186
187
  ### useOptimizeModel
187
188
 
@@ -295,9 +296,15 @@ The `useOptimizeModel` hook returns the following:
295
296
 
296
297
  - `load(model)`: Loads a Three.js `Object3D` model into the optimizer.
297
298
  - `getModel()`: Retrieves the optimized model as a binary array buffer.
298
- - `simplifyOptimization()`: Simplifies the current model using the `MeshoptSimplifier`.
299
- - `dedupOptimization()`: Removes duplicate vertices and meshes.
300
- - `quantizeOptimization()`: Reduces the precision of vertex attributes.
299
+ - `simplifyOptimization(options)`: Simplifies the current model using the `MeshoptSimplifier`.
300
+ - `dedupOptimization(options)`: Removes duplicate vertices and meshes.
301
+ - `quantizeOptimization(options)`: Reduces the precision of vertex attributes.
302
+ - `texturesOptimization(options)`: Compresses related textures.
303
+ - `getSize()`: Object with byte size of gltf scene and a formatted megabyte string
304
+ - `reset()`: Resets the current optimizer model and report state.
305
+ - `report`: @gltf-transform gltf report object with relevant details about a gltf scene
306
+ - `error`: Stores any possible optimization errors
307
+ - `loading`: Boolean for when the model is being loaded
301
308
 
302
309
  ### useExportModel
303
310
 
package/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./model-context-ChF_IVjD.cjs"),o=require("./use-optimize-model-BN-fP4La.cjs"),t=require("./use-export-model-BBfXwJbA.cjs");exports.ModelContext=e.ModelContext;exports.ModelFileTypes=e.ModelFileTypes;exports.ModelProvider=e.ModelProvider;exports.useLoadModel=e.useLoadModel;exports.useModelContext=e.useModelContext;exports.useOptimizeModel=o.useOptimizeModel;exports.useExportModel=t.useExportModel;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./model-context-DLPGvQ8f.cjs"),o=require("./use-optimize-model-7wjiNiSZ.cjs"),t=require("./use-export-model-BBfXwJbA.cjs");exports.ModelContext=e.ModelContext;exports.ModelFileTypes=e.ModelFileTypes;exports.ModelProvider=e.ModelProvider;exports.useLoadModel=e.useLoadModel;exports.useModelContext=e.useModelContext;exports.useOptimizeModel=o.useOptimizeModel;exports.useExportModel=t.useExportModel;
package/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as s, M as a, b as d, u as r, c as t } from "./model-context-DDCJu7oe.js";
2
- import { u as M } from "./use-optimize-model-C46Fr7jH.js";
1
+ import { a as s, M as a, b as d, u as r, c as t } from "./model-context-hgFMs-nK.js";
2
+ import { u as M } from "./use-optimize-model-CVcoeFrO.js";
3
3
  import { u as p } from "./use-export-model-CUUL3YCH.js";
4
4
  export {
5
5
  s as ModelContext,
@@ -6,4 +6,4 @@ fflate - fast JavaScript compression/decompression
6
6
  Licensed under MIT. https://github.com/101arrowz/fflate/blob/master/LICENSE
7
7
  version 0.8.2
8
8
  */var v=Uint8Array,nA=Uint16Array,Dt=Int32Array,Qe=new v([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),de=new v([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Rt=new v([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),he=function(n,A){for(var e=new nA(31),a=0;a<31;++a)e[a]=A+=1<<n[a-1];for(var t=new Dt(e[30]),a=1;a<30;++a)for(var i=e[a];i<e[a+1];++i)t[i]=i-e[a]<<5|a;return{b:e,r:t}},pe=he(Qe,2),ue=pe.b,Ft=pe.r;ue[28]=258,Ft[258]=28;var kt=he(de,0),St=kt.b,xA=new nA(32768);for(var M=0;M<32768;++M){var eA=(M&43690)>>1|(M&21845)<<1;eA=(eA&52428)>>2|(eA&13107)<<2,eA=(eA&61680)>>4|(eA&3855)<<4,xA[M]=((eA&65280)>>8|(eA&255)<<8)>>1}var IA=function(n,A,e){for(var a=n.length,t=0,i=new nA(A);t<a;++t)n[t]&&++i[n[t]-1];var s=new nA(A);for(t=1;t<A;++t)s[t]=s[t-1]+i[t-1]<<1;var o;if(e){o=new nA(1<<A);var r=15-A;for(t=0;t<a;++t)if(n[t])for(var c=t<<4|n[t],B=A-n[t],I=s[n[t]-1]++<<B,l=I|(1<<B)-1;I<=l;++I)o[xA[I]>>r]=c}else for(o=new nA(a),t=0;t<a;++t)n[t]&&(o[t]=xA[s[n[t]-1]++]>>15-n[t]);return o},BA=new v(288);for(var M=0;M<144;++M)BA[M]=8;for(var M=144;M<256;++M)BA[M]=9;for(var M=256;M<280;++M)BA[M]=7;for(var M=280;M<288;++M)BA[M]=8;var me=new v(32);for(var M=0;M<32;++M)me[M]=5;var yt=IA(BA,9,1),Gt=IA(me,5,1),RA=function(n){for(var A=n[0],e=1;e<n.length;++e)n[e]>A&&(A=n[e]);return A},J=function(n,A,e){var a=A/8|0;return(n[a]|n[a+1]<<8)>>(A&7)&e},FA=function(n,A){var e=A/8|0;return(n[e]|n[e+1]<<8|n[e+2]<<16)>>(A&7)},xt=function(n){return(n+7)/8|0},UA=function(n,A,e){return(A==null||A<0)&&(A=0),(e==null||e>n.length)&&(e=n.length),new v(n.subarray(A,e))},Lt=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],j=function(n,A,e){var a=new Error(A||Lt[n]);if(a.code=n,Error.captureStackTrace&&Error.captureStackTrace(a,j),!e)throw a;return a},Tt=function(n,A,e,a){var t=n.length,i=a?a.length:0;if(!t||A.f&&!A.l)return e||new v(0);var s=!e,o=s||A.i!=2,r=A.i;s&&(e=new v(t*3));var c=function(OA){var vA=e.length;if(OA>vA){var PA=new v(Math.max(vA*2,OA));PA.set(e),e=PA}},B=A.f||0,I=A.p||0,l=A.b||0,C=A.l,E=A.d,h=A.m,u=A.n,Q=t*8;do{if(!C){B=J(n,I,1);var f=J(n,I+1,3);if(I+=3,f)if(f==1)C=yt,E=Gt,h=9,u=5;else if(f==2){var S=J(n,I,31)+257,x=J(n,I+10,15)+4,U=S+J(n,I+5,31)+1;I+=14;for(var b=new v(U),d=new v(19),w=0;w<x;++w)d[Rt[w]]=J(n,I+w*3,7);I+=x*3;for(var R=RA(d),D=(1<<R)-1,y=IA(d,R,1),w=0;w<U;){var k=y[J(n,I,D)];I+=k&15;var p=k>>4;if(p<16)b[w++]=p;else{var L=0,T=0;for(p==16?(T=3+J(n,I,3),I+=2,L=b[w-1]):p==17?(T=3+J(n,I,7),I+=3):p==18&&(T=11+J(n,I,127),I+=7);T--;)b[w++]=L}}var N=b.subarray(0,S),H=b.subarray(S);h=RA(N),u=RA(H),C=IA(N,h,1),E=IA(H,u,1)}else j(1);else{var p=xt(I)+4,m=n[p-4]|n[p-3]<<8,F=p+m;if(F>t){r&&j(0);break}o&&c(l+m),e.set(n.subarray(p,F),l),A.b=l+=m,A.p=I=F*8,A.f=B;continue}if(I>Q){r&&j(0);break}}o&&c(l+131072);for(var K=(1<<h)-1,$=(1<<u)-1,iA=I;;iA=I){var L=C[FA(n,I)&K],tA=L>>4;if(I+=L&15,I>Q){r&&j(0);break}if(L||j(2),tA<256)e[l++]=tA;else if(tA==256){iA=I,C=null;break}else{var _A=tA-254;if(tA>264){var w=tA-257,rA=Qe[w];_A=J(n,I,(1<<rA)-1)+ue[w],I+=rA}var lA=E[FA(n,I)&$],CA=lA>>4;lA||j(3),I+=lA&15;var H=St[CA];if(CA>3){var rA=de[CA];H+=FA(n,I)&(1<<rA)-1,I+=rA}if(I>Q){r&&j(0);break}o&&c(l+131072);var qA=l+_A;if(l<H){var HA=i-H,De=Math.min(H,qA);for(HA+l<0&&j(3);l<De;++l)e[l]=a[HA+l]}for(;l<qA;++l)e[l]=e[l-H]}}A.l=C,A.p=iA,A.b=l,A.f=B,C&&(B=1,A.m=h,A.d=E,A.n=u)}while(!B);return l!=e.length&&s?UA(e,0,l):e.subarray(0,l)},Mt=new v(0),V=function(n,A){return n[A]|n[A+1]<<8},Y=function(n,A){return(n[A]|n[A+1]<<8|n[A+2]<<16|n[A+3]<<24)>>>0},kA=function(n,A){return Y(n,A)+Y(n,A+4)*4294967296};function Ut(n,A){return Tt(n,{i:2},A&&A.out,A&&A.dictionary)}var LA=typeof TextDecoder<"u"&&new TextDecoder,Nt=0;try{LA.decode(Mt,{stream:!0}),Nt=1}catch{}var _t=function(n){for(var A="",e=0;;){var a=n[e++],t=(a>127)+(a>223)+(a>239);if(e+t>n.length)return{s:A,r:UA(n,e-1)};t?t==3?(a=((a&15)<<18|(n[e++]&63)<<12|(n[e++]&63)<<6|n[e++]&63)-65536,A+=String.fromCharCode(55296|a>>10,56320|a&1023)):t&1?A+=String.fromCharCode((a&31)<<6|n[e++]&63):A+=String.fromCharCode((a&15)<<12|(n[e++]&63)<<6|n[e++]&63):A+=String.fromCharCode(a)}};function TA(n,A){if(A){for(var e="",a=0;a<n.length;a+=16384)e+=String.fromCharCode.apply(null,n.subarray(a,a+16384));return e}else{if(LA)return LA.decode(n);var t=_t(n),i=t.s,e=t.r;return e.length&&j(8),i}}var qt=function(n,A){return A+30+V(n,A+26)+V(n,A+28)},Ht=function(n,A,e){var a=V(n,A+28),t=TA(n.subarray(A+46,A+46+a),!(V(n,A+8)&2048)),i=A+46+a,s=Y(n,A+20),o=e&&s==4294967295?Ot(n,i):[s,Y(n,A+24),Y(n,A+42)],r=o[0],c=o[1],B=o[2];return[V(n,A+10),r,c,t,i+V(n,A+30)+V(n,A+32),B]},Ot=function(n,A){for(;V(n,A)!=1;A+=4+V(n,A+2));return[kA(n,A+12),kA(n,A+4),kA(n,A+20)]};function vt(n,A){for(var e={},a=n.length-22;Y(n,a)!=101010256;--a)(!a||n.length-a>65558)&&j(13);var t=V(n,a+8);if(!t)return{};var i=Y(n,a+16),s=i==4294967295||t==65535;if(s){var o=Y(n,a-12);s=Y(n,o)==101075792,s&&(t=Y(n,o+32),i=Y(n,o+48))}for(var r=0;r<t;++r){var c=Ht(n,i,s),B=c[0],I=c[1],l=c[2],C=c[3],E=c[4],h=c[5],u=qt(n,h);i=E,B?B==8?e[C]=Ut(n.subarray(u,u+I),{out:new v(l)}):j(14,"unknown compression type "+B):e[C]=UA(n,u,u+I)}return e}class Pt{parse(A){const e={},a=A.split(`
9
- `);let t=null,i=e;const s=[e];for(const o of a)if(o.includes("=")){const r=o.split("="),c=r[0].trim(),B=r[1].trim();if(B.endsWith("{")){const I={};s.push(I),i[c]=I,i=I}else if(B.endsWith("(")){const I=B.slice(0,-1);i[c]=I;const l={};s.push(l),i=l}else i[c]=B}else if(o.endsWith("{")){const r=i[t]||{};s.push(r),i[t]=r,i=r}else if(o.endsWith("}")){if(s.pop(),s.length===0)continue;i=s[s.length-1]}else if(o.endsWith("(")){const r={};s.push(r),t=o.split("(")[0].trim()||t,i[t]=r,i=r}else o.endsWith(")")?(s.pop(),i=s[s.length-1]):t=o.trim();return e}}class jt extends g.Loader{constructor(A){super(A)}load(A,e,a,t){const i=this,s=new g.FileLoader(i.manager);s.setPath(i.path),s.setResponseType("arraybuffer"),s.setRequestHeader(i.requestHeader),s.setWithCredentials(i.withCredentials),s.load(A,function(o){try{e(i.parse(o))}catch(r){t?t(r):console.error(r),i.manager.itemError(A)}},a,t)}parse(A){const e=new Pt;function a(b){const d={};new g.FileLoader().setResponseType("arraybuffer");for(const R in b){if(R.endsWith("png")){const D=new Blob([b[R]],{type:{type:"image/png"}});d[R]=URL.createObjectURL(D)}if(R.endsWith("usd")||R.endsWith("usda")){if(t(b[R]))throw Error("THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.");const D=TA(b[R]);d[R]=e.parse(D)}}return d}function t(b){const d=b.slice(0,7),w=new Uint8Array([80,88,82,45,85,83,68,67]);return d.every((R,D)=>R===w[D])}function i(b){if(b.length<1)return;const d=Object.keys(b)[0];let w=!1;if(d.endsWith("usda"))return b[d];if(d.endsWith("usdc"))w=!0;else if(d.endsWith("usd"))if(t(b[d]))w=!0;else return b[d];if(w)throw Error("THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.")}const s=vt(new Uint8Array(A)),o=a(s),r=i(s),c=TA(r),B=e.parse(c);function I(b){if(b){if("prepend references"in b){const w=b["prepend references"].split("@"),R=w[1].replace(/^.\//,""),D=w[2].replace(/^<\//,"").replace(/>$/,"");return l(o[R],D)}return l(b)}}function l(b,d){if(b){if(d!==void 0){const w=`def Mesh "${d}"`;if(w in b)return b[w]}for(const w in b){const R=b[w];if(w.startsWith("def Mesh"))return R;if(typeof R=="object"){const D=l(R);if(D)return D}}}}function C(b){if(!b)return;const d=new g.BufferGeometry;let w=null,R=null,D=null,y=-1;if("int[] faceVertexIndices"in b&&(w=JSON.parse(b["int[] faceVertexIndices"])),"int[] faceVertexCounts"in b&&(R=JSON.parse(b["int[] faceVertexCounts"]),w=E(w,R)),"point3f[] points"in b){const k=JSON.parse(b["point3f[] points"].replace(/[()]*/g,""));y=k.length;let L=new g.BufferAttribute(new Float32Array(k),3);w!==null&&(L=h(L,w)),d.setAttribute("position",L)}if("float2[] primvars:st"in b&&(b["texCoord2f[] primvars:st"]=b["float2[] primvars:st"]),"texCoord2f[] primvars:st"in b){D=JSON.parse(b["texCoord2f[] primvars:st"].replace(/[()]*/g,""));let k=new g.BufferAttribute(new Float32Array(D),2);w!==null&&(k=h(k,w)),d.setAttribute("uv",k)}if("int[] primvars:st:indices"in b&&D!==null){const k=new g.BufferAttribute(new Float32Array(D),2);let L=JSON.parse(b["int[] primvars:st:indices"]);L=E(L,R),d.setAttribute("uv",h(k,L))}if("normal3f[] normals"in b){const k=JSON.parse(b["normal3f[] normals"].replace(/[()]*/g,""));let L=new g.BufferAttribute(new Float32Array(k),3);if(k.length===y)w!==null&&(L=h(L,w));else{let T=Array.from(Array(k.length/3).keys());T=E(T,R),L=h(L,T)}d.setAttribute("normal",L)}else d.computeVertexNormals();return d}function E(b,d){const w=[];for(let R=0;R<d.length;R++){const D=d[R],y=R*D;if(D===3){const k=b[y+0],L=b[y+1],T=b[y+2];w.push(k,L,T)}else if(D===4){const k=b[y+0],L=b[y+1],T=b[y+2],N=b[y+3];w.push(k,L,T),w.push(k,T,N)}else console.warn("THREE.USDZLoader: Face vertex count of %s unsupported.",D)}return w}function h(b,d){const w=b.array,R=b.itemSize,D=new w.constructor(d.length*R);let y=0,k=0;for(let L=0,T=d.length;L<T;L++){y=d[L]*R;for(let N=0;N<R;N++)D[k++]=w[y++]}return new g.BufferAttribute(D,R)}function u(b){if(b){if("rel material:binding"in b){const R=b["rel material:binding"].replace(/^<\//,"").replace(/>$/,"").split("/");return Q(B,` "${R[1]}"`)}return Q(b)}}function Q(b,d=""){for(const w in b){const R=b[w];if(w.startsWith("def Material"+d))return R;if(typeof R=="object"){const D=Q(R,d);if(D)return D}}}function f(b,d){d["float inputs:rotation"]&&(b.rotation=parseFloat(d["float inputs:rotation"])),d["float2 inputs:scale"]&&(b.repeat=new g.Vector2().fromArray(JSON.parse("["+d["float2 inputs:scale"].replace(/[()]*/g,"")+"]"))),d["float2 inputs:translation"]&&(b.offset=new g.Vector2().fromArray(JSON.parse("["+d["float2 inputs:translation"].replace(/[()]*/g,"")+"]")))}function p(b){const d=new g.MeshPhysicalMaterial;if(b!==void 0){const w=b["token outputs:surface.connect"],R=/(\w+).output/.exec(w)[1],D=b[`def Shader "${R}"`];if(D!==void 0){if("color3f inputs:diffuseColor.connect"in D){const y=D["color3f inputs:diffuseColor.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.map=F(k),d.map.colorSpace=g.SRGBColorSpace,'def Shader "Transform2d_diffuse"'in b&&f(d.map,b['def Shader "Transform2d_diffuse"'])}else if("color3f inputs:diffuseColor"in D){const y=D["color3f inputs:diffuseColor"].replace(/[()]*/g,"");d.color.fromArray(JSON.parse("["+y+"]"))}if("color3f inputs:emissiveColor.connect"in D){const y=D["color3f inputs:emissiveColor.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.emissiveMap=F(k),d.emissiveMap.colorSpace=g.SRGBColorSpace,d.emissive.set(16777215),'def Shader "Transform2d_emissive"'in b&&f(d.emissiveMap,b['def Shader "Transform2d_emissive"'])}else if("color3f inputs:emissiveColor"in D){const y=D["color3f inputs:emissiveColor"].replace(/[()]*/g,"");d.emissive.fromArray(JSON.parse("["+y+"]"))}if("normal3f inputs:normal.connect"in D){const y=D["normal3f inputs:normal.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.normalMap=F(k),d.normalMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_normal"'in b&&f(d.normalMap,b['def Shader "Transform2d_normal"'])}if("float inputs:roughness.connect"in D){const y=D["float inputs:roughness.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.roughness=1,d.roughnessMap=F(k),d.roughnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_roughness"'in b&&f(d.roughnessMap,b['def Shader "Transform2d_roughness"'])}else"float inputs:roughness"in D&&(d.roughness=parseFloat(D["float inputs:roughness"]));if("float inputs:metallic.connect"in D){const y=D["float inputs:metallic.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.metalness=1,d.metalnessMap=F(k),d.metalnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_metallic"'in b&&f(d.metalnessMap,b['def Shader "Transform2d_metallic"'])}else"float inputs:metallic"in D&&(d.metalness=parseFloat(D["float inputs:metallic"]));if("float inputs:clearcoat.connect"in D){const y=D["float inputs:clearcoat.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.clearcoat=1,d.clearcoatMap=F(k),d.clearcoatMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_clearcoat"'in b&&f(d.clearcoatMap,b['def Shader "Transform2d_clearcoat"'])}else"float inputs:clearcoat"in D&&(d.clearcoat=parseFloat(D["float inputs:clearcoat"]));if("float inputs:clearcoatRoughness.connect"in D){const y=D["float inputs:clearcoatRoughness.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.clearcoatRoughness=1,d.clearcoatRoughnessMap=F(k),d.clearcoatRoughnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_clearcoatRoughness"'in b&&f(d.clearcoatRoughnessMap,b['def Shader "Transform2d_clearcoatRoughness"'])}else"float inputs:clearcoatRoughness"in D&&(d.clearcoatRoughness=parseFloat(D["float inputs:clearcoatRoughness"]));if("float inputs:ior"in D&&(d.ior=parseFloat(D["float inputs:ior"])),"float inputs:occlusion.connect"in D){const y=D["float inputs:occlusion.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.aoMap=F(k),d.aoMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_occlusion"'in b&&f(d.aoMap,b['def Shader "Transform2d_occlusion"'])}}}return d}function m(b,d){for(const w in b){const R=b[w];if(w.startsWith(`def Shader "${d}"`))return R;if(typeof R=="object"){const D=m(R,d);if(D)return D}}}function F(b){if("asset inputs:file"in b){const d=b["asset inputs:file"].replace(/@*/g,"").trim(),R=new g.TextureLoader().load(o[d]),D={'"clamp"':g.ClampToEdgeWrapping,'"mirror"':g.MirroredRepeatWrapping,'"repeat"':g.RepeatWrapping};return"token inputs:wrapS"in b&&(R.wrapS=D[b["token inputs:wrapS"]]),"token inputs:wrapT"in b&&(R.wrapT=D[b["token inputs:wrapT"]]),R}return null}function S(b){const d=C(I(b)),w=p(u(b)),R=d?new g.Mesh(d,w):new g.Object3D;if("matrix4d xformOp:transform"in b){const D=JSON.parse("["+b["matrix4d xformOp:transform"].replace(/[()]*/g,"")+"]");R.matrix.fromArray(D),R.matrix.decompose(R.position,R.quaternion,R.scale)}return R}function x(b,d){for(const w in b)if(w.startsWith("def Scope"))x(b[w],d);else if(w.startsWith("def Xform")){const R=S(b[w]);/def Xform "(\w+)"/.test(w)&&(R.name=/def Xform "(\w+)"/.exec(w)[1]),d.add(R),x(b[w],R)}}const U=new g.Group;return x(B,U),U}}function Kt(){const n=new jt;return n.manager.onError=A=>{W.emit("load-error",`Failed to load file ${A}`)},n}function Jt(n){const A=q.useCallback(async(a,t,i)=>{var B,I;const s=new Map(t.map(l=>[l.name,l])),o=(((B=a.buffers)==null?void 0:B.length)||0)+(((I=a.images)==null?void 0:I.length)||0);let r=0;const c=()=>{r++,i(r/o*100)};if(a.buffers)for(let l=0;l<a.buffers.length;l++){const C=a.buffers[l];if(!C.uri||C.uri.startsWith("data:")){c();continue}const E=C.uri.split("/").pop()||"",h=s.get(E);if(h){const u=await h.arrayBuffer(),Q=await jA(u);C.uri=`data:application/octet-stream;base64,${Q}`}c()}if(a.images)for(let l=0;l<a.images.length;l++){const C=a.images[l];if(!C.uri||C.uri.startsWith("data:")){c();continue}const E=C.uri.split("/").pop()||"",h=s.get(E);if(h){const u=await h.arrayBuffer(),Q=await jA(u),f=h.type||"image/png";C.uri=`data:${f};base64,${Q}`}c()}return a},[]);return{loadGltf:q.useCallback((a,t,i)=>{const s=new FileReader;s.onload=async o=>{var I;const r=JSON.parse((I=o.target)==null?void 0:I.result);i(10);const c=await A(r,t,l=>{i(10+l*.8)});MA().parse(JSON.stringify(c),"",l=>{n({type:"set-file",payload:{model:l.scene,type:O.gltf,name:a.name}})}),i(100),n({type:"set-file-loading",payload:!1})},s.readAsText(a)},[n,A])}}function Yt(n){return{loadBinary:q.useCallback((e,a,t)=>{const i=new FileReader;i.onload=async s=>{var o;if((o=s.target)!=null&&o.result){const r=s.target.result;if(a===O.glb)MA().parse(r,"",B=>{n({type:"set-file",payload:{model:B.scene,type:O.glb,name:e.name}})});else if(a===O.usdz){const B=Kt().parse(r);n({type:"set-file",payload:{model:B,type:O.usdz,name:e.name}})}t(),n({type:"set-file-loading",payload:!1})}},i.onerror=s=>{console.error("Error reading file:",s),n({type:"set-file-loading",payload:!1})},i.readAsArrayBuffer(e)},[n])}}function we(n){const A=q.useRef(!1),[e,a]=q.useReducer(Fe,Ae),{loadGltf:t}=Jt(a),{loadBinary:i}=Yt(a),s=q.useCallback((l,C)=>l.find(E=>E.name.endsWith("."+C)),[]),o=q.useCallback(l=>{a({type:"set-progress",payload:l}),W.emit("load-progress",l)},[]),r=q.useCallback(()=>{a({type:"reset-state"}),W.emit("load-reset")},[]),c=q.useCallback(l=>{if(l.length===0)return;const C=s(l,O.gltf),E=s(l,O.glb),h=s(l,O.usdz),u=[C,E,h].filter(Boolean);if(u.length>1){W.emit("multiple-models",u);return}const Q=l.filter(p=>p!==C&&p!==E&&p!==h),f=p=>{o(p),p===100&&(A.current=!0)};if(C)t(C,Q,f);else if(E)i(E,O.glb,()=>f(100));else if(h)i(h,O.usdz,()=>f(100));else{W.emit("not-loaded-files",l),a({type:"set-file-loading",payload:!1});return}},[o,s,t,i]),B=q.useCallback(async l=>{const C=[];W.emit("load-start"),a({type:"reset-state"}),a({type:"set-file-loading",payload:!0}),o(0),A.current=!1;for(const E of l)if(E instanceof File)C.push(E);else if("kind"in E&&E.kind==="directory"){const h=await ke(E);C.push(...h)}c(C)},[c,o]);q.useEffect(()=>{A.current&&e.file&&(W.emit("load-complete",e.file),A.current=!1,n&&e.file.model&&n.load(e.file.model))},[e.file,n]);const I=Wt(n,a,e.file);return{...e,on:W.on,off:W.off,load:B,reset:r,optimize:I}}function Wt(n,A,e){const a=q.useCallback(i=>{MA().parse(i,"",o=>{A({type:"set-file",payload:{model:o.scene,type:O.glb,name:(e==null?void 0:e.name)||"optimized.glb"}})},o=>{console.error("Error loading new model:",o)})},[A,e]),t=q.useCallback(async(i,s)=>{if(!n||!i){console.warn("Optimizer or optimization function is not available");return}try{await i(s);const o=await n.getModel();o&&a(o)}catch(o){console.error("Optimization failed:",o)}},[n,a]);return n?{simplifyOptimization:i=>t(n.simplifyOptimization,i),dedupOptimization:i=>t(n.dedupOptimization,i),quantizeOptimization:i=>t(n.quantizeOptimization,i),getSize:n.getSize,reset:n.reset,report:n.report,error:n.error,loading:n.loading}:{simplifyOptimization:()=>{console.warn("Optimizer is not available")},dedupOptimization:()=>{console.warn("Optimizer is not available")},quantizeOptimization:()=>{console.warn("Optimizer is not available")},getSize:()=>{console.warn("Optimizer is not available")},reset:()=>{console.warn("Optimizer is not available")},report:null,error:null,loading:!1}}const NA=q.createContext({}),Vt=({children:n,optimizer:A})=>{const e=we(A);return Re.jsx(NA.Provider,{value:e,children:n})},zt=()=>q.useContext(NA);exports.ModelContext=NA;exports.ModelFileTypes=O;exports.ModelProvider=Vt;exports.useLoadModel=we;exports.useModelContext=zt;
9
+ `);let t=null,i=e;const s=[e];for(const o of a)if(o.includes("=")){const r=o.split("="),c=r[0].trim(),B=r[1].trim();if(B.endsWith("{")){const I={};s.push(I),i[c]=I,i=I}else if(B.endsWith("(")){const I=B.slice(0,-1);i[c]=I;const l={};s.push(l),i=l}else i[c]=B}else if(o.endsWith("{")){const r=i[t]||{};s.push(r),i[t]=r,i=r}else if(o.endsWith("}")){if(s.pop(),s.length===0)continue;i=s[s.length-1]}else if(o.endsWith("(")){const r={};s.push(r),t=o.split("(")[0].trim()||t,i[t]=r,i=r}else o.endsWith(")")?(s.pop(),i=s[s.length-1]):t=o.trim();return e}}class jt extends g.Loader{constructor(A){super(A)}load(A,e,a,t){const i=this,s=new g.FileLoader(i.manager);s.setPath(i.path),s.setResponseType("arraybuffer"),s.setRequestHeader(i.requestHeader),s.setWithCredentials(i.withCredentials),s.load(A,function(o){try{e(i.parse(o))}catch(r){t?t(r):console.error(r),i.manager.itemError(A)}},a,t)}parse(A){const e=new Pt;function a(b){const d={};new g.FileLoader().setResponseType("arraybuffer");for(const R in b){if(R.endsWith("png")){const D=new Blob([b[R]],{type:{type:"image/png"}});d[R]=URL.createObjectURL(D)}if(R.endsWith("usd")||R.endsWith("usda")){if(t(b[R]))throw Error("THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.");const D=TA(b[R]);d[R]=e.parse(D)}}return d}function t(b){const d=b.slice(0,7),w=new Uint8Array([80,88,82,45,85,83,68,67]);return d.every((R,D)=>R===w[D])}function i(b){if(b.length<1)return;const d=Object.keys(b)[0];let w=!1;if(d.endsWith("usda"))return b[d];if(d.endsWith("usdc"))w=!0;else if(d.endsWith("usd"))if(t(b[d]))w=!0;else return b[d];if(w)throw Error("THREE.USDZLoader: Crate files (.usdc or binary .usd) are not supported.")}const s=vt(new Uint8Array(A)),o=a(s),r=i(s),c=TA(r),B=e.parse(c);function I(b){if(b){if("prepend references"in b){const w=b["prepend references"].split("@"),R=w[1].replace(/^.\//,""),D=w[2].replace(/^<\//,"").replace(/>$/,"");return l(o[R],D)}return l(b)}}function l(b,d){if(b){if(d!==void 0){const w=`def Mesh "${d}"`;if(w in b)return b[w]}for(const w in b){const R=b[w];if(w.startsWith("def Mesh"))return R;if(typeof R=="object"){const D=l(R);if(D)return D}}}}function C(b){if(!b)return;const d=new g.BufferGeometry;let w=null,R=null,D=null,y=-1;if("int[] faceVertexIndices"in b&&(w=JSON.parse(b["int[] faceVertexIndices"])),"int[] faceVertexCounts"in b&&(R=JSON.parse(b["int[] faceVertexCounts"]),w=E(w,R)),"point3f[] points"in b){const k=JSON.parse(b["point3f[] points"].replace(/[()]*/g,""));y=k.length;let L=new g.BufferAttribute(new Float32Array(k),3);w!==null&&(L=h(L,w)),d.setAttribute("position",L)}if("float2[] primvars:st"in b&&(b["texCoord2f[] primvars:st"]=b["float2[] primvars:st"]),"texCoord2f[] primvars:st"in b){D=JSON.parse(b["texCoord2f[] primvars:st"].replace(/[()]*/g,""));let k=new g.BufferAttribute(new Float32Array(D),2);w!==null&&(k=h(k,w)),d.setAttribute("uv",k)}if("int[] primvars:st:indices"in b&&D!==null){const k=new g.BufferAttribute(new Float32Array(D),2);let L=JSON.parse(b["int[] primvars:st:indices"]);L=E(L,R),d.setAttribute("uv",h(k,L))}if("normal3f[] normals"in b){const k=JSON.parse(b["normal3f[] normals"].replace(/[()]*/g,""));let L=new g.BufferAttribute(new Float32Array(k),3);if(k.length===y)w!==null&&(L=h(L,w));else{let T=Array.from(Array(k.length/3).keys());T=E(T,R),L=h(L,T)}d.setAttribute("normal",L)}else d.computeVertexNormals();return d}function E(b,d){const w=[];for(let R=0;R<d.length;R++){const D=d[R],y=R*D;if(D===3){const k=b[y+0],L=b[y+1],T=b[y+2];w.push(k,L,T)}else if(D===4){const k=b[y+0],L=b[y+1],T=b[y+2],N=b[y+3];w.push(k,L,T),w.push(k,T,N)}else console.warn("THREE.USDZLoader: Face vertex count of %s unsupported.",D)}return w}function h(b,d){const w=b.array,R=b.itemSize,D=new w.constructor(d.length*R);let y=0,k=0;for(let L=0,T=d.length;L<T;L++){y=d[L]*R;for(let N=0;N<R;N++)D[k++]=w[y++]}return new g.BufferAttribute(D,R)}function u(b){if(b){if("rel material:binding"in b){const R=b["rel material:binding"].replace(/^<\//,"").replace(/>$/,"").split("/");return Q(B,` "${R[1]}"`)}return Q(b)}}function Q(b,d=""){for(const w in b){const R=b[w];if(w.startsWith("def Material"+d))return R;if(typeof R=="object"){const D=Q(R,d);if(D)return D}}}function f(b,d){d["float inputs:rotation"]&&(b.rotation=parseFloat(d["float inputs:rotation"])),d["float2 inputs:scale"]&&(b.repeat=new g.Vector2().fromArray(JSON.parse("["+d["float2 inputs:scale"].replace(/[()]*/g,"")+"]"))),d["float2 inputs:translation"]&&(b.offset=new g.Vector2().fromArray(JSON.parse("["+d["float2 inputs:translation"].replace(/[()]*/g,"")+"]")))}function p(b){const d=new g.MeshPhysicalMaterial;if(b!==void 0){const w=b["token outputs:surface.connect"],R=/(\w+).output/.exec(w)[1],D=b[`def Shader "${R}"`];if(D!==void 0){if("color3f inputs:diffuseColor.connect"in D){const y=D["color3f inputs:diffuseColor.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.map=F(k),d.map.colorSpace=g.SRGBColorSpace,'def Shader "Transform2d_diffuse"'in b&&f(d.map,b['def Shader "Transform2d_diffuse"'])}else if("color3f inputs:diffuseColor"in D){const y=D["color3f inputs:diffuseColor"].replace(/[()]*/g,"");d.color.fromArray(JSON.parse("["+y+"]"))}if("color3f inputs:emissiveColor.connect"in D){const y=D["color3f inputs:emissiveColor.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.emissiveMap=F(k),d.emissiveMap.colorSpace=g.SRGBColorSpace,d.emissive.set(16777215),'def Shader "Transform2d_emissive"'in b&&f(d.emissiveMap,b['def Shader "Transform2d_emissive"'])}else if("color3f inputs:emissiveColor"in D){const y=D["color3f inputs:emissiveColor"].replace(/[()]*/g,"");d.emissive.fromArray(JSON.parse("["+y+"]"))}if("normal3f inputs:normal.connect"in D){const y=D["normal3f inputs:normal.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.normalMap=F(k),d.normalMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_normal"'in b&&f(d.normalMap,b['def Shader "Transform2d_normal"'])}if("float inputs:roughness.connect"in D){const y=D["float inputs:roughness.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.roughness=1,d.roughnessMap=F(k),d.roughnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_roughness"'in b&&f(d.roughnessMap,b['def Shader "Transform2d_roughness"'])}else"float inputs:roughness"in D&&(d.roughness=parseFloat(D["float inputs:roughness"]));if("float inputs:metallic.connect"in D){const y=D["float inputs:metallic.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.metalness=1,d.metalnessMap=F(k),d.metalnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_metallic"'in b&&f(d.metalnessMap,b['def Shader "Transform2d_metallic"'])}else"float inputs:metallic"in D&&(d.metalness=parseFloat(D["float inputs:metallic"]));if("float inputs:clearcoat.connect"in D){const y=D["float inputs:clearcoat.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.clearcoat=1,d.clearcoatMap=F(k),d.clearcoatMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_clearcoat"'in b&&f(d.clearcoatMap,b['def Shader "Transform2d_clearcoat"'])}else"float inputs:clearcoat"in D&&(d.clearcoat=parseFloat(D["float inputs:clearcoat"]));if("float inputs:clearcoatRoughness.connect"in D){const y=D["float inputs:clearcoatRoughness.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.clearcoatRoughness=1,d.clearcoatRoughnessMap=F(k),d.clearcoatRoughnessMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_clearcoatRoughness"'in b&&f(d.clearcoatRoughnessMap,b['def Shader "Transform2d_clearcoatRoughness"'])}else"float inputs:clearcoatRoughness"in D&&(d.clearcoatRoughness=parseFloat(D["float inputs:clearcoatRoughness"]));if("float inputs:ior"in D&&(d.ior=parseFloat(D["float inputs:ior"])),"float inputs:occlusion.connect"in D){const y=D["float inputs:occlusion.connect"],k=m(B,/(\w+).output/.exec(y)[1]);d.aoMap=F(k),d.aoMap.colorSpace=g.NoColorSpace,'def Shader "Transform2d_occlusion"'in b&&f(d.aoMap,b['def Shader "Transform2d_occlusion"'])}}}return d}function m(b,d){for(const w in b){const R=b[w];if(w.startsWith(`def Shader "${d}"`))return R;if(typeof R=="object"){const D=m(R,d);if(D)return D}}}function F(b){if("asset inputs:file"in b){const d=b["asset inputs:file"].replace(/@*/g,"").trim(),R=new g.TextureLoader().load(o[d]),D={'"clamp"':g.ClampToEdgeWrapping,'"mirror"':g.MirroredRepeatWrapping,'"repeat"':g.RepeatWrapping};return"token inputs:wrapS"in b&&(R.wrapS=D[b["token inputs:wrapS"]]),"token inputs:wrapT"in b&&(R.wrapT=D[b["token inputs:wrapT"]]),R}return null}function S(b){const d=C(I(b)),w=p(u(b)),R=d?new g.Mesh(d,w):new g.Object3D;if("matrix4d xformOp:transform"in b){const D=JSON.parse("["+b["matrix4d xformOp:transform"].replace(/[()]*/g,"")+"]");R.matrix.fromArray(D),R.matrix.decompose(R.position,R.quaternion,R.scale)}return R}function x(b,d){for(const w in b)if(w.startsWith("def Scope"))x(b[w],d);else if(w.startsWith("def Xform")){const R=S(b[w]);/def Xform "(\w+)"/.test(w)&&(R.name=/def Xform "(\w+)"/.exec(w)[1]),d.add(R),x(b[w],R)}}const U=new g.Group;return x(B,U),U}}function Kt(){const n=new jt;return n.manager.onError=A=>{W.emit("load-error",`Failed to load file ${A}`)},n}function Jt(n){const A=q.useCallback(async(a,t,i)=>{var B,I;const s=new Map(t.map(l=>[l.name,l])),o=(((B=a.buffers)==null?void 0:B.length)||0)+(((I=a.images)==null?void 0:I.length)||0);let r=0;const c=()=>{r++,i(r/o*100)};if(a.buffers)for(let l=0;l<a.buffers.length;l++){const C=a.buffers[l];if(!C.uri||C.uri.startsWith("data:")){c();continue}const E=C.uri.split("/").pop()||"",h=s.get(E);if(h){const u=await h.arrayBuffer(),Q=await jA(u);C.uri=`data:application/octet-stream;base64,${Q}`}c()}if(a.images)for(let l=0;l<a.images.length;l++){const C=a.images[l];if(!C.uri||C.uri.startsWith("data:")){c();continue}const E=C.uri.split("/").pop()||"",h=s.get(E);if(h){const u=await h.arrayBuffer(),Q=await jA(u),f=h.type||"image/png";C.uri=`data:${f};base64,${Q}`}c()}return a},[]);return{loadGltf:q.useCallback((a,t,i)=>{const s=new FileReader;s.onload=async o=>{var I;const r=JSON.parse((I=o.target)==null?void 0:I.result);i(10);const c=await A(r,t,l=>{i(10+l*.8)});MA().parse(JSON.stringify(c),"",l=>{n({type:"set-file",payload:{model:l.scene,type:O.gltf,name:a.name}})}),i(100),n({type:"set-file-loading",payload:!1})},s.readAsText(a)},[n,A])}}function Yt(n){return{loadBinary:q.useCallback((e,a,t)=>{const i=new FileReader;i.onload=async s=>{var o;if((o=s.target)!=null&&o.result){const r=s.target.result;if(a===O.glb)MA().parse(r,"",B=>{n({type:"set-file",payload:{model:B.scene,type:O.glb,name:e.name}})});else if(a===O.usdz){const B=Kt().parse(r);n({type:"set-file",payload:{model:B,type:O.usdz,name:e.name}})}t(),n({type:"set-file-loading",payload:!1})}},i.onerror=s=>{console.error("Error reading file:",s),n({type:"set-file-loading",payload:!1})},i.readAsArrayBuffer(e)},[n])}}function we(n){const A=q.useRef(!1),[e,a]=q.useReducer(Fe,Ae),{loadGltf:t}=Jt(a),{loadBinary:i}=Yt(a),s=q.useCallback((l,C)=>l.find(E=>E.name.endsWith("."+C)),[]),o=q.useCallback(l=>{a({type:"set-progress",payload:l}),W.emit("load-progress",l)},[]),r=q.useCallback(()=>{a({type:"reset-state"}),W.emit("load-reset")},[]),c=q.useCallback(l=>{if(l.length===0)return;const C=s(l,O.gltf),E=s(l,O.glb),h=s(l,O.usdz),u=[C,E,h].filter(Boolean);if(u.length>1){W.emit("multiple-models",u);return}const Q=l.filter(p=>p!==C&&p!==E&&p!==h),f=p=>{o(p),p===100&&(A.current=!0)};if(C)t(C,Q,f);else if(E)i(E,O.glb,()=>f(100));else if(h)i(h,O.usdz,()=>f(100));else{W.emit("not-loaded-files",l),a({type:"set-file-loading",payload:!1});return}},[o,s,t,i]),B=q.useCallback(async l=>{const C=[];W.emit("load-start"),a({type:"reset-state"}),a({type:"set-file-loading",payload:!0}),o(0),A.current=!1;for(const E of l)if(E instanceof File)C.push(E);else if("kind"in E&&E.kind==="directory"){const h=await ke(E);C.push(...h)}c(C)},[c,o]);q.useEffect(()=>{A.current&&e.file&&(W.emit("load-complete",e.file),A.current=!1,n&&e.file.model&&n.load(e.file.model))},[e.file,n]);const I=Wt(n,a,e.file);return{...e,on:W.on,off:W.off,load:B,reset:r,optimize:I}}function Wt(n,A,e){const a=q.useCallback(i=>{MA().parse(i.buffer,"",o=>{A({type:"set-file",payload:{model:o.scene,type:O.glb,name:(e==null?void 0:e.name)||"optimized.glb"}})},o=>{console.error("Error loading new model:",o)})},[A,e]),t=q.useCallback(async(i,s)=>{if(!n||!i){console.warn("Optimizer or optimization function is not available");return}try{await i(s);const o=await n.getModel();o&&a(o)}catch(o){console.error("Optimization failed:",o)}},[n,a]);return n?{simplifyOptimization:i=>t(n.simplifyOptimization,i),dedupOptimization:i=>t(n.dedupOptimization,i),quantizeOptimization:i=>t(n.quantizeOptimization,i),texturesCompressOptimization:i=>t(n.texturesOptimization,i),getSize:n.getSize,reset:n.reset,report:n.report,error:n.error,loading:n.loading}:{simplifyOptimization:()=>{console.warn("Optimizer is not available")},dedupOptimization:()=>{console.warn("Optimizer is not available")},quantizeOptimization:()=>{console.warn("Optimizer is not available")},texturesCompressOptimization:()=>{console.warn("Optimizer is not available")},getSize:()=>{console.warn("Optimizer is not available")},reset:()=>{console.warn("Optimizer is not available")},report:null,error:null,loading:!1}}const NA=q.createContext({}),Vt=({children:n,optimizer:A})=>{const e=we(A);return Re.jsx(NA.Provider,{value:e,children:n})},zt=()=>q.useContext(NA);exports.ModelContext=NA;exports.ModelFileTypes=O;exports.ModelProvider=Vt;exports.useLoadModel=we;exports.useModelContext=zt;
@@ -18,9 +18,22 @@ const BA = {}, V = {
18
18
  };
19
19
  var q = /* @__PURE__ */ ((n) => (n.gltf = "gltf", n.glb = "glb", n.usdz = "usdz", n))(q || {});
20
20
  const He = {
21
+ /**
22
+ * Currently loaded file
23
+ */
21
24
  file: null,
25
+ /**
26
+ * Flag indicating if a file is currently being loaded
27
+ */
22
28
  isFileLoading: !1,
29
+ /**
30
+ * Current loading progress (0-100)
31
+ */
23
32
  progress: 0,
33
+ /**
34
+ * List of supported file types
35
+ * @type {ModelFileTypes[]}
36
+ */
24
37
  supportedFileTypes: Object.values(q)
25
38
  };
26
39
  function Ca(n, A) {
@@ -3308,10 +3321,39 @@ function Ls(n) {
3308
3321
  );
3309
3322
  return {
3310
3323
  ...e,
3324
+ /**
3325
+ * Add an event listener to the event system.
3326
+ */
3311
3327
  on: V.on,
3328
+ /**
3329
+ * Remove an event listener from the event system.
3330
+ */
3312
3331
  off: V.off,
3332
+ /**
3333
+ * Load a model and integrate it with the optimizer if available.
3334
+ * This also makes the model available in the use-model-context hook.
3335
+ */
3313
3336
  load: I,
3337
+ /**
3338
+ * Reset the model and optimizer state to the initial state.
3339
+ */
3314
3340
  reset: r,
3341
+ /**
3342
+ * Integration of the optimizer
3343
+ * An object containing functions to interact with the optimizer.
3344
+ *
3345
+ * It exposes the following functions:
3346
+ *
3347
+ * - `simplifyOptimization(options?: SimplifyOptions)`: Runs the simplification optimization with the given options.
3348
+ * - `dedupOptimization(options?: DedupOptions)`: Runs the deduplication optimization with the given options.
3349
+ * - `quantizeOptimization(options?: QuantizeOptions)`: Runs the quantization optimization with the given options.
3350
+ * - `texturesCompressionOptimization(options?: TextureCompressionOptions)`: Runs the texture compression optimization with the given options.
3351
+ * - `getSize()`: Returns the size of the optimized model.
3352
+ * - `reset()`: Resets the optimizer.
3353
+ * - `report`: The report state of the optimizer.
3354
+ * - `error`: The error state of the optimizer.
3355
+ * - `loading`: The loading state of the optimizer.
3356
+ */
3315
3357
  optimize: g
3316
3358
  };
3317
3359
  }
@@ -3319,7 +3361,7 @@ function Ms(n, A, e) {
3319
3361
  const a = z(
3320
3362
  (s) => {
3321
3363
  oe().parse(
3322
- s,
3364
+ s.buffer,
3323
3365
  "",
3324
3366
  (o) => {
3325
3367
  A({
@@ -3363,6 +3405,10 @@ function Ms(n, A, e) {
3363
3405
  n.quantizeOptimization,
3364
3406
  s
3365
3407
  ),
3408
+ texturesCompressOptimization: (s) => t(
3409
+ n.texturesOptimization,
3410
+ s
3411
+ ),
3366
3412
  getSize: n.getSize,
3367
3413
  reset: n.reset,
3368
3414
  report: n.report,
@@ -3381,6 +3427,9 @@ function Ms(n, A, e) {
3381
3427
  quantizeOptimization: () => {
3382
3428
  console.warn("Optimizer is not available");
3383
3429
  },
3430
+ texturesCompressOptimization: () => {
3431
+ console.warn("Optimizer is not available");
3432
+ },
3384
3433
  getSize: () => {
3385
3434
  console.warn("Optimizer is not available");
3386
3435
  },
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.0",
2
+ "version": "0.7.0",
3
3
  "name": "@vctrl/hooks",
4
4
  "description": "vctrl/hooks is a React hooks package designed to simplify 3D model loading and management within React applications. It's part of the vectreal-core ecosystem and is primarily used in the vctrl/viewer React component and the official website application.",
5
5
  "bugs": {
@@ -46,10 +46,12 @@
46
46
  "react": "18.3.1"
47
47
  },
48
48
  "dependencies": {
49
+ "jszip": "^3.10.1",
50
+ "file-saver": "^2.0.5",
49
51
  "three": "^0.168.0",
50
52
  "@gltf-transform/core": "^4.0.8",
51
53
  "@gltf-transform/functions": "^4.0.8",
52
- "@gltf-transform/extensions": "^4.0.8",
54
+ "@gltf-transform/extensions": "^4.0.10",
53
55
  "meshoptimizer": "^0.21.0"
54
56
  }
55
57
  }
@@ -14,6 +14,7 @@ declare const ModelContext: import('react').Context<{
14
14
  } | undefined) => Promise<void>;
15
15
  dedupOptimization: (options?: import('@gltf-transform/functions').DedupOptions | undefined) => Promise<void>;
16
16
  quantizeOptimization: (options?: import('@gltf-transform/functions').QuantizeOptions | undefined) => Promise<void>;
17
+ texturesCompressOptimization: (options?: import('@gltf-transform/functions').TextureCompressOptions | undefined) => Promise<void>;
17
18
  getSize: () => import('../use-optimize-model/types').ModelSize | null;
18
19
  reset: () => void;
19
20
  report: import('@gltf-transform/functions').InspectReport | null;
@@ -23,6 +24,7 @@ declare const ModelContext: import('react').Context<{
23
24
  simplifyOptimization: () => void;
24
25
  dedupOptimization: () => void;
25
26
  quantizeOptimization: () => void;
27
+ texturesCompressOptimization: () => void;
26
28
  getSize: () => void;
27
29
  reset: () => void;
28
30
  report: null;
@@ -47,6 +49,7 @@ declare const useModelContext: () => {
47
49
  } | undefined) => Promise<void>;
48
50
  dedupOptimization: (options?: import('@gltf-transform/functions').DedupOptions | undefined) => Promise<void>;
49
51
  quantizeOptimization: (options?: import('@gltf-transform/functions').QuantizeOptions | undefined) => Promise<void>;
52
+ texturesCompressOptimization: (options?: import('@gltf-transform/functions').TextureCompressOptions | undefined) => Promise<void>;
50
53
  getSize: () => import('../use-optimize-model/types').ModelSize | null;
51
54
  reset: () => void;
52
55
  report: import('@gltf-transform/functions').InspectReport | null;
@@ -56,6 +59,7 @@ declare const useModelContext: () => {
56
59
  simplifyOptimization: () => void;
57
60
  dedupOptimization: () => void;
58
61
  quantizeOptimization: () => void;
62
+ texturesCompressOptimization: () => void;
59
63
  getSize: () => void;
60
64
  reset: () => void;
61
65
  report: null;
@@ -1,4 +1,12 @@
1
1
  import { Action, State } from './types';
2
+ /**
3
+ * Initial state for the useReadModelFiles hook
4
+ *
5
+ * @property file - Currently loaded file
6
+ * @property isFileLoading - Flag indicating if a file is currently being loaded
7
+ * @property progress - Current loading progress (0-100)
8
+ * @property supportedFileTypes - List of supported file types
9
+ */
2
10
  export declare const initialState: State;
3
11
  /**
4
12
  * Reducer function for the useReadModelFiles hook
@@ -7,10 +7,39 @@ import { ModelFileTypes, InputFileOrDirectory, ModelFile } from './types';
7
7
  * @returns An object containing the state, event handlers, and optimization functions.
8
8
  */
9
9
  declare function useLoadModel(optimizer?: ReturnType<typeof useOptimizeModel>): {
10
+ /**
11
+ * Add an event listener to the event system.
12
+ */
10
13
  on: <T extends import('./types').EventTypes>(event: T, handler?: import('./types').EventHandler<T>) => void;
14
+ /**
15
+ * Remove an event listener from the event system.
16
+ */
11
17
  off: <T extends import('./types').EventTypes>(event: T, handler?: import('./types').EventHandler<T>) => void;
18
+ /**
19
+ * Load a model and integrate it with the optimizer if available.
20
+ * This also makes the model available in the use-model-context hook.
21
+ */
12
22
  load: (filesOrDirectories: InputFileOrDirectory) => Promise<void>;
23
+ /**
24
+ * Reset the model and optimizer state to the initial state.
25
+ */
13
26
  reset: () => void;
27
+ /**
28
+ * Integration of the optimizer
29
+ * An object containing functions to interact with the optimizer.
30
+ *
31
+ * It exposes the following functions:
32
+ *
33
+ * - `simplifyOptimization(options?: SimplifyOptions)`: Runs the simplification optimization with the given options.
34
+ * - `dedupOptimization(options?: DedupOptions)`: Runs the deduplication optimization with the given options.
35
+ * - `quantizeOptimization(options?: QuantizeOptions)`: Runs the quantization optimization with the given options.
36
+ * - `texturesCompressionOptimization(options?: TextureCompressionOptions)`: Runs the texture compression optimization with the given options.
37
+ * - `getSize()`: Returns the size of the optimized model.
38
+ * - `reset()`: Resets the optimizer.
39
+ * - `report`: The report state of the optimizer.
40
+ * - `error`: The error state of the optimizer.
41
+ * - `loading`: The loading state of the optimizer.
42
+ */
14
43
  optimize: {
15
44
  simplifyOptimization: (options?: {
16
45
  ratio?: number;
@@ -18,6 +47,7 @@ declare function useLoadModel(optimizer?: ReturnType<typeof useOptimizeModel>):
18
47
  } | undefined) => Promise<void>;
19
48
  dedupOptimization: (options?: import('@gltf-transform/functions').DedupOptions | undefined) => Promise<void>;
20
49
  quantizeOptimization: (options?: import('@gltf-transform/functions').QuantizeOptions | undefined) => Promise<void>;
50
+ texturesCompressOptimization: (options?: import('@gltf-transform/functions').TextureCompressOptions | undefined) => Promise<void>;
21
51
  getSize: () => import('../use-optimize-model/types').ModelSize | null;
22
52
  reset: () => void;
23
53
  report: import('@gltf-transform/functions').InspectReport | null;
@@ -27,6 +57,7 @@ declare function useLoadModel(optimizer?: ReturnType<typeof useOptimizeModel>):
27
57
  simplifyOptimization: () => void;
28
58
  dedupOptimization: () => void;
29
59
  quantizeOptimization: () => void;
60
+ texturesCompressOptimization: () => void;
30
61
  getSize: () => void;
31
62
  reset: () => void;
32
63
  report: null;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./model-context-ChF_IVjD.cjs");exports.ModelContext=e.ModelContext;exports.ModelFileTypes=e.ModelFileTypes;exports.ModelProvider=e.ModelProvider;exports.useLoadModel=e.useLoadModel;exports.useModelContext=e.useModelContext;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./model-context-DLPGvQ8f.cjs");exports.ModelContext=e.ModelContext;exports.ModelFileTypes=e.ModelFileTypes;exports.ModelProvider=e.ModelProvider;exports.useLoadModel=e.useLoadModel;exports.useModelContext=e.useModelContext;
@@ -1,4 +1,4 @@
1
- import { a as s, M as a, b as d, u as l, c as M } from "./model-context-DDCJu7oe.js";
1
+ import { a as s, M as a, b as d, u as l, c as M } from "./model-context-hgFMs-nK.js";
2
2
  export {
3
3
  s as ModelContext,
4
4
  a as ModelFileTypes,
@@ -1,5 +1,5 @@
1
1
  import { Object3D } from 'three';
2
- import { dedup, quantize } from '@gltf-transform/functions';
2
+ import { dedup, quantize, textureCompress } from '@gltf-transform/functions';
3
3
  import { ModelSize } from './types';
4
4
  /**
5
5
  * Custom React hook for optimizing Three.js models using glTF-Transform.
@@ -11,7 +11,7 @@ import { ModelSize } from './types';
11
11
  */
12
12
  declare const useOptimizeModel: () => {
13
13
  load: (model: Object3D) => Promise<void>;
14
- getModel: () => Promise<ArrayBuffer | null>;
14
+ getModel: () => Promise<Uint8Array | null>;
15
15
  getSize: () => ModelSize | null;
16
16
  report: import('@gltf-transform/functions').InspectReport | null;
17
17
  simplifyOptimization: (options?: {
@@ -20,6 +20,7 @@ declare const useOptimizeModel: () => {
20
20
  }) => Promise<void>;
21
21
  dedupOptimization: (options?: Parameters<typeof dedup>[0]) => Promise<void>;
22
22
  quantizeOptimization: (options?: Parameters<typeof quantize>[0]) => Promise<void>;
23
+ texturesOptimization: (options?: Parameters<typeof textureCompress>[0]) => Promise<void>;
23
24
  reset: () => void;
24
25
  error: Error | null;
25
26
  loading: boolean;
@@ -0,0 +1 @@
1
+ "use strict";const t=require("react"),x=require("./GLTFExporter-ltc8rmzz.cjs"),k=require("@gltf-transform/core"),a=require("@gltf-transform/functions"),L=require("@gltf-transform/extensions"),T=require("meshoptimizer"),y={modelDoc:null,modelReport:null,error:null,loading:!1},q=(i,o)=>{switch(o.type){case"LOAD_START":return{...i,loading:!0,error:null};case"LOAD_SUCCESS":return{...i,loading:!1,modelDoc:o.payload.modelDoc,modelReport:o.payload.modelReport};case"LOAD_ERROR":return{...i,loading:!1,error:o.payload};case"RESET":return{...y};default:return i}},_=()=>{const[i,o]=t.useReducer(q,y),{modelDoc:s,modelReport:c,error:f,loading:R}=i,S=t.useRef(new x.GLTFExporter),m=t.useRef(new k.WebIO().registerExtensions([L.KHRMeshQuantization])),z=t.useCallback(async e=>{o({type:"LOAD_START"});try{const r={binary:!0},l=await S.current.parseAsync(e,r),u=new Uint8Array(l),p=await m.current.readBinary(u),d=a.inspect(p);o({type:"LOAD_SUCCESS",payload:{modelDoc:p,modelReport:d}})}catch(r){o({type:"LOAD_ERROR",payload:r}),console.error("Error loading model:",r)}},[]),n=t.useCallback(async e=>{if(s)try{await s.transform(...e);const r=a.inspect(s);o({type:"LOAD_SUCCESS",payload:{modelDoc:s,modelReport:r}})}catch(r){console.error("Error applying transforms:",r)}},[s]),O=t.useCallback(async e=>{const{ratio:r=.5,error:l=.001}=e||{};await n([a.weld(),a.simplify({simplifier:T.MeshoptSimplifier,ratio:r,error:l})])},[n]),C=t.useCallback(async e=>{await n([a.dedup(e)])},[n]),E=t.useCallback(async e=>{await n([a.quantize(e)])},[n]),w=t.useCallback(async e=>{e&&await n([a.textureCompress(e)])},[n]),b=t.useCallback(async()=>{if(!s)return null;try{return await m.current.writeBinary(s)}catch(e){return console.error("Error getting model binary:",e),null}},[s]),g=t.useCallback(()=>{if(!c)return null;const e=d=>d.reduce((A,h)=>A+h.size,0),r=e(c.meshes.properties),l=e(c.textures.properties),u=r+l,p=`${(u/(1024*1024)).toFixed(2)} MB`;return{fileSize:u,displayFileSize:p}},[c]),D=t.useCallback(()=>{o({type:"RESET"})},[]);return{load:z,getModel:b,getSize:g,report:c,simplifyOptimization:O,dedupOptimization:C,quantizeOptimization:E,texturesOptimization:w,reset:D,error:f,loading:R}};exports.useOptimizeModel=_;
@@ -0,0 +1,117 @@
1
+ import { useReducer as T, useRef as m, useCallback as o } from "react";
2
+ import { G as _ } from "./GLTFExporter-Q5UJ5eb1.js";
3
+ import { WebIO as b } from "@gltf-transform/core";
4
+ import { inspect as y, weld as M, simplify as B, dedup as U, quantize as F, textureCompress as q } from "@gltf-transform/functions";
5
+ import { KHRMeshQuantization as G } from "@gltf-transform/extensions";
6
+ import { MeshoptSimplifier as k } from "meshoptimizer";
7
+ const f = {
8
+ modelDoc: null,
9
+ modelReport: null,
10
+ error: null,
11
+ loading: !1
12
+ }, H = (i, t) => {
13
+ switch (t.type) {
14
+ case "LOAD_START":
15
+ return { ...i, loading: !0, error: null };
16
+ case "LOAD_SUCCESS":
17
+ return {
18
+ ...i,
19
+ loading: !1,
20
+ modelDoc: t.payload.modelDoc,
21
+ modelReport: t.payload.modelReport
22
+ };
23
+ case "LOAD_ERROR":
24
+ return { ...i, loading: !1, error: t.payload };
25
+ case "RESET":
26
+ return { ...f };
27
+ default:
28
+ return i;
29
+ }
30
+ }, v = () => {
31
+ const [i, t] = T(H, f), { modelDoc: n, modelReport: a, error: R, loading: S } = i, O = m(new _()), d = m(
32
+ new b().registerExtensions([G])
33
+ ), z = o(async (r) => {
34
+ t({ type: "LOAD_START" });
35
+ try {
36
+ const e = { binary: !0 }, l = await O.current.parseAsync(r, e), c = new Uint8Array(l), p = await d.current.readBinary(c), u = y(p);
37
+ t({
38
+ type: "LOAD_SUCCESS",
39
+ payload: { modelDoc: p, modelReport: u }
40
+ });
41
+ } catch (e) {
42
+ t({ type: "LOAD_ERROR", payload: e }), console.error("Error loading model:", e);
43
+ }
44
+ }, []), s = o(
45
+ async (r) => {
46
+ if (n)
47
+ try {
48
+ await n.transform(...r);
49
+ const e = y(n);
50
+ t({
51
+ type: "LOAD_SUCCESS",
52
+ payload: { modelDoc: n, modelReport: e }
53
+ });
54
+ } catch (e) {
55
+ console.error("Error applying transforms:", e);
56
+ }
57
+ },
58
+ [n]
59
+ ), E = o(
60
+ async (r) => {
61
+ const { ratio: e = 0.5, error: l = 1e-3 } = r || {};
62
+ await s([
63
+ M(),
64
+ B({
65
+ simplifier: k,
66
+ ratio: e,
67
+ error: l
68
+ })
69
+ ]);
70
+ },
71
+ [s]
72
+ ), w = o(
73
+ async (r) => {
74
+ await s([U(r)]);
75
+ },
76
+ [s]
77
+ ), g = o(
78
+ async (r) => {
79
+ await s([F(r)]);
80
+ },
81
+ [s]
82
+ ), D = o(
83
+ async (r) => {
84
+ r && await s([q(r)]);
85
+ },
86
+ [s]
87
+ ), A = o(async () => {
88
+ if (!n) return null;
89
+ try {
90
+ return await d.current.writeBinary(n);
91
+ } catch (r) {
92
+ return console.error("Error getting model binary:", r), null;
93
+ }
94
+ }, [n]), h = o(() => {
95
+ if (!a) return null;
96
+ const r = (u) => u.reduce((C, L) => C + L.size, 0), e = r(a.meshes.properties), l = r(a.textures.properties), c = e + l, p = `${(c / (1024 * 1024)).toFixed(2)} MB`;
97
+ return { fileSize: c, displayFileSize: p };
98
+ }, [a]), x = o(() => {
99
+ t({ type: "RESET" });
100
+ }, []);
101
+ return {
102
+ load: z,
103
+ getModel: A,
104
+ getSize: h,
105
+ report: a,
106
+ simplifyOptimization: E,
107
+ dedupOptimization: w,
108
+ quantizeOptimization: g,
109
+ texturesOptimization: D,
110
+ reset: x,
111
+ error: R,
112
+ loading: S
113
+ };
114
+ };
115
+ export {
116
+ v as u
117
+ };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./use-optimize-model-BN-fP4La.cjs");exports.useOptimizeModel=e.useOptimizeModel;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./use-optimize-model-7wjiNiSZ.cjs");exports.useOptimizeModel=e.useOptimizeModel;
@@ -1,4 +1,4 @@
1
- import { u as i } from "./use-optimize-model-C46Fr7jH.js";
1
+ import { u as i } from "./use-optimize-model-CVcoeFrO.js";
2
2
  export {
3
3
  i as useOptimizeModel
4
4
  };
@@ -1 +0,0 @@
1
- "use strict";const t=require("react"),h=require("./GLTFExporter-ltc8rmzz.cjs"),L=require("@gltf-transform/core"),i=require("@gltf-transform/functions"),T=require("@gltf-transform/extensions"),k=require("meshoptimizer"),m={modelDoc:null,modelReport:null,error:null,loading:!1},q=(n,o)=>{switch(o.type){case"LOAD_START":return{...n,loading:!0,error:null};case"LOAD_SUCCESS":return{...n,loading:!1,modelDoc:o.payload.modelDoc,modelReport:o.payload.modelReport};case"LOAD_ERROR":return{...n,loading:!1,error:o.payload};case"RESET":return{...m};default:return n}},x=()=>{const[n,o]=t.useReducer(q,m),{modelDoc:s,modelReport:l,error:f,loading:R}=n,S=t.useRef(new h.GLTFExporter),y=t.useRef(new L.WebIO().registerExtensions([T.KHRMeshQuantization])),z=t.useCallback(async e=>{o({type:"LOAD_START"});try{const r={binary:!0},c=await S.current.parseAsync(e,r),u=new Uint8Array(c),p=await y.current.readBinary(u),d=i.inspect(p);o({type:"LOAD_SUCCESS",payload:{modelDoc:p,modelReport:d}})}catch(r){o({type:"LOAD_ERROR",payload:r}),console.error("Error loading model:",r)}},[]),a=t.useCallback(async e=>{if(s)try{await s.transform(...e);const r=i.inspect(s);o({type:"LOAD_SUCCESS",payload:{modelDoc:s,modelReport:r}})}catch(r){console.error("Error applying transforms:",r)}},[s]),E=t.useCallback(async e=>{const{ratio:r=.5,error:c=.001}=e||{};await a([i.weld(),i.simplify({simplifier:k.MeshoptSimplifier,ratio:r,error:c})])},[a]),O=t.useCallback(async e=>{await a([i.dedup(e)])},[a]),C=t.useCallback(async e=>{await a([i.quantize(e)])},[a]),w=t.useCallback(async()=>{if(!s)return null;try{return await y.current.writeBinary(s)}catch(e){return console.error("Error getting model binary:",e),null}},[s]),b=t.useCallback(()=>{if(!l)return null;const e=d=>d.reduce((D,A)=>D+A.size,0),r=e(l.meshes.properties),c=e(l.textures.properties),u=r+c,p=`${(u/(1024*1024)).toFixed(2)} MB`;return{fileSize:u,displayFileSize:p}},[l]),g=t.useCallback(()=>{o({type:"RESET"})},[]);return{load:z,getModel:w,getSize:b,report:l,simplifyOptimization:E,dedupOptimization:O,quantizeOptimization:C,reset:g,error:f,loading:R}};exports.useOptimizeModel=x;
@@ -1,111 +0,0 @@
1
- import { useReducer as x, useRef as m, useCallback as n } from "react";
2
- import { G as C } from "./GLTFExporter-Q5UJ5eb1.js";
3
- import { WebIO as _ } from "@gltf-transform/core";
4
- import { inspect as y, weld as b, simplify as M, dedup as B, quantize as U } from "@gltf-transform/functions";
5
- import { KHRMeshQuantization as F } from "@gltf-transform/extensions";
6
- import { MeshoptSimplifier as q } from "meshoptimizer";
7
- const f = {
8
- modelDoc: null,
9
- modelReport: null,
10
- error: null,
11
- loading: !1
12
- }, G = (i, o) => {
13
- switch (o.type) {
14
- case "LOAD_START":
15
- return { ...i, loading: !0, error: null };
16
- case "LOAD_SUCCESS":
17
- return {
18
- ...i,
19
- loading: !1,
20
- modelDoc: o.payload.modelDoc,
21
- modelReport: o.payload.modelReport
22
- };
23
- case "LOAD_ERROR":
24
- return { ...i, loading: !1, error: o.payload };
25
- case "RESET":
26
- return { ...f };
27
- default:
28
- return i;
29
- }
30
- }, $ = () => {
31
- const [i, o] = x(G, f), { modelDoc: t, modelReport: a, error: R, loading: S } = i, E = m(new C()), u = m(
32
- new _().registerExtensions([F])
33
- ), O = n(async (r) => {
34
- o({ type: "LOAD_START" });
35
- try {
36
- const e = { binary: !0 }, l = await E.current.parseAsync(r, e), c = new Uint8Array(l), p = await u.current.readBinary(c), d = y(p);
37
- o({
38
- type: "LOAD_SUCCESS",
39
- payload: { modelDoc: p, modelReport: d }
40
- });
41
- } catch (e) {
42
- o({ type: "LOAD_ERROR", payload: e }), console.error("Error loading model:", e);
43
- }
44
- }, []), s = n(
45
- async (r) => {
46
- if (t)
47
- try {
48
- await t.transform(...r);
49
- const e = y(t);
50
- o({
51
- type: "LOAD_SUCCESS",
52
- payload: { modelDoc: t, modelReport: e }
53
- });
54
- } catch (e) {
55
- console.error("Error applying transforms:", e);
56
- }
57
- },
58
- [t]
59
- ), z = n(
60
- async (r) => {
61
- const { ratio: e = 0.5, error: l = 1e-3 } = r || {};
62
- await s([
63
- b(),
64
- M({
65
- simplifier: q,
66
- ratio: e,
67
- error: l
68
- })
69
- ]);
70
- },
71
- [s]
72
- ), w = n(
73
- async (r) => {
74
- await s([B(r)]);
75
- },
76
- [s]
77
- ), g = n(
78
- async (r) => {
79
- await s([U(r)]);
80
- },
81
- [s]
82
- ), D = n(async () => {
83
- if (!t) return null;
84
- try {
85
- return await u.current.writeBinary(t);
86
- } catch (r) {
87
- return console.error("Error getting model binary:", r), null;
88
- }
89
- }, [t]), A = n(() => {
90
- if (!a) return null;
91
- const r = (d) => d.reduce((L, T) => L + T.size, 0), e = r(a.meshes.properties), l = r(a.textures.properties), c = e + l, p = `${(c / (1024 * 1024)).toFixed(2)} MB`;
92
- return { fileSize: c, displayFileSize: p };
93
- }, [a]), h = n(() => {
94
- o({ type: "RESET" });
95
- }, []);
96
- return {
97
- load: O,
98
- getModel: D,
99
- getSize: A,
100
- report: a,
101
- simplifyOptimization: z,
102
- dedupOptimization: w,
103
- quantizeOptimization: g,
104
- reset: h,
105
- error: R,
106
- loading: S
107
- };
108
- };
109
- export {
110
- $ as u
111
- };