markuno_lib 1.1.53 → 1.1.54

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/bin/markcad3d.js CHANGED
@@ -1,4 +1,4 @@
1
- import*as THREE from"three";import{PIF,hash,clean,getshape,raccordabezier}from"#markuno_cad";export{clamp}from"#markuno_cad";import{clean as clean$1,getcolonne,muClComments}from"#markuno_lib";const SIDE=THREE.DoubleSide;let materialline1=new THREE.LineBasicMaterial({color:3158064}),materialline2=new THREE.LineBasicMaterial({color:5263440});const mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgray1=new THREE.MeshStandardMaterial({color:8421504,roughness:.5,metalness:.4,side:SIDE}),mgray2=new THREE.MeshStandardMaterial({color:11579568,roughness:.5,metalness:.4,side:SIDE}),mred=new THREE.MeshStandardMaterial({color:16711680,roughness:.5,metalness:.4,side:SIDE}),mblue=new THREE.MeshStandardMaterial({color:1982639,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE}),mblack=new THREE.MeshStandardMaterial({color:0,roughness:.5,metalness:.4,side:SIDE}),scaleunit=.001;function groupfromgeometry(geometry,material,x,y,z,name,layer){let child=new THREE.Group;child.position.set(x,y,z),child.name=name;const mesh=new THREE.Mesh(geometry,material);mesh.name=name,mesh.castShadow=!0,mesh.receiveShadow=!0,mesh.layers.set(layer);const edges=new THREE.EdgesGeometry(geometry),lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(30),child.add(mesh),child.add(lineSegments),child}function posiziona(grp,pos={}){let tm=new THREE.Group;if(grp){let g2=grp.clone(),tm2=g2,{sl:sl=0,sa:sa=0,sp:sp=0,ax:ax=0,ay:ay=0,az:az=0,ul:ul=0,ua:ua=0,up:up=0,scale:scale=1,scx:scx=scale,scy:scy=scale,scz:scz=scale,emitters:emitters,emittersname:emittersname}=pos;if(tm.position.set(sl,sa,sp),tm.rotation.set(ax*PIF,ay*PIF,az*PIF),(ul||ua||up)&&(tm2=new THREE.Group,tm2.add(g2),tm2.position.set(ul,ua,up)),tm.scale.set(scx,scy,scz),tm.add(tm2),emitters&&emitters.length)for(let e of emitters)e.name=e.name||emittersname,tm.add(getemitter(e))}return tm}function edgesfromgeometry(g1,layer=30){return getlinesgeom(new THREE.EdgesGeometry(g1,40),layer)}function getlinesgeom(edges,layer=30){const lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(layer),lineSegments}function getmesh(geom,material,layer=1,clone=!1){let m=new THREE.Mesh(geom,clone?material.clone():material);return m.castShadow=!0,m.receiveShadow=!0,m.layers.set(layer),m}function get3dshape(punti,material,layer){if(!punti||punti.length<3)return new THREE.BufferGeometry;const vertices=[];for(let i=0;i<punti.length;i++){const p1=punti[i],p2=punti[(i+1)%punti.length];vertices.push(p1.x,0,p1.y),vertices.push(p2.x,0,p2.y)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3));let m=new THREE.LineSegments(geometry,material);return m.layers.set(layer),m}function creategroup(name){let g=new THREE.Group;return g.name=name||"$$",g}function svuotanodo(n){!function _dispose(node){if(node.children.length){[...node.children].forEach((child=>{_dispose(child),node.remove(child)}))}node.geometry&&node.geometry.dispose(),node.material&&(Array.isArray(node.material)?node.material.forEach((m=>m.dispose())):node.material.dispose())}(n)}function deletegroup(grpbase,name){if(!grpbase?.children)return;let gr=grpbase.children.find((e=>e.name==name));if(gr){for(;gr.children.length>0;){const child=gr.children[0];gr.remove(child)}gr.parent&&gr.parent.remove(gr),gr=null}}function randombasemat(){const material=new THREE.LineBasicMaterial,color=new THREE.Color;return color.setHSL(Math.random(),.7,.4),material.color=color,material}
1
+ import*as THREE from"three";import{TrianglesDrawMode,TriangleFanDrawMode,TriangleStripDrawMode,Loader,LoaderUtils,FileLoader,MeshPhysicalMaterial,Vector2,Color,LinearSRGBColorSpace,SRGBColorSpace,SpotLight,PointLight,DirectionalLight,Matrix4,Vector3,Quaternion,InstancedMesh,InstancedBufferAttribute,Object3D,TextureLoader,ImageBitmapLoader,BufferAttribute,InterleavedBuffer,InterleavedBufferAttribute,LinearMipmapLinearFilter,NearestMipmapLinearFilter,LinearMipmapNearestFilter,NearestMipmapNearestFilter,LinearFilter,NearestFilter,RepeatWrapping,MirroredRepeatWrapping,ClampToEdgeWrapping,PointsMaterial,Material,LineBasicMaterial,MeshStandardMaterial,DoubleSide,MeshBasicMaterial,PropertyBinding,BufferGeometry,SkinnedMesh,Mesh,LineSegments,Line,LineLoop,Points,Group,PerspectiveCamera,MathUtils,OrthographicCamera,Skeleton,AnimationClip,Bone,InterpolateDiscrete,InterpolateLinear,Texture,VectorKeyframeTrack,NumberKeyframeTrack,QuaternionKeyframeTrack,ColorManagement,FrontSide,Interpolant,Box3,Sphere,CompressedCubeTexture,UnsignedByteType,CompressedArrayTexture,CompressedTexture,DisplayP3ColorSpace,LinearDisplayP3ColorSpace,NoColorSpace,RGBA_ASTC_6x6_Format,RedFormat,RGFormat,RGBAFormat,HalfFloatType,FloatType,DataTexture,Data3DTexture,RGBA_S3TC_DXT1_Format,RGB_PVRTC_4BPPV1_Format,RGB_ETC2_Format,RGB_ETC1_Format,RGBA_S3TC_DXT5_Format,RGBA_PVRTC_4BPPV1_Format,RGBA_ETC2_EAC_Format,RGBA_BPTC_Format,RGBA_ASTC_4x4_Format,MeshPhongMaterial,AdditiveBlending,Float32BufferAttribute}from"three";import{hash,PIF,clean as clean$1,getshape,raccordabezier}from"#markuno_cad";export{clamp}from"#markuno_cad";import{getcolonne,clean,muClComments}from"#markuno_lib";const mgreen$1=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:THREE.DoubleSide});function getorientate(ori,x,y,z){switch(x=x||0,y=y||0,z=z||0,ori.trim().toLowerCase()){case"alp":return{x:y,y:x,z:z};case"apl":return{x:y,y:z,z:x};case"pla":return{x:z,y:x,z:y};case"pal":return{x:z,y:y,z:x};case"lpa":return{x:x,y:z,z:y};default:return{x:x,y:y,z:z}}}function parselavs(ori,id,x=0,y=0,z=0,lavorazioni="",facce="",def=""){let lavcods=muClComments(lavorazioni),rets=[];for(let lavcod of lavcods){var rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(lavcod);if(rr&&rr[1]){let lav={name:rr[1].trim().toLowerCase(),...getorientate(ori,x,y,z),id:id,facce:facce};if(rr[2]){let aa=getcolonne(rr[2]);for(let a of aa){let i=a.indexOf("=");i>0&&(lav[a.slice(0,i).trim()]=a.slice(i+1).trim())}}rets.push(lav)}}return!rets.length&&def&&rets.push({name:def,...getorientate(ori,x,y,z),id:id,facce:facce}),rets}function getemitter(data){let{d:d,name:name,x:x,y:y,z:z,lavs:lavs="",ids:ids="",faces:faces=null,size:size=5}=data;ids=getcolonne(clean(ids,!0));const emitter=new THREE.Object3D;if(emitter.position.set(x,y,z),emitter.userData={emitter:!0,lavs:lavs,ids:ids,faces:faces,size:size,name:name},d){const geometry=new THREE.SphereGeometry(size||5,8,8),material=new THREE.MeshBasicMaterial({color:16711680}),mesh=new THREE.Mesh(geometry,material);emitter.add(mesh)}return emitter}function getreceiver(gcad,data){gcad.gmats.__istask=1;let{d:d,ori:ori="LAP",x:x=0,y:y=0,z:z=0,tipo:tipo="",start:start="",end:end=""}=data;tipo=clean(tipo,!0);const receiver=new THREE.Object3D;if(receiver.position.set(x/2,y/2,z/2),receiver.userData={receiver:!0,ori:(ori||"").trim().toLowerCase(),x:x,y:y,z:z,tipo:tipo,start:start,end:end},d){const geometry=new THREE.BoxGeometry(x,y,z),mesh=new THREE.Mesh(geometry,mgreen$1);mesh.position.set(0,0,0),receiver.add(mesh)}return receiver}function calcolatasks(scena){const emitterWorldPosition=new WeakMap,receiverWorldMatrixInverse=new WeakMap;function boxBoxIntersects(pos,l,x,y,z){return pos.x+l>0&&pos.x-l<x&&pos.y+l>0&&pos.y-l<y&&pos.z+l>0&&pos.z-l<z}function getFacceToccate(pos,sogliafaccia,x,y,z,filtra){const facce=[];function addfaccia(f){filtra&&!filtra.includes(f)||facce.push(f)}return Math.abs(pos.x-0)<sogliafaccia&&addfaccia("s"),Math.abs(pos.x-x)<sogliafaccia&&addfaccia("d"),Math.abs(pos.y-0)<sogliafaccia&&addfaccia("b"),Math.abs(pos.y-y)<sogliafaccia&&addfaccia("a"),Math.abs(pos.z-0)<sogliafaccia&&addfaccia("z"),Math.abs(pos.z-z)<sogliafaccia&&addfaccia("f"),facce.join("")}function getEmitterWorldPosition(emitter){if(!emitterWorldPosition.has(emitter)){const pos=new THREE.Vector3;emitter.getWorldPosition(pos),emitterWorldPosition.set(emitter,pos)}return emitterWorldPosition.get(emitter)}function getReceiverWorldMatrixInverse(receiver){if(!receiverWorldMatrixInverse.has(receiver)){const inv=receiver.matrixWorld.clone().invert();receiverWorldMatrixInverse.set(receiver,inv)}return receiverWorldMatrixInverse.get(receiver)}scena.updateMatrixWorld(!0);const receivers=[],emitters=[];!function scan(obj){obj.userData?.receiver&&receivers.push(obj),obj.userData?.emitter&&emitters.push(obj),obj.children&&obj.children.forEach(scan)}(scena);let tasks=[];for(const receiver of receivers){const{mat:mat,ori:ori,x:x,y:y,z:z,start:start,end:end,tipo:tipo,size:size}=receiver.userData;let singletask={id:mat,...getorientate(ori,x,y,z),tipo:tipo,ori:ori,lavs:[]};start&&singletask.lavs.push(...parselavs(ori,"_start",0,0,0,start,"",""));const matrixInverse=getReceiverWorldMatrixInverse(receiver);for(const emitter of emitters){if("string"==typeof tipo&&""!==tipo){const idx=emitter.userData.ids;if(Array.isArray(idx)&&idx.length>0&&!idx.includes("*")&&!idx.includes(tipo))continue}const posLocalAdj=getEmitterWorldPosition(emitter).clone().applyMatrix4(matrixInverse).clone().add(new THREE.Vector3(x/2,y/2,z/2));if(!boxBoxIntersects(posLocalAdj,emitter.userData.size??0,x,y,z))continue;const facceToccate=getFacceToccate(posLocalAdj,emitter.userData.soglia??2,x,y,z,emitter.userData.faces);facceToccate&&facceToccate.length&&singletask.lavs.push(...parselavs(ori,emitter.userData.name,posLocalAdj.x,posLocalAdj.y,posLocalAdj.z,emitter.userData.lavs,facceToccate,"nd"))}end&&singletask.lavs.push(...parselavs(ori,"_end",0,0,0,end,"","")),singletask.lavs.length&&tasks.push(singletask)}return tasks}const SIDE=THREE.DoubleSide;let materialline1=new THREE.LineBasicMaterial({color:3158064}),materialline2=new THREE.LineBasicMaterial({color:5263440});const mwhite=new THREE.MeshStandardMaterial({color:16777215,roughness:.5,metalness:.4,side:SIDE}),mgray1=new THREE.MeshStandardMaterial({color:8421504,roughness:.5,metalness:.4,side:SIDE}),mgray2=new THREE.MeshStandardMaterial({color:11579568,roughness:.5,metalness:.4,side:SIDE}),mred=new THREE.MeshStandardMaterial({color:16711680,roughness:.5,metalness:.4,side:SIDE}),mblue=new THREE.MeshStandardMaterial({color:1982639,roughness:.5,metalness:.4,side:SIDE}),mgreen=new THREE.MeshStandardMaterial({color:36864,roughness:.5,metalness:.4,side:SIDE}),mblack=new THREE.MeshStandardMaterial({color:0,roughness:.5,metalness:.4,side:SIDE}),scaleunit=.001;function groupfromgeometry(geometry,material,x,y,z,name,layer){let child=new THREE.Group;child.position.set(x,y,z),child.name=name;const mesh=new THREE.Mesh(geometry,material);mesh.name=name,mesh.castShadow=!0,mesh.receiveShadow=!0,mesh.layers.set(layer);const edges=new THREE.EdgesGeometry(geometry),lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(30),child.add(mesh),child.add(lineSegments),child}function posiziona(grp,pos={}){let tm=new THREE.Group;if(grp){let g2=grp.clone(),tm2=g2,{sl:sl=0,sa:sa=0,sp:sp=0,ax:ax=0,ay:ay=0,az:az=0,ul:ul=0,ua:ua=0,up:up=0,scale:scale=1,scx:scx=scale,scy:scy=scale,scz:scz=scale,emitters:emitters,emittersname:emittersname}=pos;if(tm.position.set(sl,sa,sp),tm.rotation.set(ax*PIF,ay*PIF,az*PIF),(ul||ua||up)&&(tm2=new THREE.Group,tm2.add(g2),tm2.position.set(ul,ua,up)),tm.scale.set(scx,scy,scz),tm.add(tm2),emitters&&emitters.length)for(let e of emitters)e.name=e.name||emittersname,tm.add(getemitter(e))}return tm}function edgesfromgeometry(g1,layer=30){return getlinesgeom(new THREE.EdgesGeometry(g1,40),layer)}function getlinesgeom(edges,layer=30){const lineSegments=new THREE.LineSegments(edges,materialline1);return lineSegments.layers.set(layer),lineSegments}function getmesh(geom,material,layer=1,clone=!1){let m=new THREE.Mesh(geom,clone?material.clone():material);return m.castShadow=!0,m.receiveShadow=!0,m.layers.set(layer),m}function get3dshape(punti,material,layer){if(!punti||punti.length<3)return new THREE.BufferGeometry;const vertices=[];for(let i=0;i<punti.length;i++){const p1=punti[i],p2=punti[(i+1)%punti.length];vertices.push(p1.x,0,p1.y),vertices.push(p2.x,0,p2.y)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3));let m=new THREE.LineSegments(geometry,material);return m.layers.set(layer),m}function creategroup(name){let g=new THREE.Group;return g.name=name||"$$",g}function svuotanodo(n){!function _dispose(node){if(node.children.length){[...node.children].forEach((child=>{_dispose(child),node.remove(child)}))}node.geometry&&node.geometry.dispose(),node.material&&(Array.isArray(node.material)?node.material.forEach((m=>m.dispose())):node.material.dispose())}(n)}function deletegroup(grpbase,name){if(!grpbase?.children)return;let gr=grpbase.children.find((e=>e.name==name));if(gr){for(;gr.children.length>0;){const child=gr.children[0];gr.remove(child)}gr.parent&&gr.parent.remove(gr),gr=null}}function randombasemat(){const material=new THREE.LineBasicMaterial,color=new THREE.Color;return color.setHSL(Math.random(),.7,.4),material.color=color,material}
2
2
  /**
3
3
  * Crea una linea 3D
4
4
  * @param {Object} l - Oggetto contenente punti p1 e p2
@@ -13,7 +13,7 @@ import*as THREE from"three";import{PIF,hash,clean,getshape,raccordabezier}from"#
13
13
  * @param {THREE.Material} [mat=null] - Materiale da applicare
14
14
  * @param {number} [size=5] - Dimensione della sfera
15
15
  * @returns {THREE.Mesh} Punto 3D
16
- */function getpoint(p,id,mat=null,size=5){const pointgeom=new THREE.SphereGeometry(size,8,8);let tm=new THREE.Mesh(pointgeom,mat||randombasemat());return tm.position.set(p.x,0,p.y),tm}const suffissoMap={"":{prop:"map",extra:null},n:{prop:"normalMap",extra:null},h:{prop:"displacementMap",extra:"displacementScale"},a:{prop:"aoMap",extra:"aoMapIntensity"},r:{prop:"roughnessMap",extra:null},b:{prop:"bumpMap",extra:"bumpScale"},m:{prop:"metalnessMap",extra:null},e:{prop:"emissiveMap",extra:["emissive","emissiveIntensity"]}};async function smat(gcad,file,op={}){op||(op={});let ky=hash(file+JSON.stringify(op));return gcad.smats[ky]||(gcad.smats[ky]=await async function smat0(gcad,file,op={}){let paramstr="",isColore=!1;file.startsWith("#")&&(isColore=!0,/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})(?=$|[\[(])/.test(file)||(file=file.slice(1)));let basefile=file;const paramMatch=file.match(/^(.*)\[([^\]]+)\]$/);paramMatch&&(basefile=paramMatch[1],paramstr=paramMatch[2]);const p={};paramstr&&paramstr.split(/[,;]/).forEach((kv=>{let[k,v]=kv.split("=").map((x=>x.trim()));void 0!==v&&(["e"].includes(k)?p[k]=v.startsWith("0x")?parseInt(v):v:isNaN(parseFloat(v))?p[k]=v:p[k]=parseFloat(v))}));const mappaParam={s:["sx","sy"],sx:["sx"],sy:["sy"],rot:["rot"],r:["roughness"],m:["metalness"],h:["displacementScale"],d:["bumpScale"],b:["bumpScale"],e:["emissive"],ei:["emissiveIntensity"],ao:["aoMapIntensity"],env:["envMapIntensity"],o:["opacity"],t:["transparent"],at:["alphaTest"]};let optot={...op};for(let k in p)if(mappaParam[k])for(let t of mappaParam[k])optot[t]=p[k];let sx=(optot.sx??1)*(p.sx??p.s??1),sy=(optot.sy??1)*(p.sy??p.s??1),rot=((optot.rot??0)+(p.rot??0))*PIF;try{let tm={roughness:optot.roughness??.7,metalness:optot.metalness??.3,side:THREE.DoubleSide,envMapIntensity:optot.env??1};if(file.includes("(")||isColore){let{base:base,files:files}=function getFilesToLoad(isColore,basefile){let files=[],m=basefile.match(/^([^(]+)\((([a-zA-Z0-9_\-]+)_([a-z]+)|([a-z]+))\)$/);if(!m)return{base:basefile,files:files};let base=m[1],mapalias=m[3]||base,suffstr=m[4]||m[5]||"";isColore||files.push({suff:"",file:`${base}.webp`});for(let s of suffstr)suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`});return{base:base,files:files}}(isColore,basefile);if(files&&files.length){let textures=await Promise.all(files.map((f=>gcad.tex(f.file,sx,sy,rot).catch((()=>null)))));for(let i=0;i<files.length;i++){let t=textures[i];if(!t)continue;let suff=files[i].suff,{prop:prop,extra:extra}=suffissoMap[suff];tm[prop]=t,extra&&("displacementScale"===extra?tm.displacementScale=optot.displacementScale??.1:"bumpScale"===extra?tm.bumpScale=optot.bumpScale??.05:"aoMapIntensity"===extra?tm.aoMapIntensity=optot.aoMapIntensity??1:Array.isArray(extra)&&extra.includes("emissive")&&(tm.emissive=optot.emissive??16777215,tm.emissiveIntensity=optot.emissiveIntensity??1))}}isColore&&(tm.color=base)}else if(basefile.includes(".")){let tx=await gcad.tex(basefile,sx,sy,rot);if(!tx)return mwhite;tm.map=tx}return["opacity","alphaTest"].forEach((k=>{void 0!==optot[k]&&(tm[k]=optot[k])})),(void 0!==tm.opacity&&tm.opacity<1||optot.transparent)&&(tm.transparent=!0),new THREE.MeshStandardMaterial(tm)}catch(error){return mwhite}}(gcad,file,op)),gcad.smats[ky]}function getfakeshadow(gcad,shape,alfa){let ky=`fk${shape.key}${alfa}`,{p1:p1,width:width,height:height}=shape.dims();gcad.texture||(gcad.texture={});let tm=gcad.texture[ky];tm||(tm=function createBlurredShadowTextureFromPoints(mshape,size=256,blurPx=32,alpha=.2,p1,width,height){if(!width||!height||!mshape.pt||mshape.pt.length<2)return;const minX=p1.x,minY=p1.y,shapeWidth=width,shapeHeight=height,points=mshape.pt,extra=2*blurPx,canvas=document.createElement("canvas");canvas.width=size+2*extra,canvas.height=size+2*extra;const ctx=canvas.getContext("2d");ctx.save(),ctx.translate(extra,extra),ctx.scale(size/shapeWidth,size/shapeHeight),ctx.translate(-minX,-minY),ctx.filter=`blur(${blurPx}px)`,ctx.beginPath(),ctx.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)ctx.lineTo(points[i].x,points[i].y);ctx.closePath(),ctx.fillStyle=`rgba(0,0,0,${alpha})`,ctx.fill(),ctx.restore();const texture=new THREE.CanvasTexture(canvas);return texture.needsUpdate=!0,texture}(shape,256,32,alfa,p1,width,height),gcad.texture[ky]=tm);const fakeShape=function pointsToShape(points){const fakeShape=new THREE.Shape;fakeShape.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)fakeShape.lineTo(points[i].x,points[i].y);return fakeShape}(shape.pt),shadowGeometry=new THREE.ShapeGeometry(fakeShape);!function applyUVtoShapeGeometry(geometry,minX,minY,width,height){const pos=geometry.attributes.position,uv=[];for(let i=0;i<pos.count;i++){const x=pos.getX(i),y=pos.getY(i);uv.push((x-minX)/width,(y-minY)/height)}geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uv,2))}(shadowGeometry,p1.x,p1.y,width,height);const shadowMaterial=new THREE.MeshBasicMaterial({map:tm,transparent:!0,depthWrite:!1,side:THREE.DoubleSide});let ms=new THREE.Mesh(shadowGeometry,shadowMaterial);return ms.layers.set(9),ms.rotation.x=Math.PI/2,ms}function addmovpivot(gcad,grp,movimento,op={},x=0,y=0,z=0){if(movimento=clean(movimento,!0),!gcad.movs[movimento])return grp;gcad.movs[movimento];const pivotLocal=new THREE.Vector3(x,y,z),isZeroPivot=0===pivotLocal.lengthSq(),pivotGroup=new THREE.Group;pivotGroup.name=`pivot_${movimento}`;const movimentoGroup=new THREE.Group;if(movimentoGroup.name=`mov_${movimento}`,isZeroPivot)pivotGroup.position.copy(grp.position),pivotGroup.quaternion.copy(grp.quaternion),grp.position.set(0,0,0),grp.rotation.set(0,0,0);else{const pivotWorld=pivotLocal.clone().applyMatrix4(grp.matrixWorld);pivotGroup.position.copy(pivotWorld);const offset=pivotLocal.clone().negate();grp.position.add(offset),pivotGroup.quaternion.copy(grp.getWorldQuaternion(new THREE.Quaternion)),grp.rotation.set(0,0,0)}return movimentoGroup.add(grp),pivotGroup.add(movimentoGroup),op||(op={}),op.inmov=!1,op.key=movimento,op.dt=0,op.dtstart=!1,movimentoGroup.userData.mov={...op},pivotGroup}
16
+ */function getpoint(p,id,mat=null,size=5){const pointgeom=new THREE.SphereGeometry(size,8,8);let tm=new THREE.Mesh(pointgeom,mat||randombasemat());return tm.position.set(p.x,0,p.y),tm}const suffissoMap={"":{prop:"map",extra:null},n:{prop:"normalMap",extra:null},h:{prop:"displacementMap",extra:"displacementScale"},a:{prop:"aoMap",extra:"aoMapIntensity"},r:{prop:"roughnessMap",extra:null},b:{prop:"bumpMap",extra:"bumpScale"},m:{prop:"metalnessMap",extra:null},e:{prop:"emissiveMap",extra:["emissive","emissiveIntensity"]}};async function smat(gcad,file,op={}){op||(op={});let ky=hash(file+JSON.stringify(op));return gcad.smats[ky]||(gcad.smats[ky]=await async function smat0(gcad,file,op={}){let paramstr="",isColore=!1;file.startsWith("#")&&(isColore=!0,/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})(?=$|[\[(])/.test(file)||(file=file.slice(1)));let basefile=file;const paramMatch=file.match(/^(.*)\[([^\]]+)\]$/);paramMatch&&(basefile=paramMatch[1],paramstr=paramMatch[2]);const p={};paramstr&&paramstr.split(/[,;]/).forEach((kv=>{let[k,v]=kv.split("=").map((x=>x.trim()));void 0!==v&&(["e"].includes(k)?p[k]=v.startsWith("0x")?parseInt(v):v:isNaN(parseFloat(v))?p[k]=v:p[k]=parseFloat(v))}));const mappaParam={s:["sx","sy"],sx:["sx"],sy:["sy"],rot:["rot"],r:["roughness"],m:["metalness"],h:["displacementScale"],d:["bumpScale"],b:["bumpScale"],e:["emissive"],ei:["emissiveIntensity"],ao:["aoMapIntensity"],env:["envMapIntensity"],o:["opacity"],t:["transparent"],at:["alphaTest"]};let optot={...op};for(let k in p)if(mappaParam[k])for(let t of mappaParam[k])optot[t]=p[k];let sx=(optot.sx??1)*(p.sx??p.s??1),sy=(optot.sy??1)*(p.sy??p.s??1),rot=((optot.rot??0)+(p.rot??0))*PIF;try{let tm={roughness:optot.roughness??.7,metalness:optot.metalness??.3,side:THREE.DoubleSide,envMapIntensity:optot.env??1};if(file.includes("(")||isColore){let{base:base,files:files}=function getFilesToLoad(isColore,basefile){let files=[],m=basefile.match(/^([^(]+)\((([a-zA-Z0-9_\-]+)_([a-z]+)|([a-z]+))\)$/);if(!m)return{base:basefile,files:files};let base=m[1],mapalias=m[3]||base,suffstr=m[4]||m[5]||"";isColore||files.push({suff:"",file:`${base}.webp`});for(let s of suffstr)suffissoMap[s]&&files.push({suff:s,file:`${mapalias}_${s}.webp`});return{base:base,files:files}}(isColore,basefile);if(files&&files.length){let textures=await Promise.all(files.map((f=>gcad.tex(f.file,sx,sy,rot).catch((()=>null)))));for(let i=0;i<files.length;i++){let t=textures[i];if(!t)continue;let suff=files[i].suff,{prop:prop,extra:extra}=suffissoMap[suff];tm[prop]=t,extra&&("displacementScale"===extra?tm.displacementScale=optot.displacementScale??.1:"bumpScale"===extra?tm.bumpScale=optot.bumpScale??.05:"aoMapIntensity"===extra?tm.aoMapIntensity=optot.aoMapIntensity??1:Array.isArray(extra)&&extra.includes("emissive")&&(tm.emissive=optot.emissive??16777215,tm.emissiveIntensity=optot.emissiveIntensity??1))}}isColore&&(tm.color=base)}else if(basefile.includes(".")){let tx=await gcad.tex(basefile,sx,sy,rot);if(!tx)return mwhite;tm.map=tx}return["opacity","alphaTest"].forEach((k=>{void 0!==optot[k]&&(tm[k]=optot[k])})),(void 0!==tm.opacity&&tm.opacity<1||optot.transparent)&&(tm.transparent=!0),new THREE.MeshStandardMaterial(tm)}catch(error){return mwhite}}(gcad,file,op)),gcad.smats[ky]}function getfakeshadow(gcad,shape,alfa){let ky=`fk${shape.key}${alfa}`,{p1:p1,width:width,height:height}=shape.dims();gcad.texture||(gcad.texture={});let tm=gcad.texture[ky];tm||(tm=function createBlurredShadowTextureFromPoints(mshape,size=256,blurPx=32,alpha=.2,p1,width,height){if(!width||!height||!mshape.pt||mshape.pt.length<2)return;const minX=p1.x,minY=p1.y,shapeWidth=width,shapeHeight=height,points=mshape.pt,extra=2*blurPx,canvas=document.createElement("canvas");canvas.width=size+2*extra,canvas.height=size+2*extra;const ctx=canvas.getContext("2d");ctx.save(),ctx.translate(extra,extra),ctx.scale(size/shapeWidth,size/shapeHeight),ctx.translate(-minX,-minY),ctx.filter=`blur(${blurPx}px)`,ctx.beginPath(),ctx.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)ctx.lineTo(points[i].x,points[i].y);ctx.closePath(),ctx.fillStyle=`rgba(0,0,0,${alpha})`,ctx.fill(),ctx.restore();const texture=new THREE.CanvasTexture(canvas);return texture.needsUpdate=!0,texture}(shape,256,32,alfa,p1,width,height),gcad.texture[ky]=tm);const fakeShape=function pointsToShape(points){const fakeShape=new THREE.Shape;fakeShape.moveTo(points[0].x,points[0].y);for(let i=1;i<points.length;i++)fakeShape.lineTo(points[i].x,points[i].y);return fakeShape}(shape.pt),shadowGeometry=new THREE.ShapeGeometry(fakeShape);!function applyUVtoShapeGeometry(geometry,minX,minY,width,height){const pos=geometry.attributes.position,uv=[];for(let i=0;i<pos.count;i++){const x=pos.getX(i),y=pos.getY(i);uv.push((x-minX)/width,(y-minY)/height)}geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uv,2))}(shadowGeometry,p1.x,p1.y,width,height);const shadowMaterial=new THREE.MeshBasicMaterial({map:tm,transparent:!0,depthWrite:!1,side:THREE.DoubleSide});let ms=new THREE.Mesh(shadowGeometry,shadowMaterial);return ms.layers.set(9),ms.rotation.x=Math.PI/2,ms}function addmovpivot(gcad,grp,movimento,op={},x=0,y=0,z=0){if(movimento=clean$1(movimento,!0),!gcad.movs[movimento])return grp;gcad.movs[movimento];const pivotLocal=new THREE.Vector3(x,y,z),isZeroPivot=0===pivotLocal.lengthSq(),pivotGroup=new THREE.Group;pivotGroup.name=`pivot_${movimento}`;const movimentoGroup=new THREE.Group;if(movimentoGroup.name=`mov_${movimento}`,isZeroPivot)pivotGroup.position.copy(grp.position),pivotGroup.quaternion.copy(grp.quaternion),grp.position.set(0,0,0),grp.rotation.set(0,0,0);else{const pivotWorld=pivotLocal.clone().applyMatrix4(grp.matrixWorld);pivotGroup.position.copy(pivotWorld);const offset=pivotLocal.clone().negate();grp.position.add(offset),pivotGroup.quaternion.copy(grp.getWorldQuaternion(new THREE.Quaternion)),grp.rotation.set(0,0,0)}return movimentoGroup.add(grp),pivotGroup.add(movimentoGroup),op||(op={}),op.inmov=!1,op.key=movimento,op.dt=0,op.dtstart=!1,movimentoGroup.userData.mov={...op},pivotGroup}
17
17
  /**
18
18
  * Crea un gestore di movimento per animare oggetti 3D.
19
19
  * @param {string} key - Chiave identificativa del movimento
@@ -37,7 +37,7 @@ import*as THREE from"three";import{PIF,hash,clean,getshape,raccordabezier}from"#
37
37
  * @property {string} key - Chiave del movimento
38
38
  * @property {function} step - Esegue un passo dell'animazione
39
39
  * @property {function} reset - Resetta l'oggetto alla posizione iniziale
40
- */function getmovimento(key,gtimeline=[]){let totale=0,timeline=[];const _cleartimeline=()=>{timeline=[],totale=0},_add=(t,op={})=>{t&&timeline.push({...op,time:t}),totale=timeline.reduce(((t,e)=>t+(e.time||0)),0)};_cleartimeline(),gtimeline&&gtimeline.length&&gtimeline.forEach((e=>_add(e.time,e)));const _resetmov=grp=>{const{mov:mov}=grp?.userData||{};mov&&(mov.inmov=!1,grp.position.set(0,0,0),grp.scale.set(1,1,1),grp.rotation.set(0,0,0))};return{get tline(){return totale},clear:_cleartimeline,add:_add,key:key,step:(grp,callback)=>{if(!grp||!grp.userData?.mov||!totale)return;const{mov:mov}=grp.userData;if(!mov.inmov)return;let dt=mov.dt-mov.dtstart;if(mov.ripeti)dt%=totale;else if(dt>totale)return void _resetmov(grp);let x=0,y=0,z=0,ax=0,ay=0,az=0,sx=1,sy=1,sz=1,t=null,accumTime=0;for(let step of timeline){if(accumTime+=step.time,dt<accumTime){const c=step.time>0?(dt-(accumTime-step.time))/step.time:1,_calc=(f,def=0)=>"function"==typeof f?f(mov)*c:(f||def)*c;x+=_calc(step.x),y+=_calc(step.y),z+=_calc(step.z),sx*=1+_calc(step.sx??step.s,0),sy*=1+_calc(step.sy??step.s,0),sz*=1+_calc(step.sz??step.s,0),ax+=_calc(step.ax)*PIF,ay+=_calc(step.ay)*PIF,az+=_calc(step.az)*PIF,void 0!==step.t&&(t="function"==typeof step.t?step.t(mov)*c:step.t*c);break}{const _calc=(f,def=0)=>"function"==typeof f?f(mov):f||def;x+=_calc(step.x),y+=_calc(step.y),z+=_calc(step.z),sx*=1+_calc(step.sx??step.s,0),sy*=1+_calc(step.sy??step.s,0),sz*=1+_calc(step.sz??step.s,0),ax+=_calc(step.ax)*PIF,ay+=_calc(step.ay)*PIF,az+=_calc(step.az)*PIF,void 0!==step.t&&(t="function"==typeof step.t?step.t(mov):step.t)}}grp.position.set(x,y,z),grp.scale.set(sx,sy,sz),grp.rotation.set(ax,ay,az),null!==t&&grp.traverse((obj=>{if(obj.material){(Array.isArray(obj.material)?obj.material:[obj.material]).forEach((mat=>{mat.transparent&&(mat.opacity=1-t)}))}})),callback&&callback(grp,dt)},reset:_resetmov}}function getorientate(ori,x,y,z){switch(x=x||0,y=y||0,z=z||0,ori.trim().toLowerCase()){case"alp":return{x:y,y:x,z:z};case"apl":return{x:y,y:z,z:x};case"pla":return{x:z,y:x,z:y};case"pal":return{x:z,y:y,z:x};case"lpa":return{x:x,y:z,z:y};default:return{x:x,y:y,z:z}}}function parselavs(ori,id,x=0,y=0,z=0,lavorazioni="",facce="",def=""){let lavcods=muClComments(lavorazioni),rets=[];for(let lavcod of lavcods){var rr=/^([({}):$\w.\\/]+)[\s;,]*(.*)?$/im.exec(lavcod);if(rr&&rr[1]){let lav={name:rr[1].trim().toLowerCase(),...getorientate(ori,x,y,z),id:id,facce:facce};if(rr[2]){let aa=getcolonne(rr[2]);for(let a of aa){let i=a.indexOf("=");i>0&&(lav[a.slice(0,i).trim()]=a.slice(i+1).trim())}}rets.push(lav)}}return!rets.length&&def&&rets.push({name:def,...getorientate(ori,x,y,z),id:id,facce:facce}),rets}function getemitter(data){let{d:d,name:name,x:x,y:y,z:z,lavs:lavs="",ids:ids="",faces:faces=null,size:size=5}=data;ids=getcolonne(clean$1(ids,!0));const emitter=new THREE.Object3D;if(emitter.position.set(x,y,z),emitter.userData={emitter:!0,lavs:lavs,ids:ids,faces:faces,size:size,name:name},d){const geometry=new THREE.SphereGeometry(size||5,8,8),material=new THREE.MeshBasicMaterial({color:16711680}),mesh=new THREE.Mesh(geometry,material);emitter.add(mesh)}return emitter}function getreceiver(gcad,data){gcad.gmats.__istask=1;let{d:d,ori:ori="LAP",x:x=0,y:y=0,z:z=0,tipo:tipo="",start:start="",end:end=""}=data;tipo=clean$1(tipo,!0);const receiver=new THREE.Object3D;if(receiver.position.set(x/2,y/2,z/2),receiver.userData={receiver:!0,ori:(ori||"").trim().toLowerCase(),x:x,y:y,z:z,tipo:tipo,start:start,end:end},d){const geometry=new THREE.BoxGeometry(x,y,z),mesh=new THREE.Mesh(geometry,mgreen);mesh.position.set(0,0,0),receiver.add(mesh)}return receiver}function calcolatasks(scena){const emitterWorldPosition=new WeakMap,receiverWorldMatrixInverse=new WeakMap;function boxBoxIntersects(pos,l,x,y,z){return pos.x+l>0&&pos.x-l<x&&pos.y+l>0&&pos.y-l<y&&pos.z+l>0&&pos.z-l<z}function getFacceToccate(pos,sogliafaccia,x,y,z,filtra){const facce=[];function addfaccia(f){filtra&&!filtra.includes(f)||facce.push(f)}return Math.abs(pos.x-0)<sogliafaccia&&addfaccia("s"),Math.abs(pos.x-x)<sogliafaccia&&addfaccia("d"),Math.abs(pos.y-0)<sogliafaccia&&addfaccia("b"),Math.abs(pos.y-y)<sogliafaccia&&addfaccia("a"),Math.abs(pos.z-0)<sogliafaccia&&addfaccia("z"),Math.abs(pos.z-z)<sogliafaccia&&addfaccia("f"),facce.join("")}function getEmitterWorldPosition(emitter){if(!emitterWorldPosition.has(emitter)){const pos=new THREE.Vector3;emitter.getWorldPosition(pos),emitterWorldPosition.set(emitter,pos)}return emitterWorldPosition.get(emitter)}function getReceiverWorldMatrixInverse(receiver){if(!receiverWorldMatrixInverse.has(receiver)){const inv=receiver.matrixWorld.clone().invert();receiverWorldMatrixInverse.set(receiver,inv)}return receiverWorldMatrixInverse.get(receiver)}scena.updateMatrixWorld(!0);const receivers=[],emitters=[];!function scan(obj){obj.userData?.receiver&&receivers.push(obj),obj.userData?.emitter&&emitters.push(obj),obj.children&&obj.children.forEach(scan)}(scena);let tasks=[];for(const receiver of receivers){const{mat:mat,ori:ori,x:x,y:y,z:z,start:start,end:end,tipo:tipo,size:size}=receiver.userData;let singletask={id:mat,...getorientate(ori,x,y,z),tipo:tipo,ori:ori,lavs:[]};start&&singletask.lavs.push(...parselavs(ori,"_start",0,0,0,start,"",""));const matrixInverse=getReceiverWorldMatrixInverse(receiver);for(const emitter of emitters){if("string"==typeof tipo&&""!==tipo){const idx=emitter.userData.ids;if(Array.isArray(idx)&&idx.length>0&&!idx.includes("*")&&!idx.includes(tipo))continue}const posLocalAdj=getEmitterWorldPosition(emitter).clone().applyMatrix4(matrixInverse).clone().add(new THREE.Vector3(x/2,y/2,z/2));if(!boxBoxIntersects(posLocalAdj,emitter.userData.size??0,x,y,z))continue;const facceToccate=getFacceToccate(posLocalAdj,emitter.userData.soglia??2,x,y,z,emitter.userData.faces);facceToccate&&facceToccate.length&&singletask.lavs.push(...parselavs(ori,emitter.userData.name,posLocalAdj.x,posLocalAdj.y,posLocalAdj.z,emitter.userData.lavs,facceToccate,"nd"))}end&&singletask.lavs.push(...parselavs(ori,"_end",0,0,0,end,"","")),singletask.lavs.length&&tasks.push(singletask)}return tasks}let globalLabelCanvas=null,globalLabelContext=null;
40
+ */function getmovimento(key,gtimeline=[]){let totale=0,timeline=[];const _cleartimeline=()=>{timeline=[],totale=0},_add=(t,op={})=>{t&&timeline.push({...op,time:t}),totale=timeline.reduce(((t,e)=>t+(e.time||0)),0)};_cleartimeline(),gtimeline&&gtimeline.length&&gtimeline.forEach((e=>_add(e.time,e)));const _resetmov=grp=>{const{mov:mov}=grp?.userData||{};mov&&(mov.inmov=!1,grp.position.set(0,0,0),grp.scale.set(1,1,1),grp.rotation.set(0,0,0))};return{get tline(){return totale},clear:_cleartimeline,add:_add,key:key,step:(grp,callback)=>{if(!grp||!grp.userData?.mov||!totale)return;const{mov:mov}=grp.userData;if(!mov.inmov)return;let dt=mov.dt-mov.dtstart;if(mov.ripeti)dt%=totale;else if(dt>totale)return void _resetmov(grp);let x=0,y=0,z=0,ax=0,ay=0,az=0,sx=1,sy=1,sz=1,t=null,accumTime=0;for(let step of timeline){if(accumTime+=step.time,dt<accumTime){const c=step.time>0?(dt-(accumTime-step.time))/step.time:1,_calc=(f,def=0)=>"function"==typeof f?f(mov)*c:(f||def)*c;x+=_calc(step.x),y+=_calc(step.y),z+=_calc(step.z),sx*=1+_calc(step.sx??step.s,0),sy*=1+_calc(step.sy??step.s,0),sz*=1+_calc(step.sz??step.s,0),ax+=_calc(step.ax)*PIF,ay+=_calc(step.ay)*PIF,az+=_calc(step.az)*PIF,void 0!==step.t&&(t="function"==typeof step.t?step.t(mov)*c:step.t*c);break}{const _calc=(f,def=0)=>"function"==typeof f?f(mov):f||def;x+=_calc(step.x),y+=_calc(step.y),z+=_calc(step.z),sx*=1+_calc(step.sx??step.s,0),sy*=1+_calc(step.sy??step.s,0),sz*=1+_calc(step.sz??step.s,0),ax+=_calc(step.ax)*PIF,ay+=_calc(step.ay)*PIF,az+=_calc(step.az)*PIF,void 0!==step.t&&(t="function"==typeof step.t?step.t(mov):step.t)}}grp.position.set(x,y,z),grp.scale.set(sx,sy,sz),grp.rotation.set(ax,ay,az),null!==t&&grp.traverse((obj=>{if(obj.material){(Array.isArray(obj.material)?obj.material:[obj.material]).forEach((mat=>{mat.transparent&&(mat.opacity=1-t)}))}})),callback&&callback(grp,dt)},reset:_resetmov}}let globalLabelCanvas=null,globalLabelContext=null;
41
41
  /**
42
42
  * Crea un punto di riferimento invisibile nell'albero 3D
43
43
  * @param {number} x - Coordinata X
@@ -90,7 +90,13 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
90
90
  * @param {BufferGeometry} geometry
91
91
  * @param {number} tolerance
92
92
  * @return {BufferGeometry}
93
- */function pannellogeometry(gcad,l,a,p,r1=0,r2=0,r3=0,r4=0,b=0,npt=2){let ky=hash(`pg--${l}|${a}|${p}|${r1}|${r2}|${r3}|${r4}|${b}|${npt}`);if(l-=.01,a-=.01,p-=.01,!gcad.geo[ky]){l-=2*b,a-=2*b,p-=2*b;let tm=getshape();const vv=[{x:r4,y:0},{x:a-r1,y:0},{x:a,y:r1},{x:a,y:p-r2},{x:a-r2,y:p},{x:r3,y:p},{x:0,y:p-r3},{x:0,y:r4}];tm.addpt(vv[0]),tm.addpt(vv[1]),r1&&tm.addpt(raccordabezier(vv[0],vv[1],vv[2],vv[3],npt)),tm.addpt(vv[2]),tm.addpt(vv[3]),r2&&tm.addpt(raccordabezier(vv[2],vv[3],vv[4],vv[5],npt)),tm.addpt(vv[4]),tm.addpt(vv[5]),r3&&tm.addpt(raccordabezier(vv[4],vv[5],vv[6],vv[7],npt)),tm.addpt(vv[6]),tm.addpt(vv[7]),r2&&tm.addpt(raccordabezier(vv[6],vv[7],vv[0],vv[1],npt)),tm.removeduplicate(.01);let pts=tm.pt;const shape=new THREE.Shape;shape.moveTo(pts[0].x,pts[0].y);for(let i=1;i<pts.length;i++)shape.lineTo(pts[i].x,pts[i].y);shape.lineTo(pts[0].x,pts[0].y);const extrudeSettings={depth:l,bevelEnabled:b>0,bevelThickness:b,bevelSize:b,bevelSegments:1};let xgeo=new THREE.ExtrudeGeometry(shape,extrudeSettings);xgeo=function mergeVertices(geometry,tolerance=1e-4){tolerance=Math.max(tolerance,Number.EPSILON);const hashToIndex={},indices=geometry.getIndex(),positions=geometry.getAttribute("position"),vertexCount=indices?indices.count:positions.count;let nextIndex=0;const attributeNames=Object.keys(geometry.attributes),tmpAttributes={},tmpMorphAttributes={},newIndices=[],getters=["getX","getY","getZ","getW"],setters=["setX","setY","setZ","setW"];for(let i=0,l=attributeNames.length;i<l;i++){const name=attributeNames[i],attr=geometry.attributes[name];tmpAttributes[name]=new attr.constructor(new attr.array.constructor(attr.count*attr.itemSize),attr.itemSize,attr.normalized);const morphAttributes=geometry.morphAttributes[name];morphAttributes&&(tmpMorphAttributes[name]||(tmpMorphAttributes[name]=[]),morphAttributes.forEach(((morphAttr,i)=>{const array=new morphAttr.array.constructor(morphAttr.count*morphAttr.itemSize);tmpMorphAttributes[name][i]=new morphAttr.constructor(array,morphAttr.itemSize,morphAttr.normalized)})))}const halfTolerance=.5*tolerance,exponent=Math.log10(1/tolerance),hashMultiplier=Math.pow(10,exponent),hashAdditive=halfTolerance*hashMultiplier;for(let i=0;i<vertexCount;i++){const index=indices?indices.getX(i):i;let hash="";for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),itemSize=attribute.itemSize;for(let k=0;k<itemSize;k++)hash+=~~(attribute[getters[k]](index)*hashMultiplier+hashAdditive)+","}if(hash in hashToIndex)newIndices.push(hashToIndex[hash]);else{for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),morphAttributes=geometry.morphAttributes[name],itemSize=attribute.itemSize,newArray=tmpAttributes[name],newMorphArrays=tmpMorphAttributes[name];for(let k=0;k<itemSize;k++){const getterFunc=getters[k],setterFunc=setters[k];if(newArray[setterFunc](nextIndex,attribute[getterFunc](index)),morphAttributes)for(let m=0,ml=morphAttributes.length;m<ml;m++)newMorphArrays[m][setterFunc](nextIndex,morphAttributes[m][getterFunc](index))}}hashToIndex[hash]=nextIndex,newIndices.push(nextIndex),nextIndex++}}const result=geometry.clone();for(const name in geometry.attributes){const tmpAttribute=tmpAttributes[name];if(result.setAttribute(name,new tmpAttribute.constructor(tmpAttribute.array.slice(0,nextIndex*tmpAttribute.itemSize),tmpAttribute.itemSize,tmpAttribute.normalized)),name in tmpMorphAttributes)for(let j=0;j<tmpMorphAttributes[name].length;j++){const tmpMorphAttribute=tmpMorphAttributes[name][j];result.morphAttributes[name][j]=new tmpMorphAttribute.constructor(tmpMorphAttribute.array.slice(0,nextIndex*tmpMorphAttribute.itemSize),tmpMorphAttribute.itemSize,tmpMorphAttribute.normalized)}}return result.setIndex(newIndices),result}(xgeo),xgeo.computeVertexNormals();const uv=xgeo.attributes.uv;let x1=Math.random()*l,y1=Math.random()*(a+p);for(let i=0;i<uv.count;i++)uv.setXY(i,uv.getX(i)+x1,uv.getY(i)+y1);uv.needsUpdate=!0,gcad.geo[ky]=xgeo}return gcad.geo[ky]}function getpannello(gcad,orientamento,x,y,z,mat1,mat2,options){options||(options={});let l,a,p,{r:r,r1:r1,r2:r2,r3:r3,r4:r4,b:b,npt:npt}=options;r1=r1||r||0,r2=r2||r||0,r3=r3||r||0,r4=r4||r||0,npt=npt||2,b=b||0,(b>=x/2||b>=y/2||b>=z/2)&&(b=0),l="L"==(orientamento=orientamento.trim().toUpperCase())[0]?x:"A"==orientamento[0]?y:z,a="L"==orientamento[1]?x:"A"==orientamento[1]?y:z,p="L"==orientamento[2]?x:"A"==orientamento[2]?y:z;let grp=new THREE.Group;if(!options.nolines){let segments=edgesfromgeometry(new THREE.BoxGeometry(x,y,z));segments.position.set(x/2,y/2,z/2),grp.add(segments)}let mesh=getmesh(pannellogeometry(gcad,l,a,p,r1,r2,r3,r4,b,npt),[mat2||mgreen,mat1||mwhite]);mesh.name="pannello",mesh.layers.set(1);let m2=mesh;return b&&(mesh.position.set(b,b,b),m2=new THREE.Group,m2.add(mesh)),mesh=function meshrotate(orientamento,mesh,x=0,y=0,z=0){switch(orientamento.trim().toUpperCase()){case"LPA":mesh.rotation.y=Math.PI/2,mesh.rotation.x=Math.PI,mesh.position.set(0,z,0);break;case"ALP":mesh.rotation.x=Math.PI/2,mesh.position.set(0,x,0);break;case"APL":mesh.rotation.x=-Math.PI/2,mesh.rotation.z=-Math.PI/2;break;case"PLA":break;case"PAL":mesh.rotation.z=Math.PI/2,mesh.position.set(z,0,0);break;case"LAP":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI/2}return mesh}(orientamento,m2,l,a,p),grp.add(mesh),grp}function earcut(data,holeIndices,dim=2){const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedList(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,invSize;if(hasHoles&&(outerNode=function eliminateHoles(data,holeIndices,outerNode,dim){const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const list=linkedList(data,holeIndices[i]*dim,i<len-1?holeIndices[i+1]*dim:data.length,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort(compareXYSlope);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode);return outerNode}(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=1/0,minY=1/0;let maxX=-1/0,maxY=-1/0;for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?32767/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize,0),triangles}function linkedList(data,start,end,dim,clockwise){let last;if(clockwise===function signedArea(data,start,end,dim){let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum}(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);return last&&equals(last,last.next)&&(removeNode(last),last=last.next),last}function filterPoints(start,end){if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals(p,p.next)&&0!==area(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end}function earcutLinked(ear,triangles,dim,minX,minY,invSize,pass){if(!ear)return;!pass&&invSize&&function indexCurve(start,minX,minY,invSize){let p=start;do{0===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,function sortLinked(list){let numMerges,inSize=1;do{let e,p=list;list=null;let tail=null;for(numMerges=0;p;){numMerges++;let q=p,pSize=0;for(let i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||p.z<=q.z)?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1);return list}(p)}(ear,minX,minY,invSize);let stop=ear;for(;ear.prev!==ear.next;){const prev=ear.prev,next=ear.next;if(invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i,ear.i,next.i),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?earcutLinked(ear=cureLocalIntersections(filterPoints(ear),triangles),triangles,dim,minX,minY,invSize,2):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}}}function isEar(ear){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy);let p=c.next;for(;p!==a;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.next}return!0}function isEarHashed(ear,minX,minY,invSize){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy),minZ=zOrder(x0,y0,minX,minY,invSize),maxZ=zOrder(x1,y1,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0}function cureLocalIntersections(start,triangles){let p=start;do{const a=p.prev,b=p.next.next;!equals(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i,p.i,b.i),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)}function splitEarcut(start,triangles,dim,minX,minY,invSize){let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize,0),void earcutLinked(c,triangles,dim,minX,minY,invSize,0)}b=b.next}a=a.next}while(a!==start)}function compareXYSlope(a,b){let result=a.x-b.x;if(0===result&&(result=a.y-b.y,0===result)){result=(a.next.y-a.y)/(a.next.x-a.x)-(b.next.y-b.y)/(b.next.x-b.x)}return result}function eliminateHole(hole,outerNode){const bridge=function findHoleBridge(hole,outerNode){let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;if(equals(hole,p))return p;do{if(equals(hole,p.next))return p.next;if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx&&(qx=x,m=p.x<p.next.x?p:p.next,x===hx))return m}p=p.next}while(p!==outerNode);if(!m)return null;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&&sectorContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m}(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole);return filterPoints(bridgeReverse,bridgeReverse.next),filterPoints(bridge,bridge.next)}function sectorContainsSector(m,p){return area(m.prev,m,p.prev)<0&&area(p.next,m,m.next)<0}function zOrder(x,y,minX,minY,invSize){return(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=(x-minX)*invSize|0)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=(y-minY)*invSize|0)|y<<8))|y<<4))|y<<2))|y<<1))<<1}function getLeftmost(start){let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost}function pointInTriangle(ax,ay,bx,by,cx,cy,px,py){return(cx-px)*(ay-py)>=(ax-px)*(cy-py)&&(ax-px)*(by-py)>=(bx-px)*(ay-py)&&(bx-px)*(cy-py)>=(cx-px)*(by-py)}function pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,px,py){return!(ax===px&&ay===py)&&pointInTriangle(ax,ay,bx,by,cx,cy,px,py)}function isValidDiagonal(a,b){return a.next.i!==b.i&&a.prev.i!==b.i&&!function intersectsPolygon(a,b){let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1}(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&function middleInside(a,b){let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside}(a,b)&&(area(a.prev,a,b.prev)||area(a,b.prev,b))||equals(a,b)&&area(a.prev,a,a.next)>0&&area(b.prev,b,b.next)>0)}function area(p,q,r){return(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y)}function equals(p1,p2){return p1.x===p2.x&&p1.y===p2.y}function intersects(p1,q1,p2,q2){const o1=sign(area(p1,q1,p2)),o2=sign(area(p1,q1,q2)),o3=sign(area(p2,q2,p1)),o4=sign(area(p2,q2,q1));return o1!==o2&&o3!==o4||(!(0!==o1||!onSegment(p1,p2,q1))||(!(0!==o2||!onSegment(p1,q2,q1))||(!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2)))))}function onSegment(p,q,r){return q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y)}function sign(num){return num>0?1:num<0?-1:0}function locallyInside(a,b){return area(a.prev,a,a.next)<0?area(a,b,a.next)>=0&&area(a,a.prev,b)>=0:area(a,b,a.prev)<0||area(a,a.next,b)<0}function splitPolygon(a,b){const a2=createNode(a.i,a.x,a.y),b2=createNode(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2}function insertNode(i,x,y,last){const p=createNode(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p}function removeNode(p){p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)}function createNode(i,x,y){return{i:i,x:x,y:y,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function infoestrudi(shape,hshape,pts,options){options||(options={}),pts||(pts=[]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),{mi:mi,ma:ma}=shape.pt.reduce(((t,e)=>(t.mi.x=Math.min(t.mi.x,e.x),t.mi.y=Math.min(t.mi.y,e.y),t.ma.x=Math.max(t.ma.x,e.x),t.ma.y=Math.max(t.ma.y,e.y),t)),{mi:{x:1e9,y:1e9},ma:{x:-1e9,y:-1e9}}),lmax=0,lmin=1e9;function getpars(p){p.z1=getzeta(p.x,p.y,p0,coeffbase1,coeffbase2),p.z2=getzeta(p.x,p.y,p1,coefftop1,coefftop2),p.l=Math.abs(p.z2-p.z1)}for(let p of pts)getpars(p);getpars(mi),getpars(ma);let rect=[{x:mi.x,y:mi.y},{x:ma.x,y:mi.y},{x:ma.x,y:ma.y},{x:mi.x,y:ma.y}];for(let r of rect)getpars(r),r.l>lmax&&(lmax=r.l),r.l<lmin&&(lmin=r.l);return{aini:options.coeffbase1||0,aini2:options.coeffbase2||0,afin:options.coefftop1||0,afin2:options.coefftop2||0,pts:pts,mi:mi,ma:ma,rect:rect,dimx:ma.x-mi.x,dimy:ma.y-mi.y,lnom:p1-p0,lmax:lmax,lmin:lmin,lmed:(lmax+lmin)/2}}function getzeta(x,y,zbase,cx,cy){return x*cx+y*cy+zbase}function sidegeomfromshapes(gcad,ky,s1,s2,invert=!1){if(s1&&s2){if(s1.length!==s2.length)throw new Error("shapes with different length");if(s1.length<2)throw new Error("I percorsi devono contenere almeno due punti ciascuno.");if(!gcad.geo[ky]){const positions=[],uvs=[],indices=[],np=s1.length,addpts=ss=>{for(const s of ss)positions.push(s.x,s.y,s.z),uvs.push(s.u,s.v)},equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z,addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)};addpts(s1),addpts(s2);for(let i=0;i<np-1;i++){const j=i+1;equalpos(s1[i],s1[j])||addindexquad(i,j,i+np,j+np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}}function bottomgeomfromshape(gcad,inverti,outer,holes,c=0,a=0,b=0){let ky=`bg:${c}|${a}${b}|${outer.key}|${inverti}`;for(let h of holes)ky=`${ky}|${h.key}`;if(ky=hash(ky),!gcad.geo[ky]){let triangles,pos=[],hl=[],cc=outer.pt.length;if(pos=outer.vec,Array.isArray(holes)){for(let h of holes)hl.push(cc),cc+=h.pt.length,pos=[...pos,...h.vec];triangles=earcut(pos,hl)}else triangles=earcut(pos);const geometry=new THREE.BufferGeometry,vertices=[],uvs=[],indices=[];for(let i=0;i<triangles.length;i++){const index=triangles[i],x=pos[2*index],y=-pos[2*index+1],z=getzeta(x,y,c,a,b);vertices.push(x,y,z),uvs.push(y,x)}for(let i=0;i<triangles.length;i+=3)inverti?indices.push(i,i+2,i+1):indices.push(i,i+1,i+2);geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}function estrusorotate(orientamento,mesh,z=0){switch(orientamento.trim().toUpperCase().slice(0,1)){case"A":mesh.rotation.x=-Math.PI/2;break;case"L":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI;break;case"P":mesh.rotation.z=Math.PI/2}return mesh}
93
+ */
94
+ /**
95
+ * @param {BufferGeometry} geometry
96
+ * @param {number} drawMode
97
+ * @return {BufferGeometry}
98
+ */
99
+ function toTrianglesDrawMode(geometry,drawMode){if(drawMode===TrianglesDrawMode)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),geometry;if(drawMode===TriangleFanDrawMode||drawMode===TriangleStripDrawMode){let index=geometry.getIndex();if(null===index){const indices=[],position=geometry.getAttribute("position");if(void 0===position)return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),geometry;for(let i=0;i<position.count;i++)indices.push(i);geometry.setIndex(indices),index=geometry.getIndex()}const numberOfTriangles=index.count-2,newIndices=[];if(drawMode===TriangleFanDrawMode)for(let i=1;i<=numberOfTriangles;i++)newIndices.push(index.getX(0)),newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1));else for(let i=0;i<numberOfTriangles;i++)i%2==0?(newIndices.push(index.getX(i)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i+2))):(newIndices.push(index.getX(i+2)),newIndices.push(index.getX(i+1)),newIndices.push(index.getX(i)));newIndices.length/3!==numberOfTriangles&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const newGeometry=geometry.clone();return newGeometry.setIndex(newIndices),newGeometry.clearGroups(),newGeometry}return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",drawMode),geometry}function pannellogeometry(gcad,l,a,p,r1=0,r2=0,r3=0,r4=0,b=0,npt=2){let ky=hash(`pg--${l}|${a}|${p}|${r1}|${r2}|${r3}|${r4}|${b}|${npt}`);if(l-=.01,a-=.01,p-=.01,!gcad.geo[ky]){l-=2*b,a-=2*b,p-=2*b;let tm=getshape();const vv=[{x:r4,y:0},{x:a-r1,y:0},{x:a,y:r1},{x:a,y:p-r2},{x:a-r2,y:p},{x:r3,y:p},{x:0,y:p-r3},{x:0,y:r4}];tm.addpt(vv[0]),tm.addpt(vv[1]),r1&&tm.addpt(raccordabezier(vv[0],vv[1],vv[2],vv[3],npt)),tm.addpt(vv[2]),tm.addpt(vv[3]),r2&&tm.addpt(raccordabezier(vv[2],vv[3],vv[4],vv[5],npt)),tm.addpt(vv[4]),tm.addpt(vv[5]),r3&&tm.addpt(raccordabezier(vv[4],vv[5],vv[6],vv[7],npt)),tm.addpt(vv[6]),tm.addpt(vv[7]),r2&&tm.addpt(raccordabezier(vv[6],vv[7],vv[0],vv[1],npt)),tm.removeduplicate(.01);let pts=tm.pt;const shape=new THREE.Shape;shape.moveTo(pts[0].x,pts[0].y);for(let i=1;i<pts.length;i++)shape.lineTo(pts[i].x,pts[i].y);shape.lineTo(pts[0].x,pts[0].y);const extrudeSettings={depth:l,bevelEnabled:b>0,bevelThickness:b,bevelSize:b,bevelSegments:1};let xgeo=new THREE.ExtrudeGeometry(shape,extrudeSettings);xgeo=function mergeVertices(geometry,tolerance=1e-4){tolerance=Math.max(tolerance,Number.EPSILON);const hashToIndex={},indices=geometry.getIndex(),positions=geometry.getAttribute("position"),vertexCount=indices?indices.count:positions.count;let nextIndex=0;const attributeNames=Object.keys(geometry.attributes),tmpAttributes={},tmpMorphAttributes={},newIndices=[],getters=["getX","getY","getZ","getW"],setters=["setX","setY","setZ","setW"];for(let i=0,l=attributeNames.length;i<l;i++){const name=attributeNames[i],attr=geometry.attributes[name];tmpAttributes[name]=new attr.constructor(new attr.array.constructor(attr.count*attr.itemSize),attr.itemSize,attr.normalized);const morphAttributes=geometry.morphAttributes[name];morphAttributes&&(tmpMorphAttributes[name]||(tmpMorphAttributes[name]=[]),morphAttributes.forEach(((morphAttr,i)=>{const array=new morphAttr.array.constructor(morphAttr.count*morphAttr.itemSize);tmpMorphAttributes[name][i]=new morphAttr.constructor(array,morphAttr.itemSize,morphAttr.normalized)})))}const halfTolerance=.5*tolerance,exponent=Math.log10(1/tolerance),hashMultiplier=Math.pow(10,exponent),hashAdditive=halfTolerance*hashMultiplier;for(let i=0;i<vertexCount;i++){const index=indices?indices.getX(i):i;let hash="";for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),itemSize=attribute.itemSize;for(let k=0;k<itemSize;k++)hash+=~~(attribute[getters[k]](index)*hashMultiplier+hashAdditive)+","}if(hash in hashToIndex)newIndices.push(hashToIndex[hash]);else{for(let j=0,l=attributeNames.length;j<l;j++){const name=attributeNames[j],attribute=geometry.getAttribute(name),morphAttributes=geometry.morphAttributes[name],itemSize=attribute.itemSize,newArray=tmpAttributes[name],newMorphArrays=tmpMorphAttributes[name];for(let k=0;k<itemSize;k++){const getterFunc=getters[k],setterFunc=setters[k];if(newArray[setterFunc](nextIndex,attribute[getterFunc](index)),morphAttributes)for(let m=0,ml=morphAttributes.length;m<ml;m++)newMorphArrays[m][setterFunc](nextIndex,morphAttributes[m][getterFunc](index))}}hashToIndex[hash]=nextIndex,newIndices.push(nextIndex),nextIndex++}}const result=geometry.clone();for(const name in geometry.attributes){const tmpAttribute=tmpAttributes[name];if(result.setAttribute(name,new tmpAttribute.constructor(tmpAttribute.array.slice(0,nextIndex*tmpAttribute.itemSize),tmpAttribute.itemSize,tmpAttribute.normalized)),name in tmpMorphAttributes)for(let j=0;j<tmpMorphAttributes[name].length;j++){const tmpMorphAttribute=tmpMorphAttributes[name][j];result.morphAttributes[name][j]=new tmpMorphAttribute.constructor(tmpMorphAttribute.array.slice(0,nextIndex*tmpMorphAttribute.itemSize),tmpMorphAttribute.itemSize,tmpMorphAttribute.normalized)}}return result.setIndex(newIndices),result}(xgeo),xgeo.computeVertexNormals();const uv=xgeo.attributes.uv;let x1=Math.random()*l,y1=Math.random()*(a+p);for(let i=0;i<uv.count;i++)uv.setXY(i,uv.getX(i)+x1,uv.getY(i)+y1);uv.needsUpdate=!0,gcad.geo[ky]=xgeo}return gcad.geo[ky]}function getpannello(gcad,orientamento,x,y,z,mat1,mat2,options){options||(options={});let l,a,p,{r:r,r1:r1,r2:r2,r3:r3,r4:r4,b:b,npt:npt}=options;r1=r1||r||0,r2=r2||r||0,r3=r3||r||0,r4=r4||r||0,npt=npt||2,b=b||0,(b>=x/2||b>=y/2||b>=z/2)&&(b=0),l="L"==(orientamento=orientamento.trim().toUpperCase())[0]?x:"A"==orientamento[0]?y:z,a="L"==orientamento[1]?x:"A"==orientamento[1]?y:z,p="L"==orientamento[2]?x:"A"==orientamento[2]?y:z;let grp=new THREE.Group;if(!options.nolines){let segments=edgesfromgeometry(new THREE.BoxGeometry(x,y,z));segments.position.set(x/2,y/2,z/2),grp.add(segments)}let mesh=getmesh(pannellogeometry(gcad,l,a,p,r1,r2,r3,r4,b,npt),[mat2||mgreen,mat1||mwhite]);mesh.name="pannello",mesh.layers.set(1);let m2=mesh;return b&&(mesh.position.set(b,b,b),m2=new THREE.Group,m2.add(mesh)),mesh=function meshrotate(orientamento,mesh,x=0,y=0,z=0){switch(orientamento.trim().toUpperCase()){case"LPA":mesh.rotation.y=Math.PI/2,mesh.rotation.x=Math.PI,mesh.position.set(0,z,0);break;case"ALP":mesh.rotation.x=Math.PI/2,mesh.position.set(0,x,0);break;case"APL":mesh.rotation.x=-Math.PI/2,mesh.rotation.z=-Math.PI/2;break;case"PLA":break;case"PAL":mesh.rotation.z=Math.PI/2,mesh.position.set(z,0,0);break;case"LAP":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI/2}return mesh}(orientamento,m2,l,a,p),grp.add(mesh),grp}function earcut(data,holeIndices,dim=2){const hasHoles=holeIndices&&holeIndices.length,outerLen=hasHoles?holeIndices[0]*dim:data.length;let outerNode=linkedList(data,0,outerLen,dim,!0);const triangles=[];if(!outerNode||outerNode.next===outerNode.prev)return triangles;let minX,minY,invSize;if(hasHoles&&(outerNode=function eliminateHoles(data,holeIndices,outerNode,dim){const queue=[];for(let i=0,len=holeIndices.length;i<len;i++){const list=linkedList(data,holeIndices[i]*dim,i<len-1?holeIndices[i+1]*dim:data.length,dim,!1);list===list.next&&(list.steiner=!0),queue.push(getLeftmost(list))}queue.sort(compareXYSlope);for(let i=0;i<queue.length;i++)outerNode=eliminateHole(queue[i],outerNode);return outerNode}(data,holeIndices,outerNode,dim)),data.length>80*dim){minX=1/0,minY=1/0;let maxX=-1/0,maxY=-1/0;for(let i=dim;i<outerLen;i+=dim){const x=data[i],y=data[i+1];x<minX&&(minX=x),y<minY&&(minY=y),x>maxX&&(maxX=x),y>maxY&&(maxY=y)}invSize=Math.max(maxX-minX,maxY-minY),invSize=0!==invSize?32767/invSize:0}return earcutLinked(outerNode,triangles,dim,minX,minY,invSize,0),triangles}function linkedList(data,start,end,dim,clockwise){let last;if(clockwise===function signedArea(data,start,end,dim){let sum=0;for(let i=start,j=end-dim;i<end;i+=dim)sum+=(data[j]-data[i])*(data[i+1]+data[j+1]),j=i;return sum}(data,start,end,dim)>0)for(let i=start;i<end;i+=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);else for(let i=end-dim;i>=start;i-=dim)last=insertNode(i/dim|0,data[i],data[i+1],last);return last&&equals(last,last.next)&&(removeNode(last),last=last.next),last}function filterPoints(start,end){if(!start)return start;end||(end=start);let again,p=start;do{if(again=!1,p.steiner||!equals(p,p.next)&&0!==area(p.prev,p,p.next))p=p.next;else{if(removeNode(p),p=end=p.prev,p===p.next)break;again=!0}}while(again||p!==end);return end}function earcutLinked(ear,triangles,dim,minX,minY,invSize,pass){if(!ear)return;!pass&&invSize&&function indexCurve(start,minX,minY,invSize){let p=start;do{0===p.z&&(p.z=zOrder(p.x,p.y,minX,minY,invSize)),p.prevZ=p.prev,p.nextZ=p.next,p=p.next}while(p!==start);p.prevZ.nextZ=null,p.prevZ=null,function sortLinked(list){let numMerges,inSize=1;do{let e,p=list;list=null;let tail=null;for(numMerges=0;p;){numMerges++;let q=p,pSize=0;for(let i=0;i<inSize&&(pSize++,q=q.nextZ,q);i++);let qSize=inSize;for(;pSize>0||qSize>0&&q;)0!==pSize&&(0===qSize||!q||p.z<=q.z)?(e=p,p=p.nextZ,pSize--):(e=q,q=q.nextZ,qSize--),tail?tail.nextZ=e:list=e,e.prevZ=tail,tail=e;p=q}tail.nextZ=null,inSize*=2}while(numMerges>1);return list}(p)}(ear,minX,minY,invSize);let stop=ear;for(;ear.prev!==ear.next;){const prev=ear.prev,next=ear.next;if(invSize?isEarHashed(ear,minX,minY,invSize):isEar(ear))triangles.push(prev.i,ear.i,next.i),removeNode(ear),ear=next.next,stop=next.next;else if((ear=next)===stop){pass?1===pass?earcutLinked(ear=cureLocalIntersections(filterPoints(ear),triangles),triangles,dim,minX,minY,invSize,2):2===pass&&splitEarcut(ear,triangles,dim,minX,minY,invSize):earcutLinked(filterPoints(ear),triangles,dim,minX,minY,invSize,1);break}}}function isEar(ear){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy);let p=c.next;for(;p!==a;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.next}return!0}function isEarHashed(ear,minX,minY,invSize){const a=ear.prev,b=ear,c=ear.next;if(area(a,b,c)>=0)return!1;const ax=a.x,bx=b.x,cx=c.x,ay=a.y,by=b.y,cy=c.y,x0=Math.min(ax,bx,cx),y0=Math.min(ay,by,cy),x1=Math.max(ax,bx,cx),y1=Math.max(ay,by,cy),minZ=zOrder(x0,y0,minX,minY,invSize),maxZ=zOrder(x1,y1,minX,minY,invSize);let p=ear.prevZ,n=ear.nextZ;for(;p&&p.z>=minZ&&n&&n.z<=maxZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;if(p=p.prevZ,n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}for(;p&&p.z>=minZ;){if(p.x>=x0&&p.x<=x1&&p.y>=y0&&p.y<=y1&&p!==a&&p!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,p.x,p.y)&&area(p.prev,p,p.next)>=0)return!1;p=p.prevZ}for(;n&&n.z<=maxZ;){if(n.x>=x0&&n.x<=x1&&n.y>=y0&&n.y<=y1&&n!==a&&n!==c&&pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,n.x,n.y)&&area(n.prev,n,n.next)>=0)return!1;n=n.nextZ}return!0}function cureLocalIntersections(start,triangles){let p=start;do{const a=p.prev,b=p.next.next;!equals(a,b)&&intersects(a,p,p.next,b)&&locallyInside(a,b)&&locallyInside(b,a)&&(triangles.push(a.i,p.i,b.i),removeNode(p),removeNode(p.next),p=start=b),p=p.next}while(p!==start);return filterPoints(p)}function splitEarcut(start,triangles,dim,minX,minY,invSize){let a=start;do{let b=a.next.next;for(;b!==a.prev;){if(a.i!==b.i&&isValidDiagonal(a,b)){let c=splitPolygon(a,b);return a=filterPoints(a,a.next),c=filterPoints(c,c.next),earcutLinked(a,triangles,dim,minX,minY,invSize,0),void earcutLinked(c,triangles,dim,minX,minY,invSize,0)}b=b.next}a=a.next}while(a!==start)}function compareXYSlope(a,b){let result=a.x-b.x;if(0===result&&(result=a.y-b.y,0===result)){result=(a.next.y-a.y)/(a.next.x-a.x)-(b.next.y-b.y)/(b.next.x-b.x)}return result}function eliminateHole(hole,outerNode){const bridge=function findHoleBridge(hole,outerNode){let p=outerNode;const hx=hole.x,hy=hole.y;let m,qx=-1/0;if(equals(hole,p))return p;do{if(equals(hole,p.next))return p.next;if(hy<=p.y&&hy>=p.next.y&&p.next.y!==p.y){const x=p.x+(hy-p.y)*(p.next.x-p.x)/(p.next.y-p.y);if(x<=hx&&x>qx&&(qx=x,m=p.x<p.next.x?p:p.next,x===hx))return m}p=p.next}while(p!==outerNode);if(!m)return null;const stop=m,mx=m.x,my=m.y;let tanMin=1/0;p=m;do{if(hx>=p.x&&p.x>=mx&&hx!==p.x&&pointInTriangle(hy<my?hx:qx,hy,mx,my,hy<my?qx:hx,hy,p.x,p.y)){const tan=Math.abs(hy-p.y)/(hx-p.x);locallyInside(p,hole)&&(tan<tanMin||tan===tanMin&&(p.x>m.x||p.x===m.x&&sectorContainsSector(m,p)))&&(m=p,tanMin=tan)}p=p.next}while(p!==stop);return m}(hole,outerNode);if(!bridge)return outerNode;const bridgeReverse=splitPolygon(bridge,hole);return filterPoints(bridgeReverse,bridgeReverse.next),filterPoints(bridge,bridge.next)}function sectorContainsSector(m,p){return area(m.prev,m,p.prev)<0&&area(p.next,m,m.next)<0}function zOrder(x,y,minX,minY,invSize){return(x=1431655765&((x=858993459&((x=252645135&((x=16711935&((x=(x-minX)*invSize|0)|x<<8))|x<<4))|x<<2))|x<<1))|(y=1431655765&((y=858993459&((y=252645135&((y=16711935&((y=(y-minY)*invSize|0)|y<<8))|y<<4))|y<<2))|y<<1))<<1}function getLeftmost(start){let p=start,leftmost=start;do{(p.x<leftmost.x||p.x===leftmost.x&&p.y<leftmost.y)&&(leftmost=p),p=p.next}while(p!==start);return leftmost}function pointInTriangle(ax,ay,bx,by,cx,cy,px,py){return(cx-px)*(ay-py)>=(ax-px)*(cy-py)&&(ax-px)*(by-py)>=(bx-px)*(ay-py)&&(bx-px)*(cy-py)>=(cx-px)*(by-py)}function pointInTriangleExceptFirst(ax,ay,bx,by,cx,cy,px,py){return!(ax===px&&ay===py)&&pointInTriangle(ax,ay,bx,by,cx,cy,px,py)}function isValidDiagonal(a,b){return a.next.i!==b.i&&a.prev.i!==b.i&&!function intersectsPolygon(a,b){let p=a;do{if(p.i!==a.i&&p.next.i!==a.i&&p.i!==b.i&&p.next.i!==b.i&&intersects(p,p.next,a,b))return!0;p=p.next}while(p!==a);return!1}(a,b)&&(locallyInside(a,b)&&locallyInside(b,a)&&function middleInside(a,b){let p=a,inside=!1;const px=(a.x+b.x)/2,py=(a.y+b.y)/2;do{p.y>py!=p.next.y>py&&p.next.y!==p.y&&px<(p.next.x-p.x)*(py-p.y)/(p.next.y-p.y)+p.x&&(inside=!inside),p=p.next}while(p!==a);return inside}(a,b)&&(area(a.prev,a,b.prev)||area(a,b.prev,b))||equals(a,b)&&area(a.prev,a,a.next)>0&&area(b.prev,b,b.next)>0)}function area(p,q,r){return(q.y-p.y)*(r.x-q.x)-(q.x-p.x)*(r.y-q.y)}function equals(p1,p2){return p1.x===p2.x&&p1.y===p2.y}function intersects(p1,q1,p2,q2){const o1=sign(area(p1,q1,p2)),o2=sign(area(p1,q1,q2)),o3=sign(area(p2,q2,p1)),o4=sign(area(p2,q2,q1));return o1!==o2&&o3!==o4||(!(0!==o1||!onSegment(p1,p2,q1))||(!(0!==o2||!onSegment(p1,q2,q1))||(!(0!==o3||!onSegment(p2,p1,q2))||!(0!==o4||!onSegment(p2,q1,q2)))))}function onSegment(p,q,r){return q.x<=Math.max(p.x,r.x)&&q.x>=Math.min(p.x,r.x)&&q.y<=Math.max(p.y,r.y)&&q.y>=Math.min(p.y,r.y)}function sign(num){return num>0?1:num<0?-1:0}function locallyInside(a,b){return area(a.prev,a,a.next)<0?area(a,b,a.next)>=0&&area(a,a.prev,b)>=0:area(a,b,a.prev)<0||area(a,a.next,b)<0}function splitPolygon(a,b){const a2=createNode(a.i,a.x,a.y),b2=createNode(b.i,b.x,b.y),an=a.next,bp=b.prev;return a.next=b,b.prev=a,a2.next=an,an.prev=a2,b2.next=a2,a2.prev=b2,bp.next=b2,b2.prev=bp,b2}function insertNode(i,x,y,last){const p=createNode(i,x,y);return last?(p.next=last.next,p.prev=last,last.next.prev=p,last.next=p):(p.prev=p,p.next=p),p}function removeNode(p){p.next.prev=p.prev,p.prev.next=p.next,p.prevZ&&(p.prevZ.nextZ=p.nextZ),p.nextZ&&(p.nextZ.prevZ=p.prevZ)}function createNode(i,x,y){return{i:i,x:x,y:y,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function infoestrudi(shape,hshape,pts,options){options||(options={}),pts||(pts=[]);let p0=options.p0||0,coeffbase1=Math.tan(options.coeffbase1*PIF||0),coeffbase2=Math.tan(options.coeffbase2*PIF||0),p1=hshape||options.p1||20,coefftop1=Math.tan(options.coefftop1*PIF||0),coefftop2=Math.tan(options.coefftop2*PIF||0),{mi:mi,ma:ma}=shape.pt.reduce(((t,e)=>(t.mi.x=Math.min(t.mi.x,e.x),t.mi.y=Math.min(t.mi.y,e.y),t.ma.x=Math.max(t.ma.x,e.x),t.ma.y=Math.max(t.ma.y,e.y),t)),{mi:{x:1e9,y:1e9},ma:{x:-1e9,y:-1e9}}),lmax=0,lmin=1e9;function getpars(p){p.z1=getzeta(p.x,p.y,p0,coeffbase1,coeffbase2),p.z2=getzeta(p.x,p.y,p1,coefftop1,coefftop2),p.l=Math.abs(p.z2-p.z1)}for(let p of pts)getpars(p);getpars(mi),getpars(ma);let rect=[{x:mi.x,y:mi.y},{x:ma.x,y:mi.y},{x:ma.x,y:ma.y},{x:mi.x,y:ma.y}];for(let r of rect)getpars(r),r.l>lmax&&(lmax=r.l),r.l<lmin&&(lmin=r.l);return{aini:options.coeffbase1||0,aini2:options.coeffbase2||0,afin:options.coefftop1||0,afin2:options.coefftop2||0,pts:pts,mi:mi,ma:ma,rect:rect,dimx:ma.x-mi.x,dimy:ma.y-mi.y,lnom:p1-p0,lmax:lmax,lmin:lmin,lmed:(lmax+lmin)/2}}function getzeta(x,y,zbase,cx,cy){return x*cx+y*cy+zbase}function sidegeomfromshapes(gcad,ky,s1,s2,invert=!1){if(s1&&s2){if(s1.length!==s2.length)throw new Error("shapes with different length");if(s1.length<2)throw new Error("I percorsi devono contenere almeno due punti ciascuno.");if(!gcad.geo[ky]){const positions=[],uvs=[],indices=[],np=s1.length,addpts=ss=>{for(const s of ss)positions.push(s.x,s.y,s.z),uvs.push(s.u,s.v)},equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z,addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)};addpts(s1),addpts(s2);for(let i=0;i<np-1;i++){const j=i+1;equalpos(s1[i],s1[j])||addindexquad(i,j,i+np,j+np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}}function bottomgeomfromshape(gcad,inverti,outer,holes,c=0,a=0,b=0){let ky=`bg:${c}|${a}${b}|${outer.key}|${inverti}`;for(let h of holes)ky=`${ky}|${h.key}`;if(ky=hash(ky),!gcad.geo[ky]){let triangles,pos=[],hl=[],cc=outer.pt.length;if(pos=outer.vec,Array.isArray(holes)){for(let h of holes)hl.push(cc),cc+=h.pt.length,pos=[...pos,...h.vec];triangles=earcut(pos,hl)}else triangles=earcut(pos);const geometry=new THREE.BufferGeometry,vertices=[],uvs=[],indices=[];for(let i=0;i<triangles.length;i++){const index=triangles[i],x=pos[2*index],y=-pos[2*index+1],z=getzeta(x,y,c,a,b);vertices.push(x,y,z),uvs.push(y,x)}for(let i=0;i<triangles.length;i+=3)inverti?indices.push(i,i+2,i+1):indices.push(i,i+1,i+2);geometry.setAttribute("position",new THREE.Float32BufferAttribute(vertices,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad.geo[ky]=geometry}return gcad.geo[ky]}function estrusorotate(orientamento,mesh,z=0){switch(orientamento.trim().toUpperCase().slice(0,1)){case"A":mesh.rotation.x=-Math.PI/2;break;case"L":mesh.rotation.y=Math.PI/2,mesh.rotation.z=Math.PI;break;case"P":mesh.rotation.z=Math.PI/2}return mesh}
94
100
  /**
95
101
  * Crea una geometria estrusa con opzioni avanzate
96
102
  * @param {string} orient - Orientamento dell'estrusione
@@ -110,4 +116,448 @@ function getcilindro(gcad,ori,h,r1,r2,mats=mwhite,options){options||(options={})
110
116
  * @param {Array} mats - Array di materiali
111
117
  * @param {Object} options - Opzioni di configurazione
112
118
  * @returns {THREE.Group} Gruppo contenente la geometria estrusa
113
- */function estrusopat(gcad,orient,pat,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase){let gb=new THREE.Group,g1=bottomgeomfromshape(gcad,!1,shape,[],0,0,0);gb.add(getmesh(g1,mats[0]||mwhite)),gb.add(edgesfromgeometry(g1));let seg1=pat.infosegmento(0,!0);grp.add(posiziona(gb,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}if(!options.notop){let gt=new THREE.Group,g2=bottomgeomfromshape(gcad,!0,shape,[],0,0,0);gt.add(getmesh(g2,mats[1]||mats[0]||mwhite)),gt.add(edgesfromgeometry(g2));let seg1=pat.infosegmento(pat.pt.length-1,!0);grp.add(posiziona(gt,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}const geo1=function sidegeomfrompat(gcad,pbase,pat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${invert}`;if(ky=hash(ky),!gcad.geo[ky]){const positions=[],uvs=[],indices=[],np=pbase.length,lp=pat.pt.length,equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z;let l0=0;for(let ii=0;ii<lp;ii++){const addpts=(ss,mat,deltav)=>{for(const s of ss){let p=new THREE.Vector3(s.x,s.y,s.z);p.applyMatrix4(mat),positions.push(p.x,p.y,p.z),uvs.push(s.u,s.v+deltav)}};let seg1=pat.infosegmento(ii,!0),obj=new THREE.Object3D;obj.position.set(seg1.x,0,seg1.y),obj.rotation.set(0,(90-seg1.ang)*PIF,0),obj.updateMatrix(),addpts(pbase,obj.matrix,l0),l0+=seg1.l}for(let li=0;li<lp-1;li++)for(let i=0;i<np-1;i++){const addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)},j=i+1;equalpos(pbase[i],pbase[j])||addindexquad(i+li*np,j+li*np,i+(li+1)*np,j+(li+1)*np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad[ky]=geometry}return gcad[ky]}(gcad,pbase,pat,invert);return options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),estrusorotate(orient,grp,0)}async function spritemat(gcad,file){try{let tm={transparent:!0,depthTest:!1,depthWrite:!1,fog:!1,toneMapped:!1};if(file.startsWith("#"))tm.color=file;else{let tx=await gcad.tex(file,1e3,1e3);tx?tm.map=tx:tm.color="black"}return new THREE.SpriteMaterial(tm)}catch(error){return mwhite}}function getsprite0(ispunto,x,y,z,mat,options={}){options||(options={});let{size:size=50,pick:pick=!1,screen:screen=!1,sizex:sizex,sizey:sizey}=options;const sprite=new THREE.Sprite(mat);sprite.position.set(0,0,0),sprite.userData.issprite=!0,sprite.userData.ispunto=ispunto,sprite.userData.ispick=pick,sprite.userData.isScreen=screen,sprite.renderOrder=999,sprite.layers.set(29),sprite.name=ispunto?"_punto":"_sprite";let gr=new THREE.Group;return gr.position.set(x,y,z),gr.scale.set(sizex||size,sizey||sizex||size,1),gr.add(sprite),gr.traverse((obj=>{obj.material&&(obj.material.depthTest=!1,obj.material.depthWrite=!1)})),gr.renderOrder=999,gr}async function getpunto(gcad,x,y,z,color="yellow",options){options||(options={size:20}),options.screen=!0;const texture=await function createCircleTexture(gcad,size=64,color="rgba(255,0,0,1)"){const ky=`ct|${size}|${color}`;if(!gcad.textures[ky]){const canvas=document.createElement("canvas");canvas.width=canvas.height=size;const ctx=canvas.getContext("2d"),radius=size/2;ctx.clearRect(0,0,size,size),ctx.fillStyle=color,ctx.beginPath(),ctx.arc(radius,radius,radius,0,2*Math.PI),ctx.fill();const texture=new THREE.CanvasTexture(canvas);texture.needsUpdate=!0,gcad.textures[ky]=texture}return gcad.textures[ky]}(gcad,64,color);return getsprite0(!0,x,y,z,new THREE.SpriteMaterial({map:texture,transparent:!0,fog:!1,toneMapped:!1}),options)}function getsprite(gcad,x,y,z,mat,options={}){return getsprite0(!1,x,y,z,mat,options)}function setLineColorMode(white){white?(materialline1.color.set(16777215),materialline2.color.set(16777215)):(materialline1.color.set(3158064),materialline2.color.set(5263440)),materialline1.needsUpdate=!0,materialline2.needsUpdate=!0}export{SIDE,addmovpivot,calcolatasks,creategroup,deletegroup,edgesfromgeometry,estruso,estrusopat,get3dshape,getbox,getcilindro,getcyl,getemitter,getface,getfakeshadow,getline,getlinesgeom,getmesh,getmovimento,getpannello,getpoint,getpunto,getquota,getreceiver,getriferimento,getsprite,gettarghetta,groupfromgeometry,infoestrudi,materialline1,materialline2,mblack,mblue,mgray1,mgray2,mgreen,mred,mwhite,posiziona,randombasemat,revolve,scaleunit,setLineColorMode,smat,spritemat,svuotanodo};
119
+ */function estrusopat(gcad,orient,pat,shape,mats,options){options||(options={});let invert=options.invert;mats||(mats=[]);let open=options.open;if(!pat.pt?.length)return;let pbase=shape.to3d(0,0,0,0,open),grp=new THREE.Group;if(!options.nobase){let gb=new THREE.Group,g1=bottomgeomfromshape(gcad,!1,shape,[],0,0,0);gb.add(getmesh(g1,mats[0]||mwhite)),gb.add(edgesfromgeometry(g1));let seg1=pat.infosegmento(0,!0);grp.add(posiziona(gb,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}if(!options.notop){let gt=new THREE.Group,g2=bottomgeomfromshape(gcad,!0,shape,[],0,0,0);gt.add(getmesh(g2,mats[1]||mats[0]||mwhite)),gt.add(edgesfromgeometry(g2));let seg1=pat.infosegmento(pat.pt.length-1,!0);grp.add(posiziona(gt,{sl:seg1.x,sp:seg1.y,sa:0,ay:90-seg1.ang}))}const geo1=function sidegeomfrompat(gcad,pbase,pat,invert){let ky=`bsg:${pbase.key}|${pat.key}|${invert}`;if(ky=hash(ky),!gcad.geo[ky]){const positions=[],uvs=[],indices=[],np=pbase.length,lp=pat.pt.length,equalpos=(p1,p2)=>p1.x===p2.x&&p1.y===p2.y&&p1.z===p2.z;let l0=0;for(let ii=0;ii<lp;ii++){const addpts=(ss,mat,deltav)=>{for(const s of ss){let p=new THREE.Vector3(s.x,s.y,s.z);p.applyMatrix4(mat),positions.push(p.x,p.y,p.z),uvs.push(s.u,s.v+deltav)}};let seg1=pat.infosegmento(ii,!0),obj=new THREE.Object3D;obj.position.set(seg1.x,0,seg1.y),obj.rotation.set(0,(90-seg1.ang)*PIF,0),obj.updateMatrix(),addpts(pbase,obj.matrix,l0),l0+=seg1.l}for(let li=0;li<lp-1;li++)for(let i=0;i<np-1;i++){const addindexquad=(i1,i2,i3,i4)=>{invert?indices.push(i1,i3,i2,i3,i4,i2):indices.push(i1,i2,i3,i3,i2,i4)},j=i+1;equalpos(pbase[i],pbase[j])||addindexquad(i+li*np,j+li*np,i+(li+1)*np,j+(li+1)*np)}const geometry=new THREE.BufferGeometry;geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions,3)),geometry.setAttribute("uv",new THREE.Float32BufferAttribute(uvs,2)),geometry.setIndex(indices),geometry.computeVertexNormals(),gcad[ky]=geometry}return gcad[ky]}(gcad,pbase,pat,invert);return options.nolines||options.nosidelines||grp.add(edgesfromgeometry(geo1)),grp.add(getmesh(geo1,mats[2]||mats[0]||mwhite)),estrusorotate(orient,grp,0)}async function spritemat(gcad,file){try{let tm={transparent:!0,depthTest:!1,depthWrite:!1,fog:!1,toneMapped:!1};if(file.startsWith("#"))tm.color=file;else{let tx=await gcad.tex(file,1e3,1e3);tx?tm.map=tx:tm.color="black"}return new THREE.SpriteMaterial(tm)}catch(error){return mwhite}}function getsprite0(ispunto,x,y,z,mat,options={}){options||(options={});let{size:size=50,pick:pick=!1,screen:screen=!1,sizex:sizex,sizey:sizey}=options;const sprite=new THREE.Sprite(mat);sprite.position.set(0,0,0),sprite.userData.issprite=!0,sprite.userData.ispunto=ispunto,sprite.userData.ispick=pick,sprite.userData.isScreen=screen,sprite.renderOrder=999,sprite.layers.set(29),sprite.name=ispunto?"_punto":"_sprite";let gr=new THREE.Group;return gr.position.set(x,y,z),gr.scale.set(sizex||size,sizey||sizex||size,1),gr.add(sprite),gr.traverse((obj=>{obj.material&&(obj.material.depthTest=!1,obj.material.depthWrite=!1)})),gr.renderOrder=999,gr}async function getpunto(gcad,x,y,z,color="yellow",options){options||(options={size:20}),options.screen=!0;const texture=await function createCircleTexture(gcad,size=64,color="rgba(255,0,0,1)"){const ky=`ct|${size}|${color}`;if(!gcad.textures[ky]){const canvas=document.createElement("canvas");canvas.width=canvas.height=size;const ctx=canvas.getContext("2d"),radius=size/2;ctx.clearRect(0,0,size,size),ctx.fillStyle=color,ctx.beginPath(),ctx.arc(radius,radius,radius,0,2*Math.PI),ctx.fill();const texture=new THREE.CanvasTexture(canvas);texture.needsUpdate=!0,gcad.textures[ky]=texture}return gcad.textures[ky]}(gcad,64,color);return getsprite0(!0,x,y,z,new THREE.SpriteMaterial({map:texture,transparent:!0,fog:!1,toneMapped:!1}),options)}function getsprite(gcad,x,y,z,mat,options={}){return getsprite0(!1,x,y,z,mat,options)}class GLTFLoader extends Loader{constructor(manager){super(manager),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register((function(parser){return new GLTFMaterialsClearcoatExtension(parser)})),this.register((function(parser){return new GLTFMaterialsDispersionExtension(parser)})),this.register((function(parser){return new GLTFTextureBasisUExtension(parser)})),this.register((function(parser){return new GLTFTextureWebPExtension(parser)})),this.register((function(parser){return new GLTFTextureAVIFExtension(parser)})),this.register((function(parser){return new GLTFMaterialsSheenExtension(parser)})),this.register((function(parser){return new GLTFMaterialsTransmissionExtension(parser)})),this.register((function(parser){return new GLTFMaterialsVolumeExtension(parser)})),this.register((function(parser){return new GLTFMaterialsIorExtension(parser)})),this.register((function(parser){return new GLTFMaterialsEmissiveStrengthExtension(parser)})),this.register((function(parser){return new GLTFMaterialsSpecularExtension(parser)})),this.register((function(parser){return new GLTFMaterialsIridescenceExtension(parser)})),this.register((function(parser){return new GLTFMaterialsAnisotropyExtension(parser)})),this.register((function(parser){return new GLTFMaterialsBumpExtension(parser)})),this.register((function(parser){return new GLTFLightsExtension(parser)})),this.register((function(parser){return new GLTFMeshoptCompression(parser)})),this.register((function(parser){return new GLTFMeshGpuInstancing(parser)}))}load(url,onLoad,onProgress,onError){const scope=this;let resourcePath;if(""!==this.resourcePath)resourcePath=this.resourcePath;else if(""!==this.path){const relativeUrl=LoaderUtils.extractUrlBase(url);resourcePath=LoaderUtils.resolveURL(relativeUrl,this.path)}else resourcePath=LoaderUtils.extractUrlBase(url);this.manager.itemStart(url);const _onError=function(e){onError?onError(e):console.error(e),scope.manager.itemError(url),scope.manager.itemEnd(url)},loader=new FileLoader(this.manager);loader.setPath(this.path),loader.setResponseType("arraybuffer"),loader.setRequestHeader(this.requestHeader),loader.setWithCredentials(this.withCredentials),loader.load(url,(function(data){try{scope.parse(data,resourcePath,(function(gltf){onLoad(gltf),scope.manager.itemEnd(url)}),_onError)}catch(e){_onError(e)}}),onProgress,_onError)}setDRACOLoader(dracoLoader){return this.dracoLoader=dracoLoader,this}setDDSLoader(){throw new Error('THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".')}setKTX2Loader(ktx2Loader){return this.ktx2Loader=ktx2Loader,this}setMeshoptDecoder(meshoptDecoder){return this.meshoptDecoder=meshoptDecoder,this}register(callback){return-1===this.pluginCallbacks.indexOf(callback)&&this.pluginCallbacks.push(callback),this}unregister(callback){return-1!==this.pluginCallbacks.indexOf(callback)&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback),1),this}parse(data,path,onLoad,onError){let json;const extensions={},plugins={},textDecoder=new TextDecoder;if("string"==typeof data)json=JSON.parse(data);else if(data instanceof ArrayBuffer){if(textDecoder.decode(new Uint8Array(data,0,4))===BINARY_EXTENSION_HEADER_MAGIC){try{extensions[EXTENSIONS.KHR_BINARY_GLTF]=new GLTFBinaryExtension(data)}catch(error){return void(onError&&onError(error))}json=JSON.parse(extensions[EXTENSIONS.KHR_BINARY_GLTF].content)}else json=JSON.parse(textDecoder.decode(data))}else json=data;if(void 0===json.asset||json.asset.version[0]<2)return void(onError&&onError(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.")));const parser=new GLTFParser(json,{path:path||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});parser.fileLoader.setRequestHeader(this.requestHeader);for(let i=0;i<this.pluginCallbacks.length;i++){const plugin=this.pluginCallbacks[i](parser);plugin.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),plugins[plugin.name]=plugin,extensions[plugin.name]=!0}if(json.extensionsUsed)for(let i=0;i<json.extensionsUsed.length;++i){const extensionName=json.extensionsUsed[i],extensionsRequired=json.extensionsRequired||[];switch(extensionName){case EXTENSIONS.KHR_MATERIALS_UNLIT:extensions[extensionName]=new GLTFMaterialsUnlitExtension;break;case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:extensions[extensionName]=new GLTFDracoMeshCompressionExtension(json,this.dracoLoader);break;case EXTENSIONS.KHR_TEXTURE_TRANSFORM:extensions[extensionName]=new GLTFTextureTransformExtension;break;case EXTENSIONS.KHR_MESH_QUANTIZATION:extensions[extensionName]=new GLTFMeshQuantizationExtension;break;default:extensionsRequired.indexOf(extensionName)>=0&&void 0===plugins[extensionName]&&console.warn('THREE.GLTFLoader: Unknown extension "'+extensionName+'".')}}parser.setExtensions(extensions),parser.setPlugins(plugins),parser.parse(onLoad,onError)}parseAsync(data,path){const scope=this;return new Promise((function(resolve,reject){scope.parse(data,path,resolve,reject)}))}}function GLTFRegistry(){let objects={};return{get:function(key){return objects[key]},add:function(key,object){objects[key]=object},remove:function(key){delete objects[key]},removeAll:function(){objects={}}}}
120
+ /*********************************/
121
+ /********** EXTENSIONS ***********/
122
+ /*********************************/const EXTENSIONS={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};
123
+ /**
124
+ * Punctual Lights Extension
125
+ *
126
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
127
+ */class GLTFLightsExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const parser=this.parser,nodeDefs=this.parser.json.nodes||[];for(let nodeIndex=0,nodeLength=nodeDefs.length;nodeIndex<nodeLength;nodeIndex++){const nodeDef=nodeDefs[nodeIndex];nodeDef.extensions&&nodeDef.extensions[this.name]&&void 0!==nodeDef.extensions[this.name].light&&parser._addNodeRef(this.cache,nodeDef.extensions[this.name].light)}}_loadLight(lightIndex){const parser=this.parser,cacheKey="light:"+lightIndex;let dependency=parser.cache.get(cacheKey);if(dependency)return dependency;const json=parser.json,lightDef=((json.extensions&&json.extensions[this.name]||{}).lights||[])[lightIndex];let lightNode;const color=new Color(16777215);void 0!==lightDef.color&&color.setRGB(lightDef.color[0],lightDef.color[1],lightDef.color[2],LinearSRGBColorSpace);const range=void 0!==lightDef.range?lightDef.range:0;switch(lightDef.type){case"directional":lightNode=new DirectionalLight(color),lightNode.target.position.set(0,0,-1),lightNode.add(lightNode.target);break;case"point":lightNode=new PointLight(color),lightNode.distance=range;break;case"spot":lightNode=new SpotLight(color),lightNode.distance=range,lightDef.spot=lightDef.spot||{},lightDef.spot.innerConeAngle=void 0!==lightDef.spot.innerConeAngle?lightDef.spot.innerConeAngle:0,lightDef.spot.outerConeAngle=void 0!==lightDef.spot.outerConeAngle?lightDef.spot.outerConeAngle:Math.PI/4,lightNode.angle=lightDef.spot.outerConeAngle,lightNode.penumbra=1-lightDef.spot.innerConeAngle/lightDef.spot.outerConeAngle,lightNode.target.position.set(0,0,-1),lightNode.add(lightNode.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+lightDef.type)}return lightNode.position.set(0,0,0),lightNode.decay=2,assignExtrasToUserData(lightNode,lightDef),void 0!==lightDef.intensity&&(lightNode.intensity=lightDef.intensity),lightNode.name=parser.createUniqueName(lightDef.name||"light_"+lightIndex),dependency=Promise.resolve(lightNode),parser.cache.add(cacheKey,dependency),dependency}getDependency(type,index){if("light"===type)return this._loadLight(index)}createNodeAttachment(nodeIndex){const self=this,parser=this.parser,nodeDef=parser.json.nodes[nodeIndex],lightIndex=(nodeDef.extensions&&nodeDef.extensions[this.name]||{}).light;return void 0===lightIndex?null:this._loadLight(lightIndex).then((function(light){return parser._getNodeRef(self.cache,lightIndex,light)}))}}
128
+ /**
129
+ * Unlit Materials Extension
130
+ *
131
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
132
+ */class GLTFMaterialsUnlitExtension{constructor(){this.name=EXTENSIONS.KHR_MATERIALS_UNLIT}getMaterialType(){return MeshBasicMaterial}extendParams(materialParams,materialDef,parser){const pending=[];materialParams.color=new Color(1,1,1),materialParams.opacity=1;const metallicRoughness=materialDef.pbrMetallicRoughness;if(metallicRoughness){if(Array.isArray(metallicRoughness.baseColorFactor)){const array=metallicRoughness.baseColorFactor;materialParams.color.setRGB(array[0],array[1],array[2],LinearSRGBColorSpace),materialParams.opacity=array[3]}void 0!==metallicRoughness.baseColorTexture&&pending.push(parser.assignTexture(materialParams,"map",metallicRoughness.baseColorTexture,SRGBColorSpace))}return Promise.all(pending)}}
133
+ /**
134
+ * Materials Emissive Strength Extension
135
+ *
136
+ * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
137
+ */class GLTFMaterialsEmissiveStrengthExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(materialIndex,materialParams){const materialDef=this.parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const emissiveStrength=materialDef.extensions[this.name].emissiveStrength;return void 0!==emissiveStrength&&(materialParams.emissiveIntensity=emissiveStrength),Promise.resolve()}}
138
+ /**
139
+ * Clearcoat Materials Extension
140
+ *
141
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
142
+ */class GLTFMaterialsClearcoatExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_CLEARCOAT}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];if(void 0!==extension.clearcoatFactor&&(materialParams.clearcoat=extension.clearcoatFactor),void 0!==extension.clearcoatTexture&&pending.push(parser.assignTexture(materialParams,"clearcoatMap",extension.clearcoatTexture)),void 0!==extension.clearcoatRoughnessFactor&&(materialParams.clearcoatRoughness=extension.clearcoatRoughnessFactor),void 0!==extension.clearcoatRoughnessTexture&&pending.push(parser.assignTexture(materialParams,"clearcoatRoughnessMap",extension.clearcoatRoughnessTexture)),void 0!==extension.clearcoatNormalTexture&&(pending.push(parser.assignTexture(materialParams,"clearcoatNormalMap",extension.clearcoatNormalTexture)),void 0!==extension.clearcoatNormalTexture.scale)){const scale=extension.clearcoatNormalTexture.scale;materialParams.clearcoatNormalScale=new Vector2(scale,scale)}return Promise.all(pending)}}
143
+ /**
144
+ * Materials dispersion Extension
145
+ *
146
+ * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion
147
+ */class GLTFMaterialsDispersionExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_DISPERSION}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const materialDef=this.parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const extension=materialDef.extensions[this.name];return materialParams.dispersion=void 0!==extension.dispersion?extension.dispersion:0,Promise.resolve()}}
148
+ /**
149
+ * Iridescence Materials Extension
150
+ *
151
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
152
+ */class GLTFMaterialsIridescenceExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_IRIDESCENCE}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];return void 0!==extension.iridescenceFactor&&(materialParams.iridescence=extension.iridescenceFactor),void 0!==extension.iridescenceTexture&&pending.push(parser.assignTexture(materialParams,"iridescenceMap",extension.iridescenceTexture)),void 0!==extension.iridescenceIor&&(materialParams.iridescenceIOR=extension.iridescenceIor),void 0===materialParams.iridescenceThicknessRange&&(materialParams.iridescenceThicknessRange=[100,400]),void 0!==extension.iridescenceThicknessMinimum&&(materialParams.iridescenceThicknessRange[0]=extension.iridescenceThicknessMinimum),void 0!==extension.iridescenceThicknessMaximum&&(materialParams.iridescenceThicknessRange[1]=extension.iridescenceThicknessMaximum),void 0!==extension.iridescenceThicknessTexture&&pending.push(parser.assignTexture(materialParams,"iridescenceThicknessMap",extension.iridescenceThicknessTexture)),Promise.all(pending)}}
153
+ /**
154
+ * Sheen Materials Extension
155
+ *
156
+ * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
157
+ */class GLTFMaterialsSheenExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_SHEEN}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[];materialParams.sheenColor=new Color(0,0,0),materialParams.sheenRoughness=0,materialParams.sheen=1;const extension=materialDef.extensions[this.name];if(void 0!==extension.sheenColorFactor){const colorFactor=extension.sheenColorFactor;materialParams.sheenColor.setRGB(colorFactor[0],colorFactor[1],colorFactor[2],LinearSRGBColorSpace)}return void 0!==extension.sheenRoughnessFactor&&(materialParams.sheenRoughness=extension.sheenRoughnessFactor),void 0!==extension.sheenColorTexture&&pending.push(parser.assignTexture(materialParams,"sheenColorMap",extension.sheenColorTexture,SRGBColorSpace)),void 0!==extension.sheenRoughnessTexture&&pending.push(parser.assignTexture(materialParams,"sheenRoughnessMap",extension.sheenRoughnessTexture)),Promise.all(pending)}}
158
+ /**
159
+ * Transmission Materials Extension
160
+ *
161
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
162
+ * Draft: https://github.com/KhronosGroup/glTF/pull/1698
163
+ */class GLTFMaterialsTransmissionExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_TRANSMISSION}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];return void 0!==extension.transmissionFactor&&(materialParams.transmission=extension.transmissionFactor),void 0!==extension.transmissionTexture&&pending.push(parser.assignTexture(materialParams,"transmissionMap",extension.transmissionTexture)),Promise.all(pending)}}
164
+ /**
165
+ * Materials Volume Extension
166
+ *
167
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
168
+ */class GLTFMaterialsVolumeExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_VOLUME}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];materialParams.thickness=void 0!==extension.thicknessFactor?extension.thicknessFactor:0,void 0!==extension.thicknessTexture&&pending.push(parser.assignTexture(materialParams,"thicknessMap",extension.thicknessTexture)),materialParams.attenuationDistance=extension.attenuationDistance||1/0;const colorArray=extension.attenuationColor||[1,1,1];return materialParams.attenuationColor=(new Color).setRGB(colorArray[0],colorArray[1],colorArray[2],LinearSRGBColorSpace),Promise.all(pending)}}
169
+ /**
170
+ * Materials ior Extension
171
+ *
172
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
173
+ */class GLTFMaterialsIorExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_IOR}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const materialDef=this.parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const extension=materialDef.extensions[this.name];return materialParams.ior=void 0!==extension.ior?extension.ior:1.5,Promise.resolve()}}
174
+ /**
175
+ * Materials specular Extension
176
+ *
177
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
178
+ */class GLTFMaterialsSpecularExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_SPECULAR}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];materialParams.specularIntensity=void 0!==extension.specularFactor?extension.specularFactor:1,void 0!==extension.specularTexture&&pending.push(parser.assignTexture(materialParams,"specularIntensityMap",extension.specularTexture));const colorArray=extension.specularColorFactor||[1,1,1];return materialParams.specularColor=(new Color).setRGB(colorArray[0],colorArray[1],colorArray[2],LinearSRGBColorSpace),void 0!==extension.specularColorTexture&&pending.push(parser.assignTexture(materialParams,"specularColorMap",extension.specularColorTexture,SRGBColorSpace)),Promise.all(pending)}}
179
+ /**
180
+ * Materials bump Extension
181
+ *
182
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
183
+ */class GLTFMaterialsBumpExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.EXT_MATERIALS_BUMP}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];return materialParams.bumpScale=void 0!==extension.bumpFactor?extension.bumpFactor:1,void 0!==extension.bumpTexture&&pending.push(parser.assignTexture(materialParams,"bumpMap",extension.bumpTexture)),Promise.all(pending)}}
184
+ /**
185
+ * Materials anisotropy Extension
186
+ *
187
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_anisotropy
188
+ */class GLTFMaterialsAnisotropyExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_MATERIALS_ANISOTROPY}getMaterialType(materialIndex){const materialDef=this.parser.json.materials[materialIndex];return materialDef.extensions&&materialDef.extensions[this.name]?MeshPhysicalMaterial:null}extendMaterialParams(materialIndex,materialParams){const parser=this.parser,materialDef=parser.json.materials[materialIndex];if(!materialDef.extensions||!materialDef.extensions[this.name])return Promise.resolve();const pending=[],extension=materialDef.extensions[this.name];return void 0!==extension.anisotropyStrength&&(materialParams.anisotropy=extension.anisotropyStrength),void 0!==extension.anisotropyRotation&&(materialParams.anisotropyRotation=extension.anisotropyRotation),void 0!==extension.anisotropyTexture&&pending.push(parser.assignTexture(materialParams,"anisotropyMap",extension.anisotropyTexture)),Promise.all(pending)}}
189
+ /**
190
+ * BasisU Texture Extension
191
+ *
192
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
193
+ */class GLTFTextureBasisUExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.KHR_TEXTURE_BASISU}loadTexture(textureIndex){const parser=this.parser,json=parser.json,textureDef=json.textures[textureIndex];if(!textureDef.extensions||!textureDef.extensions[this.name])return null;const extension=textureDef.extensions[this.name],loader=parser.options.ktx2Loader;if(!loader){if(json.extensionsRequired&&json.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return parser.loadTextureImage(textureIndex,extension.source,loader)}}
194
+ /**
195
+ * WebP Texture Extension
196
+ *
197
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp
198
+ */class GLTFTextureWebPExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.EXT_TEXTURE_WEBP,this.isSupported=null}loadTexture(textureIndex){const name=this.name,parser=this.parser,json=parser.json,textureDef=json.textures[textureIndex];if(!textureDef.extensions||!textureDef.extensions[name])return null;const extension=textureDef.extensions[name],source=json.images[extension.source];let loader=parser.textureLoader;if(source.uri){const handler=parser.options.manager.getHandler(source.uri);null!==handler&&(loader=handler)}return this.detectSupport().then((function(isSupported){if(isSupported)return parser.loadTextureImage(textureIndex,extension.source,loader);if(json.extensionsRequired&&json.extensionsRequired.indexOf(name)>=0)throw new Error("THREE.GLTFLoader: WebP required by asset but unsupported.");return parser.loadTexture(textureIndex)}))}detectSupport(){return this.isSupported||(this.isSupported=new Promise((function(resolve){const image=new Image;image.src="data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",image.onload=image.onerror=function(){resolve(1===image.height)}}))),this.isSupported}}
199
+ /**
200
+ * AVIF Texture Extension
201
+ *
202
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_avif
203
+ */class GLTFTextureAVIFExtension{constructor(parser){this.parser=parser,this.name=EXTENSIONS.EXT_TEXTURE_AVIF,this.isSupported=null}loadTexture(textureIndex){const name=this.name,parser=this.parser,json=parser.json,textureDef=json.textures[textureIndex];if(!textureDef.extensions||!textureDef.extensions[name])return null;const extension=textureDef.extensions[name],source=json.images[extension.source];let loader=parser.textureLoader;if(source.uri){const handler=parser.options.manager.getHandler(source.uri);null!==handler&&(loader=handler)}return this.detectSupport().then((function(isSupported){if(isSupported)return parser.loadTextureImage(textureIndex,extension.source,loader);if(json.extensionsRequired&&json.extensionsRequired.indexOf(name)>=0)throw new Error("THREE.GLTFLoader: AVIF required by asset but unsupported.");return parser.loadTexture(textureIndex)}))}detectSupport(){return this.isSupported||(this.isSupported=new Promise((function(resolve){const image=new Image;image.src="data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=",image.onload=image.onerror=function(){resolve(1===image.height)}}))),this.isSupported}}
204
+ /**
205
+ * meshopt BufferView Compression Extension
206
+ *
207
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
208
+ */class GLTFMeshoptCompression{constructor(parser){this.name=EXTENSIONS.EXT_MESHOPT_COMPRESSION,this.parser=parser}loadBufferView(index){const json=this.parser.json,bufferView=json.bufferViews[index];if(bufferView.extensions&&bufferView.extensions[this.name]){const extensionDef=bufferView.extensions[this.name],buffer=this.parser.getDependency("buffer",extensionDef.buffer),decoder=this.parser.options.meshoptDecoder;if(!decoder||!decoder.supported){if(json.extensionsRequired&&json.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return buffer.then((function(res){const byteOffset=extensionDef.byteOffset||0,byteLength=extensionDef.byteLength||0,count=extensionDef.count,stride=extensionDef.byteStride,source=new Uint8Array(res,byteOffset,byteLength);return decoder.decodeGltfBufferAsync?decoder.decodeGltfBufferAsync(count,stride,source,extensionDef.mode,extensionDef.filter).then((function(res){return res.buffer})):decoder.ready.then((function(){const result=new ArrayBuffer(count*stride);return decoder.decodeGltfBuffer(new Uint8Array(result),count,stride,source,extensionDef.mode,extensionDef.filter),result}))}))}return null}}
209
+ /**
210
+ * GPU Instancing Extension
211
+ *
212
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
213
+ *
214
+ */class GLTFMeshGpuInstancing{constructor(parser){this.name=EXTENSIONS.EXT_MESH_GPU_INSTANCING,this.parser=parser}createNodeMesh(nodeIndex){const json=this.parser.json,nodeDef=json.nodes[nodeIndex];if(!nodeDef.extensions||!nodeDef.extensions[this.name]||void 0===nodeDef.mesh)return null;const meshDef=json.meshes[nodeDef.mesh];for(const primitive of meshDef.primitives)if(primitive.mode!==WEBGL_CONSTANTS.TRIANGLES&&primitive.mode!==WEBGL_CONSTANTS.TRIANGLE_STRIP&&primitive.mode!==WEBGL_CONSTANTS.TRIANGLE_FAN&&void 0!==primitive.mode)return null;const attributesDef=nodeDef.extensions[this.name].attributes,pending=[],attributes={};for(const key in attributesDef)pending.push(this.parser.getDependency("accessor",attributesDef[key]).then((accessor=>(attributes[key]=accessor,attributes[key]))));return pending.length<1?null:(pending.push(this.parser.createNodeMesh(nodeIndex)),Promise.all(pending).then((results=>{const nodeObject=results.pop(),meshes=nodeObject.isGroup?nodeObject.children:[nodeObject],count=results[0].count,instancedMeshes=[];for(const mesh of meshes){const m=new Matrix4,p=new Vector3,q=new Quaternion,s=new Vector3(1,1,1),instancedMesh=new InstancedMesh(mesh.geometry,mesh.material,count);for(let i=0;i<count;i++)attributes.TRANSLATION&&p.fromBufferAttribute(attributes.TRANSLATION,i),attributes.ROTATION&&q.fromBufferAttribute(attributes.ROTATION,i),attributes.SCALE&&s.fromBufferAttribute(attributes.SCALE,i),instancedMesh.setMatrixAt(i,m.compose(p,q,s));for(const attributeName in attributes)if("_COLOR_0"===attributeName){const attr=attributes[attributeName];instancedMesh.instanceColor=new InstancedBufferAttribute(attr.array,attr.itemSize,attr.normalized)}else"TRANSLATION"!==attributeName&&"ROTATION"!==attributeName&&"SCALE"!==attributeName&&mesh.geometry.setAttribute(attributeName,attributes[attributeName]);Object3D.prototype.copy.call(instancedMesh,mesh),this.parser.assignFinalMaterial(instancedMesh),instancedMeshes.push(instancedMesh)}return nodeObject.isGroup?(nodeObject.clear(),nodeObject.add(...instancedMeshes),nodeObject):instancedMeshes[0]})))}}const BINARY_EXTENSION_HEADER_MAGIC="glTF",BINARY_EXTENSION_CHUNK_TYPES_JSON=1313821514,BINARY_EXTENSION_CHUNK_TYPES_BIN=5130562;class GLTFBinaryExtension{constructor(data){this.name=EXTENSIONS.KHR_BINARY_GLTF,this.content=null,this.body=null;const headerView=new DataView(data,0,12),textDecoder=new TextDecoder;if(this.header={magic:textDecoder.decode(new Uint8Array(data.slice(0,4))),version:headerView.getUint32(4,!0),length:headerView.getUint32(8,!0)},this.header.magic!==BINARY_EXTENSION_HEADER_MAGIC)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const chunkContentsLength=this.header.length-12,chunkView=new DataView(data,12);let chunkIndex=0;for(;chunkIndex<chunkContentsLength;){const chunkLength=chunkView.getUint32(chunkIndex,!0);chunkIndex+=4;const chunkType=chunkView.getUint32(chunkIndex,!0);if(chunkIndex+=4,chunkType===BINARY_EXTENSION_CHUNK_TYPES_JSON){const contentArray=new Uint8Array(data,12+chunkIndex,chunkLength);this.content=textDecoder.decode(contentArray)}else if(chunkType===BINARY_EXTENSION_CHUNK_TYPES_BIN){const byteOffset=12+chunkIndex;this.body=data.slice(byteOffset,byteOffset+chunkLength)}chunkIndex+=chunkLength}if(null===this.content)throw new Error("THREE.GLTFLoader: JSON content not found.")}}
215
+ /**
216
+ * DRACO Mesh Compression Extension
217
+ *
218
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
219
+ */class GLTFDracoMeshCompressionExtension{constructor(json,dracoLoader){if(!dracoLoader)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=EXTENSIONS.KHR_DRACO_MESH_COMPRESSION,this.json=json,this.dracoLoader=dracoLoader,this.dracoLoader.preload()}decodePrimitive(primitive,parser){const json=this.json,dracoLoader=this.dracoLoader,bufferViewIndex=primitive.extensions[this.name].bufferView,gltfAttributeMap=primitive.extensions[this.name].attributes,threeAttributeMap={},attributeNormalizedMap={},attributeTypeMap={};for(const attributeName in gltfAttributeMap){const threeAttributeName=ATTRIBUTES[attributeName]||attributeName.toLowerCase();threeAttributeMap[threeAttributeName]=gltfAttributeMap[attributeName]}for(const attributeName in primitive.attributes){const threeAttributeName=ATTRIBUTES[attributeName]||attributeName.toLowerCase();if(void 0!==gltfAttributeMap[attributeName]){const accessorDef=json.accessors[primitive.attributes[attributeName]],componentType=WEBGL_COMPONENT_TYPES[accessorDef.componentType];attributeTypeMap[threeAttributeName]=componentType.name,attributeNormalizedMap[threeAttributeName]=!0===accessorDef.normalized}}return parser.getDependency("bufferView",bufferViewIndex).then((function(bufferView){return new Promise((function(resolve,reject){dracoLoader.decodeDracoFile(bufferView,(function(geometry){for(const attributeName in geometry.attributes){const attribute=geometry.attributes[attributeName],normalized=attributeNormalizedMap[attributeName];void 0!==normalized&&(attribute.normalized=normalized)}resolve(geometry)}),threeAttributeMap,attributeTypeMap,LinearSRGBColorSpace,reject)}))}))}}
220
+ /**
221
+ * Texture Transform Extension
222
+ *
223
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform
224
+ */class GLTFTextureTransformExtension{constructor(){this.name=EXTENSIONS.KHR_TEXTURE_TRANSFORM}extendTexture(texture,transform){return void 0!==transform.texCoord&&transform.texCoord!==texture.channel||void 0!==transform.offset||void 0!==transform.rotation||void 0!==transform.scale?(texture=texture.clone(),void 0!==transform.texCoord&&(texture.channel=transform.texCoord),void 0!==transform.offset&&texture.offset.fromArray(transform.offset),void 0!==transform.rotation&&(texture.rotation=transform.rotation),void 0!==transform.scale&&texture.repeat.fromArray(transform.scale),texture.needsUpdate=!0,texture):texture}}
225
+ /**
226
+ * Mesh Quantization Extension
227
+ *
228
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization
229
+ */class GLTFMeshQuantizationExtension{constructor(){this.name=EXTENSIONS.KHR_MESH_QUANTIZATION}}
230
+ /*********************************/
231
+ /********** INTERPOLATION ********/
232
+ /*********************************/class GLTFCubicSplineInterpolant extends Interpolant{constructor(parameterPositions,sampleValues,sampleSize,resultBuffer){super(parameterPositions,sampleValues,sampleSize,resultBuffer)}copySampleValue_(index){const result=this.resultBuffer,values=this.sampleValues,valueSize=this.valueSize,offset=index*valueSize*3+valueSize;for(let i=0;i!==valueSize;i++)result[i]=values[offset+i];return result}interpolate_(i1,t0,t,t1){const result=this.resultBuffer,values=this.sampleValues,stride=this.valueSize,stride2=2*stride,stride3=3*stride,td=t1-t0,p=(t-t0)/td,pp=p*p,ppp=pp*p,offset1=i1*stride3,offset0=offset1-stride3,s2=-2*ppp+3*pp,s3=ppp-pp,s0=1-s2,s1=s3-pp+p;for(let i=0;i!==stride;i++){const p0=values[offset0+i+stride],m0=values[offset0+i+stride2]*td,p1=values[offset1+i+stride],m1=values[offset1+i]*td;result[i]=s0*p0+s1*m0+s2*p1+s3*m1}return result}}const _q=new Quaternion;class GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant{interpolate_(i1,t0,t,t1){const result=super.interpolate_(i1,t0,t,t1);return _q.fromArray(result).normalize().toArray(result),result}}
233
+ /*********************************/
234
+ /********** INTERNALS ************/
235
+ /*********************************/const WEBGL_CONSTANTS={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},WEBGL_COMPONENT_TYPES={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},WEBGL_FILTERS={9728:NearestFilter,9729:LinearFilter,9984:NearestMipmapNearestFilter,9985:LinearMipmapNearestFilter,9986:NearestMipmapLinearFilter,9987:LinearMipmapLinearFilter},WEBGL_WRAPPINGS={33071:ClampToEdgeWrapping,33648:MirroredRepeatWrapping,10497:RepeatWrapping},WEBGL_TYPE_SIZES={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},ATTRIBUTES={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},PATH_PROPERTIES={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},INTERPOLATION={CUBICSPLINE:void 0,LINEAR:InterpolateLinear,STEP:InterpolateDiscrete},ALPHA_MODES_OPAQUE="OPAQUE",ALPHA_MODES_MASK="MASK",ALPHA_MODES_BLEND="BLEND";function addUnknownExtensionsToUserData(knownExtensions,object,objectDef){for(const name in objectDef.extensions)void 0===knownExtensions[name]&&(object.userData.gltfExtensions=object.userData.gltfExtensions||{},object.userData.gltfExtensions[name]=objectDef.extensions[name])}
236
+ /**
237
+ * @param {Object3D|Material|BufferGeometry} object
238
+ * @param {GLTF.definition} gltfDef
239
+ */function assignExtrasToUserData(object,gltfDef){void 0!==gltfDef.extras&&("object"==typeof gltfDef.extras?Object.assign(object.userData,gltfDef.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+gltfDef.extras))}
240
+ /**
241
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
242
+ *
243
+ * @param {BufferGeometry} geometry
244
+ * @param {Array<GLTF.Target>} targets
245
+ * @param {GLTFParser} parser
246
+ * @return {Promise<BufferGeometry>}
247
+ */
248
+ /**
249
+ * @param {Mesh} mesh
250
+ * @param {GLTF.Mesh} meshDef
251
+ */
252
+ function updateMorphTargets(mesh,meshDef){if(mesh.updateMorphTargets(),void 0!==meshDef.weights)for(let i=0,il=meshDef.weights.length;i<il;i++)mesh.morphTargetInfluences[i]=meshDef.weights[i];if(meshDef.extras&&Array.isArray(meshDef.extras.targetNames)){const targetNames=meshDef.extras.targetNames;if(mesh.morphTargetInfluences.length===targetNames.length){mesh.morphTargetDictionary={};for(let i=0,il=targetNames.length;i<il;i++)mesh.morphTargetDictionary[targetNames[i]]=i}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function createPrimitiveKey(primitiveDef){let geometryKey;const dracoExtension=primitiveDef.extensions&&primitiveDef.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION];if(geometryKey=dracoExtension?"draco:"+dracoExtension.bufferView+":"+dracoExtension.indices+":"+createAttributesKey(dracoExtension.attributes):primitiveDef.indices+":"+createAttributesKey(primitiveDef.attributes)+":"+primitiveDef.mode,void 0!==primitiveDef.targets)for(let i=0,il=primitiveDef.targets.length;i<il;i++)geometryKey+=":"+createAttributesKey(primitiveDef.targets[i]);return geometryKey}function createAttributesKey(attributes){let attributesKey="";const keys=Object.keys(attributes).sort();for(let i=0,il=keys.length;i<il;i++)attributesKey+=keys[i]+":"+attributes[keys[i]]+";";return attributesKey}function getNormalizedComponentScale(constructor){switch(constructor){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}const _identityMatrix=new Matrix4;class GLTFParser{constructor(json={},options={}){this.json=json,this.extensions={},this.plugins={},this.options=options,this.cache=new GLTFRegistry,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let isSafari=!1,safariVersion=-1,isFirefox=!1,firefoxVersion=-1;if("undefined"!=typeof navigator){const userAgent=navigator.userAgent;isSafari=!0===/^((?!chrome|android).)*safari/i.test(userAgent);const safariMatch=userAgent.match(/Version\/(\d+)/);safariVersion=isSafari&&safariMatch?parseInt(safariMatch[1],10):-1,isFirefox=userAgent.indexOf("Firefox")>-1,firefoxVersion=isFirefox?userAgent.match(/Firefox\/([0-9]+)\./)[1]:-1}"undefined"==typeof createImageBitmap||isSafari&&safariVersion<17||isFirefox&&firefoxVersion<98?this.textureLoader=new TextureLoader(this.options.manager):this.textureLoader=new ImageBitmapLoader(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new FileLoader(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),"use-credentials"===this.options.crossOrigin&&this.fileLoader.setWithCredentials(!0)}setExtensions(extensions){this.extensions=extensions}setPlugins(plugins){this.plugins=plugins}parse(onLoad,onError){const parser=this,json=this.json,extensions=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll((function(ext){return ext._markDefs&&ext._markDefs()})),Promise.all(this._invokeAll((function(ext){return ext.beforeRoot&&ext.beforeRoot()}))).then((function(){return Promise.all([parser.getDependencies("scene"),parser.getDependencies("animation"),parser.getDependencies("camera")])})).then((function(dependencies){const result={scene:dependencies[0][json.scene||0],scenes:dependencies[0],animations:dependencies[1],cameras:dependencies[2],asset:json.asset,parser:parser,userData:{}};return addUnknownExtensionsToUserData(extensions,result,json),assignExtrasToUserData(result,json),Promise.all(parser._invokeAll((function(ext){return ext.afterRoot&&ext.afterRoot(result)}))).then((function(){for(const scene of result.scenes)scene.updateMatrixWorld();onLoad(result)}))})).catch(onError)}
253
+ /**
254
+ * Marks the special nodes/meshes in json for efficient parse.
255
+ */_markDefs(){const nodeDefs=this.json.nodes||[],skinDefs=this.json.skins||[],meshDefs=this.json.meshes||[];for(let skinIndex=0,skinLength=skinDefs.length;skinIndex<skinLength;skinIndex++){const joints=skinDefs[skinIndex].joints;for(let i=0,il=joints.length;i<il;i++)nodeDefs[joints[i]].isBone=!0}for(let nodeIndex=0,nodeLength=nodeDefs.length;nodeIndex<nodeLength;nodeIndex++){const nodeDef=nodeDefs[nodeIndex];void 0!==nodeDef.mesh&&(this._addNodeRef(this.meshCache,nodeDef.mesh),void 0!==nodeDef.skin&&(meshDefs[nodeDef.mesh].isSkinnedMesh=!0)),void 0!==nodeDef.camera&&this._addNodeRef(this.cameraCache,nodeDef.camera)}}
256
+ /**
257
+ * Counts references to shared node / Object3D resources. These resources
258
+ * can be reused, or "instantiated", at multiple nodes in the scene
259
+ * hierarchy. Mesh, Camera, and Light instances are instantiated and must
260
+ * be marked. Non-scenegraph resources (like Materials, Geometries, and
261
+ * Textures) can be reused directly and are not marked here.
262
+ *
263
+ * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
264
+ */_addNodeRef(cache,index){void 0!==index&&(void 0===cache.refs[index]&&(cache.refs[index]=cache.uses[index]=0),cache.refs[index]++)}
265
+ /** Returns a reference to a shared resource, cloning it if necessary. */_getNodeRef(cache,index,object){if(cache.refs[index]<=1)return object;const ref=object.clone(),updateMappings=(original,clone)=>{const mappings=this.associations.get(original);null!=mappings&&this.associations.set(clone,mappings);for(const[i,child]of original.children.entries())updateMappings(child,clone.children[i])};return updateMappings(object,ref),ref.name+="_instance_"+cache.uses[index]++,ref}_invokeOne(func){const extensions=Object.values(this.plugins);extensions.push(this);for(let i=0;i<extensions.length;i++){const result=func(extensions[i]);if(result)return result}return null}_invokeAll(func){const extensions=Object.values(this.plugins);extensions.unshift(this);const pending=[];for(let i=0;i<extensions.length;i++){const result=func(extensions[i]);result&&pending.push(result)}return pending}
266
+ /**
267
+ * Requests the specified dependency asynchronously, with caching.
268
+ * @param {string} type
269
+ * @param {number} index
270
+ * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
271
+ */getDependency(type,index){const cacheKey=type+":"+index;let dependency=this.cache.get(cacheKey);if(!dependency){switch(type){case"scene":dependency=this.loadScene(index);break;case"node":dependency=this._invokeOne((function(ext){return ext.loadNode&&ext.loadNode(index)}));break;case"mesh":dependency=this._invokeOne((function(ext){return ext.loadMesh&&ext.loadMesh(index)}));break;case"accessor":dependency=this.loadAccessor(index);break;case"bufferView":dependency=this._invokeOne((function(ext){return ext.loadBufferView&&ext.loadBufferView(index)}));break;case"buffer":dependency=this.loadBuffer(index);break;case"material":dependency=this._invokeOne((function(ext){return ext.loadMaterial&&ext.loadMaterial(index)}));break;case"texture":dependency=this._invokeOne((function(ext){return ext.loadTexture&&ext.loadTexture(index)}));break;case"skin":dependency=this.loadSkin(index);break;case"animation":dependency=this._invokeOne((function(ext){return ext.loadAnimation&&ext.loadAnimation(index)}));break;case"camera":dependency=this.loadCamera(index);break;default:if(dependency=this._invokeOne((function(ext){return ext!=this&&ext.getDependency&&ext.getDependency(type,index)})),!dependency)throw new Error("Unknown type: "+type)}this.cache.add(cacheKey,dependency)}return dependency}
272
+ /**
273
+ * Requests all dependencies of the specified type asynchronously, with caching.
274
+ * @param {string} type
275
+ * @return {Promise<Array<Object>>}
276
+ */getDependencies(type){let dependencies=this.cache.get(type);if(!dependencies){const parser=this,defs=this.json[type+("mesh"===type?"es":"s")]||[];dependencies=Promise.all(defs.map((function(def,index){return parser.getDependency(type,index)}))),this.cache.add(type,dependencies)}return dependencies}
277
+ /**
278
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
279
+ * @param {number} bufferIndex
280
+ * @return {Promise<ArrayBuffer>}
281
+ */loadBuffer(bufferIndex){const bufferDef=this.json.buffers[bufferIndex],loader=this.fileLoader;if(bufferDef.type&&"arraybuffer"!==bufferDef.type)throw new Error("THREE.GLTFLoader: "+bufferDef.type+" buffer type is not supported.");if(void 0===bufferDef.uri&&0===bufferIndex)return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body);const options=this.options;return new Promise((function(resolve,reject){loader.load(LoaderUtils.resolveURL(bufferDef.uri,options.path),resolve,void 0,(function(){reject(new Error('THREE.GLTFLoader: Failed to load buffer "'+bufferDef.uri+'".'))}))}))}
282
+ /**
283
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
284
+ * @param {number} bufferViewIndex
285
+ * @return {Promise<ArrayBuffer>}
286
+ */loadBufferView(bufferViewIndex){const bufferViewDef=this.json.bufferViews[bufferViewIndex];return this.getDependency("buffer",bufferViewDef.buffer).then((function(buffer){const byteLength=bufferViewDef.byteLength||0,byteOffset=bufferViewDef.byteOffset||0;return buffer.slice(byteOffset,byteOffset+byteLength)}))}
287
+ /**
288
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
289
+ * @param {number} accessorIndex
290
+ * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
291
+ */loadAccessor(accessorIndex){const parser=this,json=this.json,accessorDef=this.json.accessors[accessorIndex];if(void 0===accessorDef.bufferView&&void 0===accessorDef.sparse){const itemSize=WEBGL_TYPE_SIZES[accessorDef.type],TypedArray=WEBGL_COMPONENT_TYPES[accessorDef.componentType],normalized=!0===accessorDef.normalized,array=new TypedArray(accessorDef.count*itemSize);return Promise.resolve(new BufferAttribute(array,itemSize,normalized))}const pendingBufferViews=[];return void 0!==accessorDef.bufferView?pendingBufferViews.push(this.getDependency("bufferView",accessorDef.bufferView)):pendingBufferViews.push(null),void 0!==accessorDef.sparse&&(pendingBufferViews.push(this.getDependency("bufferView",accessorDef.sparse.indices.bufferView)),pendingBufferViews.push(this.getDependency("bufferView",accessorDef.sparse.values.bufferView))),Promise.all(pendingBufferViews).then((function(bufferViews){const bufferView=bufferViews[0],itemSize=WEBGL_TYPE_SIZES[accessorDef.type],TypedArray=WEBGL_COMPONENT_TYPES[accessorDef.componentType],elementBytes=TypedArray.BYTES_PER_ELEMENT,itemBytes=elementBytes*itemSize,byteOffset=accessorDef.byteOffset||0,byteStride=void 0!==accessorDef.bufferView?json.bufferViews[accessorDef.bufferView].byteStride:void 0,normalized=!0===accessorDef.normalized;let array,bufferAttribute;if(byteStride&&byteStride!==itemBytes){const ibSlice=Math.floor(byteOffset/byteStride),ibCacheKey="InterleavedBuffer:"+accessorDef.bufferView+":"+accessorDef.componentType+":"+ibSlice+":"+accessorDef.count;let ib=parser.cache.get(ibCacheKey);ib||(array=new TypedArray(bufferView,ibSlice*byteStride,accessorDef.count*byteStride/elementBytes),ib=new InterleavedBuffer(array,byteStride/elementBytes),parser.cache.add(ibCacheKey,ib)),bufferAttribute=new InterleavedBufferAttribute(ib,itemSize,byteOffset%byteStride/elementBytes,normalized)}else array=null===bufferView?new TypedArray(accessorDef.count*itemSize):new TypedArray(bufferView,byteOffset,accessorDef.count*itemSize),bufferAttribute=new BufferAttribute(array,itemSize,normalized);if(void 0!==accessorDef.sparse){const itemSizeIndices=WEBGL_TYPE_SIZES.SCALAR,TypedArrayIndices=WEBGL_COMPONENT_TYPES[accessorDef.sparse.indices.componentType],byteOffsetIndices=accessorDef.sparse.indices.byteOffset||0,byteOffsetValues=accessorDef.sparse.values.byteOffset||0,sparseIndices=new TypedArrayIndices(bufferViews[1],byteOffsetIndices,accessorDef.sparse.count*itemSizeIndices),sparseValues=new TypedArray(bufferViews[2],byteOffsetValues,accessorDef.sparse.count*itemSize);null!==bufferView&&(bufferAttribute=new BufferAttribute(bufferAttribute.array.slice(),bufferAttribute.itemSize,bufferAttribute.normalized));for(let i=0,il=sparseIndices.length;i<il;i++){const index=sparseIndices[i];if(bufferAttribute.setX(index,sparseValues[i*itemSize]),itemSize>=2&&bufferAttribute.setY(index,sparseValues[i*itemSize+1]),itemSize>=3&&bufferAttribute.setZ(index,sparseValues[i*itemSize+2]),itemSize>=4&&bufferAttribute.setW(index,sparseValues[i*itemSize+3]),itemSize>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}}return bufferAttribute}))}
292
+ /**
293
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
294
+ * @param {number} textureIndex
295
+ * @return {Promise<THREE.Texture|null>}
296
+ */loadTexture(textureIndex){const json=this.json,options=this.options,sourceIndex=json.textures[textureIndex].source,sourceDef=json.images[sourceIndex];let loader=this.textureLoader;if(sourceDef.uri){const handler=options.manager.getHandler(sourceDef.uri);null!==handler&&(loader=handler)}return this.loadTextureImage(textureIndex,sourceIndex,loader)}loadTextureImage(textureIndex,sourceIndex,loader){const parser=this,json=this.json,textureDef=json.textures[textureIndex],sourceDef=json.images[sourceIndex],cacheKey=(sourceDef.uri||sourceDef.bufferView)+":"+textureDef.sampler;if(this.textureCache[cacheKey])return this.textureCache[cacheKey];const promise=this.loadImageSource(sourceIndex,loader).then((function(texture){texture.flipY=!1,texture.name=textureDef.name||sourceDef.name||"",""===texture.name&&"string"==typeof sourceDef.uri&&!1===sourceDef.uri.startsWith("data:image/")&&(texture.name=sourceDef.uri);const sampler=(json.samplers||{})[textureDef.sampler]||{};return texture.magFilter=WEBGL_FILTERS[sampler.magFilter]||LinearFilter,texture.minFilter=WEBGL_FILTERS[sampler.minFilter]||LinearMipmapLinearFilter,texture.wrapS=WEBGL_WRAPPINGS[sampler.wrapS]||RepeatWrapping,texture.wrapT=WEBGL_WRAPPINGS[sampler.wrapT]||RepeatWrapping,parser.associations.set(texture,{textures:textureIndex}),texture})).catch((function(){return null}));return this.textureCache[cacheKey]=promise,promise}loadImageSource(sourceIndex,loader){const parser=this,json=this.json,options=this.options;if(void 0!==this.sourceCache[sourceIndex])return this.sourceCache[sourceIndex].then((texture=>texture.clone()));const sourceDef=json.images[sourceIndex],URL=self.URL||self.webkitURL;let sourceURI=sourceDef.uri||"",isObjectURL=!1;if(void 0!==sourceDef.bufferView)sourceURI=parser.getDependency("bufferView",sourceDef.bufferView).then((function(bufferView){isObjectURL=!0;const blob=new Blob([bufferView],{type:sourceDef.mimeType});return sourceURI=URL.createObjectURL(blob),sourceURI}));else if(void 0===sourceDef.uri)throw new Error("THREE.GLTFLoader: Image "+sourceIndex+" is missing URI and bufferView");const promise=Promise.resolve(sourceURI).then((function(sourceURI){return new Promise((function(resolve,reject){let onLoad=resolve;!0===loader.isImageBitmapLoader&&(onLoad=function(imageBitmap){const texture=new Texture(imageBitmap);texture.needsUpdate=!0,resolve(texture)}),loader.load(LoaderUtils.resolveURL(sourceURI,options.path),onLoad,void 0,reject)}))})).then((function(texture){return!0===isObjectURL&&URL.revokeObjectURL(sourceURI),assignExtrasToUserData(texture,sourceDef),texture.userData.mimeType=sourceDef.mimeType||function getImageURIMimeType(uri){return uri.search(/\.jpe?g($|\?)/i)>0||0===uri.search(/^data\:image\/jpeg/)?"image/jpeg":uri.search(/\.webp($|\?)/i)>0||0===uri.search(/^data\:image\/webp/)?"image/webp":"image/png"}(sourceDef.uri),texture})).catch((function(error){throw console.error("THREE.GLTFLoader: Couldn't load texture",sourceURI),error}));return this.sourceCache[sourceIndex]=promise,promise}
297
+ /**
298
+ * Asynchronously assigns a texture to the given material parameters.
299
+ * @param {Object} materialParams
300
+ * @param {string} mapName
301
+ * @param {Object} mapDef
302
+ * @return {Promise<Texture>}
303
+ */assignTexture(materialParams,mapName,mapDef,colorSpace){const parser=this;return this.getDependency("texture",mapDef.index).then((function(texture){if(!texture)return null;if(void 0!==mapDef.texCoord&&mapDef.texCoord>0&&((texture=texture.clone()).channel=mapDef.texCoord),parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]){const transform=void 0!==mapDef.extensions?mapDef.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]:void 0;if(transform){const gltfReference=parser.associations.get(texture);texture=parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM].extendTexture(texture,transform),parser.associations.set(texture,gltfReference)}}return void 0!==colorSpace&&(texture.colorSpace=colorSpace),materialParams[mapName]=texture,texture}))}
304
+ /**
305
+ * Assigns final material to a Mesh, Line, or Points instance. The instance
306
+ * already has a material (generated from the glTF material options alone)
307
+ * but reuse of the same glTF material may require multiple threejs materials
308
+ * to accommodate different primitive types, defines, etc. New materials will
309
+ * be created if necessary, and reused from a cache.
310
+ * @param {Object3D} mesh Mesh, Line, or Points instance.
311
+ */assignFinalMaterial(mesh){const geometry=mesh.geometry;let material=mesh.material;const useDerivativeTangents=void 0===geometry.attributes.tangent,useVertexColors=void 0!==geometry.attributes.color,useFlatShading=void 0===geometry.attributes.normal;if(mesh.isPoints){const cacheKey="PointsMaterial:"+material.uuid;let pointsMaterial=this.cache.get(cacheKey);pointsMaterial||(pointsMaterial=new PointsMaterial,Material.prototype.copy.call(pointsMaterial,material),pointsMaterial.color.copy(material.color),pointsMaterial.map=material.map,pointsMaterial.sizeAttenuation=!1,this.cache.add(cacheKey,pointsMaterial)),material=pointsMaterial}else if(mesh.isLine){const cacheKey="LineBasicMaterial:"+material.uuid;let lineMaterial=this.cache.get(cacheKey);lineMaterial||(lineMaterial=new LineBasicMaterial,Material.prototype.copy.call(lineMaterial,material),lineMaterial.color.copy(material.color),lineMaterial.map=material.map,this.cache.add(cacheKey,lineMaterial)),material=lineMaterial}if(useDerivativeTangents||useVertexColors||useFlatShading){let cacheKey="ClonedMaterial:"+material.uuid+":";useDerivativeTangents&&(cacheKey+="derivative-tangents:"),useVertexColors&&(cacheKey+="vertex-colors:"),useFlatShading&&(cacheKey+="flat-shading:");let cachedMaterial=this.cache.get(cacheKey);cachedMaterial||(cachedMaterial=material.clone(),useVertexColors&&(cachedMaterial.vertexColors=!0),useFlatShading&&(cachedMaterial.flatShading=!0),useDerivativeTangents&&(cachedMaterial.normalScale&&(cachedMaterial.normalScale.y*=-1),cachedMaterial.clearcoatNormalScale&&(cachedMaterial.clearcoatNormalScale.y*=-1)),this.cache.add(cacheKey,cachedMaterial),this.associations.set(cachedMaterial,this.associations.get(material))),material=cachedMaterial}mesh.material=material}getMaterialType(){return MeshStandardMaterial}
312
+ /**
313
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
314
+ * @param {number} materialIndex
315
+ * @return {Promise<Material>}
316
+ */loadMaterial(materialIndex){const parser=this,json=this.json,extensions=this.extensions,materialDef=json.materials[materialIndex];let materialType;const materialParams={},pending=[];if((materialDef.extensions||{})[EXTENSIONS.KHR_MATERIALS_UNLIT]){const kmuExtension=extensions[EXTENSIONS.KHR_MATERIALS_UNLIT];materialType=kmuExtension.getMaterialType(),pending.push(kmuExtension.extendParams(materialParams,materialDef,parser))}else{const metallicRoughness=materialDef.pbrMetallicRoughness||{};if(materialParams.color=new Color(1,1,1),materialParams.opacity=1,Array.isArray(metallicRoughness.baseColorFactor)){const array=metallicRoughness.baseColorFactor;materialParams.color.setRGB(array[0],array[1],array[2],LinearSRGBColorSpace),materialParams.opacity=array[3]}void 0!==metallicRoughness.baseColorTexture&&pending.push(parser.assignTexture(materialParams,"map",metallicRoughness.baseColorTexture,SRGBColorSpace)),materialParams.metalness=void 0!==metallicRoughness.metallicFactor?metallicRoughness.metallicFactor:1,materialParams.roughness=void 0!==metallicRoughness.roughnessFactor?metallicRoughness.roughnessFactor:1,void 0!==metallicRoughness.metallicRoughnessTexture&&(pending.push(parser.assignTexture(materialParams,"metalnessMap",metallicRoughness.metallicRoughnessTexture)),pending.push(parser.assignTexture(materialParams,"roughnessMap",metallicRoughness.metallicRoughnessTexture))),materialType=this._invokeOne((function(ext){return ext.getMaterialType&&ext.getMaterialType(materialIndex)})),pending.push(Promise.all(this._invokeAll((function(ext){return ext.extendMaterialParams&&ext.extendMaterialParams(materialIndex,materialParams)}))))}!0===materialDef.doubleSided&&(materialParams.side=DoubleSide);const alphaMode=materialDef.alphaMode||ALPHA_MODES_OPAQUE;if(alphaMode===ALPHA_MODES_BLEND?(materialParams.transparent=!0,materialParams.depthWrite=!1):(materialParams.transparent=!1,alphaMode===ALPHA_MODES_MASK&&(materialParams.alphaTest=void 0!==materialDef.alphaCutoff?materialDef.alphaCutoff:.5)),void 0!==materialDef.normalTexture&&materialType!==MeshBasicMaterial&&(pending.push(parser.assignTexture(materialParams,"normalMap",materialDef.normalTexture)),materialParams.normalScale=new Vector2(1,1),void 0!==materialDef.normalTexture.scale)){const scale=materialDef.normalTexture.scale;materialParams.normalScale.set(scale,scale)}if(void 0!==materialDef.occlusionTexture&&materialType!==MeshBasicMaterial&&(pending.push(parser.assignTexture(materialParams,"aoMap",materialDef.occlusionTexture)),void 0!==materialDef.occlusionTexture.strength&&(materialParams.aoMapIntensity=materialDef.occlusionTexture.strength)),void 0!==materialDef.emissiveFactor&&materialType!==MeshBasicMaterial){const emissiveFactor=materialDef.emissiveFactor;materialParams.emissive=(new Color).setRGB(emissiveFactor[0],emissiveFactor[1],emissiveFactor[2],LinearSRGBColorSpace)}return void 0!==materialDef.emissiveTexture&&materialType!==MeshBasicMaterial&&pending.push(parser.assignTexture(materialParams,"emissiveMap",materialDef.emissiveTexture,SRGBColorSpace)),Promise.all(pending).then((function(){const material=new materialType(materialParams);return materialDef.name&&(material.name=materialDef.name),assignExtrasToUserData(material,materialDef),parser.associations.set(material,{materials:materialIndex}),materialDef.extensions&&addUnknownExtensionsToUserData(extensions,material,materialDef),material}))}
317
+ /** When Object3D instances are targeted by animation, they need unique names. */createUniqueName(originalName){const sanitizedName=PropertyBinding.sanitizeNodeName(originalName||"");return sanitizedName in this.nodeNamesUsed?sanitizedName+"_"+ ++this.nodeNamesUsed[sanitizedName]:(this.nodeNamesUsed[sanitizedName]=0,sanitizedName)}
318
+ /**
319
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
320
+ *
321
+ * Creates BufferGeometries from primitives.
322
+ *
323
+ * @param {Array<GLTF.Primitive>} primitives
324
+ * @return {Promise<Array<BufferGeometry>>}
325
+ */loadGeometries(primitives){const parser=this,extensions=this.extensions,cache=this.primitiveCache;function createDracoPrimitive(primitive){return extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(primitive,parser).then((function(geometry){return addPrimitiveAttributes(geometry,primitive,parser)}))}const pending=[];for(let i=0,il=primitives.length;i<il;i++){const primitive=primitives[i],cacheKey=createPrimitiveKey(primitive),cached=cache[cacheKey];if(cached)pending.push(cached.promise);else{let geometryPromise;geometryPromise=primitive.extensions&&primitive.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]?createDracoPrimitive(primitive):addPrimitiveAttributes(new BufferGeometry,primitive,parser),cache[cacheKey]={primitive:primitive,promise:geometryPromise},pending.push(geometryPromise)}}return Promise.all(pending)}
326
+ /**
327
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
328
+ * @param {number} meshIndex
329
+ * @return {Promise<Group|Mesh|SkinnedMesh>}
330
+ */loadMesh(meshIndex){const parser=this,json=this.json,extensions=this.extensions,meshDef=json.meshes[meshIndex],primitives=meshDef.primitives,pending=[];for(let i=0,il=primitives.length;i<il;i++){const material=void 0===primitives[i].material?(void 0===(cache=this.cache).DefaultMaterial&&(cache.DefaultMaterial=new MeshStandardMaterial({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:FrontSide})),cache.DefaultMaterial):this.getDependency("material",primitives[i].material);pending.push(material)}
331
+ /**
332
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
333
+ */
334
+ var cache;return pending.push(parser.loadGeometries(primitives)),Promise.all(pending).then((function(results){const materials=results.slice(0,results.length-1),geometries=results[results.length-1],meshes=[];for(let i=0,il=geometries.length;i<il;i++){const geometry=geometries[i],primitive=primitives[i];let mesh;const material=materials[i];if(primitive.mode===WEBGL_CONSTANTS.TRIANGLES||primitive.mode===WEBGL_CONSTANTS.TRIANGLE_STRIP||primitive.mode===WEBGL_CONSTANTS.TRIANGLE_FAN||void 0===primitive.mode)mesh=!0===meshDef.isSkinnedMesh?new SkinnedMesh(geometry,material):new Mesh(geometry,material),!0===mesh.isSkinnedMesh&&mesh.normalizeSkinWeights(),primitive.mode===WEBGL_CONSTANTS.TRIANGLE_STRIP?mesh.geometry=toTrianglesDrawMode(mesh.geometry,TriangleStripDrawMode):primitive.mode===WEBGL_CONSTANTS.TRIANGLE_FAN&&(mesh.geometry=toTrianglesDrawMode(mesh.geometry,TriangleFanDrawMode));else if(primitive.mode===WEBGL_CONSTANTS.LINES)mesh=new LineSegments(geometry,material);else if(primitive.mode===WEBGL_CONSTANTS.LINE_STRIP)mesh=new Line(geometry,material);else if(primitive.mode===WEBGL_CONSTANTS.LINE_LOOP)mesh=new LineLoop(geometry,material);else{if(primitive.mode!==WEBGL_CONSTANTS.POINTS)throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+primitive.mode);mesh=new Points(geometry,material)}Object.keys(mesh.geometry.morphAttributes).length>0&&updateMorphTargets(mesh,meshDef),mesh.name=parser.createUniqueName(meshDef.name||"mesh_"+meshIndex),assignExtrasToUserData(mesh,meshDef),primitive.extensions&&addUnknownExtensionsToUserData(extensions,mesh,primitive),parser.assignFinalMaterial(mesh),meshes.push(mesh)}for(let i=0,il=meshes.length;i<il;i++)parser.associations.set(meshes[i],{meshes:meshIndex,primitives:i});if(1===meshes.length)return meshDef.extensions&&addUnknownExtensionsToUserData(extensions,meshes[0],meshDef),meshes[0];const group=new Group;meshDef.extensions&&addUnknownExtensionsToUserData(extensions,group,meshDef),parser.associations.set(group,{meshes:meshIndex});for(let i=0,il=meshes.length;i<il;i++)group.add(meshes[i]);return group}))}
335
+ /**
336
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
337
+ * @param {number} cameraIndex
338
+ * @return {Promise<THREE.Camera>}
339
+ */loadCamera(cameraIndex){let camera;const cameraDef=this.json.cameras[cameraIndex],params=cameraDef[cameraDef.type];if(params)return"perspective"===cameraDef.type?camera=new PerspectiveCamera(MathUtils.radToDeg(params.yfov),params.aspectRatio||1,params.znear||1,params.zfar||2e6):"orthographic"===cameraDef.type&&(camera=new OrthographicCamera(-params.xmag,params.xmag,params.ymag,-params.ymag,params.znear,params.zfar)),cameraDef.name&&(camera.name=this.createUniqueName(cameraDef.name)),assignExtrasToUserData(camera,cameraDef),Promise.resolve(camera);console.warn("THREE.GLTFLoader: Missing camera parameters.")}
340
+ /**
341
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
342
+ * @param {number} skinIndex
343
+ * @return {Promise<Skeleton>}
344
+ */loadSkin(skinIndex){const skinDef=this.json.skins[skinIndex],pending=[];for(let i=0,il=skinDef.joints.length;i<il;i++)pending.push(this._loadNodeShallow(skinDef.joints[i]));return void 0!==skinDef.inverseBindMatrices?pending.push(this.getDependency("accessor",skinDef.inverseBindMatrices)):pending.push(null),Promise.all(pending).then((function(results){const inverseBindMatrices=results.pop(),jointNodes=results,bones=[],boneInverses=[];for(let i=0,il=jointNodes.length;i<il;i++){const jointNode=jointNodes[i];if(jointNode){bones.push(jointNode);const mat=new Matrix4;null!==inverseBindMatrices&&mat.fromArray(inverseBindMatrices.array,16*i),boneInverses.push(mat)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',skinDef.joints[i])}return new Skeleton(bones,boneInverses)}))}
345
+ /**
346
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
347
+ * @param {number} animationIndex
348
+ * @return {Promise<AnimationClip>}
349
+ */loadAnimation(animationIndex){const json=this.json,parser=this,animationDef=json.animations[animationIndex],animationName=animationDef.name?animationDef.name:"animation_"+animationIndex,pendingNodes=[],pendingInputAccessors=[],pendingOutputAccessors=[],pendingSamplers=[],pendingTargets=[];for(let i=0,il=animationDef.channels.length;i<il;i++){const channel=animationDef.channels[i],sampler=animationDef.samplers[channel.sampler],target=channel.target,name=target.node,input=void 0!==animationDef.parameters?animationDef.parameters[sampler.input]:sampler.input,output=void 0!==animationDef.parameters?animationDef.parameters[sampler.output]:sampler.output;void 0!==target.node&&(pendingNodes.push(this.getDependency("node",name)),pendingInputAccessors.push(this.getDependency("accessor",input)),pendingOutputAccessors.push(this.getDependency("accessor",output)),pendingSamplers.push(sampler),pendingTargets.push(target))}return Promise.all([Promise.all(pendingNodes),Promise.all(pendingInputAccessors),Promise.all(pendingOutputAccessors),Promise.all(pendingSamplers),Promise.all(pendingTargets)]).then((function(dependencies){const nodes=dependencies[0],inputAccessors=dependencies[1],outputAccessors=dependencies[2],samplers=dependencies[3],targets=dependencies[4],tracks=[];for(let i=0,il=nodes.length;i<il;i++){const node=nodes[i],inputAccessor=inputAccessors[i],outputAccessor=outputAccessors[i],sampler=samplers[i],target=targets[i];if(void 0===node)continue;node.updateMatrix&&node.updateMatrix();const createdTracks=parser._createAnimationTracks(node,inputAccessor,outputAccessor,sampler,target);if(createdTracks)for(let k=0;k<createdTracks.length;k++)tracks.push(createdTracks[k])}return new AnimationClip(animationName,void 0,tracks)}))}createNodeMesh(nodeIndex){const json=this.json,parser=this,nodeDef=json.nodes[nodeIndex];return void 0===nodeDef.mesh?null:parser.getDependency("mesh",nodeDef.mesh).then((function(mesh){const node=parser._getNodeRef(parser.meshCache,nodeDef.mesh,mesh);return void 0!==nodeDef.weights&&node.traverse((function(o){if(o.isMesh)for(let i=0,il=nodeDef.weights.length;i<il;i++)o.morphTargetInfluences[i]=nodeDef.weights[i]})),node}))}
350
+ /**
351
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
352
+ * @param {number} nodeIndex
353
+ * @return {Promise<Object3D>}
354
+ */loadNode(nodeIndex){const parser=this,nodeDef=this.json.nodes[nodeIndex],nodePending=parser._loadNodeShallow(nodeIndex),childPending=[],childrenDef=nodeDef.children||[];for(let i=0,il=childrenDef.length;i<il;i++)childPending.push(parser.getDependency("node",childrenDef[i]));const skeletonPending=void 0===nodeDef.skin?Promise.resolve(null):parser.getDependency("skin",nodeDef.skin);return Promise.all([nodePending,Promise.all(childPending),skeletonPending]).then((function(results){const node=results[0],children=results[1],skeleton=results[2];null!==skeleton&&node.traverse((function(mesh){mesh.isSkinnedMesh&&mesh.bind(skeleton,_identityMatrix)}));for(let i=0,il=children.length;i<il;i++)node.add(children[i]);return node}))}_loadNodeShallow(nodeIndex){const json=this.json,extensions=this.extensions,parser=this;if(void 0!==this.nodeCache[nodeIndex])return this.nodeCache[nodeIndex];const nodeDef=json.nodes[nodeIndex],nodeName=nodeDef.name?parser.createUniqueName(nodeDef.name):"",pending=[],meshPromise=parser._invokeOne((function(ext){return ext.createNodeMesh&&ext.createNodeMesh(nodeIndex)}));return meshPromise&&pending.push(meshPromise),void 0!==nodeDef.camera&&pending.push(parser.getDependency("camera",nodeDef.camera).then((function(camera){return parser._getNodeRef(parser.cameraCache,nodeDef.camera,camera)}))),parser._invokeAll((function(ext){return ext.createNodeAttachment&&ext.createNodeAttachment(nodeIndex)})).forEach((function(promise){pending.push(promise)})),this.nodeCache[nodeIndex]=Promise.all(pending).then((function(objects){let node;if(node=!0===nodeDef.isBone?new Bone:objects.length>1?new Group:1===objects.length?objects[0]:new Object3D,node!==objects[0])for(let i=0,il=objects.length;i<il;i++)node.add(objects[i]);if(nodeDef.name&&(node.userData.name=nodeDef.name,node.name=nodeName),assignExtrasToUserData(node,nodeDef),nodeDef.extensions&&addUnknownExtensionsToUserData(extensions,node,nodeDef),void 0!==nodeDef.matrix){const matrix=new Matrix4;matrix.fromArray(nodeDef.matrix),node.applyMatrix4(matrix)}else void 0!==nodeDef.translation&&node.position.fromArray(nodeDef.translation),void 0!==nodeDef.rotation&&node.quaternion.fromArray(nodeDef.rotation),void 0!==nodeDef.scale&&node.scale.fromArray(nodeDef.scale);return parser.associations.has(node)||parser.associations.set(node,{}),parser.associations.get(node).nodes=nodeIndex,node})),this.nodeCache[nodeIndex]}
355
+ /**
356
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
357
+ * @param {number} sceneIndex
358
+ * @return {Promise<Group>}
359
+ */loadScene(sceneIndex){const extensions=this.extensions,sceneDef=this.json.scenes[sceneIndex],parser=this,scene=new Group;sceneDef.name&&(scene.name=parser.createUniqueName(sceneDef.name)),assignExtrasToUserData(scene,sceneDef),sceneDef.extensions&&addUnknownExtensionsToUserData(extensions,scene,sceneDef);const nodeIds=sceneDef.nodes||[],pending=[];for(let i=0,il=nodeIds.length;i<il;i++)pending.push(parser.getDependency("node",nodeIds[i]));return Promise.all(pending).then((function(nodes){for(let i=0,il=nodes.length;i<il;i++)scene.add(nodes[i]);return parser.associations=(node=>{const reducedAssociations=new Map;for(const[key,value]of parser.associations)(key instanceof Material||key instanceof Texture)&&reducedAssociations.set(key,value);return node.traverse((node=>{const mappings=parser.associations.get(node);null!=mappings&&reducedAssociations.set(node,mappings)})),reducedAssociations})(scene),scene}))}_createAnimationTracks(node,inputAccessor,outputAccessor,sampler,target){const tracks=[],targetName=node.name?node.name:node.uuid,targetNames=[];let TypedKeyframeTrack;switch(PATH_PROPERTIES[target.path]===PATH_PROPERTIES.weights?node.traverse((function(object){object.morphTargetInfluences&&targetNames.push(object.name?object.name:object.uuid)})):targetNames.push(targetName),PATH_PROPERTIES[target.path]){case PATH_PROPERTIES.weights:TypedKeyframeTrack=NumberKeyframeTrack;break;case PATH_PROPERTIES.rotation:TypedKeyframeTrack=QuaternionKeyframeTrack;break;case PATH_PROPERTIES.position:case PATH_PROPERTIES.scale:TypedKeyframeTrack=VectorKeyframeTrack;break;default:if(1===outputAccessor.itemSize)TypedKeyframeTrack=NumberKeyframeTrack;else TypedKeyframeTrack=VectorKeyframeTrack}const interpolation=void 0!==sampler.interpolation?INTERPOLATION[sampler.interpolation]:InterpolateLinear,outputArray=this._getArrayFromAccessor(outputAccessor);for(let j=0,jl=targetNames.length;j<jl;j++){const track=new TypedKeyframeTrack(targetNames[j]+"."+PATH_PROPERTIES[target.path],inputAccessor.array,outputArray,interpolation);"CUBICSPLINE"===sampler.interpolation&&this._createCubicSplineTrackInterpolant(track),tracks.push(track)}return tracks}_getArrayFromAccessor(accessor){let outputArray=accessor.array;if(accessor.normalized){const scale=getNormalizedComponentScale(outputArray.constructor),scaled=new Float32Array(outputArray.length);for(let j=0,jl=outputArray.length;j<jl;j++)scaled[j]=outputArray[j]*scale;outputArray=scaled}return outputArray}_createCubicSplineTrackInterpolant(track){track.createInterpolant=function InterpolantFactoryMethodGLTFCubicSpline(result){return new(this instanceof QuaternionKeyframeTrack?GLTFCubicSplineQuaternionInterpolant:GLTFCubicSplineInterpolant)(this.times,this.values,this.getValueSize()/3,result)},track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}
360
+ /**
361
+ * @param {BufferGeometry} geometry
362
+ * @param {GLTF.Primitive} primitiveDef
363
+ * @param {GLTFParser} parser
364
+ */
365
+ /**
366
+ * @param {BufferGeometry} geometry
367
+ * @param {GLTF.Primitive} primitiveDef
368
+ * @param {GLTFParser} parser
369
+ * @return {Promise<BufferGeometry>}
370
+ */
371
+ function addPrimitiveAttributes(geometry,primitiveDef,parser){const attributes=primitiveDef.attributes,pending=[];function assignAttributeAccessor(accessorIndex,attributeName){return parser.getDependency("accessor",accessorIndex).then((function(accessor){geometry.setAttribute(attributeName,accessor)}))}for(const gltfAttributeName in attributes){const threeAttributeName=ATTRIBUTES[gltfAttributeName]||gltfAttributeName.toLowerCase();threeAttributeName in geometry.attributes||pending.push(assignAttributeAccessor(attributes[gltfAttributeName],threeAttributeName))}if(void 0!==primitiveDef.indices&&!geometry.index){const accessor=parser.getDependency("accessor",primitiveDef.indices).then((function(accessor){geometry.setIndex(accessor)}));pending.push(accessor)}return ColorManagement.workingColorSpace!==LinearSRGBColorSpace&&"COLOR_0"in attributes&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${ColorManagement.workingColorSpace}" not supported.`),assignExtrasToUserData(geometry,primitiveDef),function computeBounds(geometry,primitiveDef,parser){const attributes=primitiveDef.attributes,box=new Box3;if(void 0===attributes.POSITION)return;{const accessor=parser.json.accessors[attributes.POSITION],min=accessor.min,max=accessor.max;if(void 0===min||void 0===max)return void console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");if(box.set(new Vector3(min[0],min[1],min[2]),new Vector3(max[0],max[1],max[2])),accessor.normalized){const boxScale=getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);box.min.multiplyScalar(boxScale),box.max.multiplyScalar(boxScale)}}const targets=primitiveDef.targets;if(void 0!==targets){const maxDisplacement=new Vector3,vector=new Vector3;for(let i=0,il=targets.length;i<il;i++){const target=targets[i];if(void 0!==target.POSITION){const accessor=parser.json.accessors[target.POSITION],min=accessor.min,max=accessor.max;if(void 0!==min&&void 0!==max){if(vector.setX(Math.max(Math.abs(min[0]),Math.abs(max[0]))),vector.setY(Math.max(Math.abs(min[1]),Math.abs(max[1]))),vector.setZ(Math.max(Math.abs(min[2]),Math.abs(max[2]))),accessor.normalized){const boxScale=getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);vector.multiplyScalar(boxScale)}maxDisplacement.max(vector)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}box.expandByVector(maxDisplacement)}geometry.boundingBox=box;const sphere=new Sphere;box.getCenter(sphere.center),sphere.radius=box.min.distanceTo(box.max)/2,geometry.boundingSphere=sphere}(geometry,primitiveDef,parser),Promise.all(pending).then((function(){return void 0!==primitiveDef.targets?function addMorphTargets(geometry,targets,parser){let hasMorphPosition=!1,hasMorphNormal=!1,hasMorphColor=!1;for(let i=0,il=targets.length;i<il;i++){const target=targets[i];if(void 0!==target.POSITION&&(hasMorphPosition=!0),void 0!==target.NORMAL&&(hasMorphNormal=!0),void 0!==target.COLOR_0&&(hasMorphColor=!0),hasMorphPosition&&hasMorphNormal&&hasMorphColor)break}if(!hasMorphPosition&&!hasMorphNormal&&!hasMorphColor)return Promise.resolve(geometry);const pendingPositionAccessors=[],pendingNormalAccessors=[],pendingColorAccessors=[];for(let i=0,il=targets.length;i<il;i++){const target=targets[i];if(hasMorphPosition){const pendingAccessor=void 0!==target.POSITION?parser.getDependency("accessor",target.POSITION):geometry.attributes.position;pendingPositionAccessors.push(pendingAccessor)}if(hasMorphNormal){const pendingAccessor=void 0!==target.NORMAL?parser.getDependency("accessor",target.NORMAL):geometry.attributes.normal;pendingNormalAccessors.push(pendingAccessor)}if(hasMorphColor){const pendingAccessor=void 0!==target.COLOR_0?parser.getDependency("accessor",target.COLOR_0):geometry.attributes.color;pendingColorAccessors.push(pendingAccessor)}}return Promise.all([Promise.all(pendingPositionAccessors),Promise.all(pendingNormalAccessors),Promise.all(pendingColorAccessors)]).then((function(accessors){const morphPositions=accessors[0],morphNormals=accessors[1],morphColors=accessors[2];return hasMorphPosition&&(geometry.morphAttributes.position=morphPositions),hasMorphNormal&&(geometry.morphAttributes.normal=morphNormals),hasMorphColor&&(geometry.morphAttributes.color=morphColors),geometry.morphTargetsRelative=!0,geometry}))}(geometry,primitiveDef.targets,parser):geometry}))}const _taskCache$1=new WeakMap;class DRACOLoader extends Loader{constructor(manager){super(manager),this.decoderPath="",this.decoderConfig={},this.decoderBinary=null,this.decoderPending=null,this.workerLimit=4,this.workerPool=[],this.workerNextTaskID=1,this.workerSourceURL="",this.defaultAttributeIDs={position:"POSITION",normal:"NORMAL",color:"COLOR",uv:"TEX_COORD"},this.defaultAttributeTypes={position:"Float32Array",normal:"Float32Array",color:"Float32Array",uv:"Float32Array"}}setDecoderPath(path){return this.decoderPath=path,this}setDecoderConfig(config){return this.decoderConfig=config,this}setWorkerLimit(workerLimit){return this.workerLimit=workerLimit,this}load(url,onLoad,onProgress,onError){const loader=new FileLoader(this.manager);loader.setPath(this.path),loader.setResponseType("arraybuffer"),loader.setRequestHeader(this.requestHeader),loader.setWithCredentials(this.withCredentials),loader.load(url,(buffer=>{this.parse(buffer,onLoad,onError)}),onProgress,onError)}parse(buffer,onLoad,onError=()=>{}){this.decodeDracoFile(buffer,onLoad,null,null,SRGBColorSpace,onError).catch(onError)}decodeDracoFile(buffer,callback,attributeIDs,attributeTypes,vertexColorSpace=LinearSRGBColorSpace,onError=()=>{}){const taskConfig={attributeIDs:attributeIDs||this.defaultAttributeIDs,attributeTypes:attributeTypes||this.defaultAttributeTypes,useUniqueIDs:!!attributeIDs,vertexColorSpace:vertexColorSpace};return this.decodeGeometry(buffer,taskConfig).then(callback).catch(onError)}decodeGeometry(buffer,taskConfig){const taskKey=JSON.stringify(taskConfig);if(_taskCache$1.has(buffer)){const cachedTask=_taskCache$1.get(buffer);if(cachedTask.key===taskKey)return cachedTask.promise;if(0===buffer.byteLength)throw new Error("THREE.DRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred.")}let worker;const taskID=this.workerNextTaskID++,taskCost=buffer.byteLength,geometryPending=this._getWorker(taskID,taskCost).then((_worker=>(worker=_worker,new Promise(((resolve,reject)=>{worker._callbacks[taskID]={resolve:resolve,reject:reject},worker.postMessage({type:"decode",id:taskID,taskConfig:taskConfig,buffer:buffer},[buffer])}))))).then((message=>this._createGeometry(message.geometry)));return geometryPending.catch((()=>!0)).then((()=>{worker&&taskID&&this._releaseTask(worker,taskID)})),_taskCache$1.set(buffer,{key:taskKey,promise:geometryPending}),geometryPending}_createGeometry(geometryData){const geometry=new BufferGeometry;geometryData.index&&geometry.setIndex(new BufferAttribute(geometryData.index.array,1));for(let i=0;i<geometryData.attributes.length;i++){const result=geometryData.attributes[i],name=result.name,array=result.array,itemSize=result.itemSize,attribute=new BufferAttribute(array,itemSize);"color"===name&&(this._assignVertexColorSpace(attribute,result.vertexColorSpace),attribute.normalized=array instanceof Float32Array==!1),geometry.setAttribute(name,attribute)}return geometry}_assignVertexColorSpace(attribute,inputColorSpace){if(inputColorSpace!==SRGBColorSpace)return;const _color=new Color;for(let i=0,il=attribute.count;i<il;i++)_color.fromBufferAttribute(attribute,i).convertSRGBToLinear(),attribute.setXYZ(i,_color.r,_color.g,_color.b)}_loadLibrary(url,responseType){const loader=new FileLoader(this.manager);return loader.setPath(this.decoderPath),loader.setResponseType(responseType),loader.setWithCredentials(this.withCredentials),new Promise(((resolve,reject)=>{loader.load(url,resolve,void 0,reject)}))}preload(){return this._initDecoder(),this}_initDecoder(){if(this.decoderPending)return this.decoderPending;const useJS="object"!=typeof WebAssembly||"js"===this.decoderConfig.type,librariesPending=[];return useJS?librariesPending.push(this._loadLibrary("draco_decoder.js","text")):(librariesPending.push(this._loadLibrary("draco_wasm_wrapper.js","text")),librariesPending.push(this._loadLibrary("draco_decoder.wasm","arraybuffer"))),this.decoderPending=Promise.all(librariesPending).then((libraries=>{const jsContent=libraries[0];useJS||(this.decoderConfig.wasmBinary=libraries[1]);const fn=DRACOWorker.toString(),body=["/* draco decoder */",jsContent,"","/* worker */",fn.substring(fn.indexOf("{")+1,fn.lastIndexOf("}"))].join("\n");this.workerSourceURL=URL.createObjectURL(new Blob([body]))})),this.decoderPending}_getWorker(taskID,taskCost){return this._initDecoder().then((()=>{if(this.workerPool.length<this.workerLimit){const worker=new Worker(this.workerSourceURL);worker._callbacks={},worker._taskCosts={},worker._taskLoad=0,worker.postMessage({type:"init",decoderConfig:this.decoderConfig}),worker.onmessage=function(e){const message=e.data;switch(message.type){case"decode":worker._callbacks[message.id].resolve(message);break;case"error":worker._callbacks[message.id].reject(message);break;default:console.error('THREE.DRACOLoader: Unexpected message, "'+message.type+'"')}},this.workerPool.push(worker)}else this.workerPool.sort((function(a,b){return a._taskLoad>b._taskLoad?-1:1}));const worker=this.workerPool[this.workerPool.length-1];return worker._taskCosts[taskID]=taskCost,worker._taskLoad+=taskCost,worker}))}_releaseTask(worker,taskID){worker._taskLoad-=worker._taskCosts[taskID],delete worker._callbacks[taskID],delete worker._taskCosts[taskID]}debug(){console.log("Task load: ",this.workerPool.map((worker=>worker._taskLoad)))}dispose(){for(let i=0;i<this.workerPool.length;++i)this.workerPool[i].terminate();return this.workerPool.length=0,""!==this.workerSourceURL&&URL.revokeObjectURL(this.workerSourceURL),this}}function DRACOWorker(){let decoderConfig,decoderPending;function decodeAttribute(draco,decoder,dracoGeometry,attributeName,attributeType,attribute){const numComponents=attribute.num_components(),numValues=dracoGeometry.num_points()*numComponents,byteLength=numValues*attributeType.BYTES_PER_ELEMENT,dataType=function getDracoDataType(draco,attributeType){switch(attributeType){case Float32Array:return draco.DT_FLOAT32;case Int8Array:return draco.DT_INT8;case Int16Array:return draco.DT_INT16;case Int32Array:return draco.DT_INT32;case Uint8Array:return draco.DT_UINT8;case Uint16Array:return draco.DT_UINT16;case Uint32Array:return draco.DT_UINT32}}(draco,attributeType),ptr=draco._malloc(byteLength);decoder.GetAttributeDataArrayForAllPoints(dracoGeometry,attribute,dataType,byteLength,ptr);const array=new attributeType(draco.HEAPF32.buffer,ptr,numValues).slice();return draco._free(ptr),{name:attributeName,array:array,itemSize:numComponents}}onmessage=function(e){const message=e.data;switch(message.type){case"init":decoderConfig=message.decoderConfig,decoderPending=new Promise((function(resolve){decoderConfig.onModuleLoaded=function(draco){resolve({draco:draco})},DracoDecoderModule(decoderConfig)}));break;case"decode":const buffer=message.buffer,taskConfig=message.taskConfig;decoderPending.then((module=>{const draco=module.draco,decoder=new draco.Decoder;try{const geometry=function decodeGeometry(draco,decoder,array,taskConfig){const attributeIDs=taskConfig.attributeIDs,attributeTypes=taskConfig.attributeTypes;let dracoGeometry,decodingStatus;const geometryType=decoder.GetEncodedGeometryType(array);if(geometryType===draco.TRIANGULAR_MESH)dracoGeometry=new draco.Mesh,decodingStatus=decoder.DecodeArrayToMesh(array,array.byteLength,dracoGeometry);else{if(geometryType!==draco.POINT_CLOUD)throw new Error("THREE.DRACOLoader: Unexpected geometry type.");dracoGeometry=new draco.PointCloud,decodingStatus=decoder.DecodeArrayToPointCloud(array,array.byteLength,dracoGeometry)}if(!decodingStatus.ok()||0===dracoGeometry.ptr)throw new Error("THREE.DRACOLoader: Decoding failed: "+decodingStatus.error_msg());const geometry={index:null,attributes:[]};for(const attributeName in attributeIDs){const attributeType=self[attributeTypes[attributeName]];let attribute,attributeID;if(taskConfig.useUniqueIDs)attributeID=attributeIDs[attributeName],attribute=decoder.GetAttributeByUniqueId(dracoGeometry,attributeID);else{if(attributeID=decoder.GetAttributeId(dracoGeometry,draco[attributeIDs[attributeName]]),-1===attributeID)continue;attribute=decoder.GetAttribute(dracoGeometry,attributeID)}const attributeResult=decodeAttribute(draco,decoder,dracoGeometry,attributeName,attributeType,attribute);"color"===attributeName&&(attributeResult.vertexColorSpace=taskConfig.vertexColorSpace),geometry.attributes.push(attributeResult)}geometryType===draco.TRIANGULAR_MESH&&(geometry.index=function decodeIndex(draco,decoder,dracoGeometry){const numFaces=dracoGeometry.num_faces(),numIndices=3*numFaces,byteLength=4*numIndices,ptr=draco._malloc(byteLength);decoder.GetTrianglesUInt32Array(dracoGeometry,byteLength,ptr);const index=new Uint32Array(draco.HEAPF32.buffer,ptr,numIndices).slice();return draco._free(ptr),{array:index,itemSize:1}}(draco,decoder,dracoGeometry));return draco.destroy(dracoGeometry),geometry}(draco,decoder,new Int8Array(buffer),taskConfig),buffers=geometry.attributes.map((attr=>attr.array.buffer));geometry.index&&buffers.push(geometry.index.array.buffer),self.postMessage({type:"decode",id:message.id,geometry:geometry},buffers)}catch(error){console.error(error),self.postMessage({type:"error",id:message.id,error:error.message})}finally{draco.destroy(decoder)}}))}}}
372
+ /**
373
+ * @author Deepkolos / https://github.com/deepkolos
374
+ */class WorkerPool{constructor(pool=4){this.pool=pool,this.queue=[],this.workers=[],this.workersResolve=[],this.workerStatus=0}_initWorker(workerId){if(!this.workers[workerId]){const worker=this.workerCreator();worker.addEventListener("message",this._onMessage.bind(this,workerId)),this.workers[workerId]=worker}}_getIdleWorker(){for(let i=0;i<this.pool;i++)if(!(this.workerStatus&1<<i))return i;return-1}_onMessage(workerId,msg){const resolve=this.workersResolve[workerId];if(resolve&&resolve(msg),this.queue.length){const{resolve:resolve,msg:msg,transfer:transfer}=this.queue.shift();this.workersResolve[workerId]=resolve,this.workers[workerId].postMessage(msg,transfer)}else this.workerStatus^=1<<workerId}setWorkerCreator(workerCreator){this.workerCreator=workerCreator}setWorkerLimit(pool){this.pool=pool}postMessage(msg,transfer){return new Promise((resolve=>{const workerId=this._getIdleWorker();-1!==workerId?(this._initWorker(workerId),this.workerStatus|=1<<workerId,this.workersResolve[workerId]=resolve,this.workers[workerId].postMessage(msg,transfer)):this.queue.push({resolve:resolve,msg:msg,transfer:transfer})}))}dispose(){this.workers.forEach((worker=>worker.terminate())),this.workersResolve.length=0,this.workers.length=0,this.queue.length=0,this.workerStatus=0}}const ct=9,gt=15,yt=16,dt=22,Ot=37,Ft=43,$t=76,se=83,pe=97,xe=100,de=103,Ae=109,Sn=165,In=166;class Si{constructor(){this.vkFormat=0,this.typeSize=1,this.pixelWidth=0,this.pixelHeight=0,this.pixelDepth=0,this.layerCount=0,this.faceCount=1,this.supercompressionScheme=0,this.levels=[],this.dataFormatDescriptor=[{vendorId:0,descriptorType:0,descriptorBlockSize:0,versionNumber:2,colorModel:0,colorPrimaries:1,transferFunction:2,flags:0,texelBlockDimension:[0,0,0,0],bytesPlane:[0,0,0,0,0,0,0,0],samples:[]}],this.keyValue={},this.globalData=null}}class Ii{constructor(t,e,n,i){this._dataView=new DataView(t.buffer,t.byteOffset+e,n),this._littleEndian=i,this._offset=0}_nextUint8(){const t=this._dataView.getUint8(this._offset);return this._offset+=1,t}_nextUint16(){const t=this._dataView.getUint16(this._offset,this._littleEndian);return this._offset+=2,t}_nextUint32(){const t=this._dataView.getUint32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint64(){const t=this._dataView.getUint32(this._offset,this._littleEndian)+2**32*this._dataView.getUint32(this._offset+4,this._littleEndian);return this._offset+=8,t}_nextInt32(){const t=this._dataView.getInt32(this._offset,this._littleEndian);return this._offset+=4,t}_skip(t){return this._offset+=t,this}_scan(t,e=0){const n=this._offset;let i=0;for(;this._dataView.getUint8(this._offset)!==e&&i<t;)i++,this._offset++;return i<t&&this._offset++,new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+n,i)}}const Ti=[171,75,84,88,32,50,48,187,13,10,26,10];function Ei(t){return"undefined"!=typeof TextDecoder?(new TextDecoder).decode(t):Buffer.from(t).toString("utf8")}let A,I,B;const g={env:{emscripten_notify_memory_growth:function(A){B=new Uint8Array(I.exports.memory.buffer)}}};class Q{init(){return A||(A="undefined"!=typeof fetch?fetch("data:application/wasm;base64,"+C).then((A=>A.arrayBuffer())).then((A=>WebAssembly.instantiate(A,g))).then(this._init):WebAssembly.instantiate(Buffer.from(C,"base64"),g).then(this._init),A)}_init(A){I=A.instance,g.env.emscripten_notify_memory_growth(0)}decode(A,g=0){if(!I)throw new Error("ZSTDDecoder: Await .init() before decoding.");const Q=A.byteLength,C=I.exports.malloc(Q);B.set(A,C),g=g||Number(I.exports.ZSTD_findDecompressedSize(C,Q));const E=I.exports.malloc(g),i=I.exports.ZSTD_decompress(E,g,C,Q),D=B.slice(E,E+i);return I.exports.free(C),I.exports.free(E),D}}const C="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IAMNACAEQQNxBEADQCACRQ0FIAAgAkF/aiICaiIDIAEgAmotAAA6AAAgA0EDcQ0ACwsgAkEDTQ0AA0AgACACQXxqIgJqIAEgAmooAgA2AgAgAkEDSw0ACwsgAkUNAgNAIAAgAkF/aiICaiABIAJqLQAAOgAAIAINAAsMAgsgAkEDTQ0AIAIhBANAIAMgASgCADYCACABQQRqIQEgA0EEaiEDIARBfGoiBEEDSw0ACyACQQNxIQILIAJFDQADQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAAL8wICAn8BfgJAIAJFDQAgACACaiIDQX9qIAE6AAAgACABOgAAIAJBA0kNACADQX5qIAE6AAAgACABOgABIANBfWogAToAACAAIAE6AAIgAkEHSQ0AIANBfGogAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa0iBUIghiAFhCEFIAMgBGohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkFgaiICQR9LDQALCyAACy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAIajYCACADCy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAFajYCACADCx8AIAAgASACKAIEEAg2AgAgARAEGiAAIAJBCGo2AgQLCAAgAGdBH3MLugUBDX8jAEEQayIKJAACfyAEQQNNBEAgCkEANgIMIApBDGogAyAEEAsaIAAgASACIApBDGpBBBAVIgBBbCAAEAMbIAAgACAESxsMAQsgAEEAIAEoAgBBAXRBAmoQECENQVQgAygAACIGQQ9xIgBBCksNABogAiAAQQVqNgIAIAMgBGoiAkF8aiEMIAJBeWohDiACQXtqIRAgAEEGaiELQQQh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ASIDNgLE4AEgACgCvOABIQQgACABNgK84AEgACABIAJqNgK44AEgACABIAQgA2tqNgLA4AELpgEBAX8gACAAKALs4QEQFjYCyOABIABCADcD+OABIABCADcDuOABIABBwOABakIANwMAIABBqNAAaiIBQYyAgOAANgIAIABBADYCmOIBIABCADcDiOEBIABCAzcDgOEBIABBrNABakHgEikCADcCACAAQbTQAWpB6BIoAgA2AgAgACABNgIMIAAgAEGYIGo2AgggACAAQaAwajYCBCAAIABBEGo2AgALYQEBf0G4fyEDAkAgAUEDSQ0AIAIgABAhIgFBA3YiADYCCCACIAFBAXE2AgQgAiABQQF2QQNxIgM2AgACQCADQX9qIgFBAksNAAJAIAFBAWsOAgEAAgtBbA8LIAAhAwsgAwsMACAAIAEgAkEAEC4LiAQCA38CfiADEBYhBCAAQQBBKBAQIQAgBCACSwRAIAQPCyABRQRAQX8PCwJAAkAgA0EBRg0AIAEoAAAiBkGo6r5pRg0AQXYhAyAGQXBxQdDUtMIBRw0BQQghAyACQQhJDQEgAEEAQSgQECEAIAEoAAQhASAAQQE2AhQgACABrTcDAEEADwsgASACIAMQLyIDIAJLDQAgACADNgIYQXIhAyABIARqIgVBf2otAAAiAkEIcQ0AIAJBIHEiBkUEQEFwIQMgBS0AACIFQacBSw0BIAVBB3GtQgEgBUEDdkEKaq2GIgdCA4h+IAd8IQggBEEBaiEECyACQQZ2IQMgAkECdiEFAkAgAkEDcUF/aiICQQJLBEBBACECDAELAkACQAJAIAJBAWsOAgECAAsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAVBAXEhBQJ+AkACQAJAIANBf2oiA0ECTQRAIANBAWsOAgIDAQtCfyAGRQ0DGiABIARqMQAADAMLIAEgBGovAACtQoACfAwCCyABIARqKAAArQwBCyABIARqKQAACyEHIAAgBTYCICAAIAI2AhwgACAHNwMAQQAhAyAAQQA2AhQgACAHIAggBhsiBzcDCCAAIAdCgIAIIAdCgIAIVBs+AhALIAMLWwEBf0G4fyEDIAIQFiICIAFNBH8gACACakF/ai0AACIAQQNxQQJ0QaAeaigC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C0Egak8NAQsgByAHKQNoNwMQIAcgBykDYDcDCCAEIA0gB0EIaiAHQdwAaiAPIA4gESAQEB4hCwwBCyACIARqIQggBCAKEAcgAkERTwRAIARBEGohAgNAIAIgCkEQaiIKEAcgAkEQaiICIAhJDQALCyAIIAlrIQIgByATNgJcIAkgCCAOa0sEQCAJIAggEWtLBEBBbCELDAILIBAgAiAOayICaiIKIANqIBBNBEAgCCAKIAMQDxoMAgsgCCAKQQAgAmsQDyEIIAcgAiADaiIDNgJkIAggAmshCCAOIQILIAlBEE8EQCADIAhqIQMDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALDAELAkAgCUEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgCUECdCIDQcAeaigCAGoiAhAXIAIgA0HgHmooAgBrIQIgBygCZCEDDAELIAggAhAMCyADQQlJDQAgAyAIaiEDIAhBCGoiCCACQQhqIgJrQQ9MBEADQCAIIAIQDCACQQhqIQIgCEEIaiIIIANJDQAMAgALAAsDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALCyAHQRhqEAQaIAsgDCALEAMiAhshDCAEIAQgC2ogAhshBCAFQX9qIgUNAAsgDBADDQFBbCEMIAdBGGoQBEECSQ0BQQAhCANAIAhBA0cEQCAAIAhBAnQiAmpBrNABaiACIAdqKAJENgIAIAhBAWohCAwBCwsgBygCXCEIC0G6fyEMIA8gCGsiACANIARrSw0AIAQEfyAEIAggABALIABqBUEACyABayEMCyAHQfAAaiQAIAwLkRcCFn8FfiMAQdABayIHJAAgByAAKALw4QEiCDYCvAEgASACaiESIAggACgCgOIBaiETAkACQCAFRQRAIAEhAwwBCyAAKALE4AEhESAAKALA4AEhFSAAKAK84AEhDyAAQQE2AozhAUEAIQgDQCAIQQNHBEAgByAIQQJ0IgJqIAAgAmpBrNABaigCADYCVCAIQQFqIQgMAQsLIAcgETYCZCAHIA82AmAgByABIA9rNgJoQWwhECAHQShqIAMgBBAGEAMNASAFQQQgBUEESBshFyAHQTxqIAdBKGogACgCABATIAdBxABqIAdBKGogACgCCBATIAdBzABqIAdB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IAdB0AFqJAAgEAslACAAQgA3AgAgAEEAOwEIIABBADoACyAAIAE2AgwgACACOgAKC7QFAQN/IwBBMGsiBCQAIABB/wFqIgVBfWohBgJAIAMvAQIEQCAEQRhqIAEgAhAGIgIQAw0BIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahASOgAAIAMgBEEIaiAEQRhqEBI6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0FIAEgBEEQaiAEQRhqEBI6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBSABIARBCGogBEEYahASOgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEjoAACABIAJqIABrIQIMAwsgAyAEQRBqIARBGGoQEjoAAiADIARBCGogBEEYahASOgADIANBBGohAwwAAAsACyAEQRhqIAEgAhAGIgIQAw0AIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahAROgAAIAMgBEEIaiAEQRhqEBE6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0EIAEgBEEQaiAEQRhqEBE6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBCABIARBCGogBEEYahAROgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEToAACABIAJqIABrIQIMAgsgAyAEQRBqIARBGGoQEToAAiADIARBCGogBEEYahAROgADIANBBGohAwwAAAsACyAEQTBqJAAgAgtpAQF/An8CQAJAIAJBB00NACABKAAAQbfIwuF+Rw0AIAAgASgABDYCmOIBQWIgAEEQaiABIAIQPiIDEAMNAhogAEKBgICAEDcDiOEBIAAgASADaiACIANrECoMAQsgACABIAIQKgtBAAsLrQMBBn8jAEGAAWsiAyQAQWIhCAJAIAJBCUkNACAAQZjQAGogAUEIaiIEIAJBeGogAEGY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wOABCwutAgIEfwF+IwBBQGoiBCQAAkACQCACQQhJDQAgASgAAEFwcUHQ1LTCAUcNACABIAIQIiEBIABCADcDCCAAQQA2AgQgACABNgIADAELIARBGGogASACEC0iAxADBEAgACADEBoMAQsgAwRAIABBuH8QGgwBCyACIAQoAjAiA2shAiABIANqIQMDQAJAIAAgAyACIARBCGoQLCIFEAMEfyAFBSACIAVBA2oiBU8NAUG4fwsQGgwCCyAGQQFqIQYgAiAFayECIAMgBWohAyAEKAIMRQ0ACyAEKAI4BEAgAkEDTQRAIABBuH8QGgwCCyADQQRqIQMLIAQoAighAiAEKQMYIQcgAEEANgIEIAAgAyABazYCACAAIAIgBmytIAcgB0J/URs3AwgLIARBQGskAAslAQF/IwBBEGsiAiQAIAIgACABEFEgAigCACEAIAJBEGokACAAC30BBH8jAEGQBGsiBCQAIARB/wE2AggCQCAEQRBqIARBCGogBEEMaiABIAIQFSIGEAMEQCAGIQUMAQtBVCEFIAQoAgwiB0EGSw0AIAMgBEEQaiAEKAIIIAcQQSIFEAMNACAAIAEgBmogAiAGayADEDwhBQsgBEGQBGokACAFC4cBAgJ/An5BABAWIQMCQANAIAEgA08EQAJAIAAoAABBcHFB0NS0wgFGBEAgACABECIiAhADRQ0BQn4PCyAAIAEQVSIEQn1WDQMgBCAFfCIFIARUIQJCfiEEIAINAyAAIAEQUiICEAMNAwsgASACayEBIAAgAmohAAwBCwtCfiAFIAEbIQQLIAQLPwIBfwF+IwBBMGsiAiQAAn5CfiACQQhqIAAgARAtDQAaQgAgAigCHEEBRg0AGiACKQMICyEDIAJBMGokACADC40BAQJ/IwBBMGsiASQAAkAgAEUNACAAKAKI4gENACABIABB/OEBaigCADYCKCABIAApAvThATcDICAAEDAgACgCqOIBIQIgASABKAIoNgIYIAEgASkDIDcDECACIAFBEGoQGyAAQQA2AqjiASABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALKgECfyMAQRBrIgAkACAAQQA2AgggAEIANwMAIAAQWCEBIABBEGokACABC4cBAQN/IwBBEGsiAiQAAkAgACgCAEUgACgCBEVzDQAgAiAAKAIINgIIIAIgACkCADcDAAJ/IAIoAgAiAQRAIAIoAghBqOMJIAERBQAMAQtBqOMJECgLIgFFDQAgASAAKQIANwL04QEgAUH84QFqIAAoAgg2AgAgARBZIAEhAwsgAkEQaiQAIAMLywEBAn8jAEEgayIBJAAgAEGBgIDAADYCtOIBIABBADYCiOIBIABBADYC7OEBIABCADcDkOIBIABBADYCpOMJIABBADYC3OIBIABCADcCzOIBIABBADYCvOIBIABBADYCxOABIABCADcCnOIBIABBpOIBakIANwIAIABBrOIBakEANgIAIAFCADcCECABQgA3AhggASABKQMYNwMIIAEgASkDEDcDACABKAIIQQh2QQFxIQIgAEEANgLg4gEgACACNgKM4gEgAUEgaiQAC3YBA38jAEEwayIBJAAgAARAIAEgAEHE0AFqIgIoAgA2AiggASAAKQK80AE3AyAgACgCACEDIAEgAigCADYCGCABIAApArzQATcDECADIAFBEGoQGyABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALzAEBAX8gACABKAK00AE2ApjiASAAIAEoAgQiAjYCwOABIAAgAjYCvOABIAAgAiABKAIIaiICNgK44AEgACACNgLE4AEgASgCuNABBEAgAEKBgICAEDcDiOEBIAAgAUGk0ABqNgIMIAAgAUGUIGo2AgggACABQZwwajYCBCAAIAFBDGo2AgAgAEGs0AFqIAFBqNABaigCADYCACAAQbDQAWogAUGs0AFqKAIANgIAIABBtNABaiABQbDQAWooAgA2AgAPCyAAQgA3A4jhAQs7ACACRQRAQbp/DwsgBEUEQEFsDwsgAiAEEGAEQCAAIAEgAiADIAQgBRBhDwsgACABIAIgAyAEIAUQZQtGAQF/IwBBEGsiBSQAIAVBCGogBBAOAn8gBS0ACQRAIAAgASACIAMgBBAyDAELIAAgASACIAMgBBA0CyEAIAVBEGokACAACzQAIAAgAyAEIAUQNiIFEAMEQCAFDwsgBSAESQR/IAEgAiADIAVqIAQgBWsgABA1BUG4fwsLRgEBfyMAQRBrIgUkACAFQQhqIAQQDgJ/IAUtAAkEQCAAIAEgAiADIAQQYgwBCyAAIAEgAiADIAQQNQshACAFQRBqJAAgAAtZAQF/QQ8hAiABIABJBEAgAUEE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",_taskCache=new WeakMap;
375
+ /**
376
+ * Loader for KTX 2.0 GPU Texture containers.
377
+ *
378
+ * KTX 2.0 is a container format for various GPU texture formats. The loader
379
+ * supports Basis Universal GPU textures, which can be quickly transcoded to
380
+ * a wide variety of GPU texture compression formats, as well as some
381
+ * uncompressed DataTexture and Data3DTexture formats.
382
+ *
383
+ * References:
384
+ * - KTX: http://github.khronos.org/KTX-Specification/
385
+ * - DFD: https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#basicdescriptor
386
+ */let _zstd,_activeLoaders=0;class KTX2Loader extends Loader{constructor(manager){super(manager),this.transcoderPath="",this.transcoderBinary=null,this.transcoderPending=null,this.workerPool=new WorkerPool,this.workerSourceURL="",this.workerConfig=null,"undefined"!=typeof MSC_TRANSCODER&&console.warn('THREE.KTX2Loader: Please update to latest "basis_transcoder". "msc_basis_transcoder" is no longer supported in three.js r125+.')}setTranscoderPath(path){return this.transcoderPath=path,this}setWorkerLimit(num){return this.workerPool.setWorkerLimit(num),this}async detectSupportAsync(renderer){return this.workerConfig={astcSupported:await renderer.hasFeatureAsync("texture-compression-astc"),etc1Supported:await renderer.hasFeatureAsync("texture-compression-etc1"),etc2Supported:await renderer.hasFeatureAsync("texture-compression-etc2"),dxtSupported:await renderer.hasFeatureAsync("texture-compression-bc"),bptcSupported:await renderer.hasFeatureAsync("texture-compression-bptc"),pvrtcSupported:await renderer.hasFeatureAsync("texture-compression-pvrtc")},this}detectSupport(renderer){return!0===renderer.isWebGPURenderer?this.workerConfig={astcSupported:renderer.hasFeature("texture-compression-astc"),etc1Supported:renderer.hasFeature("texture-compression-etc1"),etc2Supported:renderer.hasFeature("texture-compression-etc2"),dxtSupported:renderer.hasFeature("texture-compression-bc"),bptcSupported:renderer.hasFeature("texture-compression-bptc"),pvrtcSupported:renderer.hasFeature("texture-compression-pvrtc")}:this.workerConfig={astcSupported:renderer.extensions.has("WEBGL_compressed_texture_astc"),etc1Supported:renderer.extensions.has("WEBGL_compressed_texture_etc1"),etc2Supported:renderer.extensions.has("WEBGL_compressed_texture_etc"),dxtSupported:renderer.extensions.has("WEBGL_compressed_texture_s3tc"),bptcSupported:renderer.extensions.has("EXT_texture_compression_bptc"),pvrtcSupported:renderer.extensions.has("WEBGL_compressed_texture_pvrtc")||renderer.extensions.has("WEBKIT_WEBGL_compressed_texture_pvrtc")},this}init(){if(!this.transcoderPending){const jsLoader=new FileLoader(this.manager);jsLoader.setPath(this.transcoderPath),jsLoader.setWithCredentials(this.withCredentials);const jsContent=jsLoader.loadAsync("basis_transcoder.js"),binaryLoader=new FileLoader(this.manager);binaryLoader.setPath(this.transcoderPath),binaryLoader.setResponseType("arraybuffer"),binaryLoader.setWithCredentials(this.withCredentials);const binaryContent=binaryLoader.loadAsync("basis_transcoder.wasm");this.transcoderPending=Promise.all([jsContent,binaryContent]).then((([jsContent,binaryContent])=>{const fn=KTX2Loader.BasisWorker.toString(),body=["/* constants */","let _EngineFormat = "+JSON.stringify(KTX2Loader.EngineFormat),"let _TranscoderFormat = "+JSON.stringify(KTX2Loader.TranscoderFormat),"let _BasisFormat = "+JSON.stringify(KTX2Loader.BasisFormat),"/* basis_transcoder.js */",jsContent,"/* worker */",fn.substring(fn.indexOf("{")+1,fn.lastIndexOf("}"))].join("\n");this.workerSourceURL=URL.createObjectURL(new Blob([body])),this.transcoderBinary=binaryContent,this.workerPool.setWorkerCreator((()=>{const worker=new Worker(this.workerSourceURL),transcoderBinary=this.transcoderBinary.slice(0);return worker.postMessage({type:"init",config:this.workerConfig,transcoderBinary:transcoderBinary},[transcoderBinary]),worker}))})),_activeLoaders>0&&console.warn("THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues. Use a single KTX2Loader instance, or call .dispose() on old instances."),_activeLoaders++}return this.transcoderPending}load(url,onLoad,onProgress,onError){if(null===this.workerConfig)throw new Error("THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.");const loader=new FileLoader(this.manager);loader.setResponseType("arraybuffer"),loader.setWithCredentials(this.withCredentials),loader.load(url,(buffer=>{this.parse(buffer,onLoad,onError)}),onProgress,onError)}parse(buffer,onLoad,onError){if(null===this.workerConfig)throw new Error("THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.");if(_taskCache.has(buffer)){return _taskCache.get(buffer).promise.then(onLoad).catch(onError)}this._createTexture(buffer).then((texture=>onLoad?onLoad(texture):null)).catch(onError)}_createTextureFrom(transcodeResult,container){const{faces:faces,width:width,height:height,format:format,type:type,error:error,dfdFlags:dfdFlags}=transcodeResult;if("error"===type)return Promise.reject(error);let texture;if(6===container.faceCount)texture=new CompressedCubeTexture(faces,format,UnsignedByteType);else{const mipmaps=faces[0].mipmaps;texture=container.layerCount>1?new CompressedArrayTexture(mipmaps,width,height,container.layerCount,format,UnsignedByteType):new CompressedTexture(mipmaps,width,height,format,UnsignedByteType)}return texture.minFilter=1===faces[0].mipmaps.length?LinearFilter:LinearMipmapLinearFilter,texture.magFilter=LinearFilter,texture.generateMipmaps=!1,texture.needsUpdate=!0,texture.colorSpace=parseColorSpace(container),texture.premultiplyAlpha=!!(1&dfdFlags),texture}
387
+ /**
388
+ * @param {ArrayBuffer} buffer
389
+ * @param {object?} config
390
+ * @return {Promise<CompressedTexture|CompressedArrayTexture|DataTexture|Data3DTexture>}
391
+ */async _createTexture(buffer,config={}){const container=function Pi(t){const e=new Uint8Array(t.buffer,t.byteOffset,Ti.length);if(e[0]!==Ti[0]||e[1]!==Ti[1]||e[2]!==Ti[2]||e[3]!==Ti[3]||e[4]!==Ti[4]||e[5]!==Ti[5]||e[6]!==Ti[6]||e[7]!==Ti[7]||e[8]!==Ti[8]||e[9]!==Ti[9]||e[10]!==Ti[10]||e[11]!==Ti[11])throw new Error("Missing KTX 2.0 identifier.");const n=new Si,i=17*Uint32Array.BYTES_PER_ELEMENT,s=new Ii(t,Ti.length,i,!0);n.vkFormat=s._nextUint32(),n.typeSize=s._nextUint32(),n.pixelWidth=s._nextUint32(),n.pixelHeight=s._nextUint32(),n.pixelDepth=s._nextUint32(),n.layerCount=s._nextUint32(),n.faceCount=s._nextUint32();const a=s._nextUint32();n.supercompressionScheme=s._nextUint32();const r=s._nextUint32(),o=s._nextUint32(),l=s._nextUint32(),f=s._nextUint32(),U=s._nextUint64(),c=s._nextUint64(),h=new Ii(t,Ti.length+i,3*a*8,!0);for(let e=0;e<a;e++)n.levels.push({levelData:new Uint8Array(t.buffer,t.byteOffset+h._nextUint64(),h._nextUint64()),uncompressedByteLength:h._nextUint64()});const _=new Ii(t,r,o,!0),p={vendorId:_._skip(4)._nextUint16(),descriptorType:_._nextUint16(),versionNumber:_._nextUint16(),descriptorBlockSize:_._nextUint16(),colorModel:_._nextUint8(),colorPrimaries:_._nextUint8(),transferFunction:_._nextUint8(),flags:_._nextUint8(),texelBlockDimension:[_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8()],bytesPlane:[_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8()],samples:[]},g=(p.descriptorBlockSize/4-6)/4;for(let t=0;t<g;t++){const e={bitOffset:_._nextUint16(),bitLength:_._nextUint8(),channelType:_._nextUint8(),samplePosition:[_._nextUint8(),_._nextUint8(),_._nextUint8(),_._nextUint8()],sampleLower:-1/0,sampleUpper:1/0};64&e.channelType?(e.sampleLower=_._nextInt32(),e.sampleUpper=_._nextInt32()):(e.sampleLower=_._nextUint32(),e.sampleUpper=_._nextUint32()),p.samples[t]=e}n.dataFormatDescriptor.length=0,n.dataFormatDescriptor.push(p);const y=new Ii(t,l,f,!0);for(;y._offset<f;){const t=y._nextUint32(),e=y._scan(t),i=Ei(e),s=y._scan(t-e.byteLength);n.keyValue[i]=i.match(/^ktx/i)?Ei(s):s,y._offset%4&&y._skip(4-y._offset%4)}if(c<=0)return n;const x=new Ii(t,U,c,!0),u=x._nextUint16(),b=x._nextUint16(),d=x._nextUint32(),m=x._nextUint32(),w=x._nextUint32(),D=x._nextUint32(),B=[];for(let t=0;t<a;t++)B.push({imageFlags:x._nextUint32(),rgbSliceByteOffset:x._nextUint32(),rgbSliceByteLength:x._nextUint32(),alphaSliceByteOffset:x._nextUint32(),alphaSliceByteLength:x._nextUint32()});const L=U+x._offset,A=L+d,k=A+m,v=k+w,S=new Uint8Array(t.buffer,t.byteOffset+L,d),I=new Uint8Array(t.buffer,t.byteOffset+A,m),O=new Uint8Array(t.buffer,t.byteOffset+k,w),T=new Uint8Array(t.buffer,t.byteOffset+v,D);return n.globalData={endpointCount:u,selectorCount:b,imageDescs:B,endpointsData:S,selectorsData:I,tablesData:O,extendedData:T},n}(new Uint8Array(buffer));if(0!==container.vkFormat)return async function createRawTexture(container){const{vkFormat:vkFormat}=container;if(void 0===FORMAT_MAP[vkFormat])throw new Error("THREE.KTX2Loader: Unsupported vkFormat.");let zstd;2===container.supercompressionScheme&&(_zstd||(_zstd=new Promise((async resolve=>{const zstd=new Q;await zstd.init(),resolve(zstd)}))),zstd=await _zstd);const mipmaps=[];for(let levelIndex=0;levelIndex<container.levels.length;levelIndex++){const levelWidth=Math.max(1,container.pixelWidth>>levelIndex),levelHeight=Math.max(1,container.pixelHeight>>levelIndex),levelDepth=container.pixelDepth?Math.max(1,container.pixelDepth>>levelIndex):0,level=container.levels[levelIndex];let levelData,data;if(0===container.supercompressionScheme)levelData=level.levelData;else{if(2!==container.supercompressionScheme)throw new Error("THREE.KTX2Loader: Unsupported supercompressionScheme.");levelData=zstd.decode(level.levelData,level.uncompressedByteLength)}data=TYPE_MAP[vkFormat]===FloatType?new Float32Array(levelData.buffer,levelData.byteOffset,levelData.byteLength/Float32Array.BYTES_PER_ELEMENT):TYPE_MAP[vkFormat]===HalfFloatType?new Uint16Array(levelData.buffer,levelData.byteOffset,levelData.byteLength/Uint16Array.BYTES_PER_ELEMENT):levelData,mipmaps.push({data:data,width:levelWidth,height:levelHeight,depth:levelDepth})}let texture;if(UNCOMPRESSED_FORMATS.has(FORMAT_MAP[vkFormat]))texture=0===container.pixelDepth?new DataTexture(mipmaps[0].data,container.pixelWidth,container.pixelHeight):new Data3DTexture(mipmaps[0].data,container.pixelWidth,container.pixelHeight,container.pixelDepth);else{if(container.pixelDepth>0)throw new Error("THREE.KTX2Loader: Unsupported pixelDepth.");texture=new CompressedTexture(mipmaps,container.pixelWidth,container.pixelHeight)}return texture.mipmaps=mipmaps,texture.type=TYPE_MAP[vkFormat],texture.format=FORMAT_MAP[vkFormat],texture.colorSpace=parseColorSpace(container),texture.needsUpdate=!0,Promise.resolve(texture)}(container);const taskConfig=config,texturePending=this.init().then((()=>this.workerPool.postMessage({type:"transcode",buffer:buffer,taskConfig:taskConfig},[buffer]))).then((e=>this._createTextureFrom(e.data,container)));return _taskCache.set(buffer,{promise:texturePending}),texturePending}dispose(){return this.workerPool.dispose(),this.workerSourceURL&&URL.revokeObjectURL(this.workerSourceURL),_activeLoaders--,this}}KTX2Loader.BasisFormat={ETC1S:0,UASTC_4x4:1},KTX2Loader.TranscoderFormat={ETC1:0,ETC2:1,BC1:2,BC3:3,BC4:4,BC5:5,BC7_M6_OPAQUE_ONLY:6,BC7_M5:7,PVRTC1_4_RGB:8,PVRTC1_4_RGBA:9,ASTC_4x4:10,ATC_RGB:11,ATC_RGBA_INTERPOLATED_ALPHA:12,RGBA32:13,RGB565:14,BGR565:15,RGBA4444:16},KTX2Loader.EngineFormat={RGBAFormat:RGBAFormat,RGBA_ASTC_4x4_Format:RGBA_ASTC_4x4_Format,RGBA_BPTC_Format:RGBA_BPTC_Format,RGBA_ETC2_EAC_Format:RGBA_ETC2_EAC_Format,RGBA_PVRTC_4BPPV1_Format:RGBA_PVRTC_4BPPV1_Format,RGBA_S3TC_DXT5_Format:RGBA_S3TC_DXT5_Format,RGB_ETC1_Format:RGB_ETC1_Format,RGB_ETC2_Format:RGB_ETC2_Format,RGB_PVRTC_4BPPV1_Format:RGB_PVRTC_4BPPV1_Format,RGBA_S3TC_DXT1_Format:RGBA_S3TC_DXT1_Format},KTX2Loader.BasisWorker=function(){let config,transcoderPending,BasisModule;const EngineFormat=_EngineFormat,TranscoderFormat=_TranscoderFormat,BasisFormat=_BasisFormat;self.addEventListener("message",(function(e){const message=e.data;switch(message.type){case"init":config=message.config,function init(wasmBinary){transcoderPending=new Promise((resolve=>{BasisModule={wasmBinary:wasmBinary,onRuntimeInitialized:resolve},BASIS(BasisModule)})).then((()=>{BasisModule.initializeBasis(),void 0===BasisModule.KTX2File&&console.warn("THREE.KTX2Loader: Please update Basis Universal transcoder.")}))}(message.transcoderBinary);break;case"transcode":transcoderPending.then((()=>{try{const{faces:faces,buffers:buffers,width:width,height:height,hasAlpha:hasAlpha,format:format,dfdFlags:dfdFlags}=function transcode(buffer){const ktx2File=new BasisModule.KTX2File(new Uint8Array(buffer));function cleanup(){ktx2File.close(),ktx2File.delete()}if(!ktx2File.isValid())throw cleanup(),new Error("THREE.KTX2Loader:\tInvalid or unsupported .ktx2 file");const basisFormat=ktx2File.isUASTC()?BasisFormat.UASTC_4x4:BasisFormat.ETC1S,width=ktx2File.getWidth(),height=ktx2File.getHeight(),layerCount=ktx2File.getLayers()||1,levelCount=ktx2File.getLevels(),faceCount=ktx2File.getFaces(),hasAlpha=ktx2File.getHasAlpha(),dfdFlags=ktx2File.getDFDFlags(),{transcoderFormat:transcoderFormat,engineFormat:engineFormat}=function getTranscoderFormat(basisFormat,width,height,hasAlpha){let transcoderFormat,engineFormat;const options=basisFormat===BasisFormat.ETC1S?ETC1S_OPTIONS:UASTC_OPTIONS;for(let i=0;i<options.length;i++){const opt=options[i];if(config[opt.if]&&(opt.basisFormat.includes(basisFormat)&&!(hasAlpha&&opt.transcoderFormat.length<2)&&(!opt.needsPowerOfTwo||isPowerOfTwo(width)&&isPowerOfTwo(height))))return transcoderFormat=opt.transcoderFormat[hasAlpha?1:0],engineFormat=opt.engineFormat[hasAlpha?1:0],{transcoderFormat:transcoderFormat,engineFormat:engineFormat}}return console.warn("THREE.KTX2Loader: No suitable compressed texture format found. Decoding to RGBA32."),transcoderFormat=TranscoderFormat.RGBA32,engineFormat=EngineFormat.RGBAFormat,{transcoderFormat:transcoderFormat,engineFormat:engineFormat}}(basisFormat,width,height,hasAlpha);if(!width||!height||!levelCount)throw cleanup(),new Error("THREE.KTX2Loader:\tInvalid texture");if(!ktx2File.startTranscoding())throw cleanup(),new Error("THREE.KTX2Loader: .startTranscoding failed");const faces=[],buffers=[];for(let face=0;face<faceCount;face++){const mipmaps=[];for(let mip=0;mip<levelCount;mip++){const layerMips=[];let mipWidth,mipHeight;for(let layer=0;layer<layerCount;layer++){const levelInfo=ktx2File.getImageLevelInfo(mip,layer,face);0!==face||0!==mip||0!==layer||levelInfo.origWidth%4==0&&levelInfo.origHeight%4==0||console.warn("THREE.KTX2Loader: ETC1S and UASTC textures should use multiple-of-four dimensions."),levelCount>1?(mipWidth=levelInfo.origWidth,mipHeight=levelInfo.origHeight):(mipWidth=levelInfo.width,mipHeight=levelInfo.height);const dst=new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip,layer,0,transcoderFormat));if(!ktx2File.transcodeImage(dst,mip,layer,face,transcoderFormat,0,-1,-1))throw cleanup(),new Error("THREE.KTX2Loader: .transcodeImage failed.");layerMips.push(dst)}const mipData=concat(layerMips);mipmaps.push({data:mipData,width:mipWidth,height:mipHeight}),buffers.push(mipData.buffer)}faces.push({mipmaps:mipmaps,width:width,height:height,format:engineFormat})}return cleanup(),{faces:faces,buffers:buffers,width:width,height:height,hasAlpha:hasAlpha,format:engineFormat,dfdFlags:dfdFlags}}(message.buffer);self.postMessage({type:"transcode",id:message.id,faces:faces,width:width,height:height,hasAlpha:hasAlpha,format:format,dfdFlags:dfdFlags},buffers)}catch(error){console.error(error),self.postMessage({type:"error",id:message.id,error:error.message})}}))}}));const FORMAT_OPTIONS=[{if:"astcSupported",basisFormat:[BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.ASTC_4x4,TranscoderFormat.ASTC_4x4],engineFormat:[EngineFormat.RGBA_ASTC_4x4_Format,EngineFormat.RGBA_ASTC_4x4_Format],priorityETC1S:1/0,priorityUASTC:1,needsPowerOfTwo:!1},{if:"bptcSupported",basisFormat:[BasisFormat.ETC1S,BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.BC7_M5,TranscoderFormat.BC7_M5],engineFormat:[EngineFormat.RGBA_BPTC_Format,EngineFormat.RGBA_BPTC_Format],priorityETC1S:3,priorityUASTC:2,needsPowerOfTwo:!1},{if:"dxtSupported",basisFormat:[BasisFormat.ETC1S,BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.BC1,TranscoderFormat.BC3],engineFormat:[EngineFormat.RGBA_S3TC_DXT1_Format,EngineFormat.RGBA_S3TC_DXT5_Format],priorityETC1S:4,priorityUASTC:5,needsPowerOfTwo:!1},{if:"etc2Supported",basisFormat:[BasisFormat.ETC1S,BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.ETC1,TranscoderFormat.ETC2],engineFormat:[EngineFormat.RGB_ETC2_Format,EngineFormat.RGBA_ETC2_EAC_Format],priorityETC1S:1,priorityUASTC:3,needsPowerOfTwo:!1},{if:"etc1Supported",basisFormat:[BasisFormat.ETC1S,BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.ETC1],engineFormat:[EngineFormat.RGB_ETC1_Format],priorityETC1S:2,priorityUASTC:4,needsPowerOfTwo:!1},{if:"pvrtcSupported",basisFormat:[BasisFormat.ETC1S,BasisFormat.UASTC_4x4],transcoderFormat:[TranscoderFormat.PVRTC1_4_RGB,TranscoderFormat.PVRTC1_4_RGBA],engineFormat:[EngineFormat.RGB_PVRTC_4BPPV1_Format,EngineFormat.RGBA_PVRTC_4BPPV1_Format],priorityETC1S:5,priorityUASTC:6,needsPowerOfTwo:!0}],ETC1S_OPTIONS=FORMAT_OPTIONS.sort((function(a,b){return a.priorityETC1S-b.priorityETC1S})),UASTC_OPTIONS=FORMAT_OPTIONS.sort((function(a,b){return a.priorityUASTC-b.priorityUASTC}));function isPowerOfTwo(value){return value<=2||!(value&value-1)&&0!==value}
392
+ /** Concatenates N byte arrays. */function concat(arrays){if(1===arrays.length)return arrays[0];let totalByteLength=0;for(let i=0;i<arrays.length;i++){totalByteLength+=arrays[i].byteLength}const result=new Uint8Array(totalByteLength);let byteOffset=0;for(let i=0;i<arrays.length;i++){const array=arrays[i];result.set(array,byteOffset),byteOffset+=array.byteLength}return result}};const UNCOMPRESSED_FORMATS=new Set([RGBAFormat,RGFormat,RedFormat]),FORMAT_MAP={[Ae]:RGBAFormat,[pe]:RGBAFormat,[Ot]:RGBAFormat,[Ft]:RGBAFormat,[de]:RGFormat,[se]:RGFormat,[yt]:RGFormat,[dt]:RGFormat,[xe]:RedFormat,[$t]:RedFormat,[gt]:RedFormat,[ct]:RedFormat,[In]:RGBA_ASTC_6x6_Format,[Sn]:RGBA_ASTC_6x6_Format},TYPE_MAP={[Ae]:FloatType,[pe]:HalfFloatType,[Ot]:UnsignedByteType,[Ft]:UnsignedByteType,[de]:FloatType,[se]:HalfFloatType,[yt]:UnsignedByteType,[dt]:UnsignedByteType,[xe]:FloatType,[$t]:HalfFloatType,[gt]:UnsignedByteType,[ct]:UnsignedByteType,[In]:UnsignedByteType,[Sn]:UnsignedByteType};function parseColorSpace(container){const dfd=container.dataFormatDescriptor[0];return 1===dfd.colorPrimaries?2===dfd.transferFunction?SRGBColorSpace:LinearSRGBColorSpace:10===dfd.colorPrimaries?2===dfd.transferFunction?DisplayP3ColorSpace:LinearDisplayP3ColorSpace:(0===dfd.colorPrimaries||console.warn(`THREE.KTX2Loader: Unsupported color primaries, "${dfd.colorPrimaries}"`),NoColorSpace)}var MeshoptDecoder=function(){var detector=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]),wasmpack=new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]);if("object"!=typeof WebAssembly)return{supported:!1};var instance,wasm=WebAssembly.validate(detector)?"b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;t9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;h8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincehHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAci6hHalhOaAcefgohAaoclSmdxekkcbhlaHceGmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;uzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:EPliuo97eue978Jjjjjbca9Rhidndnadcl9hmbdnaec98GglTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaiaeciGgvcdtgdVcbczad9R;8kbaiabalcdtfglad;8qbbdnavTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkalaiad;8qbbskdnaec98GgxTmbcbhvabhdinadczfglalpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgvax6mbkkaxae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabaxcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbhdabheinaeaepbbbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepkbbaeczfheadclfgdav6mbkkdnaval9pmbaialciGgdcdtgeVcbc;abae9R;8kbaiabavcdtfgvae;8qbbdnadTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepklbkavaiae;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb":"b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq:P8Yqdbk;3sezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfgocl4cifcd4hxdndndndnaoc9WGgmTmbcbhPcehsawcjdfhzalhHinaraH9Rax6midnaraHaxfgl9RcK6mbczhoinawcj;cbfaogifgoc9WfhOdndndndndnaHaic9WfgAco4fRbbaAci4coG4ciGPlbedibkaO9cb83ibaOcwf9cb83ibxikaOalRblalRbbgAco4gCaCciSgCE86bbaocGfalclfaCfgORbbaAcl4ciGgCaCciSgCE86bbaocVfaOaCfgORbbaAcd4ciGgCaCciSgCE86bbaoc7faOaCfgORbbaAciGgAaAciSgAE86bbaoctfaOaAfgARbbalRbegOco4gCaCciSgCE86bbaoc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc93faAaCfgARbbaOciGgOaOciSgOE86bbaoc94faAaOfgARbbalRbdgOco4gCaCciSgCE86bbaoc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc97faAaCfgARbbaOciGgOaOciSgOE86bbaoc98faAaOfgORbbalRbiglco4gAaAciSgAE86bbaoc99faOaAfgORbbalcl4ciGgAaAciSgAE86bbaoc9:faOaAfgORbbalcd4ciGgAaAciSgAE86bbaocufaOaAfgoRbbalciGglalciSglE86bbaoalfhlxdkaOalRbwalRbbgAcl4gCaCcsSgCE86bbaocGfalcwfaCfgORbbaAcsGgAaAcsSgAE86bbaocVfaOaAfgORbbalRbegAcl4gCaCcsSgCE86bbaoc7faOaCfgORbbaAcsGgAaAcsSgAE86bbaoctfaOaAfgORbbalRbdgAcl4gCaCcsSgCE86bbaoc91faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc4faOaAfgORbbalRbigAcl4gCaCcsSgCE86bbaoc93faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc94faOaAfgORbbalRblgAcl4gCaCcsSgCE86bbaoc95faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc96faOaAfgORbbalRbvgAcl4gCaCcsSgCE86bbaoc97faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc98faOaAfgORbbalRbogAcl4gCaCcsSgCE86bbaoc99faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc9:faOaAfgORbbalRbrglcl4gAaAcsSgAE86bbaocufaOaAfgoRbbalcsGglalcsSglE86bbaoalfhlxekaOal8Pbb83bbaOcwfalcwf8Pbb83bbalczfhlkdnaiam9pmbaiczfhoaral9RcL0mekkaiam6mialTmidnakTmbawaPfRbbhOcbhoazhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkkazcefhzaPcefgPad6hsalhHaPad9hmexvkkcbhlasceGmdxikalaxad2fhCdnakTmbcbhHcehsawcjdfhminaral9Rax6mialTmdalaxfhlawaHfRbbhOcbhoamhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkamcefhmaHcefgHad6hsaHad9hmbkaChlxikcbhocehsinaral9Rax6mdalTmealaxfhlaocefgoad6hsadao9hmbkaChlxdkcbhlasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqalmbkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;yzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabavcefciGaiVcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabavcdfciGaiVcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabavcufciGaiVcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabavciGaiVcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2geTmbinababydbgdcwtcw91:Yadce91cjjj;8ifcjjj98G::NUdbabclfhbaecufgembkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaiczfhiaeczfheadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb",ready=WebAssembly.instantiate(unpack(wasm),{}).then((function(result){(instance=result.instance).exports.__wasm_call_ctors()}));function unpack(data){for(var result=new Uint8Array(data.length),i=0;i<data.length;++i){var ch=data.charCodeAt(i);result[i]=ch>96?ch-97:ch>64?ch-39:ch+4}var write=0;for(i=0;i<data.length;++i)result[write++]=result[i]<60?wasmpack[result[i]]:64*(result[i]-60)+result[++i];return result.buffer.slice(0,write)}function decode(fun,target,count,size,source,filter){var sbrk=instance.exports.sbrk,count4=count+3&-4,tp=sbrk(count4*size),sp=sbrk(source.length),heap=new Uint8Array(instance.exports.memory.buffer);heap.set(source,sp);var res=fun(tp,count,size,sp,source.length);if(0==res&&filter&&filter(tp,count4,size),target.set(heap.subarray(tp,tp+count*size)),sbrk(tp-sbrk(0)),0!=res)throw new Error("Malformed buffer data: "+res)}var filters={NONE:"",OCTAHEDRAL:"meshopt_decodeFilterOct",QUATERNION:"meshopt_decodeFilterQuat",EXPONENTIAL:"meshopt_decodeFilterExp"},decoders={ATTRIBUTES:"meshopt_decodeVertexBuffer",TRIANGLES:"meshopt_decodeIndexBuffer",INDICES:"meshopt_decodeIndexSequence"},workers=[],requestId=0;function createWorker(url){var worker={object:new Worker(url),pending:0,requests:{}};return worker.object.onmessage=function(event){var data=event.data;worker.pending-=data.count,worker.requests[data.id][data.action](data.value),delete worker.requests[data.id]},worker}function initWorkers(count){for(var source="var instance; var ready = WebAssembly.instantiate(new Uint8Array(["+new Uint8Array(unpack(wasm))+"]), {}).then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); });self.onmessage = workerProcess;"+decode.toString()+workerProcess.toString(),blob=new Blob([source],{type:"text/javascript"}),url=URL.createObjectURL(blob),i=0;i<count;++i)workers[i]=createWorker(url);URL.revokeObjectURL(url)}function workerProcess(event){ready.then((function(){var data=event.data;try{var target=new Uint8Array(data.count*data.size);decode(instance.exports[data.mode],target,data.count,data.size,data.source,instance.exports[data.filter]),self.postMessage({id:data.id,count:data.count,action:"resolve",value:target},[target.buffer])}catch(error){self.postMessage({id:data.id,count:data.count,action:"reject",value:error})}}))}return{ready:ready,supported:!0,useWorkers:function(count){initWorkers(count)},decodeVertexBuffer:function(target,count,size,source,filter){decode(instance.exports.meshopt_decodeVertexBuffer,target,count,size,source,instance.exports[filters[filter]])},decodeIndexBuffer:function(target,count,size,source){decode(instance.exports.meshopt_decodeIndexBuffer,target,count,size,source)},decodeIndexSequence:function(target,count,size,source){decode(instance.exports.meshopt_decodeIndexSequence,target,count,size,source)},decodeGltfBuffer:function(target,count,size,source,mode,filter){decode(instance.exports[decoders[mode]],target,count,size,source,instance.exports[filters[filter]])},decodeGltfBufferAsync:function(count,size,source,mode,filter){return workers.length>0?function decodeWorker(count,size,source,mode,filter){for(var worker=workers[0],i=1;i<workers.length;++i)workers[i].pending<worker.pending&&(worker=workers[i]);return new Promise((function(resolve,reject){var data=new Uint8Array(source),id=requestId++;worker.pending+=count,worker.requests[id]={resolve:resolve,reject:reject},worker.object.postMessage({id:id,count:count,size:size,source:data,mode:mode,filter:filter},[data.buffer])}))}(count,size,source,decoders[mode],filters[filter]):ready.then((function(){var target=new Uint8Array(count*size);return decode(instance.exports[decoders[mode]],target,count,size,source,instance.exports[filters[filter]]),target}))}}}();
393
+ /**
394
+ * Autodesk 3DS three.js file loader, based on lib3ds.
395
+ *
396
+ * Loads geometry with uv and materials basic properties with texture support.
397
+ *
398
+ * @class TDSLoader
399
+ * @constructor
400
+ */class TDSLoader extends Loader{constructor(manager){super(manager),this.debug=!1,this.group=null,this.materials=[],this.meshes=[]}
401
+ /**
402
+ * Load 3ds file from url.
403
+ *
404
+ * @method load
405
+ * @param {[type]} url URL for the file.
406
+ * @param {Function} onLoad onLoad callback, receives group Object3D as argument.
407
+ * @param {Function} onProgress onProgress callback.
408
+ * @param {Function} onError onError callback.
409
+ */load(url,onLoad,onProgress,onError){const scope=this,path=""===this.path?LoaderUtils.extractUrlBase(url):this.path,loader=new FileLoader(this.manager);loader.setPath(this.path),loader.setResponseType("arraybuffer"),loader.setRequestHeader(this.requestHeader),loader.setWithCredentials(this.withCredentials),loader.load(url,(function(data){try{onLoad(scope.parse(data,path))}catch(e){onError?onError(e):console.error(e),scope.manager.itemError(url)}}),onProgress,onError)}
410
+ /**
411
+ * Parse arraybuffer data and load 3ds file.
412
+ *
413
+ * @method parse
414
+ * @param {ArrayBuffer} arraybuffer Arraybuffer data to be loaded.
415
+ * @param {String} path Path for external resources.
416
+ * @return {Group} Group loaded from 3ds file.
417
+ */parse(arraybuffer,path){this.group=new Group,this.materials=[],this.meshes=[],this.readFile(arraybuffer,path);for(let i=0;i<this.meshes.length;i++)this.group.add(this.meshes[i]);return this.group}
418
+ /**
419
+ * Decode file content to read 3ds data.
420
+ *
421
+ * @method readFile
422
+ * @param {ArrayBuffer} arraybuffer Arraybuffer data to be loaded.
423
+ * @param {String} path Path for external resources.
424
+ */readFile(arraybuffer,path){const data=new DataView(arraybuffer),chunk=new Chunk(data,0,this.debugMessage);if(chunk.id===MLIBMAGIC||chunk.id===CMAGIC||chunk.id===M3DMAGIC){let next=chunk.readChunk();for(;next;){if(next.id===M3D_VERSION){const version=next.readDWord();this.debugMessage("3DS file version: "+version)}else next.id===MDATA?this.readMeshData(next,path):this.debugMessage("Unknown main chunk: "+next.hexId);next=chunk.readChunk()}}this.debugMessage("Parsed "+this.meshes.length+" meshes")}
425
+ /**
426
+ * Read mesh data chunk.
427
+ *
428
+ * @method readMeshData
429
+ * @param {Chunk} chunk to read mesh from
430
+ * @param {String} path Path for external resources.
431
+ */readMeshData(chunk,path){let next=chunk.readChunk();for(;next;){if(next.id===MESH_VERSION){const version=+next.readDWord();this.debugMessage("Mesh Version: "+version)}else if(next.id===MASTER_SCALE){const scale=next.readFloat();this.debugMessage("Master scale: "+scale),this.group.scale.set(scale,scale,scale)}else next.id===NAMED_OBJECT?(this.debugMessage("Named Object"),this.readNamedObject(next)):next.id===MAT_ENTRY?(this.debugMessage("Material"),this.readMaterialEntry(next,path)):this.debugMessage("Unknown MDATA chunk: "+next.hexId);next=chunk.readChunk()}}
432
+ /**
433
+ * Read named object chunk.
434
+ *
435
+ * @method readNamedObject
436
+ * @param {Chunk} chunk Chunk in use.
437
+ */readNamedObject(chunk){const name=chunk.readString();let next=chunk.readChunk();for(;next;){if(next.id===N_TRI_OBJECT){const mesh=this.readMesh(next);mesh.name=name,this.meshes.push(mesh)}else this.debugMessage("Unknown named object chunk: "+next.hexId);next=chunk.readChunk()}}
438
+ /**
439
+ * Read material data chunk and add it to the material list.
440
+ *
441
+ * @method readMaterialEntry
442
+ * @param {Chunk} chunk Chunk in use.
443
+ * @param {String} path Path for external resources.
444
+ */readMaterialEntry(chunk,path){let next=chunk.readChunk();const material=new MeshPhongMaterial;for(;next;){if(next.id===MAT_NAME)material.name=next.readString(),this.debugMessage(" Name: "+material.name);else if(next.id===MAT_WIRE)this.debugMessage(" Wireframe"),material.wireframe=!0;else if(next.id===MAT_WIRE_SIZE){const value=next.readByte();material.wireframeLinewidth=value,this.debugMessage(" Wireframe Thickness: "+value)}else if(next.id===MAT_TWO_SIDE)material.side=DoubleSide,this.debugMessage(" DoubleSided");else if(next.id===MAT_ADDITIVE)this.debugMessage(" Additive Blending"),material.blending=AdditiveBlending;else if(next.id===MAT_DIFFUSE)this.debugMessage(" Diffuse Color"),material.color=this.readColor(next);else if(next.id===MAT_SPECULAR)this.debugMessage(" Specular Color"),material.specular=this.readColor(next);else if(next.id===MAT_AMBIENT)this.debugMessage(" Ambient color"),material.color=this.readColor(next);else if(next.id===MAT_SHININESS){const shininess=this.readPercentage(next);material.shininess=100*shininess,this.debugMessage(" Shininess : "+shininess)}else if(next.id===MAT_TRANSPARENCY){const transparency=this.readPercentage(next);material.opacity=1-transparency,this.debugMessage(" Transparency : "+transparency),material.transparent=material.opacity<1}else next.id===MAT_TEXMAP?(this.debugMessage(" ColorMap"),material.map=this.readMap(next,path)):next.id===MAT_BUMPMAP?(this.debugMessage(" BumpMap"),material.bumpMap=this.readMap(next,path)):next.id===MAT_OPACMAP?(this.debugMessage(" OpacityMap"),material.alphaMap=this.readMap(next,path)):next.id===MAT_SPECMAP?(this.debugMessage(" SpecularMap"),material.specularMap=this.readMap(next,path)):this.debugMessage(" Unknown material chunk: "+next.hexId);next=chunk.readChunk()}this.materials[material.name]=material}
445
+ /**
446
+ * Read mesh data chunk.
447
+ *
448
+ * @method readMesh
449
+ * @param {Chunk} chunk Chunk in use.
450
+ * @return {Mesh} The parsed mesh.
451
+ */readMesh(chunk){let next=chunk.readChunk();const geometry=new BufferGeometry,material=new MeshPhongMaterial,mesh=new Mesh(geometry,material);for(mesh.name="mesh";next;){if(next.id===POINT_ARRAY){const points=next.readWord();this.debugMessage(" Vertex: "+points);const vertices=[];for(let i=0;i<points;i++)vertices.push(next.readFloat()),vertices.push(next.readFloat()),vertices.push(next.readFloat());geometry.setAttribute("position",new Float32BufferAttribute(vertices,3))}else if(next.id===FACE_ARRAY)this.readFaceArray(next,mesh);else if(next.id===TEX_VERTS){const texels=next.readWord();this.debugMessage(" UV: "+texels);const uvs=[];for(let i=0;i<texels;i++)uvs.push(next.readFloat()),uvs.push(next.readFloat());geometry.setAttribute("uv",new Float32BufferAttribute(uvs,2))}else if(next.id===MESH_MATRIX){this.debugMessage(" Tranformation Matrix (TODO)");const values=[];for(let i=0;i<12;i++)values[i]=next.readFloat();const matrix=new Matrix4;matrix.elements[0]=values[0],matrix.elements[1]=values[6],matrix.elements[2]=values[3],matrix.elements[3]=values[9],matrix.elements[4]=values[2],matrix.elements[5]=values[8],matrix.elements[6]=values[5],matrix.elements[7]=values[11],matrix.elements[8]=values[1],matrix.elements[9]=values[7],matrix.elements[10]=values[4],matrix.elements[11]=values[10],matrix.elements[12]=0,matrix.elements[13]=0,matrix.elements[14]=0,matrix.elements[15]=1,matrix.transpose();const inverse=new Matrix4;inverse.copy(matrix).invert(),geometry.applyMatrix4(inverse),matrix.decompose(mesh.position,mesh.quaternion,mesh.scale)}else this.debugMessage(" Unknown mesh chunk: "+next.hexId);next=chunk.readChunk()}return geometry.computeVertexNormals(),mesh}
452
+ /**
453
+ * Read face array data chunk.
454
+ *
455
+ * @method readFaceArray
456
+ * @param {Chunk} chunk Chunk in use.
457
+ * @param {Mesh} mesh Mesh to be filled with the data read.
458
+ */readFaceArray(chunk,mesh){const faces=chunk.readWord();this.debugMessage(" Faces: "+faces);const index=[];for(let i=0;i<faces;++i)index.push(chunk.readWord(),chunk.readWord(),chunk.readWord()),chunk.readWord();mesh.geometry.setIndex(index);let materialIndex=0,start=0;for(;!chunk.endOfChunk;){const subchunk=chunk.readChunk();if(subchunk.id===MSH_MAT_GROUP){this.debugMessage(" Material Group");const group=this.readMaterialGroup(subchunk),count=3*group.index.length;mesh.geometry.addGroup(start,count,materialIndex),start+=count,materialIndex++;const material=this.materials[group.name];!1===Array.isArray(mesh.material)&&(mesh.material=[]),void 0!==material&&mesh.material.push(material)}else this.debugMessage(" Unknown face array chunk: "+subchunk.hexId)}1===mesh.material.length&&(mesh.material=mesh.material[0])}
459
+ /**
460
+ * Read texture map data chunk.
461
+ *
462
+ * @method readMap
463
+ * @param {Chunk} chunk Chunk in use.
464
+ * @param {String} path Path for external resources.
465
+ * @return {Texture} Texture read from this data chunk.
466
+ */readMap(chunk,path){let next=chunk.readChunk(),texture={};const loader=new TextureLoader(this.manager);for(loader.setPath(this.resourcePath||path).setCrossOrigin(this.crossOrigin);next;){if(next.id===MAT_MAPNAME){const name=next.readString();texture=loader.load(name),texture.userData.name=name.split(".").slice(0,-1).join("."),this.debugMessage(" File: "+path+name)}else next.id===MAT_MAP_UOFFSET?(texture.offset.x=next.readFloat(),this.debugMessage(" OffsetX: "+texture.offset.x)):next.id===MAT_MAP_VOFFSET?(texture.offset.y=next.readFloat(),this.debugMessage(" OffsetY: "+texture.offset.y)):next.id===MAT_MAP_USCALE?(texture.repeat.x=next.readFloat(),this.debugMessage(" RepeatX: "+texture.repeat.x)):next.id===MAT_MAP_VSCALE?(texture.repeat.y=next.readFloat(),this.debugMessage(" RepeatY: "+texture.repeat.y)):this.debugMessage(" Unknown map chunk: "+next.hexId);next=chunk.readChunk()}return texture}
467
+ /**
468
+ * Read material group data chunk.
469
+ *
470
+ * @method readMaterialGroup
471
+ * @param {Chunk} chunk Chunk in use.
472
+ * @return {Object} Object with name and index of the object.
473
+ */readMaterialGroup(chunk){const name=chunk.readString(),numFaces=chunk.readWord();this.debugMessage(" Name: "+name),this.debugMessage(" Faces: "+numFaces);const index=[];for(let i=0;i<numFaces;++i)index.push(chunk.readWord());return{name:name,index:index}}
474
+ /**
475
+ * Read a color value.
476
+ *
477
+ * @method readColor
478
+ * @param {Chunk} chunk Chunk.
479
+ * @return {Color} Color value read..
480
+ */readColor(chunk){const subChunk=chunk.readChunk(),color=new Color;if(subChunk.id===COLOR_24||subChunk.id===LIN_COLOR_24){const r=subChunk.readByte(),g=subChunk.readByte(),b=subChunk.readByte();color.setRGB(r/255,g/255,b/255),this.debugMessage(" Color: "+color.r+", "+color.g+", "+color.b)}else if(subChunk.id===COLOR_F||subChunk.id===LIN_COLOR_F){const r=subChunk.readFloat(),g=subChunk.readFloat(),b=subChunk.readFloat();color.setRGB(r,g,b),this.debugMessage(" Color: "+color.r+", "+color.g+", "+color.b)}else this.debugMessage(" Unknown color chunk: "+subChunk.hexId);return color}
481
+ /**
482
+ * Read percentage value.
483
+ *
484
+ * @method readPercentage
485
+ * @param {Chunk} chunk Chunk to read data from.
486
+ * @return {Number} Data read from the dataview.
487
+ */readPercentage(chunk){const subChunk=chunk.readChunk();switch(subChunk.id){case INT_PERCENTAGE:return subChunk.readShort()/100;case FLOAT_PERCENTAGE:return subChunk.readFloat();default:return this.debugMessage(" Unknown percentage chunk: "+subChunk.hexId),0}}
488
+ /**
489
+ * Print debug message to the console.
490
+ *
491
+ * Is controlled by a flag to show or hide debug messages.
492
+ *
493
+ * @method debugMessage
494
+ * @param {Object} message Debug message to print to the console.
495
+ */debugMessage(message){this.debug&&console.log(message)}}
496
+ /** Read data/sub-chunks from chunk */class Chunk{
497
+ /**
498
+ * Create a new chunk
499
+ *
500
+ * @class Chunk
501
+ * @param {DataView} data DataView to read from.
502
+ * @param {Number} position in data.
503
+ * @param {Function} debugMessage logging callback.
504
+ */
505
+ constructor(data,position,debugMessage){this.data=data,this.offset=position,this.position=position,this.debugMessage=debugMessage,this.debugMessage instanceof Function&&(this.debugMessage=function(){}),this.id=this.readWord(),this.size=this.readDWord(),this.end=this.offset+this.size,this.end>data.byteLength&&this.debugMessage("Bad chunk size for chunk at "+position)}
506
+ /**
507
+ * read a sub cchunk.
508
+ *
509
+ * @method readChunk
510
+ * @return {Chunk | null} next sub chunk
511
+ */readChunk(){if(this.endOfChunk)return null;try{const next=new Chunk(this.data,this.position,this.debugMessage);return this.position+=next.size,next}catch(e){return this.debugMessage("Unable to read chunk at "+this.position),null}}
512
+ /**
513
+ * return the ID of this chunk as Hex
514
+ *
515
+ * @method idToString
516
+ * @return {String} hex-string of id
517
+ */get hexId(){return this.id.toString(16)}get endOfChunk(){return this.position>=this.end}
518
+ /**
519
+ * Read byte value.
520
+ *
521
+ * @method readByte
522
+ * @return {Number} Data read from the dataview.
523
+ */readByte(){const v=this.data.getUint8(this.position,!0);return this.position+=1,v}
524
+ /**
525
+ * Read 32 bit float value.
526
+ *
527
+ * @method readFloat
528
+ * @return {Number} Data read from the dataview.
529
+ */readFloat(){try{const v=this.data.getFloat32(this.position,!0);return this.position+=4,v}catch(e){return this.debugMessage(e+" "+this.position+" "+this.data.byteLength),0}}
530
+ /**
531
+ * Read 32 bit signed integer value.
532
+ *
533
+ * @method readInt
534
+ * @return {Number} Data read from the dataview.
535
+ */readInt(){const v=this.data.getInt32(this.position,!0);return this.position+=4,v}
536
+ /**
537
+ * Read 16 bit signed integer value.
538
+ *
539
+ * @method readShort
540
+ * @return {Number} Data read from the dataview.
541
+ */readShort(){const v=this.data.getInt16(this.position,!0);return this.position+=2,v}
542
+ /**
543
+ * Read 64 bit unsigned integer value.
544
+ *
545
+ * @method readDWord
546
+ * @return {Number} Data read from the dataview.
547
+ */readDWord(){const v=this.data.getUint32(this.position,!0);return this.position+=4,v}
548
+ /**
549
+ * Read 32 bit unsigned integer value.
550
+ *
551
+ * @method readWord
552
+ * @return {Number} Data read from the dataview.
553
+ */readWord(){const v=this.data.getUint16(this.position,!0);return this.position+=2,v}
554
+ /**
555
+ * Read NULL terminated ASCII string value from chunk-pos.
556
+ *
557
+ * @method readString
558
+ * @return {String} Data read from the dataview.
559
+ */readString(){let s="",c=this.readByte();for(;c;)s+=String.fromCharCode(c),c=this.readByte();return s}}const M3DMAGIC=19789,MLIBMAGIC=15786,CMAGIC=49725,M3D_VERSION=2,COLOR_F=16,COLOR_24=17,LIN_COLOR_24=18,LIN_COLOR_F=19,INT_PERCENTAGE=48,FLOAT_PERCENTAGE=49,MDATA=15677,MESH_VERSION=15678,MASTER_SCALE=256,MAT_ENTRY=45055,MAT_NAME=40960,MAT_AMBIENT=40976,MAT_DIFFUSE=40992,MAT_SPECULAR=41008,MAT_SHININESS=41024,MAT_TRANSPARENCY=41040,MAT_TWO_SIDE=41089,MAT_ADDITIVE=41091,MAT_WIRE=41093,MAT_WIRE_SIZE=41095,MAT_TEXMAP=41472,MAT_OPACMAP=41488,MAT_BUMPMAP=41520,MAT_SPECMAP=41476,MAT_MAPNAME=41728,MAT_MAP_USCALE=41812,MAT_MAP_VSCALE=41814,MAT_MAP_UOFFSET=41816,MAT_MAP_VOFFSET=41818,NAMED_OBJECT=16384,N_TRI_OBJECT=16640,POINT_ARRAY=16656,FACE_ARRAY=16672,MSH_MAT_GROUP=16688,TEX_VERTS=16704,MESH_MATRIX=16736;function newgcad(P,_cat,islog=!0){let _movs={},_textures={},_meshes={},_geometries={};const textureCache=new Map;let _smats={},_scripts={},_loadertex=new THREE.TextureLoader,_loaderGLTF=new GLTFLoader,_loader3DS=new TDSLoader;const dracoLoader=new DRACOLoader;dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.6/"),_loaderGLTF.setDRACOLoader(dracoLoader);const ktx2Loader=new KTX2Loader;ktx2Loader.setTranscoderPath("https://unpkg.com/three@0.159.0/examples/jsm/libs/basis/"),_loaderGLTF.setKTX2Loader(ktx2Loader),_loaderGLTF.setMeshoptDecoder(MeshoptDecoder);let cats=[_cat],getcat=()=>cats[cats.length-1],_gmatricole={};return{clearmatricole:()=>{_gmatricole={}},islog:islog,clear:
560
+ /**
561
+ * Libera tutte le risorse caricate
562
+ */
563
+ async function clear(){function destroymesh(mesh){function disposeMaterial(material){material.map&&material.map.dispose(),material.lightMap&&material.lightMap.dispose(),material.bumpMap&&material.bumpMap.dispose(),material.normalMap&&material.normalMap.dispose(),material.specularMap&&material.specularMap.dispose(),material.dispose()}mesh&&mesh.traverse((child=>{child.isMesh&&(child.geometry.dispose(),child.material&&(Array.isArray(child.material)?child.material.forEach(disposeMaterial):disposeMaterial(child.material)))}))}_gmatricole={},THREE.Cache.clear();for(const c in _geometries)_geometries[c]?.dispose();for(const key in _textures)if(_textures[key]){const texture=await _textures[key];texture?.dispose()}for(const key in _smats)_smats[key]&&_smats[key]?.dispose();for(const[key,texOrPromise]of textureCache.entries()){const texture=texOrPromise instanceof Promise?await texOrPromise:texOrPromise;texture?.dispose&&texture.dispose()}textureCache.clear();for(const key in _meshes)if(_meshes[key]){destroymesh(await _meshes[key])}_movs={},_textures={},_meshes={},_geometries={},_smats={},_scripts={}},getScript:async function getScript(file){file.endsWith(".custom")?file=file.slice(-7):file.endsWith(".js")&&(file=file.slice(-3));let key=hash(`${getcat()}|${file}`);if(!_scripts[key]){let script;try{script=await P.fetch("mufiles/customfn",{id:getcat(),name:file,ispar:1})}catch(error){script=`log('undefined ${getcat()}/${file}: ${error.message}');`}_scripts[key]=script}return _scripts[key]},checkScripts:async function checkScripts(files){let cl=[];if(!files||!Array.isArray(files))return;let ct=getcat();for(let f of files){let key=hash(`${ct}|${f}`);_scripts[key]||cl.push(f)}if(cl?.length){let scripts=await P.fetch("mufiles/customfn",{id:ct,name:cl,ispar:1});if(scripts)for(let s of scripts){let key=hash(`${ct}|${s.n}`);_scripts[key]=s.v}}},gmats:_gmatricole,scripts:()=>Object.keys(_scripts),geo:_geometries,movs:_movs,textures:_textures,smats:_smats,dump(){console.log(`SMATS:\n${Object.keys(_smats).join(" - ")};\nGEOMS:\n${Object.keys(_geometries).join(" - ")};\nTEX:\n${Object.keys(_textures).join(" - ")};\nMESH:\n${Object.keys(_meshes).join(" - ")};\n`)},get cat(){return getcat()},pushcat(cat){cats.push(cat)},popcat:()=>(cats.length>1&&cats.length--,getcat()),async tex(file,sx=1,sy,rot){sy||(sy=sx),rot||(rot=0);const key=hash(`${getcat()}|${file}|${sx}|${sy}|${rot}`);return _textures[key]||(_textures[key]=new Promise(((resolve,reject)=>{let url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"textures",name:file,force:1});if(textureCache.has(url)){const tex=textureCache.get(url).clone();return tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,void resolve(tex)}_loadertex.load(url,(tex=>{textureCache.set(url,tex),tex.wrapS=THREE.RepeatWrapping,tex.wrapT=THREE.RepeatWrapping,tex.repeat.set(.001*sx,.001*sy),tex.rotation=rot,resolve(tex)}),void 0,(error=>{console.log(`Manca Texture ${file}!. questo rallenta molto il processo`),delete _textures[key],resolve(void 0)}))}))),_textures[key]},async get3ds(file,callback,ky=""){file.endsWith(".3ds")&&(file=file.slice(0,-4));const modifierKey=callback?hash(callback.toString()):"nomod",key=hash(`${getcat()}|${file}.3ds|${modifierKey}|${ky}`);return _meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{let url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:".3ds"});_loader3DS.setResourcePath(url+"&tex="),_loader3DS.load(url,(object=>{callback&&object.traverse((child=>{child.isMesh&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))})),resolve(object)}),void 0,(error=>{delete _meshes[key],resolve(void 0)}))}))),_meshes[key]},async getglb(file,textures,callback=null,ky=""){const ext=".glb";file.endsWith(ext)&&(file=file.slice(0,-4)),Array.isArray(textures)||(textures=[]);const modifierKey=callback?hash(callback.toString()):"nomod",texturesKey=textures.map((tex=>tex?.uuid||"null")).join("|"),key=hash(`${getcat()}|${file}${ext}|${texturesKey}|${modifierKey}|${ky}`);return _meshes[key]||(_meshes[key]=await new Promise(((resolve,reject)=>{const url=P.fullget("mufiles/getfile",{id:getcat(),subfolder:"3d",name:file,ext:ext});_loaderGLTF.setPath(""),_loaderGLTF.setResourcePath((resource=>(console.log("risorsa",resource),`${url}&tex=${resource}`))),_loaderGLTF.load(url,(async gltf=>{gltf.scene.traverse((child=>{if(child.isMesh){child.frustumCulled=!0;(Array.isArray(child.material)?child.material:[child.material]).forEach((material=>{if(!material||!material.map)return;const originalTexName=material.map.source?.data?.src;if(!originalTexName)return;const match=originalTexName.match(/(\d{2})\.jpg$/);if(!match)return;const textureIndex=parseInt(match[1]);textures[textureIndex]&&(material.map=textures[textureIndex],material.needsUpdate=!0)})),callback&&(Array.isArray(child.material)?child.material=child.material.map((mat=>callback(mat,child))):child.material=callback(child.material,child))}})),resolve(gltf.scene)}),void 0,(error=>{console.log(error),delete _meshes[key],resolve(void 0)}))}))),_meshes[key]}}}function setLineColorMode(white){white?(materialline1.color.set(16777215),materialline2.color.set(16777215)):(materialline1.color.set(3158064),materialline2.color.set(5263440)),materialline1.needsUpdate=!0,materialline2.needsUpdate=!0}export{SIDE,addmovpivot,calcolatasks,creategroup,deletegroup,edgesfromgeometry,estruso,estrusopat,get3dshape,getbox,getcilindro,getcyl,getemitter,getface,getfakeshadow,getline,getlinesgeom,getmesh,getmovimento,getpannello,getpoint,getpunto,getquota,getreceiver,getriferimento,getsprite,gettarghetta,groupfromgeometry,infoestrudi,materialline1,materialline2,mblack,mblue,mgray1,mgray2,mgreen,mred,mwhite,newgcad,posiziona,randombasemat,revolve,scaleunit,setLineColorMode,smat,spritemat,svuotanodo};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markuno_lib",
3
- "version": "1.1.53",
3
+ "version": "1.1.54",
4
4
  "description": "Croswil Markuno Language Lib",
5
5
  "authors": [
6
6
  "Croswil <info@croswil.com>"
@@ -159,6 +159,26 @@ export const mgray2: any;
159
159
  export const mgreen: any;
160
160
  export const mred: any;
161
161
  export const mwhite: any;
162
+ export function newgcad(P: any, _cat: any, islog?: boolean): {
163
+ clearmatricole: () => void;
164
+ islog: boolean;
165
+ clear: () => Promise<void>;
166
+ getScript: (file: any) => Promise<any>;
167
+ checkScripts: (files: any) => Promise<void>;
168
+ gmats: {};
169
+ scripts: () => string[];
170
+ geo: {};
171
+ movs: {};
172
+ textures: {};
173
+ smats: {};
174
+ dump(): void;
175
+ readonly cat: any;
176
+ pushcat(cat: any): void;
177
+ popcat: () => any;
178
+ tex(file: any, sx: number, sy: any, rot: any): Promise<any>;
179
+ get3ds(file: any, callback: any, ky?: string): Promise<any>;
180
+ getglb(file: any, textures: any, callback?: any, ky?: string): Promise<any>;
181
+ };
162
182
  export function posiziona(grp: any, pos?: {}): any;
163
183
  export function randombasemat(): any;
164
184
  export function revolve(gcad: any, shape: any, orient: any, mat: any, options: any): any;