phy-engine
Version:
JavaScript 3D Physics for three.js
6 lines • 612 kB
JavaScript
/**
* @license
* Copyright 2010-2025 Phy.js Authors
* SPDX-License-Identifier: MIT
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("three")):"function"==typeof define&&define.amd?define(["exports","three"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).PHY={},e.THREE)}(this,(function(e,t){"use strict";var i="undefined"!=typeof document?document.currentScript:null;const s=Math.PI,a=s/180,r=180/s,n=Number.EPSILON,l=.5*s,h={luminousPowers:{"110000 lm (1000W)":11e4,"3500 lm (300W)":3500,"1700 lm (100W)":1700,"800 lm (60W)":800,"400 lm (40W)":400,"180 lm (25W)":180,"20 lm (4W)":20,Off:0},luminousIrradiances:{"0.0001 lx (Moonless Night)":1e-4,"0.002 lx (Night Airglow)":.002,"0.5 lx (Full Moon)":.5,"3.4 lx (City Twilight)":3.4,"50 lx (Living Room)":50,"100 lx (Very Overcast)":100,"350 lx (Office Room)":350,"400 lx (Sunrise/Sunset)":400,"1000 lx (Overcast)":1e3,"18000 lx (Daylight)":18e3,"50000 lx (Direct Sun)":5e4},exposure:e=>Math.pow(e,5),candelaToLumens:e=>4*e*Math.PI,lumensToCandela:e=>e/(4*Math.PI),todeg:r,torad:a,toFixed:(e,t=3)=>1*e.toFixed(t),toRound:(e,t=3)=>Math.trunc(e),clamp:(e,t=0,i=1)=>e=(e=e<t?t:e)>i?i:e,clampA:(e,t,i)=>Math.max(t,Math.min(i,e)),smoothstep:(e,t,i)=>e*(i=-2*(i=h.clamp(i))*i*i+3*i*i)+t*(1-i),remap:(e,t,i,s,a)=>s+(e-t)*(a-s)/(i-t),lerp:(e,t,i)=>(1-i)*e+i*t,damp:(e,t,i,s)=>h.lerp(e,t,1-Math.exp(-i*s)),nearAngle:(e,t,i=!1)=>t+Math.atan2(Math.sin(e-t),Math.cos(e-t))*(i?r:1),unwrapDeg:e=>e-360*Math.floor((e+180)/360),unwrapRad:e=>Math.atan2(Math.sin(e),Math.cos(e)),nearEquals:(e,t,i=1e-4)=>Math.abs(e-t)<=i,autoSize:(e=[1,1,1],t="box")=>{1===e.length&&(e[1]=e[0]);let i=e[0],s=e[1];return"sphere"===t&&(e=[i,i,i]),"cylinder"!==t&&"wheel"!==t&&"capsule"!==t||(e=[i,s,i]),"cone"!==t&&"pyramid"!==t||(e=[i,s,i]),2===e.length&&(e[2]=e[0]),e},shuffle:e=>{let t=e.map((e=>({value:e,sort:Math.random()}))).sort(((e,t)=>e.sort-t.sort)).map((({value:e})=>e));return t},randomSign:()=>Math.random()<.5?-1:1,randSpread:e=>e*(.5-Math.random()),rand:(e=0,t=1)=>e+Math.random()*(t-e),randInt:(e,t)=>e+Math.floor(Math.random()*(t-e+1)),randIntUnic:(e,t,i)=>{for(var s=[];s.length<i;){var a=h.randInt(e,t);-1===s.indexOf(a)&&s.push(a)}return s},fromTransform:(e,t,i,s=[0,0,0,1],a=!1)=>{let r=h.composeMatrixArray(e,t),o=h.composeMatrixArray(i,s);return a&&(r=h.invertMatrixArray(r)),r=h.multiplyMatrixArray(r,o),[r[12],r[13],r[14]]},fromTransformToQ:(e,t,i=!1)=>{let s=h.composeMatrixArray(e,t),a=h.decomposeFullMatrixArray(s).q;return i&&(a=h.quatInvert(a)),a},lerpTransform:(e,t,i)=>{let s=e[0],a=e[1],r=t[0],o=t[1];return r=h.lerpArray(s,r,i),o=h.slerpQuatArray(a,o,i),[r,o]},composeMatrixArray:(e,t,i=[1,1,1])=>{const s=t[0],a=t[1],r=t[2],o=t[3],n=s+s,l=a+a,h=r+r,c=s*n,A=s*l,u=s*h,d=a*l,p=a*h,g=r*h,m=o*n,f=o*l,b=o*h,y=i[0],I=i[1],w=i[2];return[(1-(d+g))*y,(A+b)*y,(u-f)*y,0,(A-b)*I,(1-(c+g))*I,(p+m)*I,0,(u+f)*w,(p-m)*w,(1-(c+d))*w,0,e[0],e[1],e[2],1]},multiplyMatrixArray:(e,t)=>{const i=e,s=t,a=[],r=i[0],o=i[4],n=i[8],l=i[12],h=i[1],c=i[5],A=i[9],u=i[13],d=i[2],p=i[6],g=i[10],m=i[14],f=i[3],b=i[7],y=i[11],I=i[15],w=s[0],E=s[4],C=s[8],B=s[12],x=s[1],v=s[5],M=s[9],S=s[13],k=s[2],Q=s[6],R=s[10],T=s[14],F=s[3],D=s[7],L=s[11],P=s[15];return a[0]=r*w+o*x+n*k+l*F,a[4]=r*E+o*v+n*Q+l*D,a[8]=r*C+o*M+n*R+l*L,a[12]=r*B+o*S+n*T+l*P,a[1]=h*w+c*x+A*k+u*F,a[5]=h*E+c*v+A*Q+u*D,a[9]=h*C+c*M+A*R+u*L,a[13]=h*B+c*S+A*T+u*P,a[2]=d*w+p*x+g*k+m*F,a[6]=d*E+p*v+g*Q+m*D,a[10]=d*C+p*M+g*R+m*L,a[14]=d*B+p*S+g*T+m*P,a[3]=f*w+b*x+y*k+I*F,a[7]=f*E+b*v+y*Q+I*D,a[11]=f*C+b*M+y*R+I*L,a[15]=f*B+b*S+y*T+I*P,a},invertMatrixArray:e=>{const t=e,i=t[0],s=t[1],a=t[2],r=t[3],o=t[4],n=t[5],l=t[6],h=t[7],c=t[8],A=t[9],u=t[10],d=t[11],p=t[12],g=t[13],m=t[14],f=t[15],b=A*m*h-g*u*h+g*l*d-n*m*d-A*l*f+n*u*f,y=p*u*h-c*m*h-p*l*d+o*m*d+c*l*f-o*u*f,I=c*g*h-p*A*h+p*n*d-o*g*d-c*n*f+o*A*f,w=p*A*l-c*g*l-p*n*u+o*g*u+c*n*m-o*A*m,E=i*b+s*y+a*I+r*w;if(0===E)return[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];const C=1/E;return t[0]=b*C,t[1]=(g*u*r-A*m*r-g*a*d+s*m*d+A*a*f-s*u*f)*C,t[2]=(n*m*r-g*l*r+g*a*h-s*m*h-n*a*f+s*l*f)*C,t[3]=(A*l*r-n*u*r-A*a*h+s*u*h+n*a*d-s*l*d)*C,t[4]=y*C,t[5]=(c*m*r-p*u*r+p*a*d-i*m*d-c*a*f+i*u*f)*C,t[6]=(p*l*r-o*m*r-p*a*h+i*m*h+o*a*f-i*l*f)*C,t[7]=(o*u*r-c*l*r+c*a*h-i*u*h-o*a*d+i*l*d)*C,t[8]=I*C,t[9]=(p*A*r-c*g*r-p*s*d+i*g*d+c*s*f-i*A*f)*C,t[10]=(o*g*r-p*n*r+p*s*h-i*g*h-o*s*f+i*n*f)*C,t[11]=(c*n*r-o*A*r-c*s*h+i*A*h+o*s*d-i*n*d)*C,t[12]=w*C,t[13]=(c*g*a-p*A*a+p*s*u-i*g*u-c*s*m+i*A*m)*C,t[14]=(p*n*a-o*g*a-p*s*l+i*g*l+o*s*m-i*n*m)*C,t[15]=(o*A*a-c*n*a+c*s*l-i*A*l-o*s*u+i*n*u)*C,t},matrixArrayDeterminant:e=>{const t=e,i=t[0],s=t[4],a=t[8],r=t[12],o=t[1],n=t[5],l=t[9],h=t[13],c=t[2],A=t[6],u=t[10],d=t[14];return t[3]*(+r*l*A-a*h*A-r*n*u+s*h*u+a*n*d-s*l*d)+t[7]*(+i*l*d-i*h*u+r*o*u-a*o*d+a*h*c-r*l*c)+t[11]*(+i*h*A-i*n*d-r*o*A+s*o*d+r*n*c-s*h*c)+t[15]*(-a*n*c-i*l*A+i*n*u+a*o*A-s*o*u+s*l*c)},decomposeMatrixArray:e=>[e[12],e[13],e[14]],decomposeFullMatrixArray:e=>{const t=e;let i=h.lengthArray([t[0],t[1],t[2]]);const s=h.lengthArray([t[4],t[5],t[6]]),a=h.lengthArray([t[8],t[9],t[10]]);h.matrixArrayDeterminant(e)<0&&(i=-i);let r=[...e];const o=1/i,n=1/s,l=1/a;r[0]*=o,r[1]*=o,r[2]*=o,r[4]*=n,r[5]*=n,r[6]*=n,r[8]*=l,r[9]*=l,r[10]*=l;let c=h.quatFromRotationMatrix(r);return{p:[e[12],e[13],e[14]],q:c,s:[i,s,a]}},applyTransformArray:(e,t,i,s=[1,1,1])=>{const a=h.composeMatrixArray(t,i,s),r=e[0],o=e[1],n=e[2],l=1/(a[3]*r+a[7]*o+a[11]*n+a[15]);return[(a[0]*r+a[4]*o+a[8]*n+a[12])*l,(a[1]*r+a[5]*o+a[9]*n+a[13])*l,(a[2]*r+a[6]*o+a[10]*n+a[14])*l]},slerpQuatArray:(e,t,i)=>{if(0===i)return e;if(1===i)return t;let s=[...e];const a=e[0],r=e[1],o=e[2],l=e[3],c=t[0],A=t[1],u=t[2],d=t[3];let p=l*d+a*c+r*A+o*u;if(p<0?(s=[-c,-A,-u,-d],p=-p):s=[...t],p>=1)return e;const g=1-p*p;if(g<=n){const e=1-i;return s[3]=e*l+i*s[3],s[0]=e*a+i*s[0],s[1]=e*r+i*s[1],s[2]=e*o+i*s[2],h.quatNomalize(s)}const m=Math.sqrt(g),f=Math.atan2(m,p),b=Math.sin((1-i)*f)/m,y=Math.sin(i*f)/m;return s[3]=l*b+s[3]*y,s[0]=a*b+s[0]*y,s[1]=r*b+s[1]*y,s[2]=o*b+s[2]*y,s},toLocalQuatArray:(e=[0,0,0],t)=>{let i=h.quatFromEuler(e),s=h.quatInvert(t.quaternion.toArray());return h.quatMultiply(s,i)},quatFromRotationMatrix:e=>{let t=[0,0,0,1];const i=e,s=i[0],a=i[4],r=i[8],o=i[1],n=i[5],l=i[9],h=i[2],c=i[6],A=i[10],u=s+n+A;if(u>0){const e=.5/Math.sqrt(u+1);t[3]=.25/e,t[0]=(c-l)*e,t[1]=(r-h)*e,t[2]=(o-a)*e}else if(s>n&&s>A){const e=2*Math.sqrt(1+s-n-A);t[3]=(c-l)/e,t[0]=.25*e,t[1]=(a+o)/e,t[2]=(r+h)/e}else if(n>A){const e=2*Math.sqrt(1+n-s-A);t[3]=(r-h)/e,t[0]=(a+o)/e,t[1]=.25*e,t[2]=(l+c)/e}else{const e=2*Math.sqrt(1+A-s-n);t[3]=(o-a)/e,t[0]=(r+h)/e,t[1]=(l+c)/e,t[2]=.25*e}return t},quatFromEuler:(e=[0,0,0],t=!0)=>{const i=Math.cos,s=Math.sin,r=t?a:1,o=e[0]*r*.5,n=e[1]*r*.5,l=e[2]*r*.5,h=i(o),c=i(n),A=i(l),u=s(o),d=s(n),p=s(l);return[u*c*A+h*d*p,h*d*A-u*c*p,h*c*p+u*d*A,h*c*A-u*d*p]},quatFromAxis:(e=[0,0,0],t,i=!0)=>{const s=.5*t*(i?a:1),r=Math.sin(s);return[e[0]*r,e[1]*r,e[2]*r,Math.cos(s)]},quatNomalize:e=>{let t=h.lengthArray(e);return 0===t?[0,0,0,1]:(t=1/t,h.scaleArray(e,t,4))},quatInvert:e=>[-e[0],-e[1],-e[2],e[3]],quatMultiply:(e,t)=>{const i=e[0],s=e[1],a=e[2],r=e[3],o=t[0],n=t[1],l=t[2],h=t[3];return[i*h+r*o+s*l-a*n,s*h+r*n+a*o-i*l,a*h+r*l+i*n-s*o,r*h-i*o-s*n-a*l]},quatToAxis:e=>{let t=2*Math.acos(e[3]);const i=Math.sqrt(1-e[3]*e[3]);return i<1e-4?[1,0,0]:[e[0]/i,e[1]/i,e[2]/i,t]},eulerFromMatrix:e=>{const t=e[0],i=e[4],s=e[8];e[1];const a=e[5],r=e[9];e[2];const o=e[6],n=e[10];let l=[0,0,0];return l[1]=Math.asin(h.clamp(s,-1,1)),Math.abs(s)<.9999999?(l[0]=Math.atan2(-r,n),l[2]=Math.atan2(-i,t)):(l[0]=Math.atan2(o,a),l[2]=0),l},angleTo:(e,t)=>2*Math.acos(Math.abs(h.clamp(h.dotArray(e,t),-1,1))),fixedArray:(e,t)=>{let i=e.length,s=[];for(;i--;)s[i]=h.toFixed(e[i],t);return s},getSize:e=>.001*e.byteLength+"kb",perpendicularArray:e=>{const t=Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);let i=Math.acos(e[1]/t);const s=Math.atan2(e[2],e[0]);i>l?i-=l:i+=l;return[t*Math.sin(i)*Math.cos(s),t*Math.cos(i),t*Math.sin(i)*Math.sin(s)]},crossArray:(e,t)=>{const i=e[0],s=e[1],a=e[2],r=t[0],o=t[1],n=t[2];return[s*n-a*o,a*r-i*n,i*o-s*r]},applyQuaternion:(e,t)=>{const i=e[0],s=e[1],a=e[2],r=t[0],o=t[1],n=t[2],l=t[3],h=2*(o*a-n*s),c=2*(n*i-r*a),A=2*(r*s-o*i);return[i+l*h+o*A-n*c,s+l*c+n*h-r*A,a+l*A+r*c-o*h]},nullArray:(e,t,i)=>{let s=0;for(;i--;)s+=e[t+i];return s},equalArray:(e,t)=>{let i=e.length;for(;i--;)if(e[i]!==t[i])return!1;return!0},lerpArray:(e,t,i)=>{if(0===i)return e;if(1===i)return t;let s=e.length,a=[];for(;s--;)a[s]=e[s],a[s]+=(t[s]-a[s])*i;return a},zeroArray:(e,t=0,i)=>{for(i=i??e.length;i--;)e[t+i]=0;return e},lengthArray:e=>{let t=e.length,i=0;for(;t--;)i+=e[t]*e[t];return Math.sqrt(i)},dotArray:(e,t)=>{let i=e.length,s=0;for(;i--;)s+=e[i]*t[i];return s},addArray:(e,t,i)=>{i=i??e.length;let s=[];for(;i--;)s[i]=e[i]+t[i];return s},subArray:(e,t,i)=>{i=i??e.length;let s=[];for(;i--;)s[i]=e[i]-t[i];return s},mulArray:(e,t,i)=>{if(t instanceof Array){let s=[];for(i=i??e.length;i--;)s[i]=e[i]*t[i];return s}return e.map((e=>e*t))},worldscale:(e,t)=>e.map((e=>e*t)),divArray:(e,t,i)=>h.mulArray(e,1/t,i),scaleArray:(e,t,i)=>h.mulArray(e,t,i),fillArray:(e,t,i=0,s)=>{for(s=s??e.length;s--;)t[i+s]=e[s]},copyArray:(e,t)=>{},cloneArray:e=>[...e],distanceArray:(e,t=[0,0,0])=>h.lengthArray(h.subArray(e,t)),normalizeArray:e=>h.divArray(e,h.lengthArray(e)||1),normalArray:(e,t=[0,0,0])=>h.normalizeArray(h.subArray(t,e)),getCenter:(e,t)=>(e.computeBoundingBox(),e.boundingBox.getCenter(t)),getVolume:(e,t,i=null)=>{let s=1,a=t;switch(e){case"sphere":s=4*Math.PI*a[0]*a[0]*a[0]/3;break;case"cone":s=Math.PI*a[0]*(.5*a[1])*2;break;case"box":s=.5*a[0]*8*(.5*a[1])*(.5*a[2]);break;case"cylinder":s=Math.PI*a[0]*a[0]*(.5*a[1])*2;break;case"capsule":s=4*Math.PI*a[0]*a[0]*a[0]/3+Math.PI*a[0]*a[0]*(.5*a[1])*2;break;case"convex":case"mesh":s=h.getConvexVolume(i)}return s},getConvexVolume:e=>{let t,i=e.length/3,s=[0,0,0],a=[0,0,0];for(;i--;)t=3*i,e[t]<s[0]?s[0]=e[t]:e[t]>a[0]&&(a[0]=e[t]),e[t+1]<s[1]?s[1]=e[t+1]:e[t+1]>a[1]&&(a[1]=e[t+1]),e[t+2]<s[2]?s[2]=e[t+2]:e[t+2]>a[2]&&(a[2]=e[t+2]);let r=[a[0]-s[0],a[1]-s[1],a[2]-s[2]];return.5*r[0]*8*(.5*r[1])*(.5*r[2])},massFromDensity:(e,t)=>e*t,densityFromMass:(e,t)=>e/t,toNonIndexed:e=>e.index?e.clone().toNonIndexed():e,getIndex:(e,t)=>!e.index||t?null:e.index.array||null,getSameVertex:e=>{const t=e.getAttribute("position"),i=t.array,s=[],a=[],r={};new THREE.Vector3;let o,n=0;h.getHash(e);let l,c,A=!1,u=0;for(let e=0;e<t.count;e++){n=3*e,l={x:i[n],y:i[n+1],z:i[n+2],id:e},A=!1,o=s.length;for(let t=0;t<o;t++)c=s[t],l.x===c.x&&l.y===c.y&&l.z===c.z&&(A=!0,r[e]=c.id);A||(l.id=u++,s.push(l),a.push([l.x,l.y,l.z]))}return[a,r]},getVertex:(e,t)=>{let i=e.attributes.position.array;return t&&e.index&&(i=(e=e.clone().toNonIndexed()).attributes.position.array),i},getNormal:e=>e.attributes.normal.array,getFaces:e=>{let t=[];if(e.index){let i=e.getIndex();for(let e=0;e<i.count;e+=3)t.push([i.getX(e),i.getX(e+1),i.getX(e+2)])}else{let i=e.getAttribute("position").count;for(let e=0;e<i;e+=3)t.push([e,e+1,e+2])}return t},getConnectedFaces:e=>{const t=[];let i,s,a,r,o,n,l,h=e.length,c=h;for(;c--;)for(s=e[c],i=h;i--;)i!==c&&(a=e[i],r=s.filter((e=>a.includes(e))),r.length>1&&(l=[],o=[...s],n=o.indexOf(r[0]),o.splice(n,1),n=o.indexOf(r[1]),o.splice(n,1),l.push(o[0]),o=[...a],n=o.indexOf(r[0]),o.splice(n,1),n=o.indexOf(r[1]),o.splice(n,1),l.push(o[0]),t.push(l)));return t},reduce:e=>{},barycentric:(e,t)=>{},solve:(e,t)=>{},getHash:(e,t=1e-4)=>{t=Math.max(t,Number.EPSILON);const i={},s={},a=e.getAttribute("position"),r=a.count,o=a.array,n=.5*t,l=Math.log10(1/t),h=Math.pow(10,l),c=n*h;let A;for(let e=0;e<r;e++){A=3*e;let t=`${~~(o[A]*h+c)},${~~(o[A+1]*h+c)},${~~(o[A+2]*h+c)}`;i[t]?i[t].push(e):i[t]=[e]}let u=0;for(let e in i)s[u++]=i[e];return s}},c=h,A=["PHYSX","HAVOK"],u=4e3,d=1e3,p=4e3,g=100,f=100,b=50,y=20,I={bodyFull:14,body:8,joint:16,contact:1,ray:11,character:16,vehicle:72,solver:128},w=function(e,t=!1){const i={};let s={body:u*(t?I.bodyFull:I.body),joint:d*I.joint,ray:g*I.ray,contact:p*I.contact,character:f*I.character};"PHYSX"!==e&&"AMMO"!==e||(s.vehicle=b*I.vehicle),"PHYSX"===e&&(s.solver=y*I.solver),"HAVOK"!==e&&"RAPIER"!==e&&"JOLT"!==e||(I.joint=0);let a=0;for(let e in s)i[e]=a,a+=s[e];return i.total=a,i};class E extends t.LineSegments{constructor(e,i=16776960){const s=new Uint16Array([0,1,1,2,2,3,3,4,4,5,5,0,6,7,7,8,8,9,9,10,10,11,11,6,12,13,13,14,14,15,15,16,16,17,17,12,18,19,20,21,22,23]),a=[.5,0,0,.25,.433,0,-.25,.433,0,-.5,0,0,-.25,-.433,0,.25,-.433,0,.5,0,0,.25,0,.433,-.25,0,.433,-.5,0,0,-.25,0,-.433,.25,0,-.433,0,.5,0,0,.25,.433,0,-.25,.433,0,-.5,0,0,-.25,-.433,0,.25,-.433,0,0,0,.6,0,0,0,0,0,0,.6,0,0,0,0,0,0,.6],r=new t.BufferGeometry;r.setIndex(new t.BufferAttribute(s,1)),r.setAttribute("position",new t.Float32BufferAttribute(a,3)),r.setAttribute("color",new t.Float32BufferAttribute([0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1],3)),super(r,new t.LineBasicMaterial({color:i,depthTest:!1,depthWrite:!1,toneMapped:!1,transparent:!0})),this.box=e,this.type="CircleHelper",this.geometry.computeBoundingSphere()}updateMatrixWorld(e){const t=this.box;t.isEmpty()||(t.getCenter(this.position),t.getSize(this.scale),this.scale.multiplyScalar(.5),super.updateMatrixWorld(e))}dispose(){this.geometry.dispose(),this.material.dispose()}}let C=class{constructor(){this.geoN=0,this.geo={}}unic(e){this.geo["geo"+this.geoN++]=e}set(e){this.geo[e.name]=e}get(e,i={}){if(!this.geo[e]){let i;switch(e){case"plane":i=new t.PlaneGeometry(1,1),i.rotateX(.5*-Math.PI);break;case"box":i=new t.BoxGeometry(1,1,1);break;case"sphere":i=new t.SphereGeometry(1,16,12);break;case"cylinder":i=new t.CylinderGeometry(1,1,1,16);break;case"cone":i=new t.CylinderGeometry(.001,1,1,16);break;case"particle":i=new t.SphereGeometry(1,6,4);break;case"joint":i=(new E).geometry;break;default:return null}this.geo[e]=i}return this.geo[e]}dispose(){for(let e in this.geo)this.geo[e].isBufferGeometry?this.geo[e].dispose():console.log(this.geo[e]);this.geo={},this.geoN=0}};class B{constructor(e,i="rgb(69,69,69)",s="rgb(39,39,39)"){const a=document.createElement("canvas");a.width=a.height=128;const r=a.getContext("2d");if(r.fillStyle=i,r.fillRect(0,0,128,128),e){let t,a,o,n,l=[[0,0],[32,32],[64,64],[96,96],[96,-32]],h=[[0,64],[32,96],[64,128],[96,160],[-32,32]],c=e?"rgb(128,128,255)":i,A=e?"rgb(160,100,255)":s,u=e?"rgba(100,160,255, 0.5)":"rgba(0,0,0, 0.1)";for(r.strokeStyle=u,r.lineWidth=1,t=0;t<5;t++){n=r.createLinearGradient(0,h[t][0],0,h[t][1]),n.addColorStop(0,A),n.addColorStop(1,c),r.beginPath(),r.fillStyle=n,r.rect(l[t][0],l[t][1],32,64),r.fill();for(let e=0;e<8;e++)o=2*(Math.random()-.5),r.beginPath(),r.moveTo(l[t][0]+o+2+4*e,l[t][1]),r.lineTo(l[t][0]+o+2+4*e,l[t][1]+64),r.stroke()}for(l=[[32,0],[64,32],[96,64],[-32,64],[0,96]],h=[[32,96],[64,128],[96,160],[-32,32],[0,64]],t=0;t<5;t++)for(n=r.createLinearGradient(h[t][0],0,h[t][1],0),n.addColorStop(0,c),n.addColorStop(1,A),r.beginPath(),r.fillStyle=n,r.rect(l[t][0],l[t][1],64,32),r.fill(),a=0;a<8;a++)o=2*(Math.random()-.5),r.beginPath(),r.moveTo(l[t][0],l[t][1]+o+2+4*a),r.lineTo(l[t][0]+64,l[t][1]+o+2+4*a),r.stroke()}else r.beginPath(),r.fillStyle=s,r.rect(0,0,32,64),r.rect(32,32,32,64),r.rect(64,64,32,64),r.rect(96,96,32,64),r.rect(96,-32,32,64),r.fill();const o=new t.CanvasTexture(a);return o.wrapS=o.wrapT=t.RepeatWrapping,o.repeat.x=o.repeat.y=60,e||(o.colorSpace=t.SRGBColorSpace),o}}class x extends t.MeshPhysicalMaterial{constructor(e){super(),this.defines={STANDARD:"",PHYSICAL:"",SUBSURFACE:"",USE_UV:""},this.extra={},this.addParametre("sssMap",null),this.addParametre("sssColor",new t.Color(0,0,0)),this.addParametre("sssAmbient",.5),this.addParametre("sssDistortion",.6),this.addParametre("sssAttenuation",.1),this.addParametre("sssPower",1),this.addParametre("sssScale",6),this.setValues(e);let i=this;i.onBeforeCompile=function(e){for(let t in i.extra)e.uniforms[t]={value:i.extra[t]};e.fragmentShader=e.fragmentShader.replace("#include <common>",v.common),e.fragmentShader=e.fragmentShader.replace("#include <lights_fragment_begin>",i.replaceAll(M,"RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );",v.light)),i.userData.shader=e}}addParametre(e,t){this.extra[e]=t,Object.defineProperty(this,e,{get:()=>this.extra[e],set:t=>{this.extra[e]=t,this.userData.shader&&(this.userData.shader.uniforms[e].value=this.extra[e])}})}replaceAll(e,t,i){return e.split(t).join(i)}}const v={common:"\n\t#include <common>\n\tuniform sampler2D sssMap;\n\tuniform float sssPower;\n\tuniform float sssScale;\n\tuniform float sssDistortion;\n\tuniform float sssAmbient;\n\tuniform float sssAttenuation;\n\tuniform vec3 sssColor;\n\n\tvoid RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, inout ReflectedLight reflectedLight) {\n\t\tvec3 thickness = sssColor * texture2D(sssMap, uv).r;\n\t\tvec3 scatteringHalf = normalize(directLight.direction + (geometryNormal * sssDistortion));\n\t\tfloat scatteringDot = pow(saturate(dot(geometryViewDir, -scatteringHalf)), sssPower) * sssScale;\n\t\tvec3 scatteringIllu = (scatteringDot + sssAmbient) * thickness;\n\t\treflectedLight.directDiffuse += scatteringIllu * sssAttenuation * directLight.color;\n\t}\n\t",light:"\n\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t#if defined( SUBSURFACE ) && defined( USE_UV )\n\t\tRE_Direct_Scattering(directLight, vUv, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, reflectedLight);\n\t#endif\n\t"},M="\n\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n\n#ifdef USE_CLEARCOAT\n\n\tgeometryClearcoatNormal = clearcoatNormal;\n\n#endif\n\n#ifdef USE_IRIDESCENCE\n\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\n\tif ( material.iridescenceThickness == 0.0 ) {\n\n\t\tmaterial.iridescence = 0.0;\n\n\t} else {\n\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\n\t}\n\n\tif ( material.iridescence > 0.0 ) {\n\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\n\t\t// Iridescence F0 approximation\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\n\t}\n\n#endif\n\nIncidentLight directLight;\n\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\n\t\tpointLight = pointLights[ i ];\n\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\n\t\tspotLight = spotLights[ i ];\n\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\n\t\t// spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none]\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\n\t\tdirectionalLight = directionalLights[ i ];\n\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\n\tRectAreaLight rectAreaLight;\n\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\n\t}\n\t#pragma unroll_loop_end\n\n#endif\n\n#if defined( RE_IndirectDiffuse )\n\n\tvec3 iblIrradiance = vec3( 0.0 );\n\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\n\t#if defined( USE_LIGHT_PROBES )\n\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\n\t#endif\n\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\n\t\t}\n\t\t#pragma unroll_loop_end\n\n\t#endif\n\n#endif\n\n#if defined( RE_IndirectSpecular )\n\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n\n#endif\n",S={metalness:.1,roughness:.9},k={grey:new t.Color(.18,.18,.18),black:new t.Color(.039,.039,.039),body:new t.Color(13289155),sleep:new t.Color("hsl(33, 15%, 54%)"),solid:new t.Color(7105128),base:new t.Color(13224135),brick:new t.Color(.262,.095,.061),sand:new t.Color(.44,.386,.231),gold:new t.Color(.944,.776,.373),gold2:new t.Color(.998,.981,.751),titanium:new t.Color(.633,.578,.503),titaniumSpec:new t.Color(.728,.68,.55),chrome:new t.Color(.653,.65,.615),chromeSpec:new t.Color(.675,.72,.711),copper:new t.Color(.988,.688,.448),carPaint:new t.Color(.1037792,.59212029,.85064936),clay:new t.Color("hsl(12, 30%, 40%)"),clayWhite:new t.Color(11119017),concrete:new t.Color(.51,.51,.51),Raw_Fire:new t.Color("hsl(40, 18%, 54%)"),Raw_Buff:new t.Color("hsl(33, 15%, 54%)"),Raw_Terracotta:new t.Color("hsl(12, 30%, 40%)"),Raw_Porcelain:new t.Color("hsl(45, 15%, 90%)")},Q={No:t.NoBlending,Normal:t.NormalBlending,Additive:t.AdditiveBlending,Subtractive:t.SubtractiveBlending,Multiply:t.MultiplyBlending,Eadd:t.AddEquation,Esub:t.SubtractEquation,Erev:t.ReverseSubtractEquation,Emin:t.MinEquation,Emaw:t.MaxEquation,Fzero:t.ZeroFactor,Fone:t.OneFactor,Fcolor:t.SrcColorFactor,Fcolorm:t.OneMinusSrcColorFactor,Falpha:t.SrcAlphaFactor,Falpham:t.OneMinusSrcAlphaFactor,Fdstalpha:t.DstAlphaFactor,Fdstalpham:t.OneMinusDstAlphaFactor,Fdstcolor:t.DstColorFactor,Fdstcolorm:t.OneMinusDstColorFactor,Falphasaturate:t.SrcAlphaSaturateFactor,Front:t.FrontSide,Back:t.BackSide,Double:t.DoubleSide};let R=class{constructor(){this.renderMode={value:0},this.depthPacking={value:0},this.extendMat=!1,this.isRealism=!1,this.realismOption={},this.envMapIntensity=1,this.mat={},this.TmpMat=[]}changeRenderMode(e){this.renderMode.value=e}initExtandShader(){}useRealLight(e){}setColor(e){}set(e,t,i=null){i||(i=e.onBeforeCompile),this.mat[e.name]=e}extendShader(e,t=null){}addToTmp(e){this.TmpMat.push(e)}create(e){let i,s=null;if(e.isMaterial)i=e;else{let a=void 0!==e.type?e.type:"Standard";switch(e.type&&delete e.type,s=e.beforeCompile||null,e.beforeCompile&&delete e.beforeCompile,(e.thickness||e.sheen||e.clearcoat||e.transmission||e.specularColor)&&(a="Physical"),e.normalScale&&(e.normalScale.isVector2||(e.normalScale=(new t.Vector2).fromArray(e.normalScale))),e.side&&(e.side=this.findValue(e.side)),e.shadowSide&&(e.shadowSide=this.findValue(e.shadowSide)),e.blending&&(e.blending=this.findValue(e.blending)),e.blendEquation&&(e.blendEquation=this.findValue(e.blendEquation)),e.blendEquationAlpha&&(e.blendEquationAlpha=this.findValue(e.blendEquationAlpha)),e.blendSrc&&(e.blendSrc=this.findValue(e.blendSrc)),e.blendDst&&(e.blendDst=this.findValue(e.blendDst)),e.blendDstAlpha&&(e.blendDstAlpha=this.findValue(e.blendDstAlpha)),e.blendSrcAlpha&&(e.blendSrcAlpha=this.findValue(e.blendSrcAlpha)),e.clearcoatNormalScale&&(e.clearcoatNormalScale.isVector2||(e.clearcoatNormalScale=(new t.Vector2).fromArray(e.clearcoatNormalScale))),a=a.toLowerCase(),a){case"physical":i=new t.MeshPhysicalMaterial(e),i.defines={STANDARD:"",PHYSICAL:"",USE_UV:"",USE_SPECULAR:""};break;case"phong":i=new t.MeshPhongMaterial(e);break;case"lambert":i=new t.MeshLambertMaterial(e);break;case"basic":i=new t.MeshBasicMaterial(e);break;case"line":i=new t.LineBasicMaterial(e);break;case"toon":i=new t.MeshToonMaterial(e);break;case"shadow":i=new t.ShadowMaterial(e);break;case"sss":i=new x(e);break;default:i=new t.MeshStandardMaterial(e)}}return this.mat[i.name]?null:(this.set(i,!1,s),i)}findValue(e){return"string"===e?Q[e.charAt(0).toUpperCase()+e.slice(1)]:e}addToMat(e){if(this.isRealism)for(let t in e)e[t].onBeforeCompile=function(i){EnhanceLighting(i,this.realismOption),e[t].userData.isRealism=!0,e[t].userData.shader=i};this.mat={...this.mat,...e}}changeType(){}directIntensity(e){for(let e in this.mat);}getList(){let e={...this.mat};const t=["line","debug","hide","svg"];let i=t.length;for(;i--;)delete e[t[i]];return e}get(e){if(!this.mat[e])switch(e){case"grey":this.create({name:"grey",color:k.grey,metalness:0,roughness:.5});break;case"black":this.create({name:"black",color:k.black,metalness:0,roughness:.5});break;case"body":this.create({name:"body",color:k.body,...S});break;case"sleep":this.create({name:"sleep",color:k.sleep,...S});break;case"solid":this.create({name:"solid",color:k.solid,...S});break;case"base":this.create({name:"base",color:k.base,...S});break;case"clay":this.create({name:"clay",color:k.clay,metalness:.1,roughness:.7});break;case"clayWhite":this.create({name:"clayWhite",color:k.clayWhite,metalness:.1,roughness:.7});break;case"concrete":this.create({name:"concrete",color:k.concrete,metalness:0,roughness:.9});break;case"brick":this.create({name:"brick",color:k.brick,metalness:0,roughness:.6});break;case"sand":this.create({name:"sand",color:k.sand,metalness:0,roughness:.9});break;case"chrome":this.create({name:"chrome",color:k.chrome,specularColor:k.chromeSpec,metalness:1,roughness:.075});break;case"silver":this.create({name:"silver",color:11184810,metalness:.8,roughness:.22});break;case"gold":this.create({name:"gold",color:k.gold,specularColor:k.gold2,metalness:1,roughness:.02});break;case"copper":this.create({name:"copper",color:k.copper,metalness:1,roughness:.05});break;case"titanium":this.create({name:"titanium",color:k.titanium,metalness:1,roughness:0,specularColor:k.titaniumSpec});break;case"carPaint":this.create({name:"carPaint",color:k.carPaint,metalness:0,anisotropy:new t.Vector2(.5,.5),roughness:.4,clearcoat:1,clearcoatRoughness:0});break;case"carbon":this.create({name:"carbon",map:new B,normalMap:new B(!0),clearcoat:1,clearcoatRoughness:.1,roughness:.5});break;case"cloth":this.create({name:"cloth",color:8391119,roughness:.5,sheenColor:13335807,sheen:1,sheenRoughness:.2});break;case"skinny":this.create({name:"skinny",color:14724201,...S});break;case"glass":this.create({name:"glass",color:16777215,transparent:!0,roughness:.02,metalness:0,side:t.DoubleSide,alphaToCoverage:!0,premultipliedAlpha:!0,transmission:1,clearcoat:1,thickness:.01});break;case"glassX":this.create({name:"glassX",color:16777215,alphaToCoverage:!0,transparent:!0,opacity:1,roughness:0,metalness:0,side:t.DoubleSide,transmission:1,clearcoat:1,clearcoatRoughness:0,thickness:.05,ior:1.52,shadowSide:1,reflectivity:.5,iridescence:0,specularIntensity:1,specularColor:16777215});break;case"plexi":this.create({name:"plexi",blending:t.AdditiveBlending,color:65793,transparent:!0,opacity:.7,reflectivity:.3,metalness:.6,roughness:.1,clearcoat:.2,clearcoatRoughness:.02,side:t.DoubleSide,alphaToCoverage:!0,premultipliedAlpha:!0});break;case"plexi2":this.create({name:"plexi2",blending:t.AdditiveBlending,color:65793,transparent:!1,opacity:.7,reflectivity:.3,metalness:.6,roughness:.1,clearcoat:.2,clearcoatRoughness:.02,side:t.DoubleSide,alphaToCoverage:!1,premultipliedAlpha:!0});break;case"glass2":this.create({name:"glass2",color:15658734,transparent:!0,roughness:0,alphaToCoverage:!0,opacity:.3});break;case"glass3":this.create({name:"glass3",color:0,transparent:!0,roughness:0,alphaToCoverage:!0,opacity:.4});break;case"glass_red":this.create({name:"glass_red",color:16711680,transparent:!0,roughness:0,alphaToCoverage:!0,opacity:.8});break;case"car":this.create({name:"car",color:3158064,metalness:1,roughness:.5,clearcoat:1,clearcoatRoughness:.03,sheen:.5});break;case"carGlass":this.create({name:"carGlass",color:16777215,metalness:0,roughness:0,transmission:1,ior:1.52});break;case"outline":this.create({name:"outline",color:16777215,type:"Basic",side:t.BackSide,toneMapped:!1,wireframe:!0,transparent:!0,opacity:.25});break;case"debug":this.create({name:"debug",type:"Basic",color:15953986,wireframe:!0,toneMapped:!1,transparent:!0,opacity:.5});break;case"shadow":this.create({name:"shadow",type:"shadow",color:0,opacity:.5});break;case"bones":this.create({name:"bones",color:16639958,wireframe:!0});break;case"bones2":this.create({name:"bones2",type:"basic",color:14664872,transparent:!0,opacity:.5,depthTest:!0,depthWrite:!1,alphaToCoverage:!0});break;case"button":this.create({name:"button",color:16728139,...S});break;case"line":this.create({name:"line",type:"line",vertexColors:!0,toneMapped:!1});break;case"liner":this.create({name:"liner",type:"line",vertexColors:!0,toneMapped:!1,depthTest:!0,depthWrite:!0,alphaToCoverage:!0});break;case"hide":this.create({name:"hide",type:"basic",visible:!1});break;case"particle":this.create({name:"particle",type:"basic",toneMapped:!1,color:16776960,transparent:!0,opacity:.2});break;case"svg":this.create({name:"svg",type:"basic",toneMapped:!1,vertexColors:!0,transparent:!1,side:t.DoubleSide})}return this.mat[e]}dispose(){this.isRealism=!1;for(let e in this.mat)this.mat[e].dispose(),delete this.mat[e];let e=this.TmpMat.length;for(;e--;)this.TmpMat[e].dispose();this.TmpMat=[]}upShader(){let e=this.realismOption;for(let t in this.mat){const i=this.mat[t],s=i.userData.shader;for(let t in e)s&&void 0!==s.uniforms[t]&&(s.uniforms[t].value=e[t]),i[t]&&(i[t]=e[t])}}};class T{constructor(e=-1){this.perf=window.performance,this.time={now:0,delta:0,then:0,interval:0,tmp:0,n:0,dt:0},this.fps=0,this.delta=0,this.elapsedTime=0,this.unlimited=!1,this.setFramerate(e),this.force=!1}up(e){let t=this.time;return this.unlimited&&(this.force=!0),t.now=void 0!==e?e:this.now(),t.delta=t.now-t.then,this.force&&(t.delta=t.interval,this.force=!1),!!(t.delta>=t.interval||this.unlimited)&&(t.then=this.unlimited?t.now:t.now-t.delta%t.interval,this.delta=.001*t.interval,this.elapsedTime+=this.delta,!0)}setFramerate(e){this.elapsedTime=0,this.framerate=e,this.unlimited=this.framerate<0,this.time.interval=1e3/e,60===e&&(this.time.interval=16.67)}static now(){return this.perf?this.perf.now():Date.now()}static format_time(e){return e>1e3?e/1e3+" sec":e+" ms"}}class F{constructor(){this.key=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.key2=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],this.gamepad=new D(this.key),this.useGamepad=!1,this.sameAxis=!0,document.addEventListener("keydown",function(e){this.keyDown(e)}.bind(this),!1),document.addEventListener("keyup",function(e){this.keyUp(e)}.bind(this),!1)}setKey(e,t){this.key[e]=t}update(){return this.gamepad.update(),this.gamepad.ready&&(this.useGamepad||(this.useGamepad=!0),this.gamepad.getValue(0)),this.sameAxis&&(this.key[2]=this.key[0],this.key[3]=this.key[1]),this.key}keyDown(e){var t=this.key,i=this.key2;if(e=e||window.event,this.sameAxis)switch(e.which){case 65:case 81:case 37:t[0]=-1,i[0]=1;break;case 68:case 39:t[0]=1,i[1]=1;break;case 87:case 90:case 38:t[1]=-1;break;case 83:case 40:t[1]=1;break;case 32:t[4]=1;break;case 17:case 67:t[5]=1;break;case 69:t[6]=1;break;case 16:t[7]=1}else switch(e.which){case 65:case 81:t[0]=-1,i[0]=1;break;case 68:t[0]=1,i[1]=1;break;case 87:case 90:t[1]=-1;break;case 83:t[1]=1;break;case 37:t[2]=-1,i[0]=1;break;case 39:t[2]=1,i[1]=1;break;case 38:t[3]=-1;break;case 40:t[3]=1;break;case 32:t[4]=1;break;case 17:case 67:t[5]=1;break;case 69:t[6]=1;break;case 16:t[7]=1}this.gamepad.reset()}keyUp(e){var t=this.key,i=this.key2;if(e=e||window.event,this.sameAxis)switch(e.which){case 65:case 81:case 37:t[0]=t[0]<0?0:t[0],i[0]=0;break;case 68:case 39:t[0]=t[0]>0?0:t[0],i[1]=0;break;case 87:case 90:case 38:t[1]=t[1]<0?0:t[1];break;case 83:case 40:t[1]=t[1]>0?0:t[1];break;case 32:t[4]=0;break;case 17:case 67:t[5]=0;break;case 69:t[6]=0;break;case 16:t[7]=0}else switch(e.which){case 65:case 81:t[0]=t[0]<0?0:t[0],i[0]=0;break;case 68:t[0]=t[0]>0?0:t[0],i[1]=0;break;case 87:case 90:t[1]=t[1]<0?0:t[1];break;case 83:t[1]=t[1]>0?0:t[1];break;case 37:t[2]=t[2]<0?0:t[2],i[0]=0;break;case 39:t[2]=t[2]>0?0:t[2],i[1]=0;break;case 38:t[3]=t[3]<0?0:t[3];break;case 40:t[3]=t[3]>0?0:t[3];break;case 32:t[4]=0;break;case 17:case 67:t[5]=0;break;case 69:t[6]=0;break;case 16:t[7]=0}}}class D{constructor(e){this.values=[],this.ready=0,this.key=e}update(){var e,t,i,s,a,r,o=this.fix,n=navigator.getGamepads();for(e=0;e<n.length;e++)if(r=n[e])if(i=r.axes.length,s=r.buttons.length){for(this.values[e]||(this.values[e]=[]),t=0;t<i;t++)a=o(r.axes[t],.08),0==this.ready&&0!==a&&(this.ready=1),this.values[e][t]=a;for(t=0;t<s;t++)a=o(r.buttons[t].value),0==this.ready&&0!==a&&(this.ready=1),this.values[e][i+t]=a}else this.values[e]&&(this.values[e]=null)}getValue(e){for(var t,i=19;i--;)t=this.values[e][i],0==this.ready&&0!==t&&(this.ready=1),this.key[i]=t}reset(){this.ready=0}fix(e,t){let i=Number(e.toString().substring(0,5));return t&&i<t&&i>-t&&(i=0),i}}class L{constructor(){this.id=0,this.list=[],this.type="item",this.Utils=null}reset(){let e=this.list.length;for(;e--;)this.dispose(this.list[e]);this.list=[],this.id=0}byName(e){return this.Utils.byName(e)}setName(e={}){let t=void 0!==e.name?e.name:this.type+this.id++;return e.id=this.remove(t,!0),e.name=t,t}addToWorld(e,t=-1){this.Utils.add(e),-1!==t?this.list[t]=e:this.list.push(e)}remove(e,t){let i=this.byName(e);return i?this.clear(i,t):-1}clear(e,t){let i=this.list.indexOf(e);return-1===i||t?this.list[i]=null:this.list.splice(i,1),this.dispose(e),i}dispose(e){null!==e&&this.Utils.remove(e)}add(e={}){}set(e={}){}step(e,t){}}class P extends L{constructor(e){super(),this.motor=e,this.Utils=this.motor.utils,this.type="ray",this.iType="ray"}step(e,t){let i,s,a=this.list.length;for(;a--;)i=this.list[a],s=t+a*I.ray,i.update(e,s,this.motor.reflow.ray[a]||null)}add(e={}){this.setName(e);let t=new _(e,this.motor);return t.visible=void 0===e.visible||e.visible,this.addToWorld(t,e.id),e.parent&&"string"!=typeof e.parent&&(e.parent=e.parent.name),e.callback&&delete e.callback,this.motor.post({m:"add",o:e}),t}set(e={},t=null){null===t&&(t=this.byName(e.name)),null!==t&&t.setRay(e)}}class _ extends t.Line{constructor(e={},i){super(new t.BufferGeometry,i.getMat("line")),this.motor=i,this.Utils=this.motor.utils,this.isRay=!0,this.data={hit:!1,body:"",point:[0,0,0],normal:[0,0,0],distance:0,angle:0,parent:null},this.type="ray",this.name=e.name,this.parentMesh=null,e.parent&&(this.parentMesh="string"==typeof e.parent?this.Utils.byName(e.parent):e.parent,this.data.parent=this.parentMesh),this.callback=e.callback||null,this.c0=[.1,.1,.3],this.c1=[.1,.4,.6],this.c2=[1,.1,.1],this.c3=[.1,1,.1],this.begin=new t.Vector3,this.end=new t.Vector3(0,1,0),this.tmp=new t.Vector3,this.vnormal=new t.Vector3,this.vv1=new t.Vector3,this.vv2=new t.Vector3,this.fullDistance=0,this.setRay(e);this.geometry.setAttribute("position",new t.Float32BufferAttribute([0,0,0,0,0,0,0,0,0],3)),this.geometry.setAttribute("color",new t.Float32BufferAttribute([0,0,0,0,0,0,0,0,0],3)),this.vertices=this.geometry.attributes.position,this.colors=this.geometry.attributes.color,this.local=[0,0,0,0,0,0,0,0,0],this.noRotation=e.noRotation||!1,this.fakeMatrix=new t.Matrix4,this.matrixAutoUpdate=!1,this.frustumCulled=!1}setRay(e){e.begin&&this.begin.fromArray(e.begin),e.end&&this.end.fromArray(e.end),this.fullDistance=this.begin.distanceTo(this.end)}update(e,t=0,i=null){if(this.data.hit=0!==e[t],this.data.body=i||"",this.data.distance=e[t+1],this.data.hit)this.local[0]=e[t+2],this.local[1]=e[t+3],this.local[2]=e[t+4],this.tmp.fromArray(e,t+5),this.vnormal.fromArray(e,t+8),this.data.point=this.tmp.toArray(),this.data.normal=this.vnormal.toArray(),this.tmp.toArray(this.local,3),this.vv1.fromArray(this.local).sub(this.tmp).normalize(),this.tmp.addScaledVector(this.vnormal,this.fullDistance-this.data.distance),this.tmp.toArray(this.local,6),this.data.angle=Math.floor(c.angleTo(this.vv1.toArray(),this.data.normal)*r);else if(this.parentMesh){let e;e=this.noRotation?this.fakeMatrix.setPosition(this.parentMesh.position.x,this.parentMesh.position.y,this.parentMesh.position.z):this.parentMesh.matrixWorld,this.tmp.copy(this.begin).applyMatrix4(e).toArray(this.local,0),this.tmp.copy(this.end).applyMatrix4(e),this.tmp.toArray(this.local,3),this.tmp.toArray(this.local,6)}else this.begin.toArray(this.local,0),this.end.toArray(this.local,3),this.end.toArray(this.local,6);this.updateGeometry(),this.updateMatrix(),this.callback&&this.callback(this.data)}dispose(){this.callback=null,this.parentMesh=null,this.data={},this.geometry.dispose()}raycast(){}updateGeometry(){if(!this.visible)return;let e=this.vertices.array,t=this.colors.array,i=this.local,s=this.data.hit,a=s?this.c2:this.c1,r=s?this.c3:this.c1;t[3]=a[0],t[4]=a[1],t[5]=a[2],t[6]=r[0],t[7]=r[1],t[8]=r[2],e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this.vertices.needsUpdate=!0,this.colors.needsUpdate=!0}}class G extends t.InstancedMesh{constructor(e,i,s=0){super(e,i,s),this.matrixAutoUpdate=!1,this.tmpMatrix=new t.Matrix4,this.tmpQuat=new t.Quaternion,this.instanceUv=null,this.instanceColor=null,this.needSphereUp=!1,this.isRay=!0,this.overMaterial=null,this.currentOver=-1,this.isOver=!1,this.outline=null,this.tmpElement=[]}clearOutLine(){this.overMaterial&&this.outline&&(this.parent.remove(this.outline),this.outline=null,this.currentOver=-1)}addOutLine(e){this.overMaterial&&(this.outline||(this.outline=new t.Mesh(this.geometry,this.overMaterial)),this.outline.matrixAutoUpdate=!1,this.tmpMatrix.fromArray(this.instanceMatrix.array,16*e.idx),this.outline.matrix.copy(this.tmpMatrix),this.outline.matrixWorldNeedsUpdate=!0,this.parent.add(this.outline),this.currentOver=e.idx)}over(e){e&&!this.instance.isOver&&(this.instance.isOver=!0,this.instance.addOutLine(this)),!e&&this.instance.isOver&&(this.instance.isOver=!1,this.instance.clearOutLine())}setColorAt(e,i){null===this.instanceColor&&(this.instanceColor=new t.InstancedBufferAttribute(new Float32Array(3*this.instanceMatrix.count),3)),i.isColor&&(i=i.toArray());let s=3*e;this.instanceColor.array[s]=i[0],this.instanceColor.array[s+1]=i[1],this.instanceColor.array[s+2]=i[2]}add(e,i=[0,0,0],s=[0,0,0,1],a=[1,1,1],r=null,o=null){3===s.length&&(s=this.tmpQuat.setFromEuler({_x:s[0],_y:s[1],_z:s[2],_order:"XYZ"},!1).toArray()),r&&(r.isColor&&(r=r.toArray()),null===this.instanceColor&&(this.instanceColor=new t.InstancedBufferAttribute(new Float32Array(3*this.instanceMatrix.count),3))),this.expand(i,s,a,r,o),this.tmpElement.push(e)}slice(e,t,i){let s=new Float32Array(i-t);for(let a=0;a<t+i;++a)s[a]=e[t+a];return s}remove(e){if(!this.count)return;this.tmpElement.splice(e,1);let i=[...this.instanceMatrix.array];i.splice(16*e,16),this.instanceMatrix=new t.InstancedBufferAttribute(new Float32Array(i),16),null!==this.instanceColor&&(i=[...this.instanceColor.array],i.splice(3*e,3),this.instanceColor=new t.InstancedBufferAttribute(new Float32Array(i),3)),null!==this.instanceUv&&(i=[...this.instanceUv.array],i.splice(2*e,2),this.instanceUv=new t.InstancedBufferAttribute(new Float32Array(i),2)),this.count--,this.reDistribute()}reDistribute(){let e=this.count;for(;e--;)this.tmpElement[e].idx=e}getIDName(e){return this.tmpElement[e].name}getBodyList(){let e=[],t=this.count;for(;t--;)e.push(this.tmpElement[t].name);return e}expand(e,i,s,a=[1,1,1],r){let o=null!==this.instanceMatrix?this.instanceMatrix.array:[];this.tmpMatrix.compose({x:e[0],y:e[1],z:e[2]},{_x:i[0],_y:i[1],_z:i[2],_w:i[3]},{x:s[0],y:s[1],z:s[2]}),this.instanceMatrix=new t.InstancedBufferAttribute(new Float32Array([...o,...this.tmpMatrix.toArray()]),16),null!==this.instanceColor&&(o=this.instanceColor.array,this.instanceColor=new t.InstancedBufferAttribute(new Float32Array([...o,...a]),3)),this.count++}setTransformAt(e,t,i,s){this.tmpMatrix.compose({x:t[0],y:t[1],z:t[2]},{_x:i[0],_y:i[1],_z:i[2],_w:i[3]},{x:s[0],y:s[1],z:s[2]}),this.tmpMatrix.toArray(this.instanceMatrix.array,16*e),this.needSphereUp=!0,this.outline&&this.currentOver===e&&(this.outline.matrix.copy(this.tmpMatrix),this.outline.matrixWorldNeedsUpdate=!0)}dispose(){this.clearOutLine(),this.parent.remove(this),this.geometry.dispose(),this.instanceColor=null,this.count=0,this.tmpElement=[],this.dispatchEvent({type:"dispose"})}setRaycast(e){void 0!==e&&(this.isRay=e)}raycast(e,t){this.isRay&&(this.instanceMatrix.needsUpdate=!0,super.raycast(e,t))}update(){this.instanceMatrix&&(this.instanceMatrix.needsUpdate=!0),this.instanceColor&&(this.instanceColor.needsUpdate=!0),this.needSphereUp&&this.computeBoundingSphere(),this.needSphereUp=!1,this.updateMatrix()}}class U{constructor(e=0,t=0,i=0,s=1){this.isQuaternion=!0,this._x=e,this._y=t,this._z=i,this._w=s}set(e,t,i,s){return this._x=e,this._y=t,this._z=i,this._w=s,this}fromArray(e,t=0){return this._x=e[t],this._y=e[t+1],this._z=e[t+2],this._w=e[t+3],this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._w,e}}function N(e,i=!1){const s=null!==e[0].index,a=new Set(Object.keys(e[0].attributes)),r=new Set(Object.keys(e[0].morphAttributes)),o={},n={},l=e[0].morphTargetsRelative,h=new t.BufferGeometry;let c=0;for(let t=0;t<e.length;++t){const A=e[t];let u=0;if(s!==(null!==A.index))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const e in A.attributes){if(!a.has(e))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+'. All geometries must have compatible attributes; make sure "'+e+'" attribute exists among all geometries, or in none of them.'),null;void 0===o[e]&&(o[e]=[]),o[e].push(A.attributes[e]),u++}if(u!==a.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+". Make sure all geometries have the same number of attributes."),null;if(l!==A.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const e in A.morphAttributes){if(!r.has(e))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+". .morphAttributes must be consistent throughout all geometries."),null;void 0===n[e]&&(n[e]=[]),n[e].push(A.morphAttributes[e])}if(i){let e;if(s)e=A.index.count;else{if(void 0===A.attributes.position)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+t+". The geometry must have either an index or a position attribute"),null;e=A.attributes.position.count}h.addGroup(c,e,t),c+=e}}if(s){let t=0;const i=[];for(let s=0;s<e.length;++s){const a=e[s].index;for(let e=0;e<a.count;++e)i.push(a.getX(e)+t);t+=e[s].attributes.position.count}h.setIndex(i)}for(const e in o){const t=z(o[e]);if(!t)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" attribute."),null;h.setAttribute(e,t)}for(const e in n){const t=n[e][0].length;if(0===t)break;h.morphAttributes=h.morphAttributes||{},h.morphAttributes[e]=[];for(let i=0;i<t;++i){const t=[];for(let s=0;s<n[e].length;++s)t.push(n[e][s][i]);const s=z(t);if(!s)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" morphAttribute."),null;h.morphAttributes[e].push(s)}}return h}function z(e){let i,s,a,r=-1,o=0;for(let t=0;t<e.length;++t){const n=e[t];if(void 0===i&&(i=n.array.constructor),i!==n.array.constructor)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes."),null;if(void 0===s&&(s=n.itemSize),s!==n.itemSize)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes."),null;if(void 0===a&&(a=n.normalized),a!==n.normalized)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes."),null;if(-1===r&&(r=n.gpuType),r!==n.gpuType)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes."),null;o+=n.count*s}const n=new i(o),l=new t.BufferAttribute(n,s,a);let h=0;for(let t=0;t<e.length;++t){const i=e[t];if(i.isInterleavedBufferAttribute){const e=h/s;for(let t=0,a=i.count;t<a;t++)for(let a=0;a<s;a++){const s=i.getComponent(t,a);l.setComponent(t+e,a,s)}}else n.set(i.array,h);h+=i.count*s}return void 0!==r&&(l.gpuType=r),l}function O(e,t=1e-4){t=Math.max(t,Number.EPSILON);const i={},s=e.getIndex(),a=e.getAttribute("position"),r=s?s.count:a.count;let o=0;const n=Object.keys(e.attributes),l={},h={},c=[],A=["getX","getY","getZ","getW"],u=["setX","setY","setZ","setW"];for(let t=0,i=n.length;t<i;t++){const i=n[t],s=e.attributes[i];l[i]=new s.constructor(new s.array.constructor(s.count*s.itemSize),s.itemSize,s.normalized);const a=e.morphAttributes[i];a&&(h[i]||(h[i]=[]),a.forEach(((e,t)=>{const s=new e.array.constructor(e.count*e.itemSize);h[i][t]=new e.constructor(s,e.itemSize,e.normalized)})))}const d=.5*t,p=Math.log10(1/t),g=Math.pow(10,p),m=d*g;for(let t=0;t<r;t++){const a=s?s.getX(t):t;let r="";for(let t=0,i=n.length;t<i;t++){const i=n[t],s=e.getAttribute(i),o=s.itemSize;for(let e=0;e<o;e++)r+=~~(s[A[e]](a)*g+m)+","}if(r in i)c.push(i[r]);else{for(let t=0,i=n.length;t<i;t++){const i=n[t],s=e.getAttribute(i),r=e.morphAttributes[i],c=s.itemSize,d=l[i],p=h[i];for(let e=0;e<c;e++){const t=A[e],i=u[e];if(d[i](o,s[t](a)),r)for(let e=0,s=r.length;e<s;e++)p[e][i](o,r[e][t](a))}}i[r]=o,c.push(o),o++}}const f=e.clone();for(const t in e.attributes){const e=l[t];if(f.setAttribute(t,new e.constructor(e.array.slice(0,o*e.itemSize),e.itemSize,e.normalized)),t in h)for(let e=0;e<h[t].length;e++){const i=h[t][e];f.morphAttributes[t][e]=new i.constructor(i.array.slice(0,o*i.itemSize),i.itemSize,i.normalized)}}return f.setIndex(c),f}class V extends t.BufferGeometry{constructor(e=1,i=10,s=10,a=10,r=1){super(),this.type="SphereBox",this.name="SphereBox_"+e+"_"+i+"_"+s+"_"+a+"_"+r,e=e||1,i=Math.floor(i),s=Math.floor(s),a=Math.floor(a);let o,n=new t.BoxGeometry(1,1,1,i,s,a),l=new t.Vector3,h=new t.Vector3,c=n.attributes.position.array,A=n.attributes.normal.array;for(let t=0,i=n.attributes.position.count;t<i;t++)o=3*t,l.set(c[o],c[o+1],c[o+2]),h.copy(l).normalize(),l.lerp(h,r).mul