@vctrl/hooks
Version:
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.
19 lines (16 loc) • 35.3 kB
JavaScript
"use strict";const f=require("three");let F,P,_,G;function z(a,e=1/0,t=null){P||(P=new f.PlaneGeometry(2,2,1,1)),_||(_=new f.ShaderMaterial({uniforms:{blitTexture:new f.Uniform(a)},vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = vec4(position.xy * 1.0,0.,.999999);
}`,fragmentShader:`
uniform sampler2D blitTexture;
varying vec2 vUv;
void main(){
gl_FragColor = vec4(vUv.xy, 0, 1);
#ifdef IS_SRGB
gl_FragColor = sRGBTransferOETF( texture2D( blitTexture, vUv) );
#else
gl_FragColor = texture2D( blitTexture, vUv);
#endif
}`})),_.uniforms.blitTexture.value=a,_.defines.IS_SRGB=a.colorSpace==f.SRGBColorSpace,_.needsUpdate=!0,G||(G=new f.Mesh(P,_),G.frustumCulled=!1);const r=new f.PerspectiveCamera,s=new f.Scene;s.add(G),t===null&&(t=F=new f.WebGLRenderer({antialias:!1}));const i=Math.min(a.image.width,e),n=Math.min(a.image.height,e);t.setSize(i,n),t.clear(),t.render(s,r);const o=document.createElement("canvas"),c=o.getContext("2d");o.width=i,o.height=n,c.drawImage(t.domElement,0,0,i,n);const u=new f.CanvasTexture(o);return u.minFilter=a.minFilter,u.magFilter=a.magFilter,u.wrapS=a.wrapS,u.wrapT=a.wrapT,u.name=a.name,F&&(F.forceContextLoss(),F.dispose(),F=null),u}const K={POSITION:["byte","byte normalized","unsigned byte","unsigned byte normalized","short","short normalized","unsigned short","unsigned short normalized"],NORMAL:["byte normalized","short normalized"],TANGENT:["byte normalized","short normalized"],TEXCOORD:["byte","byte normalized","unsigned byte","short","short normalized","unsigned short"]};class V{constructor(){this.pluginCallbacks=[],this.register(function(e){return new ce(e)}),this.register(function(e){return new ue(e)}),this.register(function(e){return new pe(e)}),this.register(function(e){return new de(e)}),this.register(function(e){return new xe(e)}),this.register(function(e){return new ge(e)}),this.register(function(e){return new le(e)}),this.register(function(e){return new fe(e)}),this.register(function(e){return new he(e)}),this.register(function(e){return new Te(e)}),this.register(function(e){return new me(e)}),this.register(function(e){return new Me(e)}),this.register(function(e){return new ye(e)}),this.register(function(e){return new we(e)})}register(e){return this.pluginCallbacks.indexOf(e)===-1&&this.pluginCallbacks.push(e),this}unregister(e){return this.pluginCallbacks.indexOf(e)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e),1),this}parse(e,t,r,s){const i=new ae,n=[];for(let o=0,c=this.pluginCallbacks.length;o<c;o++)n.push(this.pluginCallbacks[o](i));i.setPlugins(n),i.write(e,t,s).catch(r)}parseAsync(e,t){const r=this;return new Promise(function(s,i){r.parse(e,s,i,t)})}}const m={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,INT:5124,UNSIGNED_INT:5125,FLOAT:5126,ARRAY_BUFFER:34962,ELEMENT_ARRAY_BUFFER:34963,NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987,CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,REPEAT:10497},k="KHR_mesh_quantization",b={};b[f.NearestFilter]=m.NEAREST;b[f.NearestMipmapNearestFilter]=m.NEAREST_MIPMAP_NEAREST;b[f.NearestMipmapLinearFilter]=m.NEAREST_MIPMAP_LINEAR;b[f.LinearFilter]=m.LINEAR;b[f.LinearMipmapNearestFilter]=m.LINEAR_MIPMAP_NEAREST;b[f.LinearMipmapLinearFilter]=m.LINEAR_MIPMAP_LINEAR;b[f.ClampToEdgeWrapping]=m.CLAMP_TO_EDGE;b[f.RepeatWrapping]=m.REPEAT;b[f.MirroredRepeatWrapping]=m.MIRRORED_REPEAT;const j={scale:"scale",position:"translation",quaternion:"rotation",morphTargetInfluences:"weights"},$=new f.Color,q=12,ee=1179937895,te=2,W=8,se=1313821514,ne=5130562;function O(a,e){return a.length===e.length&&a.every(function(t,r){return t===e[r]})}function ie(a){return new TextEncoder().encode(a).buffer}function re(a){return O(a.elements,[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1])}function oe(a,e,t){const r={min:new Array(a.itemSize).fill(Number.POSITIVE_INFINITY),max:new Array(a.itemSize).fill(Number.NEGATIVE_INFINITY)};for(let s=e;s<e+t;s++)for(let i=0;i<a.itemSize;i++){let n;a.itemSize>4?n=a.array[s*a.itemSize+i]:(i===0?n=a.getX(s):i===1?n=a.getY(s):i===2?n=a.getZ(s):i===3&&(n=a.getW(s)),a.normalized===!0&&(n=f.MathUtils.normalize(n,a.array))),r.min[i]=Math.min(r.min[i],n),r.max[i]=Math.max(r.max[i],n)}return r}function Q(a){return Math.ceil(a/4)*4}function H(a,e=0){const t=Q(a.byteLength);if(t!==a.byteLength){const r=new Uint8Array(t);if(r.set(new Uint8Array(a)),e!==0)for(let s=a.byteLength;s<t;s++)r[s]=e;return r.buffer}return a}function X(){return typeof document>"u"&&typeof OffscreenCanvas<"u"?new OffscreenCanvas(1,1):document.createElement("canvas")}function J(a,e){if(a.toBlob!==void 0)return new Promise(r=>a.toBlob(r,e));let t;return e==="image/jpeg"?t=.92:e==="image/webp"&&(t=.8),a.convertToBlob({type:e,quality:t})}class ae{constructor(){this.plugins=[],this.options={},this.pending=[],this.buffers=[],this.byteOffset=0,this.buffers=[],this.nodeMap=new Map,this.skins=[],this.extensionsUsed={},this.extensionsRequired={},this.uids=new Map,this.uid=0,this.json={asset:{version:"2.0",generator:"THREE.GLTFExporter r"+f.REVISION}},this.cache={meshes:new Map,attributes:new Map,attributesNormalized:new Map,materials:new Map,textures:new Map,images:new Map}}setPlugins(e){this.plugins=e}async write(e,t,r={}){this.options=Object.assign({binary:!1,trs:!1,onlyVisible:!0,maxTextureSize:1/0,animations:[],includeCustomExtensions:!1},r),this.options.animations.length>0&&(this.options.trs=!0),this.processInput(e),await Promise.all(this.pending);const s=this,i=s.buffers,n=s.json;r=s.options;const o=s.extensionsUsed,c=s.extensionsRequired,u=new Blob(i,{type:"application/octet-stream"}),p=Object.keys(o),l=Object.keys(c);if(p.length>0&&(n.extensionsUsed=p),l.length>0&&(n.extensionsRequired=l),n.buffers&&n.buffers.length>0&&(n.buffers[0].byteLength=u.size),r.binary===!0){const M=new FileReader;M.readAsArrayBuffer(u),M.onloadend=function(){const h=H(M.result),d=new DataView(new ArrayBuffer(W));d.setUint32(0,h.byteLength,!0),d.setUint32(4,ne,!0);const x=H(ie(JSON.stringify(n)),32),T=new DataView(new ArrayBuffer(W));T.setUint32(0,x.byteLength,!0),T.setUint32(4,se,!0);const w=new ArrayBuffer(q),N=new DataView(w);N.setUint32(0,ee,!0),N.setUint32(4,te,!0);const B=q+T.byteLength+x.byteLength+d.byteLength+h.byteLength;N.setUint32(8,B,!0);const g=new Blob([w,T,x,d,h],{type:"application/octet-stream"}),y=new FileReader;y.readAsArrayBuffer(g),y.onloadend=function(){t(y.result)}}}else if(n.buffers&&n.buffers.length>0){const M=new FileReader;M.readAsDataURL(u),M.onloadend=function(){const h=M.result;n.buffers[0].uri=h,t(n)}}else t(n)}serializeUserData(e,t){if(Object.keys(e.userData).length===0)return;const r=this.options,s=this.extensionsUsed;try{const i=JSON.parse(JSON.stringify(e.userData));if(r.includeCustomExtensions&&i.gltfExtensions){t.extensions===void 0&&(t.extensions={});for(const n in i.gltfExtensions)t.extensions[n]=i.gltfExtensions[n],s[n]=!0;delete i.gltfExtensions}Object.keys(i).length>0&&(t.extras=i)}catch(i){console.warn("THREE.GLTFExporter: userData of '"+e.name+"' won't be serialized because of JSON.stringify error - "+i.message)}}getUID(e,t=!1){if(this.uids.has(e)===!1){const s=new Map;s.set(!0,this.uid++),s.set(!1,this.uid++),this.uids.set(e,s)}return this.uids.get(e).get(t)}isNormalizedNormalAttribute(e){if(this.cache.attributesNormalized.has(e))return!1;const r=new f.Vector3;for(let s=0,i=e.count;s<i;s++)if(Math.abs(r.fromBufferAttribute(e,s).length()-1)>5e-4)return!1;return!0}createNormalizedNormalAttribute(e){const t=this.cache;if(t.attributesNormalized.has(e))return t.attributesNormalized.get(e);const r=e.clone(),s=new f.Vector3;for(let i=0,n=r.count;i<n;i++)s.fromBufferAttribute(r,i),s.x===0&&s.y===0&&s.z===0?s.setX(1):s.normalize(),r.setXYZ(i,s.x,s.y,s.z);return t.attributesNormalized.set(e,r),r}applyTextureTransform(e,t){let r=!1;const s={};(t.offset.x!==0||t.offset.y!==0)&&(s.offset=t.offset.toArray(),r=!0),t.rotation!==0&&(s.rotation=t.rotation,r=!0),(t.repeat.x!==1||t.repeat.y!==1)&&(s.scale=t.repeat.toArray(),r=!0),r&&(e.extensions=e.extensions||{},e.extensions.KHR_texture_transform=s,this.extensionsUsed.KHR_texture_transform=!0)}buildMetalRoughTexture(e,t){if(e===t)return e;function r(h){return h.colorSpace===f.SRGBColorSpace?function(x){return x<.04045?x*.0773993808:Math.pow(x*.9478672986+.0521327014,2.4)}:function(x){return x}}console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures."),e instanceof f.CompressedTexture&&(e=z(e)),t instanceof f.CompressedTexture&&(t=z(t));const s=e?e.image:null,i=t?t.image:null,n=Math.max(s?s.width:0,i?i.width:0),o=Math.max(s?s.height:0,i?i.height:0),c=X();c.width=n,c.height=o;const u=c.getContext("2d",{willReadFrequently:!0});u.fillStyle="#00ffff",u.fillRect(0,0,n,o);const p=u.getImageData(0,0,n,o);if(s){u.drawImage(s,0,0,n,o);const h=r(e),d=u.getImageData(0,0,n,o).data;for(let x=2;x<d.length;x+=4)p.data[x]=h(d[x]/256)*256}if(i){u.drawImage(i,0,0,n,o);const h=r(t),d=u.getImageData(0,0,n,o).data;for(let x=1;x<d.length;x+=4)p.data[x]=h(d[x]/256)*256}u.putImageData(p,0,0);const M=(e||t).clone();return M.source=new f.Source(c),M.colorSpace=f.NoColorSpace,M.channel=(e||t).channel,e&&t&&e.channel!==t.channel&&console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match."),M}processBuffer(e){const t=this.json,r=this.buffers;return t.buffers||(t.buffers=[{byteLength:0}]),r.push(e),0}processBufferView(e,t,r,s,i){const n=this.json;n.bufferViews||(n.bufferViews=[]);let o;switch(t){case m.BYTE:case m.UNSIGNED_BYTE:o=1;break;case m.SHORT:case m.UNSIGNED_SHORT:o=2;break;default:o=4}let c=e.itemSize*o;i===m.ARRAY_BUFFER&&(c=Math.ceil(c/4)*4);const u=Q(s*c),p=new DataView(new ArrayBuffer(u));let l=0;for(let d=r;d<r+s;d++){for(let x=0;x<e.itemSize;x++){let T;e.itemSize>4?T=e.array[d*e.itemSize+x]:(x===0?T=e.getX(d):x===1?T=e.getY(d):x===2?T=e.getZ(d):x===3&&(T=e.getW(d)),e.normalized===!0&&(T=f.MathUtils.normalize(T,e.array))),t===m.FLOAT?p.setFloat32(l,T,!0):t===m.INT?p.setInt32(l,T,!0):t===m.UNSIGNED_INT?p.setUint32(l,T,!0):t===m.SHORT?p.setInt16(l,T,!0):t===m.UNSIGNED_SHORT?p.setUint16(l,T,!0):t===m.BYTE?p.setInt8(l,T):t===m.UNSIGNED_BYTE&&p.setUint8(l,T),l+=o}l%c!==0&&(l+=c-l%c)}const M={buffer:this.processBuffer(p.buffer),byteOffset:this.byteOffset,byteLength:u};return i!==void 0&&(M.target=i),i===m.ARRAY_BUFFER&&(M.byteStride=c),this.byteOffset+=u,n.bufferViews.push(M),{id:n.bufferViews.length-1,byteLength:0}}processBufferViewImage(e){const t=this,r=t.json;return r.bufferViews||(r.bufferViews=[]),new Promise(function(s){const i=new FileReader;i.readAsArrayBuffer(e),i.onloadend=function(){const n=H(i.result),o={buffer:t.processBuffer(n),byteOffset:t.byteOffset,byteLength:n.byteLength};t.byteOffset+=n.byteLength,s(r.bufferViews.push(o)-1)}})}processAccessor(e,t,r,s){const i=this.json,n={1:"SCALAR",2:"VEC2",3:"VEC3",4:"VEC4",9:"MAT3",16:"MAT4"};let o;if(e.array.constructor===Float32Array)o=m.FLOAT;else if(e.array.constructor===Int32Array)o=m.INT;else if(e.array.constructor===Uint32Array)o=m.UNSIGNED_INT;else if(e.array.constructor===Int16Array)o=m.SHORT;else if(e.array.constructor===Uint16Array)o=m.UNSIGNED_SHORT;else if(e.array.constructor===Int8Array)o=m.BYTE;else if(e.array.constructor===Uint8Array)o=m.UNSIGNED_BYTE;else throw new Error("THREE.GLTFExporter: Unsupported bufferAttribute component type: "+e.array.constructor.name);if(r===void 0&&(r=0),(s===void 0||s===1/0)&&(s=e.count),s===0)return null;const c=oe(e,r,s);let u;t!==void 0&&(u=e===t.index?m.ELEMENT_ARRAY_BUFFER:m.ARRAY_BUFFER);const p=this.processBufferView(e,o,r,s,u),l={bufferView:p.id,byteOffset:p.byteOffset,componentType:o,count:s,max:c.max,min:c.min,type:n[e.itemSize]};return e.normalized===!0&&(l.normalized=!0),i.accessors||(i.accessors=[]),i.accessors.push(l)-1}processImage(e,t,r,s="image/png"){if(e!==null){const i=this,n=i.cache,o=i.json,c=i.options,u=i.pending;n.images.has(e)||n.images.set(e,{});const p=n.images.get(e),l=s+":flipY/"+r.toString();if(p[l]!==void 0)return p[l];o.images||(o.images=[]);const M={mimeType:s},h=X();h.width=Math.min(e.width,c.maxTextureSize),h.height=Math.min(e.height,c.maxTextureSize);const d=h.getContext("2d",{willReadFrequently:!0});if(r===!0&&(d.translate(0,h.height),d.scale(1,-1)),e.data!==void 0){t!==f.RGBAFormat&&console.error("GLTFExporter: Only RGBAFormat is supported.",t),(e.width>c.maxTextureSize||e.height>c.maxTextureSize)&&console.warn("GLTFExporter: Image size is bigger than maxTextureSize",e);const T=new Uint8ClampedArray(e.height*e.width*4);for(let w=0;w<T.length;w+=4)T[w+0]=e.data[w+0],T[w+1]=e.data[w+1],T[w+2]=e.data[w+2],T[w+3]=e.data[w+3];d.putImageData(new ImageData(T,e.width,e.height),0,0)}else if(typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas)d.drawImage(e,0,0,h.width,h.height);else throw new Error("THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.");c.binary===!0?u.push(J(h,s).then(T=>i.processBufferViewImage(T)).then(T=>{M.bufferView=T})):h.toDataURL!==void 0?M.uri=h.toDataURL(s):u.push(J(h,s).then(T=>new FileReader().readAsDataURL(T)).then(T=>{M.uri=T}));const x=o.images.push(M)-1;return p[l]=x,x}else throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.")}processSampler(e){const t=this.json;t.samplers||(t.samplers=[]);const r={magFilter:b[e.magFilter],minFilter:b[e.minFilter],wrapS:b[e.wrapS],wrapT:b[e.wrapT]};return t.samplers.push(r)-1}processTexture(e){const r=this.options,s=this.cache,i=this.json;if(s.textures.has(e))return s.textures.get(e);i.textures||(i.textures=[]),e instanceof f.CompressedTexture&&(e=z(e,r.maxTextureSize));let n=e.userData.mimeType;n==="image/webp"&&(n="image/png");const o={sampler:this.processSampler(e),source:this.processImage(e.image,e.format,e.flipY,n)};e.name&&(o.name=e.name),this._invokeAll(function(u){u.writeTexture&&u.writeTexture(e,o)});const c=i.textures.push(o)-1;return s.textures.set(e,c),c}processMaterial(e){const t=this.cache,r=this.json;if(t.materials.has(e))return t.materials.get(e);if(e.isShaderMaterial)return console.warn("GLTFExporter: THREE.ShaderMaterial not supported."),null;r.materials||(r.materials=[]);const s={pbrMetallicRoughness:{}};e.isMeshStandardMaterial!==!0&&e.isMeshBasicMaterial!==!0&&console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");const i=e.color.toArray().concat([e.opacity]);if(O(i,[1,1,1,1])||(s.pbrMetallicRoughness.baseColorFactor=i),e.isMeshStandardMaterial?(s.pbrMetallicRoughness.metallicFactor=e.metalness,s.pbrMetallicRoughness.roughnessFactor=e.roughness):(s.pbrMetallicRoughness.metallicFactor=.5,s.pbrMetallicRoughness.roughnessFactor=.5),e.metalnessMap||e.roughnessMap){const o=this.buildMetalRoughTexture(e.metalnessMap,e.roughnessMap),c={index:this.processTexture(o),channel:o.channel};this.applyTextureTransform(c,o),s.pbrMetallicRoughness.metallicRoughnessTexture=c}if(e.map){const o={index:this.processTexture(e.map),texCoord:e.map.channel};this.applyTextureTransform(o,e.map),s.pbrMetallicRoughness.baseColorTexture=o}if(e.emissive){const o=e.emissive;if(Math.max(o.r,o.g,o.b)>0&&(s.emissiveFactor=e.emissive.toArray()),e.emissiveMap){const u={index:this.processTexture(e.emissiveMap),texCoord:e.emissiveMap.channel};this.applyTextureTransform(u,e.emissiveMap),s.emissiveTexture=u}}if(e.normalMap){const o={index:this.processTexture(e.normalMap),texCoord:e.normalMap.channel};e.normalScale&&e.normalScale.x!==1&&(o.scale=e.normalScale.x),this.applyTextureTransform(o,e.normalMap),s.normalTexture=o}if(e.aoMap){const o={index:this.processTexture(e.aoMap),texCoord:e.aoMap.channel};e.aoMapIntensity!==1&&(o.strength=e.aoMapIntensity),this.applyTextureTransform(o,e.aoMap),s.occlusionTexture=o}e.transparent?s.alphaMode="BLEND":e.alphaTest>0&&(s.alphaMode="MASK",s.alphaCutoff=e.alphaTest),e.side===f.DoubleSide&&(s.doubleSided=!0),e.name!==""&&(s.name=e.name),this.serializeUserData(e,s),this._invokeAll(function(o){o.writeMaterial&&o.writeMaterial(e,s)});const n=r.materials.push(s)-1;return t.materials.set(e,n),n}processMesh(e){const t=this.cache,r=this.json,s=[e.geometry.uuid];if(Array.isArray(e.material))for(let g=0,y=e.material.length;g<y;g++)s.push(e.material[g].uuid);else s.push(e.material.uuid);const i=s.join(":");if(t.meshes.has(i))return t.meshes.get(i);const n=e.geometry;let o;e.isLineSegments?o=m.LINES:e.isLineLoop?o=m.LINE_LOOP:e.isLine?o=m.LINE_STRIP:e.isPoints?o=m.POINTS:o=e.material.wireframe?m.LINES:m.TRIANGLES;const c={},u={},p=[],l=[],M={uv:"TEXCOORD_0",uv1:"TEXCOORD_1",uv2:"TEXCOORD_2",uv3:"TEXCOORD_3",color:"COLOR_0",skinWeight:"WEIGHTS_0",skinIndex:"JOINTS_0"},h=n.getAttribute("normal");h!==void 0&&!this.isNormalizedNormalAttribute(h)&&(console.warn("THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one."),n.setAttribute("normal",this.createNormalizedNormalAttribute(h)));let d=null;for(let g in n.attributes){if(g.slice(0,5)==="morph")continue;const y=n.attributes[g];if(g=M[g]||g.toUpperCase(),/^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/.test(g)||(g="_"+g),t.attributes.has(this.getUID(y))){u[g]=t.attributes.get(this.getUID(y));continue}d=null;const I=y.array;g==="JOINTS_0"&&!(I instanceof Uint16Array)&&!(I instanceof Uint8Array)&&(console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.'),d=new f.BufferAttribute(new Uint16Array(I),y.itemSize,y.normalized));const R=this.processAccessor(d||y,n);R!==null&&(g.startsWith("_")||this.detectMeshQuantization(g,y),u[g]=R,t.attributes.set(this.getUID(y),R))}if(h!==void 0&&n.setAttribute("normal",h),Object.keys(u).length===0)return null;if(e.morphTargetInfluences!==void 0&&e.morphTargetInfluences.length>0){const g=[],y=[],E={};if(e.morphTargetDictionary!==void 0)for(const I in e.morphTargetDictionary)E[e.morphTargetDictionary[I]]=I;for(let I=0;I<e.morphTargetInfluences.length;++I){const R={};let Y=!1;for(const C in n.morphAttributes){if(C!=="position"&&C!=="normal"){Y||(console.warn("GLTFExporter: Only POSITION and NORMAL morph are supported."),Y=!0);continue}const S=n.morphAttributes[C][I],D=C.toUpperCase(),U=n.attributes[C];if(t.attributes.has(this.getUID(S,!0))){R[D]=t.attributes.get(this.getUID(S,!0));continue}const v=S.clone();if(!n.morphTargetsRelative)for(let A=0,Z=S.count;A<Z;A++)for(let L=0;L<S.itemSize;L++)L===0&&v.setX(A,S.getX(A)-U.getX(A)),L===1&&v.setY(A,S.getY(A)-U.getY(A)),L===2&&v.setZ(A,S.getZ(A)-U.getZ(A)),L===3&&v.setW(A,S.getW(A)-U.getW(A));R[D]=this.processAccessor(v,n),t.attributes.set(this.getUID(U,!0),R[D])}l.push(R),g.push(e.morphTargetInfluences[I]),e.morphTargetDictionary!==void 0&&y.push(E[I])}c.weights=g,y.length>0&&(c.extras={},c.extras.targetNames=y)}const x=Array.isArray(e.material);if(x&&n.groups.length===0)return null;let T=!1;if(x&&n.index===null){const g=[];for(let y=0,E=n.attributes.position.count;y<E;y++)g[y]=y;n.setIndex(g),T=!0}const w=x?e.material:[e.material],N=x?n.groups:[{materialIndex:0,start:void 0,count:void 0}];for(let g=0,y=N.length;g<y;g++){const E={mode:o,attributes:u};if(this.serializeUserData(n,E),l.length>0&&(E.targets=l),n.index!==null){let R=this.getUID(n.index);(N[g].start!==void 0||N[g].count!==void 0)&&(R+=":"+N[g].start+":"+N[g].count),t.attributes.has(R)?E.indices=t.attributes.get(R):(E.indices=this.processAccessor(n.index,n,N[g].start,N[g].count),t.attributes.set(R,E.indices)),E.indices===null&&delete E.indices}const I=this.processMaterial(w[N[g].materialIndex]);I!==null&&(E.material=I),p.push(E)}T===!0&&n.setIndex(null),c.primitives=p,r.meshes||(r.meshes=[]),this._invokeAll(function(g){g.writeMesh&&g.writeMesh(e,c)});const B=r.meshes.push(c)-1;return t.meshes.set(i,B),B}detectMeshQuantization(e,t){if(this.extensionsUsed[k])return;let r;switch(t.array.constructor){case Int8Array:r="byte";break;case Uint8Array:r="unsigned byte";break;case Int16Array:r="short";break;case Uint16Array:r="unsigned short";break;default:return}t.normalized&&(r+=" normalized");const s=e.split("_",1)[0];K[s]&&K[s].includes(r)&&(this.extensionsUsed[k]=!0,this.extensionsRequired[k]=!0)}processCamera(e){const t=this.json;t.cameras||(t.cameras=[]);const r=e.isOrthographicCamera,s={type:r?"orthographic":"perspective"};return r?s.orthographic={xmag:e.right*2,ymag:e.top*2,zfar:e.far<=0?.001:e.far,znear:e.near<0?0:e.near}:s.perspective={aspectRatio:e.aspect,yfov:f.MathUtils.degToRad(e.fov),zfar:e.far<=0?.001:e.far,znear:e.near<0?0:e.near},e.name!==""&&(s.name=e.type),t.cameras.push(s)-1}processAnimation(e,t){const r=this.json,s=this.nodeMap;r.animations||(r.animations=[]),e=V.Utils.mergeMorphTargetTracks(e.clone(),t);const i=e.tracks,n=[],o=[];for(let c=0;c<i.length;++c){const u=i[c],p=f.PropertyBinding.parseTrackName(u.name);let l=f.PropertyBinding.findNode(t,p.nodeName);const M=j[p.propertyName];if(p.objectName==="bones"&&(l.isSkinnedMesh===!0?l=l.skeleton.getBoneByName(p.objectIndex):l=void 0),!l||!M){console.warn('THREE.GLTFExporter: Could not export animation track "%s".',u.name);continue}const h=1;let d=u.values.length/u.times.length;M===j.morphTargetInfluences&&(d/=l.morphTargetInfluences.length);let x;u.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline===!0?(x="CUBICSPLINE",d/=3):u.getInterpolation()===f.InterpolateDiscrete?x="STEP":x="LINEAR",o.push({input:this.processAccessor(new f.BufferAttribute(u.times,h)),output:this.processAccessor(new f.BufferAttribute(u.values,d)),interpolation:x}),n.push({sampler:o.length-1,target:{node:s.get(l),path:M}})}return r.animations.push({name:e.name||"clip_"+r.animations.length,samplers:o,channels:n}),r.animations.length-1}processSkin(e){const t=this.json,r=this.nodeMap,s=t.nodes[r.get(e)],i=e.skeleton;if(i===void 0)return null;const n=e.skeleton.bones[0];if(n===void 0)return null;const o=[],c=new Float32Array(i.bones.length*16),u=new f.Matrix4;for(let l=0;l<i.bones.length;++l)o.push(r.get(i.bones[l])),u.copy(i.boneInverses[l]),u.multiply(e.bindMatrix).toArray(c,l*16);return t.skins===void 0&&(t.skins=[]),t.skins.push({inverseBindMatrices:this.processAccessor(new f.BufferAttribute(c,16)),joints:o,skeleton:r.get(n)}),s.skin=t.skins.length-1}processNode(e){const t=this.json,r=this.options,s=this.nodeMap;t.nodes||(t.nodes=[]);const i={};if(r.trs){const o=e.quaternion.toArray(),c=e.position.toArray(),u=e.scale.toArray();O(o,[0,0,0,1])||(i.rotation=o),O(c,[0,0,0])||(i.translation=c),O(u,[1,1,1])||(i.scale=u)}else e.matrixAutoUpdate&&e.updateMatrix(),re(e.matrix)===!1&&(i.matrix=e.matrix.elements);if(e.name!==""&&(i.name=String(e.name)),this.serializeUserData(e,i),e.isMesh||e.isLine||e.isPoints){const o=this.processMesh(e);o!==null&&(i.mesh=o)}else e.isCamera&&(i.camera=this.processCamera(e));if(e.isSkinnedMesh&&this.skins.push(e),e.children.length>0){const o=[];for(let c=0,u=e.children.length;c<u;c++){const p=e.children[c];if(p.visible||r.onlyVisible===!1){const l=this.processNode(p);l!==null&&o.push(l)}}o.length>0&&(i.children=o)}this._invokeAll(function(o){o.writeNode&&o.writeNode(e,i)});const n=t.nodes.push(i)-1;return s.set(e,n),n}processScene(e){const t=this.json,r=this.options;t.scenes||(t.scenes=[],t.scene=0);const s={};e.name!==""&&(s.name=e.name),t.scenes.push(s);const i=[];for(let n=0,o=e.children.length;n<o;n++){const c=e.children[n];if(c.visible||r.onlyVisible===!1){const u=this.processNode(c);u!==null&&i.push(u)}}i.length>0&&(s.nodes=i),this.serializeUserData(e,s)}processObjects(e){const t=new f.Scene;t.name="AuxScene";for(let r=0;r<e.length;r++)t.children.push(e[r]);this.processScene(t)}processInput(e){const t=this.options;e=e instanceof Array?e:[e],this._invokeAll(function(s){s.beforeParse&&s.beforeParse(e)});const r=[];for(let s=0;s<e.length;s++)e[s]instanceof f.Scene?this.processScene(e[s]):r.push(e[s]);r.length>0&&this.processObjects(r);for(let s=0;s<this.skins.length;++s)this.processSkin(this.skins[s]);for(let s=0;s<t.animations.length;++s)this.processAnimation(t.animations[s],e[0]);this._invokeAll(function(s){s.afterParse&&s.afterParse(e)})}_invokeAll(e){for(let t=0,r=this.plugins.length;t<r;t++)e(this.plugins[t])}}class ce{constructor(e){this.writer=e,this.name="KHR_lights_punctual"}writeNode(e,t){if(!e.isLight)return;if(!e.isDirectionalLight&&!e.isPointLight&&!e.isSpotLight){console.warn("THREE.GLTFExporter: Only directional, point, and spot lights are supported.",e);return}const r=this.writer,s=r.json,i=r.extensionsUsed,n={};e.name&&(n.name=e.name),n.color=e.color.toArray(),n.intensity=e.intensity,e.isDirectionalLight?n.type="directional":e.isPointLight?(n.type="point",e.distance>0&&(n.range=e.distance)):e.isSpotLight&&(n.type="spot",e.distance>0&&(n.range=e.distance),n.spot={},n.spot.innerConeAngle=(1-e.penumbra)*e.angle,n.spot.outerConeAngle=e.angle),e.decay!==void 0&&e.decay!==2&&console.warn("THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2."),e.target&&(e.target.parent!==e||e.target.position.x!==0||e.target.position.y!==0||e.target.position.z!==-1)&&console.warn("THREE.GLTFExporter: Light direction may be lost. For best results, make light.target a child of the light with position 0,0,-1."),i[this.name]||(s.extensions=s.extensions||{},s.extensions[this.name]={lights:[]},i[this.name]=!0);const o=s.extensions[this.name].lights;o.push(n),t.extensions=t.extensions||{},t.extensions[this.name]={light:o.length-1}}}class ue{constructor(e){this.writer=e,this.name="KHR_materials_unlit"}writeMaterial(e,t){if(!e.isMeshBasicMaterial)return;const s=this.writer.extensionsUsed;t.extensions=t.extensions||{},t.extensions[this.name]={},s[this.name]=!0,t.pbrMetallicRoughness.metallicFactor=0,t.pbrMetallicRoughness.roughnessFactor=.9}}class le{constructor(e){this.writer=e,this.name="KHR_materials_clearcoat"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.clearcoat===0)return;const r=this.writer,s=r.extensionsUsed,i={};if(i.clearcoatFactor=e.clearcoat,e.clearcoatMap){const n={index:r.processTexture(e.clearcoatMap),texCoord:e.clearcoatMap.channel};r.applyTextureTransform(n,e.clearcoatMap),i.clearcoatTexture=n}if(i.clearcoatRoughnessFactor=e.clearcoatRoughness,e.clearcoatRoughnessMap){const n={index:r.processTexture(e.clearcoatRoughnessMap),texCoord:e.clearcoatRoughnessMap.channel};r.applyTextureTransform(n,e.clearcoatRoughnessMap),i.clearcoatRoughnessTexture=n}if(e.clearcoatNormalMap){const n={index:r.processTexture(e.clearcoatNormalMap),texCoord:e.clearcoatNormalMap.channel};e.clearcoatNormalScale.x!==1&&(n.scale=e.clearcoatNormalScale.x),r.applyTextureTransform(n,e.clearcoatNormalMap),i.clearcoatNormalTexture=n}t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class fe{constructor(e){this.writer=e,this.name="KHR_materials_dispersion"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.dispersion===0)return;const s=this.writer.extensionsUsed,i={};i.dispersion=e.dispersion,t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class he{constructor(e){this.writer=e,this.name="KHR_materials_iridescence"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.iridescence===0)return;const r=this.writer,s=r.extensionsUsed,i={};if(i.iridescenceFactor=e.iridescence,e.iridescenceMap){const n={index:r.processTexture(e.iridescenceMap),texCoord:e.iridescenceMap.channel};r.applyTextureTransform(n,e.iridescenceMap),i.iridescenceTexture=n}if(i.iridescenceIor=e.iridescenceIOR,i.iridescenceThicknessMinimum=e.iridescenceThicknessRange[0],i.iridescenceThicknessMaximum=e.iridescenceThicknessRange[1],e.iridescenceThicknessMap){const n={index:r.processTexture(e.iridescenceThicknessMap),texCoord:e.iridescenceThicknessMap.channel};r.applyTextureTransform(n,e.iridescenceThicknessMap),i.iridescenceThicknessTexture=n}t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class pe{constructor(e){this.writer=e,this.name="KHR_materials_transmission"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.transmission===0)return;const r=this.writer,s=r.extensionsUsed,i={};if(i.transmissionFactor=e.transmission,e.transmissionMap){const n={index:r.processTexture(e.transmissionMap),texCoord:e.transmissionMap.channel};r.applyTextureTransform(n,e.transmissionMap),i.transmissionTexture=n}t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class de{constructor(e){this.writer=e,this.name="KHR_materials_volume"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.transmission===0)return;const r=this.writer,s=r.extensionsUsed,i={};if(i.thicknessFactor=e.thickness,e.thicknessMap){const n={index:r.processTexture(e.thicknessMap),texCoord:e.thicknessMap.channel};r.applyTextureTransform(n,e.thicknessMap),i.thicknessTexture=n}e.attenuationDistance!==1/0&&(i.attenuationDistance=e.attenuationDistance),i.attenuationColor=e.attenuationColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class xe{constructor(e){this.writer=e,this.name="KHR_materials_ior"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.ior===1.5)return;const s=this.writer.extensionsUsed,i={};i.ior=e.ior,t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class ge{constructor(e){this.writer=e,this.name="KHR_materials_specular"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.specularIntensity===1&&e.specularColor.equals($)&&!e.specularIntensityMap&&!e.specularColorMap)return;const r=this.writer,s=r.extensionsUsed,i={};if(e.specularIntensityMap){const n={index:r.processTexture(e.specularIntensityMap),texCoord:e.specularIntensityMap.channel};r.applyTextureTransform(n,e.specularIntensityMap),i.specularTexture=n}if(e.specularColorMap){const n={index:r.processTexture(e.specularColorMap),texCoord:e.specularColorMap.channel};r.applyTextureTransform(n,e.specularColorMap),i.specularColorTexture=n}i.specularFactor=e.specularIntensity,i.specularColorFactor=e.specularColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class Te{constructor(e){this.writer=e,this.name="KHR_materials_sheen"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.sheen==0)return;const r=this.writer,s=r.extensionsUsed,i={};if(e.sheenRoughnessMap){const n={index:r.processTexture(e.sheenRoughnessMap),texCoord:e.sheenRoughnessMap.channel};r.applyTextureTransform(n,e.sheenRoughnessMap),i.sheenRoughnessTexture=n}if(e.sheenColorMap){const n={index:r.processTexture(e.sheenColorMap),texCoord:e.sheenColorMap.channel};r.applyTextureTransform(n,e.sheenColorMap),i.sheenColorTexture=n}i.sheenRoughnessFactor=e.sheenRoughness,i.sheenColorFactor=e.sheenColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class me{constructor(e){this.writer=e,this.name="KHR_materials_anisotropy"}writeMaterial(e,t){if(!e.isMeshPhysicalMaterial||e.anisotropy==0)return;const r=this.writer,s=r.extensionsUsed,i={};if(e.anisotropyMap){const n={index:r.processTexture(e.anisotropyMap)};r.applyTextureTransform(n,e.anisotropyMap),i.anisotropyTexture=n}i.anisotropyStrength=e.anisotropy,i.anisotropyRotation=e.anisotropyRotation,t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class Me{constructor(e){this.writer=e,this.name="KHR_materials_emissive_strength"}writeMaterial(e,t){if(!e.isMeshStandardMaterial||e.emissiveIntensity===1)return;const s=this.writer.extensionsUsed,i={};i.emissiveStrength=e.emissiveIntensity,t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class ye{constructor(e){this.writer=e,this.name="EXT_materials_bump"}writeMaterial(e,t){if(!e.isMeshStandardMaterial||e.bumpScale===1&&!e.bumpMap)return;const r=this.writer,s=r.extensionsUsed,i={};if(e.bumpMap){const n={index:r.processTexture(e.bumpMap),texCoord:e.bumpMap.channel};r.applyTextureTransform(n,e.bumpMap),i.bumpTexture=n}i.bumpFactor=e.bumpScale,t.extensions=t.extensions||{},t.extensions[this.name]=i,s[this.name]=!0}}class we{constructor(e){this.writer=e,this.name="EXT_mesh_gpu_instancing"}writeNode(e,t){if(!e.isInstancedMesh)return;const r=this.writer,s=e,i=new Float32Array(s.count*3),n=new Float32Array(s.count*4),o=new Float32Array(s.count*3),c=new f.Matrix4,u=new f.Vector3,p=new f.Quaternion,l=new f.Vector3;for(let h=0;h<s.count;h++)s.getMatrixAt(h,c),c.decompose(u,p,l),u.toArray(i,h*3),p.toArray(n,h*4),l.toArray(o,h*3);const M={TRANSLATION:r.processAccessor(new f.BufferAttribute(i,3)),ROTATION:r.processAccessor(new f.BufferAttribute(n,4)),SCALE:r.processAccessor(new f.BufferAttribute(o,3))};s.instanceColor&&(M._COLOR_0=r.processAccessor(s.instanceColor)),t.extensions=t.extensions||{},t.extensions[this.name]={attributes:M},r.extensionsUsed[this.name]=!0,r.extensionsRequired[this.name]=!0}}V.Utils={insertKeyframe:function(a,e){const r=a.getValueSize(),s=new a.TimeBufferType(a.times.length+1),i=new a.ValueBufferType(a.values.length+r),n=a.createInterpolant(new a.ValueBufferType(r));let o;if(a.times.length===0){s[0]=e;for(let c=0;c<r;c++)i[c]=0;o=0}else if(e<a.times[0]){if(Math.abs(a.times[0]-e)<.001)return 0;s[0]=e,s.set(a.times,1),i.set(n.evaluate(e),0),i.set(a.values,r),o=0}else if(e>a.times[a.times.length-1]){if(Math.abs(a.times[a.times.length-1]-e)<.001)return a.times.length-1;s[s.length-1]=e,s.set(a.times,0),i.set(a.values,0),i.set(n.evaluate(e),a.values.length),o=s.length-1}else for(let c=0;c<a.times.length;c++){if(Math.abs(a.times[c]-e)<.001)return c;if(a.times[c]<e&&a.times[c+1]>e){s.set(a.times.slice(0,c+1),0),s[c+1]=e,s.set(a.times.slice(c+1),c+2),i.set(a.values.slice(0,(c+1)*r),0),i.set(n.evaluate(e),(c+1)*r),i.set(a.values.slice((c+1)*r),(c+2)*r),o=c+1;break}}return a.times=s,a.values=i,o},mergeMorphTargetTracks:function(a,e){const t=[],r={},s=a.tracks;for(let i=0;i<s.length;++i){let n=s[i];const o=f.PropertyBinding.parseTrackName(n.name),c=f.PropertyBinding.findNode(e,o.nodeName);if(o.propertyName!=="morphTargetInfluences"||o.propertyIndex===void 0){t.push(n);continue}if(n.createInterpolant!==n.InterpolantFactoryMethodDiscrete&&n.createInterpolant!==n.InterpolantFactoryMethodLinear){if(n.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline)throw new Error("THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.");console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead."),n=n.clone(),n.setInterpolation(f.InterpolateLinear)}const u=c.morphTargetInfluences.length,p=c.morphTargetDictionary[o.propertyIndex];if(p===void 0)throw new Error("THREE.GLTFExporter: Morph target name not found: "+o.propertyIndex);let l;if(r[c.uuid]===void 0){l=n.clone();const h=new l.ValueBufferType(u*l.times.length);for(let d=0;d<l.times.length;d++)h[d*u+p]=l.values[d];l.name=(o.nodeName||"")+".morphTargetInfluences",l.values=h,r[c.uuid]=l,t.push(l);continue}const M=n.createInterpolant(new n.ValueBufferType(1));l=r[c.uuid];for(let h=0;h<l.times.length;h++)l.values[h*u+p]=M.evaluate(l.times[h]);for(let h=0;h<n.times.length;h++){const d=this.insertKeyframe(l,n.times[h]);l.values[d*u+p]=n.values[h]}}return a.tracks=t,a}};exports.GLTFExporter=V;