shop-components 0.2.4 → 0.2.6

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.
@@ -0,0 +1,3893 @@
1
+ "use strict";var sn=Object.create;var Ti=Object.defineProperty;var rn=Object.getOwnPropertyDescriptor;var nn=Object.getOwnPropertyNames;var on=Object.getPrototypeOf,an=Object.prototype.hasOwnProperty;var ln=(n,e,t)=>e in n?Ti(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var cn=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of nn(e))!an.call(n,s)&&s!==t&&Ti(n,s,{get:()=>e[s],enumerable:!(i=rn(e,s))||i.enumerable});return n};var un=(n,e,t)=>(t=n!=null?sn(on(n)):{},cn(e||!n||!n.__esModule?Ti(t,"default",{value:n,enumerable:!0}):t,n));var L=(n,e,t)=>(ln(n,typeof e!="symbol"?e+"":e,t),t),Ms=(n,e,t)=>{if(!e.has(n))throw TypeError("Cannot "+t)};var U=(n,e,t)=>(Ms(n,e,"read from private field"),t?t.call(n):e.get(n)),Re=(n,e,t)=>{if(e.has(n))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(n):e.set(n,t)},_e=(n,e,t,i)=>(Ms(n,e,"write to private field"),i?i.call(n,t):e.set(n,t),t);const f=require("three"),hn=require("three/examples/jsm/loaders/HDRLoader.js"),Cs=require("three/examples/jsm/postprocessing/RenderPass"),Ps=require("three/examples/jsm/postprocessing/OutlinePass"),fn=require("three/examples/jsm/postprocessing/ShaderPass"),dn=require("three/examples/jsm/shaders/FXAAShader"),pn=require("three/examples/jsm/postprocessing/UnrealBloomPass"),mn=require("three/examples/jsm/controls/OrbitControls"),gn=require("three/examples/jsm/postprocessing/OutputPass"),vn=require("three/examples/jsm/postprocessing/EffectComposer"),we=require("three/examples/jsm/renderers/CSS2DRenderer"),_n=require("three/examples/jsm/loaders/FontLoader"),ds=require("three/examples/jsm/loaders/GLTFLoader.js"),yn=require("three/examples/jsm/libs/meshopt_decoder.module.js"),xn=require("three/examples/jsm/loaders/DRACOLoader.js"),wn=require("three/examples/jsm/loaders/KTX2Loader.js"),B=require("./query-l2HhpUKG.js"),bn=require("three/examples/jsm/loaders/GLTFLoader"),An=require("three/examples/jsm/loaders/DRACOLoader"),Tn=require("three/examples/jsm/exporters/DRACOExporter"),Sn=require("three/examples/jsm/exporters/GLTFExporter"),Mn=require("three/examples/jsm/lines/LineSegments2.js"),Cn=require("three/examples/jsm/lines/LineSegmentsGeometry.js"),_r=require("three/examples/jsm/lines/LineMaterial.js"),Be=require("three-mesh-bvh"),gt=require("three/examples/jsm/postprocessing/Pass.js"),Pn=require("three/examples/jsm/lines/Line2.js"),Is=require("three/examples/jsm/lines/LineGeometry.js"),In=require("three/examples/jsm/renderers/CSS3DRenderer"),Rn=require("three/examples/jsm/utils/BufferGeometryUtils");var vt=typeof document<"u"?document.currentScript:null;function yr(n,e,t=0){if(n.isInterleavedBufferAttribute){const i=n.itemSize;for(let s=0,a=n.count;s<a;s++){const o=s+t;e.setX(o,n.getX(s)),i>=2&&e.setY(o,n.getY(s)),i>=3&&e.setZ(o,n.getZ(s)),i>=4&&e.setW(o,n.getW(s))}}else{const i=e.array,s=i.constructor,a=i.BYTES_PER_ELEMENT*n.itemSize*t;new s(i.buffer,a,n.array.length).set(n.array)}}function Ft(n,e=null){const t=n.array.constructor,i=n.normalized,s=n.itemSize,a=e===null?n.count:e;return new f.BufferAttribute(new t(s*a),s,i)}function ut(n,e){if(!n&&!e)return!0;if(!!n!=!!e)return!1;const t=n.count===e.count,i=n.normalized===e.normalized,s=n.array.constructor===e.array.constructor,a=n.itemSize===e.itemSize;return!(!t||!i||!s||!a)}function Dn(n){const e=n[0].index!==null,t=new Set(Object.keys(n[0].attributes));if(!n[0].getAttribute("position"))throw new Error("StaticGeometryGenerator: position attribute is required.");for(let i=0;i<n.length;++i){const s=n[i];let a=0;if(e!==(s.index!==null))throw new Error("StaticGeometryGenerator: All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.");for(const o in s.attributes){if(!t.has(o))throw new Error('StaticGeometryGenerator: All geometries must have compatible attributes; make sure "'+o+'" attribute exists among all geometries, or in none of them.');a++}if(a!==t.size)throw new Error("StaticGeometryGenerator: All geometries must have the same number of attributes.")}}function Ln(n){let e=0;for(let t=0,i=n.length;t<i;t++)e+=n[t].getIndex().count;return e}function En(n){let e=0;for(let t=0,i=n.length;t<i;t++)e+=n[t].getAttribute("position").count;return e}function Fn(n,e,t){n.index&&n.index.count!==e&&n.setIndex(null);const i=n.attributes;for(const s in i)i[s].count!==t&&n.deleteAttribute(s)}function Bn(n,e={},t=new f.BufferGeometry){const{useGroups:i=!1,forceUpdate:s=!1,skipAssigningAttributes:a=[],overwriteIndex:o=!0}=e;Dn(n);const c=n[0].index!==null,u=c?Ln(n):-1,m=En(n);if(Fn(t,u,m),i){let r=0;for(let l=0,h=n.length;l<h;l++){const g=n[l];let _;c?_=g.getIndex().count:_=g.getAttribute("position").count,t.addGroup(r,_,l),r+=_}}if(c){let r=!1;if(t.index||(t.setIndex(new f.BufferAttribute(new Uint32Array(u),1,!1)),r=!0),r||o){let l=0,h=0;const g=t.getIndex();for(let _=0,p=n.length;_<p;_++){const v=n[_],y=v.getIndex();if(!(!s&&!r&&a[_]))for(let w=0;w<y.count;++w)g.setX(l+w,y.getX(w)+h);l+=y.count,h+=v.getAttribute("position").count}}}const d=Object.keys(n[0].attributes);for(let r=0,l=d.length;r<l;r++){let h=!1;const g=d[r];if(!t.getAttribute(g)){const v=n[0].getAttribute(g);t.setAttribute(g,Ft(v,m)),h=!0}let _=0;const p=t.getAttribute(g);for(let v=0,y=n.length;v<y;v++){const x=n[v],w=!s&&!h&&a[v],b=x.getAttribute(g);w||yr(b,p,_),_+=b.count}}}function kn(n,e,t){const i=n.index,a=n.attributes.position.count,o=i?i.count:a;let c=n.groups;c.length===0&&(c=[{count:o,start:0,materialIndex:0}]);let u=n.getAttribute("materialIndex");if(!u||u.count!==a){let d;t.length<=255?d=new Uint8Array(a):d=new Uint16Array(a),u=new f.BufferAttribute(d,1,!1),n.deleteAttribute("materialIndex"),n.setAttribute("materialIndex",u)}const m=u.array;for(let d=0;d<c.length;d++){const r=c[d],l=r.start,h=r.count,g=Math.min(h,o-l),_=Array.isArray(e)?e[r.materialIndex]:e,p=t.indexOf(_);for(let v=0;v<g;v++){let y=l+v;i&&(y=i.getX(y)),m[y]=p}}}function On(n,e){if(!n.index){const t=n.attributes.position.count,i=new Array(t);for(let s=0;s<t;s++)i[s]=s;n.setIndex(i)}if(!n.attributes.normal&&e&&e.includes("normal")&&n.computeVertexNormals(),!n.attributes.uv&&e&&e.includes("uv")){const t=n.attributes.position.count;n.setAttribute("uv",new f.BufferAttribute(new Float32Array(t*2),2,!1))}if(!n.attributes.uv2&&e&&e.includes("uv2")){const t=n.attributes.position.count;n.setAttribute("uv2",new f.BufferAttribute(new Float32Array(t*2),2,!1))}if(!n.attributes.tangent&&e&&e.includes("tangent"))if(n.attributes.uv&&n.attributes.normal)n.computeTangents();else{const t=n.attributes.position.count;n.setAttribute("tangent",new f.BufferAttribute(new Float32Array(t*4),4,!1))}if(!n.attributes.color&&e&&e.includes("color")){const t=n.attributes.position.count,i=new Float32Array(t*4);i.fill(1),n.setAttribute("color",new f.BufferAttribute(i,4))}}function ps(n){let e=0;if(n.byteLength!==0){const t=new Uint8Array(n);for(let i=0;i<n.byteLength;i++){const s=t[i];e=(e<<5)-e+s,e|=0}}return e}function Rs(n){let e=n.uuid;const t=Object.values(n.attributes);n.index&&(t.push(n.index),e+=`index|${n.index.version}`);const i=Object.keys(t).sort();for(const s of i){const a=t[s];e+=`${s}_${a.version}|`}return e}function Ds(n){const e=n.skeleton;return e?(e.boneTexture||e.computeBoneTexture(),`${ps(e.boneTexture.image.data.buffer)}_${e.boneTexture.uuid}`):null}class zn{constructor(e=null){this.matrixWorld=new f.Matrix4,this.geometryHash=null,this.skeletonHash=null,this.primitiveCount=-1,e!==null&&this.updateFrom(e)}updateFrom(e){const t=e.geometry,i=(t.index?t.index.count:t.attributes.position.count)/3;this.matrixWorld.copy(e.matrixWorld),this.geometryHash=Rs(t),this.primitiveCount=i,this.skeletonHash=Ds(e)}didChange(e){const t=e.geometry,i=(t.index?t.index.count:t.attributes.position.count)/3;return!(this.matrixWorld.equals(e.matrixWorld)&&this.geometryHash===Rs(t)&&this.skeletonHash===Ds(e)&&this.primitiveCount===i)}}const Ve=new f.Vector3,Ue=new f.Vector3,He=new f.Vector3,Ls=new f.Vector4,Ht=new f.Vector3,Si=new f.Vector3,Es=new f.Vector4,Fs=new f.Vector4,Wt=new f.Matrix4,Bs=new f.Matrix4;function ks(n,e,t){const i=n.skeleton,s=n.geometry,a=i.bones,o=i.boneInverses;Es.fromBufferAttribute(s.attributes.skinIndex,e),Fs.fromBufferAttribute(s.attributes.skinWeight,e),Wt.elements.fill(0);for(let c=0;c<4;c++){const u=Fs.getComponent(c);if(u!==0){const m=Es.getComponent(c);Bs.multiplyMatrices(a[m].matrixWorld,o[m]),Vn(Wt,Bs,u)}}return Wt.multiply(n.bindMatrix).premultiply(n.bindMatrixInverse),t.transformDirection(Wt),t}function Mi(n,e,t,i,s){Ht.set(0,0,0);for(let a=0,o=n.length;a<o;a++){const c=e[a],u=n[a];c!==0&&(Si.fromBufferAttribute(u,i),t?Ht.addScaledVector(Si,c):Ht.addScaledVector(Si.sub(s),c))}s.add(Ht)}function Vn(n,e,t){const i=n.elements,s=e.elements;for(let a=0,o=s.length;a<o;a++)i[a]+=s[a]*t}function Un(n){const{index:e,attributes:t}=n;if(e)for(let i=0,s=e.count;i<s;i+=3){const a=e.getX(i),o=e.getX(i+2);e.setX(i,o),e.setX(i+2,a)}else for(const i in t){const s=t[i],a=s.itemSize;for(let o=0,c=s.count;o<c;o+=3)for(let u=0;u<a;u++){const m=s.getComponent(o,u),d=s.getComponent(o+2,u);s.setComponent(o,u,d),s.setComponent(o+2,u,m)}}return n}function Hn(n,e={},t=new f.BufferGeometry){e={applyWorldTransforms:!0,attributes:[],...e};const i=n.geometry,s=e.applyWorldTransforms,a=e.attributes.includes("normal"),o=e.attributes.includes("tangent"),c=i.attributes,u=t.attributes;for(const y in t.attributes)(!e.attributes.includes(y)||!(y in i.attributes))&&t.deleteAttribute(y);!t.index&&i.index&&(t.index=i.index.clone()),u.position||t.setAttribute("position",Ft(c.position)),a&&!u.normal&&c.normal&&t.setAttribute("normal",Ft(c.normal)),o&&!u.tangent&&c.tangent&&t.setAttribute("tangent",Ft(c.tangent)),ut(i.index,t.index),ut(c.position,u.position),a&&ut(c.normal,u.normal),o&&ut(c.tangent,u.tangent);const m=c.position,d=a?c.normal:null,r=o?c.tangent:null,l=i.morphAttributes.position,h=i.morphAttributes.normal,g=i.morphAttributes.tangent,_=i.morphTargetsRelative,p=n.morphTargetInfluences,v=new f.Matrix3;v.getNormalMatrix(n.matrixWorld),i.index&&t.index.array.set(i.index.array);for(let y=0,x=c.position.count;y<x;y++)Ve.fromBufferAttribute(m,y),d&&Ue.fromBufferAttribute(d,y),r&&(Ls.fromBufferAttribute(r,y),He.fromBufferAttribute(r,y)),p&&(l&&Mi(l,p,_,y,Ve),h&&Mi(h,p,_,y,Ue),g&&Mi(g,p,_,y,He)),n.isSkinnedMesh&&(n.applyBoneTransform(y,Ve),d&&ks(n,y,Ue),r&&ks(n,y,He)),s&&Ve.applyMatrix4(n.matrixWorld),u.position.setXYZ(y,Ve.x,Ve.y,Ve.z),d&&(s&&Ue.applyNormalMatrix(v),u.normal.setXYZ(y,Ue.x,Ue.y,Ue.z)),r&&(s&&He.transformDirection(n.matrixWorld),u.tangent.setXYZW(y,He.x,He.y,He.z,Ls.w));for(const y in e.attributes){const x=e.attributes[y];x==="position"||x==="tangent"||x==="normal"||!(x in c)||(u[x]||t.setAttribute(x,Ft(c[x])),ut(c[x],u[x]),yr(c[x],u[x]))}return n.matrixWorld.determinant()<0&&Un(t),t}class Wn extends f.BufferGeometry{constructor(){super(),this.version=0,this.hash=null,this._diff=new zn}isCompatible(e,t){const i=e.geometry;for(let s=0;s<t.length;s++){const a=t[s],o=i.attributes[a],c=this.attributes[a];if(o&&!ut(o,c))return!1}return!0}updateFrom(e,t){const i=this._diff;return i.didChange(e)?(Hn(e,t,this),i.updateFrom(e),this.version++,this.hash=`${this.uuid}_${this.version}`,!0):!1}}const qi=0,xr=1,wr=2;function Nn(n,e){for(let t=0,i=n.length;t<i;t++)n[t].traverseVisible(a=>{a.isMesh&&e(a)})}function Gn(n){const e=[];for(let t=0,i=n.length;t<i;t++){const s=n[t];Array.isArray(s.material)?e.push(...s.material):e.push(s.material)}return e}function qn(n,e,t){if(n.length===0){e.setIndex(null);const i=e.attributes;for(const s in i)e.deleteAttribute(s);for(const s in t.attributes)e.setAttribute(t.attributes[s],new f.BufferAttribute(new Float32Array(0),4,!1))}else Bn(n,t,e);for(const i in e.attributes)e.attributes[i].needsUpdate=!0}class jn{constructor(e){this.objects=null,this.useGroups=!0,this.applyWorldTransforms=!0,this.generateMissingAttributes=!0,this.overwriteIndex=!0,this.attributes=["position","normal","color","tangent","uv","uv2"],this._intermediateGeometry=new Map,this._geometryMergeSets=new WeakMap,this._mergeOrder=[],this._dummyMesh=null,this.setObjects(e||[])}_getDummyMesh(){if(!this._dummyMesh){const e=new f.MeshBasicMaterial,t=new f.BufferGeometry;t.setAttribute("position",new f.BufferAttribute(new Float32Array(9),3)),this._dummyMesh=new f.Mesh(t,e)}return this._dummyMesh}_getMeshes(){const e=[];return Nn(this.objects,t=>{e.push(t)}),e.sort((t,i)=>t.uuid>i.uuid?1:t.uuid<i.uuid?-1:0),e.length===0&&e.push(this._getDummyMesh()),e}_updateIntermediateGeometries(){const{_intermediateGeometry:e}=this,t=this._getMeshes(),i=new Set(e.keys()),s={attributes:this.attributes,applyWorldTransforms:this.applyWorldTransforms};for(let a=0,o=t.length;a<o;a++){const c=t[a],u=c.uuid;i.delete(u);let m=e.get(u);(!m||!m.isCompatible(c,this.attributes))&&(m&&m.dispose(),m=new Wn,e.set(u,m)),m.updateFrom(c,s)&&this.generateMissingAttributes&&On(m,this.attributes)}i.forEach(a=>{e.delete(a)})}setObjects(e){Array.isArray(e)?this.objects=[...e]:this.objects=[e]}generate(e=new f.BufferGeometry){const{useGroups:t,overwriteIndex:i,_intermediateGeometry:s,_geometryMergeSets:a}=this,o=this._getMeshes(),c=[],u=[],m=a.get(e)||[];this._updateIntermediateGeometries();let d=!1;o.length!==m.length&&(d=!0);for(let l=0,h=o.length;l<h;l++){const g=o[l],_=s.get(g.uuid);u.push(_);const p=m[l];!p||p.uuid!==_.uuid?(c.push(!1),d=!0):p.version!==_.version?c.push(!1):c.push(!0)}qn(u,e,{useGroups:t,forceUpdate:d,skipAssigningAttributes:c,overwriteIndex:i}),d&&e.dispose(),a.set(e,u.map(l=>({version:l.version,uuid:l.uuid})));let r=qi;return d?r=wr:c.includes(!1)&&(r=xr),{changeType:r,materials:Gn(o),geometry:e}}}function Yn(n){const e=new Set;for(let t=0,i=n.length;t<i;t++){const s=n[t];for(const a in s){const o=s[a];o&&o.isTexture&&e.add(o)}}return Array.from(e)}function Qn(n){const e=[],t=new Set;for(let s=0,a=n.length;s<a;s++)n[s].traverse(o=>{o.visible&&(o.isRectAreaLight||o.isSpotLight||o.isPointLight||o.isDirectionalLight)&&(e.push(o),o.iesMap&&t.add(o.iesMap))});const i=Array.from(t).sort((s,a)=>s.uuid<a.uuid?1:s.uuid>a.uuid?-1:0);return{lights:e,iesTextures:i}}class Xn{get initialized(){return!!this.bvh}constructor(e){this.bvhOptions={},this.attributes=["position","normal","tangent","color","uv","uv2"],this.generateBVH=!0,this.bvh=null,this.geometry=new f.BufferGeometry,this.staticGeometryGenerator=new jn(e),this._bvhWorker=null,this._pendingGenerate=null,this._buildAsync=!1}setObjects(e){this.staticGeometryGenerator.setObjects(e)}setBVHWorker(e){this._bvhWorker=e}async generateAsync(e=null){if(!this._bvhWorker)throw new Error('PathTracingSceneGenerator: "setBVHWorker" must be called before "generateAsync" can be called.');if(this.bvh instanceof Promise)return this._pendingGenerate||(this._pendingGenerate=new Promise(async()=>(await this.bvh,this._pendingGenerate=null,this.generateAsync(e)))),this._pendingGenerate;{this._buildAsync=!0;const t=this.generate(e);return this._buildAsync=!1,t.bvh=this.bvh=await t.bvh,t}}generate(e=null){const{staticGeometryGenerator:t,geometry:i,attributes:s}=this,a=t.objects;t.attributes=s,a.forEach(r=>{r.traverse(l=>{l.isSkinnedMesh&&l.skeleton&&l.skeleton.update()})});const o=t.generate(i),c=o.materials,u=Yn(c),{lights:m,iesTextures:d}=Qn(a);if(o.changeType!==qi&&kn(i,c,c),this.generateBVH){if(this.bvh instanceof Promise)throw new Error("PathTracingSceneGenerator: BVH is already building asynchronously.");if(o.changeType===wr){const r={strategy:Be.SAH,maxLeafTris:1,indirect:!0,onProgress:e,...this.bvhOptions};this._buildAsync?this.bvh=this._bvhWorker.generate(i,r):this.bvh=new Be.MeshBVH(i,r)}else o.changeType===xr&&this.bvh.refit()}return{bvhChanged:o.changeType!==qi,bvh:this.bvh,lights:m,iesTextures:d,geometry:i,materials:c,textures:u,objects:a}}}class ms extends f.ShaderMaterial{set needsUpdate(e){super.needsUpdate=!0,this.dispatchEvent({type:"recompilation"})}constructor(e){super(e);for(const t in this.uniforms)Object.defineProperty(this,t,{get(){return this.uniforms[t].value},set(i){this.uniforms[t].value=i}})}setDefine(e,t=void 0){if(t==null){if(e in this.defines)return delete this.defines[e],this.needsUpdate=!0,!0}else if(this.defines[e]!==t)return this.defines[e]=t,this.needsUpdate=!0,!0;return!1}}class Zn extends ms{constructor(e){super({blending:f.NoBlending,uniforms:{target1:{value:null},target2:{value:null},opacity:{value:1}},vertexShader:`
2
+
3
+ varying vec2 vUv;
4
+
5
+ void main() {
6
+
7
+ vUv = uv;
8
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
9
+
10
+ }`,fragmentShader:`
11
+
12
+ uniform float opacity;
13
+
14
+ uniform sampler2D target1;
15
+ uniform sampler2D target2;
16
+
17
+ varying vec2 vUv;
18
+
19
+ void main() {
20
+
21
+ vec4 color1 = texture2D( target1, vUv );
22
+ vec4 color2 = texture2D( target2, vUv );
23
+
24
+ float invOpacity = 1.0 - opacity;
25
+ float totalAlpha = color1.a * invOpacity + color2.a * opacity;
26
+
27
+ if ( color1.a != 0.0 || color2.a != 0.0 ) {
28
+
29
+ gl_FragColor.rgb = color1.rgb * ( invOpacity * color1.a / totalAlpha ) + color2.rgb * ( opacity * color2.a / totalAlpha );
30
+ gl_FragColor.a = totalAlpha;
31
+
32
+ } else {
33
+
34
+ gl_FragColor = vec4( 0.0 );
35
+
36
+ }
37
+
38
+ }`}),this.setValues(e)}}function Nt(n=1){let e="uint";return n>1&&(e="uvec"+n),`
39
+ ${e} sobolReverseBits( ${e} x ) {
40
+
41
+ x = ( ( ( x & 0xaaaaaaaau ) >> 1 ) | ( ( x & 0x55555555u ) << 1 ) );
42
+ x = ( ( ( x & 0xccccccccu ) >> 2 ) | ( ( x & 0x33333333u ) << 2 ) );
43
+ x = ( ( ( x & 0xf0f0f0f0u ) >> 4 ) | ( ( x & 0x0f0f0f0fu ) << 4 ) );
44
+ x = ( ( ( x & 0xff00ff00u ) >> 8 ) | ( ( x & 0x00ff00ffu ) << 8 ) );
45
+ return ( ( x >> 16 ) | ( x << 16 ) );
46
+
47
+ }
48
+
49
+ ${e} sobolHashCombine( uint seed, ${e} v ) {
50
+
51
+ return seed ^ ( v + ${e}( ( seed << 6 ) + ( seed >> 2 ) ) );
52
+
53
+ }
54
+
55
+ ${e} sobolLaineKarrasPermutation( ${e} x, ${e} seed ) {
56
+
57
+ x += seed;
58
+ x ^= x * 0x6c50b47cu;
59
+ x ^= x * 0xb82f1e52u;
60
+ x ^= x * 0xc7afe638u;
61
+ x ^= x * 0x8d22f6e6u;
62
+ return x;
63
+
64
+ }
65
+
66
+ ${e} nestedUniformScrambleBase2( ${e} x, ${e} seed ) {
67
+
68
+ x = sobolLaineKarrasPermutation( x, seed );
69
+ x = sobolReverseBits( x );
70
+ return x;
71
+
72
+ }
73
+ `}function Gt(n=1){let e="uint",t="float",i="",s=".r",a="1u";return n>1&&(e="uvec"+n,t="vec"+n,i=n+"",n===2?(s=".rg",a="uvec2( 1u, 2u )"):n===3?(s=".rgb",a="uvec3( 1u, 2u, 3u )"):(s="",a="uvec4( 1u, 2u, 3u, 4u )")),`
74
+
75
+ ${t} sobol${i}( int effect ) {
76
+
77
+ uint seed = sobolGetSeed( sobolBounceIndex, uint( effect ) );
78
+ uint index = sobolPathIndex;
79
+
80
+ uint shuffle_seed = sobolHashCombine( seed, 0u );
81
+ uint shuffled_index = nestedUniformScrambleBase2( sobolReverseBits( index ), shuffle_seed );
82
+ ${t} sobol_pt = sobolGetTexturePoint( shuffled_index )${s};
83
+ ${e} result = ${e}( sobol_pt * 16777216.0 );
84
+
85
+ ${e} seed2 = sobolHashCombine( seed, ${a} );
86
+ result = nestedUniformScrambleBase2( result, seed2 );
87
+
88
+ return SOBOL_FACTOR * ${t}( result >> 8 );
89
+
90
+ }
91
+ `}const br=`
92
+
93
+ // Utils
94
+ const float SOBOL_FACTOR = 1.0 / 16777216.0;
95
+ const uint SOBOL_MAX_POINTS = 256u * 256u;
96
+
97
+ ${Nt(1)}
98
+ ${Nt(2)}
99
+ ${Nt(3)}
100
+ ${Nt(4)}
101
+
102
+ uint sobolHash( uint x ) {
103
+
104
+ // finalizer from murmurhash3
105
+ x ^= x >> 16;
106
+ x *= 0x85ebca6bu;
107
+ x ^= x >> 13;
108
+ x *= 0xc2b2ae35u;
109
+ x ^= x >> 16;
110
+ return x;
111
+
112
+ }
113
+
114
+ `,Kn=`
115
+
116
+ const uint SOBOL_DIRECTIONS_1[ 32 ] = uint[ 32 ](
117
+ 0x80000000u, 0xc0000000u, 0xa0000000u, 0xf0000000u,
118
+ 0x88000000u, 0xcc000000u, 0xaa000000u, 0xff000000u,
119
+ 0x80800000u, 0xc0c00000u, 0xa0a00000u, 0xf0f00000u,
120
+ 0x88880000u, 0xcccc0000u, 0xaaaa0000u, 0xffff0000u,
121
+ 0x80008000u, 0xc000c000u, 0xa000a000u, 0xf000f000u,
122
+ 0x88008800u, 0xcc00cc00u, 0xaa00aa00u, 0xff00ff00u,
123
+ 0x80808080u, 0xc0c0c0c0u, 0xa0a0a0a0u, 0xf0f0f0f0u,
124
+ 0x88888888u, 0xccccccccu, 0xaaaaaaaau, 0xffffffffu
125
+ );
126
+
127
+ const uint SOBOL_DIRECTIONS_2[ 32 ] = uint[ 32 ](
128
+ 0x80000000u, 0xc0000000u, 0x60000000u, 0x90000000u,
129
+ 0xe8000000u, 0x5c000000u, 0x8e000000u, 0xc5000000u,
130
+ 0x68800000u, 0x9cc00000u, 0xee600000u, 0x55900000u,
131
+ 0x80680000u, 0xc09c0000u, 0x60ee0000u, 0x90550000u,
132
+ 0xe8808000u, 0x5cc0c000u, 0x8e606000u, 0xc5909000u,
133
+ 0x6868e800u, 0x9c9c5c00u, 0xeeee8e00u, 0x5555c500u,
134
+ 0x8000e880u, 0xc0005cc0u, 0x60008e60u, 0x9000c590u,
135
+ 0xe8006868u, 0x5c009c9cu, 0x8e00eeeeu, 0xc5005555u
136
+ );
137
+
138
+ const uint SOBOL_DIRECTIONS_3[ 32 ] = uint[ 32 ](
139
+ 0x80000000u, 0xc0000000u, 0x20000000u, 0x50000000u,
140
+ 0xf8000000u, 0x74000000u, 0xa2000000u, 0x93000000u,
141
+ 0xd8800000u, 0x25400000u, 0x59e00000u, 0xe6d00000u,
142
+ 0x78080000u, 0xb40c0000u, 0x82020000u, 0xc3050000u,
143
+ 0x208f8000u, 0x51474000u, 0xfbea2000u, 0x75d93000u,
144
+ 0xa0858800u, 0x914e5400u, 0xdbe79e00u, 0x25db6d00u,
145
+ 0x58800080u, 0xe54000c0u, 0x79e00020u, 0xb6d00050u,
146
+ 0x800800f8u, 0xc00c0074u, 0x200200a2u, 0x50050093u
147
+ );
148
+
149
+ const uint SOBOL_DIRECTIONS_4[ 32 ] = uint[ 32 ](
150
+ 0x80000000u, 0x40000000u, 0x20000000u, 0xb0000000u,
151
+ 0xf8000000u, 0xdc000000u, 0x7a000000u, 0x9d000000u,
152
+ 0x5a800000u, 0x2fc00000u, 0xa1600000u, 0xf0b00000u,
153
+ 0xda880000u, 0x6fc40000u, 0x81620000u, 0x40bb0000u,
154
+ 0x22878000u, 0xb3c9c000u, 0xfb65a000u, 0xddb2d000u,
155
+ 0x78022800u, 0x9c0b3c00u, 0x5a0fb600u, 0x2d0ddb00u,
156
+ 0xa2878080u, 0xf3c9c040u, 0xdb65a020u, 0x6db2d0b0u,
157
+ 0x800228f8u, 0x400b3cdcu, 0x200fb67au, 0xb00ddb9du
158
+ );
159
+
160
+ uint getMaskedSobol( uint index, uint directions[ 32 ] ) {
161
+
162
+ uint X = 0u;
163
+ for ( int bit = 0; bit < 32; bit ++ ) {
164
+
165
+ uint mask = ( index >> bit ) & 1u;
166
+ X ^= mask * directions[ bit ];
167
+
168
+ }
169
+ return X;
170
+
171
+ }
172
+
173
+ vec4 generateSobolPoint( uint index ) {
174
+
175
+ if ( index >= SOBOL_MAX_POINTS ) {
176
+
177
+ return vec4( 0.0 );
178
+
179
+ }
180
+
181
+ // NOTE: this sobol "direction" is also available but we can't write out 5 components
182
+ // uint x = index & 0x00ffffffu;
183
+ uint x = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_1 ) ) & 0x00ffffffu;
184
+ uint y = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_2 ) ) & 0x00ffffffu;
185
+ uint z = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_3 ) ) & 0x00ffffffu;
186
+ uint w = sobolReverseBits( getMaskedSobol( index, SOBOL_DIRECTIONS_4 ) ) & 0x00ffffffu;
187
+
188
+ return vec4( x, y, z, w ) * SOBOL_FACTOR;
189
+
190
+ }
191
+
192
+ `,$n=`
193
+
194
+ // Seeds
195
+ uniform sampler2D sobolTexture;
196
+ uint sobolPixelIndex = 0u;
197
+ uint sobolPathIndex = 0u;
198
+ uint sobolBounceIndex = 0u;
199
+
200
+ uint sobolGetSeed( uint bounce, uint effect ) {
201
+
202
+ return sobolHash(
203
+ sobolHashCombine(
204
+ sobolHashCombine(
205
+ sobolHash( bounce ),
206
+ sobolPixelIndex
207
+ ),
208
+ effect
209
+ )
210
+ );
211
+
212
+ }
213
+
214
+ vec4 sobolGetTexturePoint( uint index ) {
215
+
216
+ if ( index >= SOBOL_MAX_POINTS ) {
217
+
218
+ index = index % SOBOL_MAX_POINTS;
219
+
220
+ }
221
+
222
+ uvec2 dim = uvec2( textureSize( sobolTexture, 0 ).xy );
223
+ uint y = index / dim.x;
224
+ uint x = index - y * dim.x;
225
+ vec2 uv = vec2( x, y ) / vec2( dim );
226
+ return texture( sobolTexture, uv );
227
+
228
+ }
229
+
230
+ ${Gt(1)}
231
+ ${Gt(2)}
232
+ ${Gt(3)}
233
+ ${Gt(4)}
234
+
235
+ `;class Jn extends ms{constructor(){super({blending:f.NoBlending,uniforms:{resolution:{value:new f.Vector2}},vertexShader:`
236
+
237
+ varying vec2 vUv;
238
+ void main() {
239
+
240
+ vUv = uv;
241
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
242
+
243
+ }
244
+ `,fragmentShader:`
245
+
246
+ ${br}
247
+ ${Kn}
248
+
249
+ varying vec2 vUv;
250
+ uniform vec2 resolution;
251
+ void main() {
252
+
253
+ uint index = uint( gl_FragCoord.y ) * uint( resolution.x ) + uint( gl_FragCoord.x );
254
+ gl_FragColor = generateSobolPoint( index );
255
+
256
+ }
257
+ `})}}class eo{generate(e,t=256){const i=new f.WebGLRenderTarget(t,t,{type:f.FloatType,format:f.RGBAFormat,minFilter:f.NearestFilter,magFilter:f.NearestFilter,generateMipmaps:!1}),s=e.getRenderTarget();e.setRenderTarget(i);const a=new gt.FullScreenQuad(new Jn);return a.material.resolution.set(t,t),a.render(e),e.setRenderTarget(s),a.dispose(),i}}class to extends f.PerspectiveCamera{set bokehSize(e){this.fStop=this.getFocalLength()/e}get bokehSize(){return this.getFocalLength()/this.fStop}constructor(...e){super(...e),this.fStop=1.4,this.apertureBlades=0,this.apertureRotation=0,this.focusDistance=25,this.anamorphicRatio=1}copy(e,t){return super.copy(e,t),this.fStop=e.fStop,this.apertureBlades=e.apertureBlades,this.apertureRotation=e.apertureRotation,this.focusDistance=e.focusDistance,this.anamorphicRatio=e.anamorphicRatio,this}}class io{constructor(){this.bokehSize=0,this.apertureBlades=0,this.apertureRotation=0,this.focusDistance=10,this.anamorphicRatio=1}updateFrom(e){e instanceof to?(this.bokehSize=e.bokehSize,this.apertureBlades=e.apertureBlades,this.apertureRotation=e.apertureRotation,this.focusDistance=e.focusDistance,this.anamorphicRatio=e.anamorphicRatio):(this.bokehSize=0,this.apertureRotation=0,this.apertureBlades=0,this.focusDistance=10,this.anamorphicRatio=1)}}function Ci(n){const e=new Uint16Array(n.length);for(let t=0,i=n.length;t<i;++t)e[t]=f.DataUtils.toHalfFloat(n[t]);return e}function Os(n,e,t=0,i=n.length){let s=t,a=t+i-1;for(;s<a;){const o=s+a>>1;n[o]<e?s=o+1:a=o}return s-t}function so(n,e,t){return .2126*n+.7152*e+.0722*t}function ro(n,e=f.HalfFloatType){const t=n.clone();t.source=new f.Source({...t.image});const{width:i,height:s,data:a}=t.image;let o=a;if(t.type!==e){e===f.HalfFloatType?o=new Uint16Array(a.length):o=new Float32Array(a.length);let c;a instanceof Int8Array||a instanceof Int16Array||a instanceof Int32Array?c=2**(8*a.BYTES_PER_ELEMENT-1)-1:c=2**(8*a.BYTES_PER_ELEMENT)-1;for(let u=0,m=a.length;u<m;u++){let d=a[u];t.type===f.HalfFloatType&&(d=f.DataUtils.fromHalfFloat(a[u])),t.type!==f.FloatType&&t.type!==f.HalfFloatType&&(d/=c),e===f.HalfFloatType&&(o[u]=f.DataUtils.toHalfFloat(d))}t.image.data=o,t.type=e}if(t.flipY){const c=o;o=o.slice();for(let u=0;u<s;u++)for(let m=0;m<i;m++){const d=s-u-1,r=4*(u*i+m),l=4*(d*i+m);o[l+0]=c[r+0],o[l+1]=c[r+1],o[l+2]=c[r+2],o[l+3]=c[r+3]}t.flipY=!1,t.image.data=o}return t}class no{constructor(){const e=new f.DataTexture(Ci(new Float32Array([0,0,0,0])),1,1);e.type=f.HalfFloatType,e.format=f.RGBAFormat,e.minFilter=f.LinearFilter,e.magFilter=f.LinearFilter,e.wrapS=f.RepeatWrapping,e.wrapT=f.RepeatWrapping,e.generateMipmaps=!1,e.needsUpdate=!0;const t=new f.DataTexture(Ci(new Float32Array([0,1])),1,2);t.type=f.HalfFloatType,t.format=f.RedFormat,t.minFilter=f.LinearFilter,t.magFilter=f.LinearFilter,t.generateMipmaps=!1,t.needsUpdate=!0;const i=new f.DataTexture(Ci(new Float32Array([0,0,1,1])),2,2);i.type=f.HalfFloatType,i.format=f.RedFormat,i.minFilter=f.LinearFilter,i.magFilter=f.LinearFilter,i.generateMipmaps=!1,i.needsUpdate=!0,this.map=e,this.marginalWeights=t,this.conditionalWeights=i,this.totalSum=0}dispose(){this.marginalWeights.dispose(),this.conditionalWeights.dispose(),this.map.dispose()}updateFrom(e){const t=ro(e);t.wrapS=f.RepeatWrapping,t.wrapT=f.ClampToEdgeWrapping;const{width:i,height:s,data:a}=t.image,o=new Float32Array(i*s),c=new Float32Array(i*s),u=new Float32Array(s),m=new Float32Array(s);let d=0,r=0;for(let p=0;p<s;p++){let v=0;for(let y=0;y<i;y++){const x=p*i+y,w=f.DataUtils.fromHalfFloat(a[4*x+0]),b=f.DataUtils.fromHalfFloat(a[4*x+1]),T=f.DataUtils.fromHalfFloat(a[4*x+2]),M=so(w,b,T);v+=M,d+=M,o[x]=M,c[x]=v}if(v!==0)for(let y=p*i,x=p*i+i;y<x;y++)o[y]/=v,c[y]/=v;r+=v,u[p]=v,m[p]=r}if(r!==0)for(let p=0,v=u.length;p<v;p++)u[p]/=r,m[p]/=r;const l=new Uint16Array(s),h=new Uint16Array(i*s);for(let p=0;p<s;p++){const v=(p+1)/s,y=Os(m,v);l[p]=f.DataUtils.toHalfFloat((y+.5)/s)}for(let p=0;p<s;p++)for(let v=0;v<i;v++){const y=p*i+v,x=(v+1)/i,w=Os(c,x,p*i,i);h[y]=f.DataUtils.toHalfFloat((w+.5)/i)}this.dispose();const{marginalWeights:g,conditionalWeights:_}=this;g.image={width:s,height:1,data:l},g.needsUpdate=!0,_.image={width:i,height:s,data:h},_.needsUpdate=!0,this.totalSum=d,this.map=t}}const Pi=6,oo=0,ao=1,lo=2,co=3,uo=4,he=new f.Vector3,ee=new f.Vector3,zs=new f.Matrix4,Ze=new f.Quaternion,Vs=new f.Vector3,Ke=new f.Vector3,ho=new f.Vector3(0,1,0);class fo{constructor(){const e=new f.DataTexture(new Float32Array(4),1,1);e.format=f.RGBAFormat,e.type=f.FloatType,e.wrapS=f.ClampToEdgeWrapping,e.wrapT=f.ClampToEdgeWrapping,e.generateMipmaps=!1,e.minFilter=f.NearestFilter,e.magFilter=f.NearestFilter,this.tex=e,this.count=0}updateFrom(e,t=[]){const i=this.tex,s=Math.max(e.length*Pi,1),a=Math.ceil(Math.sqrt(s));i.image.width!==a&&(i.dispose(),i.image.data=new Float32Array(a*a*4),i.image.width=a,i.image.height=a);const o=i.image.data;for(let u=0,m=e.length;u<m;u++){const d=e[u],r=u*Pi*4;let l=0;for(let g=0;g<Pi*4;g++)o[r+g]=0;d.getWorldPosition(ee),o[r+l++]=ee.x,o[r+l++]=ee.y,o[r+l++]=ee.z;let h=oo;if(d.isRectAreaLight&&d.isCircular?h=ao:d.isSpotLight?h=lo:d.isDirectionalLight?h=co:d.isPointLight&&(h=uo),o[r+l++]=h,o[r+l++]=d.color.r,o[r+l++]=d.color.g,o[r+l++]=d.color.b,o[r+l++]=d.intensity,d.getWorldQuaternion(Ze),d.isRectAreaLight)he.set(d.width,0,0).applyQuaternion(Ze),o[r+l++]=he.x,o[r+l++]=he.y,o[r+l++]=he.z,l++,ee.set(0,d.height,0).applyQuaternion(Ze),o[r+l++]=ee.x,o[r+l++]=ee.y,o[r+l++]=ee.z,o[r+l++]=he.cross(ee).length()*(d.isCircular?Math.PI/4:1);else if(d.isSpotLight){const g=d.radius||0;Vs.setFromMatrixPosition(d.matrixWorld),Ke.setFromMatrixPosition(d.target.matrixWorld),zs.lookAt(Vs,Ke,ho),Ze.setFromRotationMatrix(zs),he.set(1,0,0).applyQuaternion(Ze),o[r+l++]=he.x,o[r+l++]=he.y,o[r+l++]=he.z,l++,ee.set(0,1,0).applyQuaternion(Ze),o[r+l++]=ee.x,o[r+l++]=ee.y,o[r+l++]=ee.z,o[r+l++]=Math.PI*g*g,o[r+l++]=g,o[r+l++]=d.decay,o[r+l++]=d.distance,o[r+l++]=Math.cos(d.angle),o[r+l++]=Math.cos(d.angle*(1-d.penumbra)),o[r+l++]=d.iesMap?t.indexOf(d.iesMap):-1}else if(d.isPointLight){const g=he.setFromMatrixPosition(d.matrixWorld);o[r+l++]=g.x,o[r+l++]=g.y,o[r+l++]=g.z,l++,l+=4,l+=1,o[r+l++]=d.decay,o[r+l++]=d.distance}else if(d.isDirectionalLight){const g=he.setFromMatrixPosition(d.matrixWorld),_=ee.setFromMatrixPosition(d.target.matrixWorld);Ke.subVectors(g,_).normalize(),o[r+l++]=Ke.x,o[r+l++]=Ke.y,o[r+l++]=Ke.z}}this.count=e.length;const c=ps(o.buffer);return this.hash!==c?(this.hash=c,i.needsUpdate=!0,!0):!1}}function Us(n,e,t,i,s){if(e>i)throw new Error;const a=n.length/e,o=n.constructor.BYTES_PER_ELEMENT*8;let c=1;switch(n.constructor){case Uint8Array:case Uint16Array:case Uint32Array:c=2**o-1;break;case Int8Array:case Int16Array:case Int32Array:c=2**(o-1)-1;break}for(let u=0;u<a;u++){const m=4*u,d=e*u;for(let r=0;r<i;r++)t[s+m+r]=e>=r+1?n[d+r]/c:0}}class po extends f.DataArrayTexture{constructor(){super(),this._textures=[],this.type=f.FloatType,this.format=f.RGBAFormat,this.internalFormat="RGBA32F"}updateAttribute(e,t){const i=this._textures[e];i.updateFrom(t);const s=i.image,a=this.image;if(s.width!==a.width||s.height!==a.height)throw new Error("FloatAttributeTextureArray: Attribute must be the same dimensions when updating single layer.");const{width:o,height:c,data:u}=a,d=o*c*4*e;let r=t.itemSize;r===3&&(r=4),Us(i.image.data,r,u,4,d),this.dispose(),this.needsUpdate=!0}setAttributes(e){const t=e[0].count,i=e.length;for(let r=0,l=i;r<l;r++)if(e[r].count!==t)throw new Error("FloatAttributeTextureArray: All attributes must have the same item count.");const s=this._textures;for(;s.length<i;){const r=new Be.FloatVertexAttributeTexture;s.push(r)}for(;s.length>i;)s.pop();for(let r=0,l=i;r<l;r++)s[r].updateFrom(e[r]);const o=s[0].image,c=this.image;(o.width!==c.width||o.height!==c.height||o.depth!==i)&&(c.width=o.width,c.height=o.height,c.depth=i,c.data=new Float32Array(c.width*c.height*c.depth*4));const{data:u,width:m,height:d}=c;for(let r=0,l=i;r<l;r++){const h=s[r],_=m*d*4*r;let p=e[r].itemSize;p===3&&(p=4),Us(h.image.data,p,u,4,_)}this.dispose(),this.needsUpdate=!0}}class mo extends po{updateNormalAttribute(e){this.updateAttribute(0,e)}updateTangentAttribute(e){this.updateAttribute(1,e)}updateUvAttribute(e){this.updateAttribute(2,e)}updateColorAttribute(e){this.updateAttribute(3,e)}updateFrom(e,t,i,s){this.setAttributes([e,t,i,s])}}function gs(n,e){return n.uuid<e.uuid?1:n.uuid>e.uuid?-1:0}function ji(n){return`${n.source.uuid}:${n.colorSpace}`}function go(n){const e=new Set,t=[];for(let i=0,s=n.length;i<s;i++){const a=n[i],o=ji(a);e.has(o)||(e.add(o),t.push(a))}return t}function vo(n){const e=n.map(i=>i.iesMap||null).filter(i=>i),t=new Set(e);return Array.from(t).sort(gs)}function _o(n){const e=new Set;for(let i=0,s=n.length;i<s;i++){const a=n[i];for(const o in a){const c=a[o];c&&c.isTexture&&e.add(c)}}const t=Array.from(e);return go(t).sort(gs)}function yo(n){const e=[];return n.traverse(t=>{t.visible&&(t.isRectAreaLight||t.isSpotLight||t.isPointLight||t.isDirectionalLight)&&e.push(t)}),e.sort(gs)}const Ar=45,Hs=Ar*4;class xo{constructor(){this._features={}}isUsed(e){return e in this._features}setUsed(e,t=!0){t===!1?delete this._features[e]:this._features[e]=!0}reset(){this._features={}}}class wo extends f.DataTexture{constructor(){super(new Float32Array(4),1,1),this.format=f.RGBAFormat,this.type=f.FloatType,this.wrapS=f.ClampToEdgeWrapping,this.wrapT=f.ClampToEdgeWrapping,this.minFilter=f.NearestFilter,this.magFilter=f.NearestFilter,this.generateMipmaps=!1,this.features=new xo}updateFrom(e,t){function i(g,_,p=-1){if(_ in g&&g[_]){const v=ji(g[_]);return r[v]}else return p}function s(g,_,p){return _ in g?g[_]:p}function a(g,_,p,v){const y=g[_]&&g[_].isTexture?g[_]:null;if(y){y.matrixAutoUpdate&&y.updateMatrix();const x=y.matrix.elements;let w=0;p[v+w++]=x[0],p[v+w++]=x[3],p[v+w++]=x[6],w++,p[v+w++]=x[1],p[v+w++]=x[4],p[v+w++]=x[7],w++}return 8}let o=0;const c=e.length*Ar,u=Math.ceil(Math.sqrt(c))||1,{image:m,features:d}=this,r={};for(let g=0,_=t.length;g<_;g++)r[ji(t[g])]=g;m.width!==u&&(this.dispose(),m.data=new Float32Array(u*u*4),m.width=u,m.height=u);const l=m.data;d.reset();for(let g=0,_=e.length;g<_;g++){const p=e[g];if(p.isFogVolumeMaterial){d.setUsed("FOG");for(let x=0;x<Hs;x++)l[o+x]=0;l[o+0*4+0]=p.color.r,l[o+0*4+1]=p.color.g,l[o+0*4+2]=p.color.b,l[o+2*4+3]=s(p,"emissiveIntensity",0),l[o+3*4+0]=p.emissive.r,l[o+3*4+1]=p.emissive.g,l[o+3*4+2]=p.emissive.b,l[o+13*4+1]=p.density,l[o+13*4+3]=0,l[o+14*4+2]=4,o+=Hs;continue}l[o++]=p.color.r,l[o++]=p.color.g,l[o++]=p.color.b,l[o++]=i(p,"map"),l[o++]=s(p,"metalness",0),l[o++]=i(p,"metalnessMap"),l[o++]=s(p,"roughness",0),l[o++]=i(p,"roughnessMap"),l[o++]=s(p,"ior",1.5),l[o++]=s(p,"transmission",0),l[o++]=i(p,"transmissionMap"),l[o++]=s(p,"emissiveIntensity",0),"emissive"in p?(l[o++]=p.emissive.r,l[o++]=p.emissive.g,l[o++]=p.emissive.b):(l[o++]=0,l[o++]=0,l[o++]=0),l[o++]=i(p,"emissiveMap"),l[o++]=i(p,"normalMap"),"normalScale"in p?(l[o++]=p.normalScale.x,l[o++]=p.normalScale.y):(l[o++]=1,l[o++]=1),l[o++]=s(p,"clearcoat",0),l[o++]=i(p,"clearcoatMap"),l[o++]=s(p,"clearcoatRoughness",0),l[o++]=i(p,"clearcoatRoughnessMap"),l[o++]=i(p,"clearcoatNormalMap"),"clearcoatNormalScale"in p?(l[o++]=p.clearcoatNormalScale.x,l[o++]=p.clearcoatNormalScale.y):(l[o++]=1,l[o++]=1),o++,l[o++]=s(p,"sheen",0),"sheenColor"in p?(l[o++]=p.sheenColor.r,l[o++]=p.sheenColor.g,l[o++]=p.sheenColor.b):(l[o++]=0,l[o++]=0,l[o++]=0),l[o++]=i(p,"sheenColorMap"),l[o++]=s(p,"sheenRoughness",0),l[o++]=i(p,"sheenRoughnessMap"),l[o++]=i(p,"iridescenceMap"),l[o++]=i(p,"iridescenceThicknessMap"),l[o++]=s(p,"iridescence",0),l[o++]=s(p,"iridescenceIOR",1.3);const v=s(p,"iridescenceThicknessRange",[100,400]);l[o++]=v[0],l[o++]=v[1],"specularColor"in p?(l[o++]=p.specularColor.r,l[o++]=p.specularColor.g,l[o++]=p.specularColor.b):(l[o++]=1,l[o++]=1,l[o++]=1),l[o++]=i(p,"specularColorMap"),l[o++]=s(p,"specularIntensity",1),l[o++]=i(p,"specularIntensityMap");const y=s(p,"thickness",0)===0&&s(p,"attenuationDistance",1/0)===1/0;if(l[o++]=Number(y),o++,"attenuationColor"in p?(l[o++]=p.attenuationColor.r,l[o++]=p.attenuationColor.g,l[o++]=p.attenuationColor.b):(l[o++]=1,l[o++]=1,l[o++]=1),l[o++]=s(p,"attenuationDistance",1/0),l[o++]=i(p,"alphaMap"),l[o++]=p.opacity,l[o++]=p.alphaTest,!y&&p.transmission>0)l[o++]=0;else switch(p.side){case f.FrontSide:l[o++]=1;break;case f.BackSide:l[o++]=-1;break;case f.DoubleSide:l[o++]=0;break}l[o++]=Number(s(p,"matte",!1)),l[o++]=Number(s(p,"castShadow",!0)),l[o++]=Number(p.vertexColors)|Number(p.flatShading)<<1,l[o++]=Number(p.transparent),o+=a(p,"map",l,o),o+=a(p,"metalnessMap",l,o),o+=a(p,"roughnessMap",l,o),o+=a(p,"transmissionMap",l,o),o+=a(p,"emissiveMap",l,o),o+=a(p,"normalMap",l,o),o+=a(p,"clearcoatMap",l,o),o+=a(p,"clearcoatNormalMap",l,o),o+=a(p,"clearcoatRoughnessMap",l,o),o+=a(p,"sheenColorMap",l,o),o+=a(p,"sheenRoughnessMap",l,o),o+=a(p,"iridescenceMap",l,o),o+=a(p,"iridescenceThicknessMap",l,o),o+=a(p,"specularColorMap",l,o),o+=a(p,"specularIntensityMap",l,o)}const h=ps(l.buffer);return this.hash!==h?(this.hash=h,this.needsUpdate=!0,!0):!1}}const Ws=new f.Color;function bo(n){return n?`${n.uuid}:${n.version}`:null}function Ao(n,e){for(const t in e)t in n&&(n[t]=e[t])}class Ns extends f.WebGLArrayRenderTarget{constructor(e,t,i){const s={format:f.RGBAFormat,type:f.UnsignedByteType,minFilter:f.LinearFilter,magFilter:f.LinearFilter,wrapS:f.RepeatWrapping,wrapT:f.RepeatWrapping,generateMipmaps:!1,...i};super(e,t,1,s),Ao(this.texture,s),this.texture.setTextures=(...o)=>{this.setTextures(...o)},this.hashes=[null];const a=new gt.FullScreenQuad(new To);this.fsQuad=a}setTextures(e,t,i=this.width,s=this.height){const a=e.getRenderTarget(),o=e.toneMapping,c=e.getClearAlpha();e.getClearColor(Ws);const u=t.length||1;(i!==this.width||s!==this.height||this.depth!==u)&&(this.setSize(i,s,u),this.hashes=new Array(u).fill(null)),e.setClearColor(0,0),e.toneMapping=f.NoToneMapping;const m=this.fsQuad,d=this.hashes;let r=!1;for(let l=0,h=u;l<h;l++){const g=t[l],_=bo(g);g&&(d[l]!==_||g.isWebGLRenderTarget)&&(g.matrixAutoUpdate=!1,g.matrix.identity(),m.material.map=g,e.setRenderTarget(this,l),m.render(e),g.updateMatrix(),g.matrixAutoUpdate=!0,d[l]=_,r=!0)}return m.material.map=null,e.setClearColor(Ws,c),e.setRenderTarget(a),e.toneMapping=o,r}dispose(){super.dispose(),this.fsQuad.dispose()}}class To extends f.ShaderMaterial{get map(){return this.uniforms.map.value}set map(e){this.uniforms.map.value=e}constructor(){super({uniforms:{map:{value:null}},vertexShader:`
258
+ varying vec2 vUv;
259
+ void main() {
260
+
261
+ vUv = uv;
262
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
263
+
264
+ }
265
+ `,fragmentShader:`
266
+ uniform sampler2D map;
267
+ varying vec2 vUv;
268
+ void main() {
269
+
270
+ gl_FragColor = texture2D( map, vUv );
271
+
272
+ }
273
+ `})}}function So(n,e=Math.random()){for(let t=n.length-1;t>0;t--){const i=Math.floor(e()*(t+1)),s=n[t];n[t]=n[i],n[i]=s}return n}class Mo{constructor(e,t,i=Math.random){const s=e**t,a=new Uint16Array(s);let o=s;for(let c=0;c<s;c++)a[c]=c;this.samples=new Float32Array(t),this.strataCount=e,this.reset=function(){for(let c=0;c<s;c++)a[c]=c;o=0},this.reshuffle=function(){o=0},this.next=function(){const{samples:c}=this;o>=a.length&&(So(a,i),this.reshuffle());let u=a[o++];for(let m=0;m<t;m++)c[m]=(u%e+i())/e,u=Math.floor(u/e);return c}}}class Co{constructor(e,t,i=Math.random){let s=0;for(const u of t)s+=u;const a=new Float32Array(s),o=[];let c=0;for(const u of t){const m=new Mo(e,u,i);m.samples=new Float32Array(a.buffer,c,m.samples.length),c+=m.samples.length*4,o.push(m)}this.samples=a,this.strataCount=e,this.next=function(){for(const u of o)u.next();return a},this.reshuffle=function(){for(const u of o)u.reshuffle()},this.reset=function(){for(const u of o)u.reset()}}}class Po{constructor(e=0){this.m=2147483648,this.a=1103515245,this.c=12345,this.seed=e}nextInt(){return this.seed=(this.a*this.seed+this.c)%this.m,this.seed}nextFloat(){return this.nextInt()/(this.m-1)}}class Io extends f.DataTexture{constructor(e=1,t=1,i=8){super(new Float32Array(1),1,1,f.RGBAFormat,f.FloatType),this.minFilter=f.NearestFilter,this.magFilter=f.NearestFilter,this.strata=i,this.sampler=null,this.generator=new Po,this.stableNoise=!1,this.random=()=>this.stableNoise?this.generator.nextFloat():Math.random(),this.init(e,t,i)}init(e=this.image.height,t=this.image.width,i=this.strata){const{image:s}=this;if(s.width===t&&s.height===e&&this.sampler!==null)return;const a=new Array(e*t).fill(4),o=new Co(i,a,this.random);s.width=t,s.height=e,s.data=o.samples,this.sampler=o,this.dispose(),this.next()}next(){this.sampler.next(),this.needsUpdate=!0}reset(){this.sampler.reset(),this.generator.seed=0}}function Ro(n,e=Math.random){for(let t=n.length-1;t>0;t--){const i=~~((e()-1e-6)*t),s=n[t];n[t]=n[i],n[i]=s}}function Do(n,e){n.fill(0);for(let t=0;t<e;t++)n[t]=1}class Gs{constructor(e){this.count=0,this.size=-1,this.sigma=-1,this.radius=-1,this.lookupTable=null,this.score=null,this.binaryPattern=null,this.resize(e),this.setSigma(1.5)}findVoid(){const{score:e,binaryPattern:t}=this;let i=1/0,s=-1;for(let a=0,o=t.length;a<o;a++){if(t[a]!==0)continue;const c=e[a];c<i&&(i=c,s=a)}return s}findCluster(){const{score:e,binaryPattern:t}=this;let i=-1/0,s=-1;for(let a=0,o=t.length;a<o;a++){if(t[a]!==1)continue;const c=e[a];c>i&&(i=c,s=a)}return s}setSigma(e){if(e===this.sigma)return;const t=~~(Math.sqrt(10*2*e**2)+1),i=2*t+1,s=new Float32Array(i*i),a=e*e;for(let o=-t;o<=t;o++)for(let c=-t;c<=t;c++){const u=(t+c)*i+o+t,m=o*o+c*c;s[u]=Math.E**(-m/(2*a))}this.lookupTable=s,this.sigma=e,this.radius=t}resize(e){this.size!==e&&(this.size=e,this.score=new Float32Array(e*e),this.binaryPattern=new Uint8Array(e*e))}invert(){const{binaryPattern:e,score:t,size:i}=this;t.fill(0);for(let s=0,a=e.length;s<a;s++)if(e[s]===0){const o=~~(s/i),c=s-o*i;this.updateScore(c,o,1),e[s]=1}else e[s]=0}updateScore(e,t,i){const{size:s,score:a,lookupTable:o}=this,c=this.radius,u=2*c+1;for(let m=-c;m<=c;m++)for(let d=-c;d<=c;d++){const r=(c+d)*u+m+c,l=o[r];let h=e+m;h=h<0?s+h:h%s;let g=t+d;g=g<0?s+g:g%s;const _=g*s+h;a[_]+=i*l}}addPointIndex(e){this.binaryPattern[e]=1;const t=this.size,i=~~(e/t),s=e-i*t;this.updateScore(s,i,1),this.count++}removePointIndex(e){this.binaryPattern[e]=0;const t=this.size,i=~~(e/t),s=e-i*t;this.updateScore(s,i,-1),this.count--}copy(e){this.resize(e.size),this.score.set(e.score),this.binaryPattern.set(e.binaryPattern),this.setSigma(e.sigma),this.count=e.count}}class Lo{constructor(){this.random=Math.random,this.sigma=1.5,this.size=64,this.majorityPointsRatio=.1,this.samples=new Gs(1),this.savedSamples=new Gs(1)}generate(){const{samples:e,savedSamples:t,sigma:i,majorityPointsRatio:s,size:a}=this;e.resize(a),e.setSigma(i);const o=Math.floor(a*a*s),c=e.binaryPattern;Do(c,o),Ro(c,this.random);for(let r=0,l=c.length;r<l;r++)c[r]===1&&e.addPointIndex(r);for(;;){const r=e.findCluster();e.removePointIndex(r);const l=e.findVoid();if(r===l){e.addPointIndex(r);break}e.addPointIndex(l)}const u=new Uint32Array(a*a);t.copy(e);let m;for(m=e.count-1;m>=0;){const r=e.findCluster();e.removePointIndex(r),u[r]=m,m--}const d=a*a;for(m=t.count;m<d/2;){const r=t.findVoid();t.addPointIndex(r),u[r]=m,m++}for(t.invert();m<d;){const r=t.findCluster();t.removePointIndex(r),u[r]=m,m++}return{data:u,maxValue:d}}}function Eo(n){return n>=3?4:n}function Fo(n){switch(n){case 1:return f.RedFormat;case 2:return f.RGFormat;default:return f.RGBAFormat}}class Bo extends f.DataTexture{constructor(e=64,t=1){super(new Float32Array(4),1,1,f.RGBAFormat,f.FloatType),this.minFilter=f.NearestFilter,this.magFilter=f.NearestFilter,this.size=e,this.channels=t,this.update()}update(){const e=this.channels,t=this.size,i=new Lo;i.channels=e,i.size=t;const s=Eo(e),a=Fo(s);(this.image.width!==t||a!==this.format)&&(this.image.width=t,this.image.height=t,this.image.data=new Float32Array(t**2*s),this.format=a,this.dispose());const o=this.image.data;for(let c=0,u=e;c<u;c++){const m=i.generate(),d=m.data,r=m.maxValue;for(let l=0,h=d.length;l<h;l++){const g=d[l]/r;o[l*s+c]=g}}this.needsUpdate=!0}}const ko=`
274
+
275
+ struct PhysicalCamera {
276
+
277
+ float focusDistance;
278
+ float anamorphicRatio;
279
+ float bokehSize;
280
+ int apertureBlades;
281
+ float apertureRotation;
282
+
283
+ };
284
+
285
+ `,Oo=`
286
+
287
+ struct EquirectHdrInfo {
288
+
289
+ sampler2D marginalWeights;
290
+ sampler2D conditionalWeights;
291
+ sampler2D map;
292
+
293
+ float totalSum;
294
+
295
+ };
296
+
297
+ `,zo=`
298
+
299
+ #define RECT_AREA_LIGHT_TYPE 0
300
+ #define CIRC_AREA_LIGHT_TYPE 1
301
+ #define SPOT_LIGHT_TYPE 2
302
+ #define DIR_LIGHT_TYPE 3
303
+ #define POINT_LIGHT_TYPE 4
304
+
305
+ struct LightsInfo {
306
+
307
+ sampler2D tex;
308
+ uint count;
309
+
310
+ };
311
+
312
+ struct Light {
313
+
314
+ vec3 position;
315
+ int type;
316
+
317
+ vec3 color;
318
+ float intensity;
319
+
320
+ vec3 u;
321
+ vec3 v;
322
+ float area;
323
+
324
+ // spot light fields
325
+ float radius;
326
+ float near;
327
+ float decay;
328
+ float distance;
329
+ float coneCos;
330
+ float penumbraCos;
331
+ int iesProfile;
332
+
333
+ };
334
+
335
+ Light readLightInfo( sampler2D tex, uint index ) {
336
+
337
+ uint i = index * 6u;
338
+
339
+ vec4 s0 = texelFetch1D( tex, i + 0u );
340
+ vec4 s1 = texelFetch1D( tex, i + 1u );
341
+ vec4 s2 = texelFetch1D( tex, i + 2u );
342
+ vec4 s3 = texelFetch1D( tex, i + 3u );
343
+
344
+ Light l;
345
+ l.position = s0.rgb;
346
+ l.type = int( round( s0.a ) );
347
+
348
+ l.color = s1.rgb;
349
+ l.intensity = s1.a;
350
+
351
+ l.u = s2.rgb;
352
+ l.v = s3.rgb;
353
+ l.area = s3.a;
354
+
355
+ if ( l.type == SPOT_LIGHT_TYPE || l.type == POINT_LIGHT_TYPE ) {
356
+
357
+ vec4 s4 = texelFetch1D( tex, i + 4u );
358
+ vec4 s5 = texelFetch1D( tex, i + 5u );
359
+ l.radius = s4.r;
360
+ l.decay = s4.g;
361
+ l.distance = s4.b;
362
+ l.coneCos = s4.a;
363
+
364
+ l.penumbraCos = s5.r;
365
+ l.iesProfile = int( round( s5.g ) );
366
+
367
+ } else {
368
+
369
+ l.radius = 0.0;
370
+ l.decay = 0.0;
371
+ l.distance = 0.0;
372
+
373
+ l.coneCos = 0.0;
374
+ l.penumbraCos = 0.0;
375
+ l.iesProfile = - 1;
376
+
377
+ }
378
+
379
+ return l;
380
+
381
+ }
382
+
383
+ `,Vo=`
384
+
385
+ struct Material {
386
+
387
+ vec3 color;
388
+ int map;
389
+
390
+ float metalness;
391
+ int metalnessMap;
392
+
393
+ float roughness;
394
+ int roughnessMap;
395
+
396
+ float ior;
397
+ float transmission;
398
+ int transmissionMap;
399
+
400
+ float emissiveIntensity;
401
+ vec3 emissive;
402
+ int emissiveMap;
403
+
404
+ int normalMap;
405
+ vec2 normalScale;
406
+
407
+ float clearcoat;
408
+ int clearcoatMap;
409
+ int clearcoatNormalMap;
410
+ vec2 clearcoatNormalScale;
411
+ float clearcoatRoughness;
412
+ int clearcoatRoughnessMap;
413
+
414
+ int iridescenceMap;
415
+ int iridescenceThicknessMap;
416
+ float iridescence;
417
+ float iridescenceIor;
418
+ float iridescenceThicknessMinimum;
419
+ float iridescenceThicknessMaximum;
420
+
421
+ vec3 specularColor;
422
+ int specularColorMap;
423
+
424
+ float specularIntensity;
425
+ int specularIntensityMap;
426
+ bool thinFilm;
427
+
428
+ vec3 attenuationColor;
429
+ float attenuationDistance;
430
+
431
+ int alphaMap;
432
+
433
+ bool castShadow;
434
+ float opacity;
435
+ float alphaTest;
436
+
437
+ float side;
438
+ bool matte;
439
+
440
+ float sheen;
441
+ vec3 sheenColor;
442
+ int sheenColorMap;
443
+ float sheenRoughness;
444
+ int sheenRoughnessMap;
445
+
446
+ bool vertexColors;
447
+ bool flatShading;
448
+ bool transparent;
449
+ bool fogVolume;
450
+
451
+ mat3 mapTransform;
452
+ mat3 metalnessMapTransform;
453
+ mat3 roughnessMapTransform;
454
+ mat3 transmissionMapTransform;
455
+ mat3 emissiveMapTransform;
456
+ mat3 normalMapTransform;
457
+ mat3 clearcoatMapTransform;
458
+ mat3 clearcoatNormalMapTransform;
459
+ mat3 clearcoatRoughnessMapTransform;
460
+ mat3 sheenColorMapTransform;
461
+ mat3 sheenRoughnessMapTransform;
462
+ mat3 iridescenceMapTransform;
463
+ mat3 iridescenceThicknessMapTransform;
464
+ mat3 specularColorMapTransform;
465
+ mat3 specularIntensityMapTransform;
466
+
467
+ };
468
+
469
+ mat3 readTextureTransform( sampler2D tex, uint index ) {
470
+
471
+ mat3 textureTransform;
472
+
473
+ vec4 row1 = texelFetch1D( tex, index );
474
+ vec4 row2 = texelFetch1D( tex, index + 1u );
475
+
476
+ textureTransform[0] = vec3(row1.r, row2.r, 0.0);
477
+ textureTransform[1] = vec3(row1.g, row2.g, 0.0);
478
+ textureTransform[2] = vec3(row1.b, row2.b, 1.0);
479
+
480
+ return textureTransform;
481
+
482
+ }
483
+
484
+ Material readMaterialInfo( sampler2D tex, uint index ) {
485
+
486
+ uint i = index * 45u;
487
+
488
+ vec4 s0 = texelFetch1D( tex, i + 0u );
489
+ vec4 s1 = texelFetch1D( tex, i + 1u );
490
+ vec4 s2 = texelFetch1D( tex, i + 2u );
491
+ vec4 s3 = texelFetch1D( tex, i + 3u );
492
+ vec4 s4 = texelFetch1D( tex, i + 4u );
493
+ vec4 s5 = texelFetch1D( tex, i + 5u );
494
+ vec4 s6 = texelFetch1D( tex, i + 6u );
495
+ vec4 s7 = texelFetch1D( tex, i + 7u );
496
+ vec4 s8 = texelFetch1D( tex, i + 8u );
497
+ vec4 s9 = texelFetch1D( tex, i + 9u );
498
+ vec4 s10 = texelFetch1D( tex, i + 10u );
499
+ vec4 s11 = texelFetch1D( tex, i + 11u );
500
+ vec4 s12 = texelFetch1D( tex, i + 12u );
501
+ vec4 s13 = texelFetch1D( tex, i + 13u );
502
+ vec4 s14 = texelFetch1D( tex, i + 14u );
503
+
504
+ Material m;
505
+ m.color = s0.rgb;
506
+ m.map = int( round( s0.a ) );
507
+
508
+ m.metalness = s1.r;
509
+ m.metalnessMap = int( round( s1.g ) );
510
+ m.roughness = s1.b;
511
+ m.roughnessMap = int( round( s1.a ) );
512
+
513
+ m.ior = s2.r;
514
+ m.transmission = s2.g;
515
+ m.transmissionMap = int( round( s2.b ) );
516
+ m.emissiveIntensity = s2.a;
517
+
518
+ m.emissive = s3.rgb;
519
+ m.emissiveMap = int( round( s3.a ) );
520
+
521
+ m.normalMap = int( round( s4.r ) );
522
+ m.normalScale = s4.gb;
523
+
524
+ m.clearcoat = s4.a;
525
+ m.clearcoatMap = int( round( s5.r ) );
526
+ m.clearcoatRoughness = s5.g;
527
+ m.clearcoatRoughnessMap = int( round( s5.b ) );
528
+ m.clearcoatNormalMap = int( round( s5.a ) );
529
+ m.clearcoatNormalScale = s6.rg;
530
+
531
+ m.sheen = s6.a;
532
+ m.sheenColor = s7.rgb;
533
+ m.sheenColorMap = int( round( s7.a ) );
534
+ m.sheenRoughness = s8.r;
535
+ m.sheenRoughnessMap = int( round( s8.g ) );
536
+
537
+ m.iridescenceMap = int( round( s8.b ) );
538
+ m.iridescenceThicknessMap = int( round( s8.a ) );
539
+ m.iridescence = s9.r;
540
+ m.iridescenceIor = s9.g;
541
+ m.iridescenceThicknessMinimum = s9.b;
542
+ m.iridescenceThicknessMaximum = s9.a;
543
+
544
+ m.specularColor = s10.rgb;
545
+ m.specularColorMap = int( round( s10.a ) );
546
+
547
+ m.specularIntensity = s11.r;
548
+ m.specularIntensityMap = int( round( s11.g ) );
549
+ m.thinFilm = bool( s11.b );
550
+
551
+ m.attenuationColor = s12.rgb;
552
+ m.attenuationDistance = s12.a;
553
+
554
+ m.alphaMap = int( round( s13.r ) );
555
+
556
+ m.opacity = s13.g;
557
+ m.alphaTest = s13.b;
558
+ m.side = s13.a;
559
+
560
+ m.matte = bool( s14.r );
561
+ m.castShadow = bool( s14.g );
562
+ m.vertexColors = bool( int( s14.b ) & 1 );
563
+ m.flatShading = bool( int( s14.b ) & 2 );
564
+ m.fogVolume = bool( int( s14.b ) & 4 );
565
+ m.transparent = bool( s14.a );
566
+
567
+ uint firstTextureTransformIdx = i + 15u;
568
+
569
+ // mat3( 1.0 ) is an identity matrix
570
+ m.mapTransform = m.map == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx );
571
+ m.metalnessMapTransform = m.metalnessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 2u );
572
+ m.roughnessMapTransform = m.roughnessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 4u );
573
+ m.transmissionMapTransform = m.transmissionMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 6u );
574
+ m.emissiveMapTransform = m.emissiveMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 8u );
575
+ m.normalMapTransform = m.normalMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 10u );
576
+ m.clearcoatMapTransform = m.clearcoatMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 12u );
577
+ m.clearcoatNormalMapTransform = m.clearcoatNormalMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 14u );
578
+ m.clearcoatRoughnessMapTransform = m.clearcoatRoughnessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 16u );
579
+ m.sheenColorMapTransform = m.sheenColorMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 18u );
580
+ m.sheenRoughnessMapTransform = m.sheenRoughnessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 20u );
581
+ m.iridescenceMapTransform = m.iridescenceMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 22u );
582
+ m.iridescenceThicknessMapTransform = m.iridescenceThicknessMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 24u );
583
+ m.specularColorMapTransform = m.specularColorMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 26u );
584
+ m.specularIntensityMapTransform = m.specularIntensityMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 28u );
585
+
586
+ return m;
587
+
588
+ }
589
+
590
+ `,Uo=`
591
+
592
+ struct SurfaceRecord {
593
+
594
+ // surface type
595
+ bool volumeParticle;
596
+
597
+ // geometry
598
+ vec3 faceNormal;
599
+ bool frontFace;
600
+ vec3 normal;
601
+ mat3 normalBasis;
602
+ mat3 normalInvBasis;
603
+
604
+ // cached properties
605
+ float eta;
606
+ float f0;
607
+
608
+ // material
609
+ float roughness;
610
+ float filteredRoughness;
611
+ float metalness;
612
+ vec3 color;
613
+ vec3 emission;
614
+
615
+ // transmission
616
+ float ior;
617
+ float transmission;
618
+ bool thinFilm;
619
+ vec3 attenuationColor;
620
+ float attenuationDistance;
621
+
622
+ // clearcoat
623
+ vec3 clearcoatNormal;
624
+ mat3 clearcoatBasis;
625
+ mat3 clearcoatInvBasis;
626
+ float clearcoat;
627
+ float clearcoatRoughness;
628
+ float filteredClearcoatRoughness;
629
+
630
+ // sheen
631
+ float sheen;
632
+ vec3 sheenColor;
633
+ float sheenRoughness;
634
+
635
+ // iridescence
636
+ float iridescence;
637
+ float iridescenceIor;
638
+ float iridescenceThickness;
639
+
640
+ // specular
641
+ vec3 specularColor;
642
+ float specularIntensity;
643
+ };
644
+
645
+ struct ScatterRecord {
646
+ float specularPdf;
647
+ float pdf;
648
+ vec3 direction;
649
+ vec3 color;
650
+ };
651
+
652
+ `,Ho=`
653
+
654
+ // samples the the given environment map in the given direction
655
+ vec3 sampleEquirectColor( sampler2D envMap, vec3 direction ) {
656
+
657
+ return texture2D( envMap, equirectDirectionToUv( direction ) ).rgb;
658
+
659
+ }
660
+
661
+ // gets the pdf of the given direction to sample
662
+ float equirectDirectionPdf( vec3 direction ) {
663
+
664
+ vec2 uv = equirectDirectionToUv( direction );
665
+ float theta = uv.y * PI;
666
+ float sinTheta = sin( theta );
667
+ if ( sinTheta == 0.0 ) {
668
+
669
+ return 0.0;
670
+
671
+ }
672
+
673
+ return 1.0 / ( 2.0 * PI * PI * sinTheta );
674
+
675
+ }
676
+
677
+ // samples the color given env map with CDF and returns the pdf of the direction
678
+ float sampleEquirect( vec3 direction, inout vec3 color ) {
679
+
680
+ float totalSum = envMapInfo.totalSum;
681
+ if ( totalSum == 0.0 ) {
682
+
683
+ color = vec3( 0.0 );
684
+ return 1.0;
685
+
686
+ }
687
+
688
+ vec2 uv = equirectDirectionToUv( direction );
689
+ color = texture2D( envMapInfo.map, uv ).rgb;
690
+
691
+ float lum = luminance( color );
692
+ ivec2 resolution = textureSize( envMapInfo.map, 0 );
693
+ float pdf = lum / totalSum;
694
+
695
+ return float( resolution.x * resolution.y ) * pdf * equirectDirectionPdf( direction );
696
+
697
+ }
698
+
699
+ // samples a direction of the envmap with color and retrieves pdf
700
+ float sampleEquirectProbability( vec2 r, inout vec3 color, inout vec3 direction ) {
701
+
702
+ // sample env map cdf
703
+ float v = texture2D( envMapInfo.marginalWeights, vec2( r.x, 0.0 ) ).x;
704
+ float u = texture2D( envMapInfo.conditionalWeights, vec2( r.y, v ) ).x;
705
+ vec2 uv = vec2( u, v );
706
+
707
+ vec3 derivedDirection = equirectUvToDirection( uv );
708
+ direction = derivedDirection;
709
+ color = texture2D( envMapInfo.map, uv ).rgb;
710
+
711
+ float totalSum = envMapInfo.totalSum;
712
+ float lum = luminance( color );
713
+ ivec2 resolution = textureSize( envMapInfo.map, 0 );
714
+ float pdf = lum / totalSum;
715
+
716
+ return float( resolution.x * resolution.y ) * pdf * equirectDirectionPdf( direction );
717
+
718
+ }
719
+ `,Wo=`
720
+
721
+ float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {
722
+
723
+ return smoothstep( coneCosine, penumbraCosine, angleCosine );
724
+
725
+ }
726
+
727
+ float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
728
+
729
+ // based upon Frostbite 3 Moving to Physically-based Rendering
730
+ // page 32, equation 26: E[window1]
731
+ // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
732
+ float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), EPSILON );
733
+
734
+ if ( cutoffDistance > 0.0 ) {
735
+
736
+ distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
737
+
738
+ }
739
+
740
+ return distanceFalloff;
741
+
742
+ }
743
+
744
+ float getPhotometricAttenuation( sampler2DArray iesProfiles, int iesProfile, vec3 posToLight, vec3 lightDir, vec3 u, vec3 v ) {
745
+
746
+ float cosTheta = dot( posToLight, lightDir );
747
+ float angle = acos( cosTheta ) / PI;
748
+
749
+ return texture2D( iesProfiles, vec3( angle, 0.0, iesProfile ) ).r;
750
+
751
+ }
752
+
753
+ struct LightRecord {
754
+
755
+ float dist;
756
+ vec3 direction;
757
+ float pdf;
758
+ vec3 emission;
759
+ int type;
760
+
761
+ };
762
+
763
+ bool intersectLightAtIndex( sampler2D lights, vec3 rayOrigin, vec3 rayDirection, uint l, inout LightRecord lightRec ) {
764
+
765
+ bool didHit = false;
766
+ Light light = readLightInfo( lights, l );
767
+
768
+ vec3 u = light.u;
769
+ vec3 v = light.v;
770
+
771
+ // check for backface
772
+ vec3 normal = normalize( cross( u, v ) );
773
+ if ( dot( normal, rayDirection ) > 0.0 ) {
774
+
775
+ u *= 1.0 / dot( u, u );
776
+ v *= 1.0 / dot( v, v );
777
+
778
+ float dist;
779
+
780
+ // MIS / light intersection is not supported for punctual lights.
781
+ if(
782
+ ( light.type == RECT_AREA_LIGHT_TYPE && intersectsRectangle( light.position, normal, u, v, rayOrigin, rayDirection, dist ) ) ||
783
+ ( light.type == CIRC_AREA_LIGHT_TYPE && intersectsCircle( light.position, normal, u, v, rayOrigin, rayDirection, dist ) )
784
+ ) {
785
+
786
+ float cosTheta = dot( rayDirection, normal );
787
+ didHit = true;
788
+ lightRec.dist = dist;
789
+ lightRec.pdf = ( dist * dist ) / ( light.area * cosTheta );
790
+ lightRec.emission = light.color * light.intensity;
791
+ lightRec.direction = rayDirection;
792
+ lightRec.type = light.type;
793
+
794
+ }
795
+
796
+ }
797
+
798
+ return didHit;
799
+
800
+ }
801
+
802
+ LightRecord randomAreaLightSample( Light light, vec3 rayOrigin, vec2 ruv ) {
803
+
804
+ vec3 randomPos;
805
+ if( light.type == RECT_AREA_LIGHT_TYPE ) {
806
+
807
+ // rectangular area light
808
+ randomPos = light.position + light.u * ( ruv.x - 0.5 ) + light.v * ( ruv.y - 0.5 );
809
+
810
+ } else if( light.type == CIRC_AREA_LIGHT_TYPE ) {
811
+
812
+ // circular area light
813
+ float r = 0.5 * sqrt( ruv.x );
814
+ float theta = ruv.y * 2.0 * PI;
815
+ float x = r * cos( theta );
816
+ float y = r * sin( theta );
817
+
818
+ randomPos = light.position + light.u * x + light.v * y;
819
+
820
+ }
821
+
822
+ vec3 toLight = randomPos - rayOrigin;
823
+ float lightDistSq = dot( toLight, toLight );
824
+ float dist = sqrt( lightDistSq );
825
+ vec3 direction = toLight / dist;
826
+ vec3 lightNormal = normalize( cross( light.u, light.v ) );
827
+
828
+ LightRecord lightRec;
829
+ lightRec.type = light.type;
830
+ lightRec.emission = light.color * light.intensity;
831
+ lightRec.dist = dist;
832
+ lightRec.direction = direction;
833
+
834
+ // TODO: the denominator is potentially zero
835
+ lightRec.pdf = lightDistSq / ( light.area * dot( direction, lightNormal ) );
836
+
837
+ return lightRec;
838
+
839
+ }
840
+
841
+ LightRecord randomSpotLightSample( Light light, sampler2DArray iesProfiles, vec3 rayOrigin, vec2 ruv ) {
842
+
843
+ float radius = light.radius * sqrt( ruv.x );
844
+ float theta = ruv.y * 2.0 * PI;
845
+ float x = radius * cos( theta );
846
+ float y = radius * sin( theta );
847
+
848
+ vec3 u = light.u;
849
+ vec3 v = light.v;
850
+ vec3 normal = normalize( cross( u, v ) );
851
+
852
+ float angle = acos( light.coneCos );
853
+ float angleTan = tan( angle );
854
+ float startDistance = light.radius / max( angleTan, EPSILON );
855
+
856
+ vec3 randomPos = light.position - normal * startDistance + u * x + v * y;
857
+ vec3 toLight = randomPos - rayOrigin;
858
+ float lightDistSq = dot( toLight, toLight );
859
+ float dist = sqrt( lightDistSq );
860
+
861
+ vec3 direction = toLight / max( dist, EPSILON );
862
+ float cosTheta = dot( direction, normal );
863
+
864
+ float spotAttenuation = light.iesProfile != - 1 ?
865
+ getPhotometricAttenuation( iesProfiles, light.iesProfile, direction, normal, u, v ) :
866
+ getSpotAttenuation( light.coneCos, light.penumbraCos, cosTheta );
867
+
868
+ float distanceAttenuation = getDistanceAttenuation( dist, light.distance, light.decay );
869
+ LightRecord lightRec;
870
+ lightRec.type = light.type;
871
+ lightRec.dist = dist;
872
+ lightRec.direction = direction;
873
+ lightRec.emission = light.color * light.intensity * distanceAttenuation * spotAttenuation;
874
+ lightRec.pdf = 1.0;
875
+
876
+ return lightRec;
877
+
878
+ }
879
+
880
+ LightRecord randomLightSample( sampler2D lights, sampler2DArray iesProfiles, uint lightCount, vec3 rayOrigin, vec3 ruv ) {
881
+
882
+ LightRecord result;
883
+
884
+ // pick a random light
885
+ uint l = uint( ruv.x * float( lightCount ) );
886
+ Light light = readLightInfo( lights, l );
887
+
888
+ if ( light.type == SPOT_LIGHT_TYPE ) {
889
+
890
+ result = randomSpotLightSample( light, iesProfiles, rayOrigin, ruv.yz );
891
+
892
+ } else if ( light.type == POINT_LIGHT_TYPE ) {
893
+
894
+ vec3 lightRay = light.u - rayOrigin;
895
+ float lightDist = length( lightRay );
896
+ float cutoffDistance = light.distance;
897
+ float distanceFalloff = 1.0 / max( pow( lightDist, light.decay ), 0.01 );
898
+ if ( cutoffDistance > 0.0 ) {
899
+
900
+ distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDist / cutoffDistance ) ) );
901
+
902
+ }
903
+
904
+ LightRecord rec;
905
+ rec.direction = normalize( lightRay );
906
+ rec.dist = length( lightRay );
907
+ rec.pdf = 1.0;
908
+ rec.emission = light.color * light.intensity * distanceFalloff;
909
+ rec.type = light.type;
910
+ result = rec;
911
+
912
+ } else if ( light.type == DIR_LIGHT_TYPE ) {
913
+
914
+ LightRecord rec;
915
+ rec.dist = 1e10;
916
+ rec.direction = light.u;
917
+ rec.pdf = 1.0;
918
+ rec.emission = light.color * light.intensity;
919
+ rec.type = light.type;
920
+
921
+ result = rec;
922
+
923
+ } else {
924
+
925
+ // sample the light
926
+ result = randomAreaLightSample( light, rayOrigin, ruv.yz );
927
+
928
+ }
929
+
930
+ return result;
931
+
932
+ }
933
+
934
+ `,No=`
935
+
936
+ vec3 sampleHemisphere( vec3 n, vec2 uv ) {
937
+
938
+ // https://www.rorydriscoll.com/2009/01/07/better-sampling/
939
+ // https://graphics.pixar.com/library/OrthonormalB/paper.pdf
940
+ float sign = n.z == 0.0 ? 1.0 : sign( n.z );
941
+ float a = - 1.0 / ( sign + n.z );
942
+ float b = n.x * n.y * a;
943
+ vec3 b1 = vec3( 1.0 + sign * n.x * n.x * a, sign * b, - sign * n.x );
944
+ vec3 b2 = vec3( b, sign + n.y * n.y * a, - n.y );
945
+
946
+ float r = sqrt( uv.x );
947
+ float theta = 2.0 * PI * uv.y;
948
+ float x = r * cos( theta );
949
+ float y = r * sin( theta );
950
+ return x * b1 + y * b2 + sqrt( 1.0 - uv.x ) * n;
951
+
952
+ }
953
+
954
+ vec2 sampleTriangle( vec2 a, vec2 b, vec2 c, vec2 r ) {
955
+
956
+ // get the edges of the triangle and the diagonal across the
957
+ // center of the parallelogram
958
+ vec2 e1 = a - b;
959
+ vec2 e2 = c - b;
960
+ vec2 diag = normalize( e1 + e2 );
961
+
962
+ // pick the point in the parallelogram
963
+ if ( r.x + r.y > 1.0 ) {
964
+
965
+ r = vec2( 1.0 ) - r;
966
+
967
+ }
968
+
969
+ return e1 * r.x + e2 * r.y;
970
+
971
+ }
972
+
973
+ vec2 sampleCircle( vec2 uv ) {
974
+
975
+ float angle = 2.0 * PI * uv.x;
976
+ float radius = sqrt( uv.y );
977
+ return vec2( cos( angle ), sin( angle ) ) * radius;
978
+
979
+ }
980
+
981
+ vec3 sampleSphere( vec2 uv ) {
982
+
983
+ float u = ( uv.x - 0.5 ) * 2.0;
984
+ float t = uv.y * PI * 2.0;
985
+ float f = sqrt( 1.0 - u * u );
986
+
987
+ return vec3( f * cos( t ), f * sin( t ), u );
988
+
989
+ }
990
+
991
+ vec2 sampleRegularPolygon( int sides, vec3 uvw ) {
992
+
993
+ sides = max( sides, 3 );
994
+
995
+ vec3 r = uvw;
996
+ float anglePerSegment = 2.0 * PI / float( sides );
997
+ float segment = floor( float( sides ) * r.x );
998
+
999
+ float angle1 = anglePerSegment * segment;
1000
+ float angle2 = angle1 + anglePerSegment;
1001
+ vec2 a = vec2( sin( angle1 ), cos( angle1 ) );
1002
+ vec2 b = vec2( 0.0, 0.0 );
1003
+ vec2 c = vec2( sin( angle2 ), cos( angle2 ) );
1004
+
1005
+ return sampleTriangle( a, b, c, r.yz );
1006
+
1007
+ }
1008
+
1009
+ // samples an aperture shape with the given number of sides. 0 means circle
1010
+ vec2 sampleAperture( int blades, vec3 uvw ) {
1011
+
1012
+ return blades == 0 ?
1013
+ sampleCircle( uvw.xy ) :
1014
+ sampleRegularPolygon( blades, uvw );
1015
+
1016
+ }
1017
+
1018
+
1019
+ `,Go=`
1020
+
1021
+ bool totalInternalReflection( float cosTheta, float eta ) {
1022
+
1023
+ float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
1024
+ return eta * sinTheta > 1.0;
1025
+
1026
+ }
1027
+
1028
+ // https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf
1029
+ float schlickFresnel( float cosine, float f0 ) {
1030
+
1031
+ return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
1032
+
1033
+ }
1034
+
1035
+ vec3 schlickFresnel( float cosine, vec3 f0 ) {
1036
+
1037
+ return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
1038
+
1039
+ }
1040
+
1041
+ vec3 schlickFresnel( float cosine, vec3 f0, vec3 f90 ) {
1042
+
1043
+ return f0 + ( f90 - f0 ) * pow( 1.0 - cosine, 5.0 );
1044
+
1045
+ }
1046
+
1047
+ float dielectricFresnel( float cosThetaI, float eta ) {
1048
+
1049
+ // https://schuttejoe.github.io/post/disneybsdf/
1050
+ float ni = eta;
1051
+ float nt = 1.0;
1052
+
1053
+ // Check for total internal reflection
1054
+ float sinThetaISq = 1.0f - cosThetaI * cosThetaI;
1055
+ float sinThetaTSq = eta * eta * sinThetaISq;
1056
+ if( sinThetaTSq >= 1.0 ) {
1057
+
1058
+ return 1.0;
1059
+
1060
+ }
1061
+
1062
+ float sinThetaT = sqrt( sinThetaTSq );
1063
+
1064
+ float cosThetaT = sqrt( max( 0.0, 1.0f - sinThetaT * sinThetaT ) );
1065
+ float rParallel = ( ( nt * cosThetaI ) - ( ni * cosThetaT ) ) / ( ( nt * cosThetaI ) + ( ni * cosThetaT ) );
1066
+ float rPerpendicular = ( ( ni * cosThetaI ) - ( nt * cosThetaT ) ) / ( ( ni * cosThetaI ) + ( nt * cosThetaT ) );
1067
+ return ( rParallel * rParallel + rPerpendicular * rPerpendicular ) / 2.0;
1068
+
1069
+ }
1070
+
1071
+ // https://raytracing.github.io/books/RayTracingInOneWeekend.html#dielectrics/schlickapproximation
1072
+ float iorRatioToF0( float eta ) {
1073
+
1074
+ return pow( ( 1.0 - eta ) / ( 1.0 + eta ), 2.0 );
1075
+
1076
+ }
1077
+
1078
+ vec3 evaluateFresnel( float cosTheta, float eta, vec3 f0, vec3 f90 ) {
1079
+
1080
+ if ( totalInternalReflection( cosTheta, eta ) ) {
1081
+
1082
+ return f90;
1083
+
1084
+ }
1085
+
1086
+ return schlickFresnel( cosTheta, f0, f90 );
1087
+
1088
+ }
1089
+
1090
+ // TODO: disney fresnel was removed and replaced with this fresnel function to better align with
1091
+ // the glTF but is causing blown out pixels. Should be revisited
1092
+ // float evaluateFresnelWeight( float cosTheta, float eta, float f0 ) {
1093
+
1094
+ // if ( totalInternalReflection( cosTheta, eta ) ) {
1095
+
1096
+ // return 1.0;
1097
+
1098
+ // }
1099
+
1100
+ // return schlickFresnel( cosTheta, f0 );
1101
+
1102
+ // }
1103
+
1104
+ // https://schuttejoe.github.io/post/disneybsdf/
1105
+ float disneyFresnel( vec3 wo, vec3 wi, vec3 wh, float f0, float eta, float metalness ) {
1106
+
1107
+ float dotHV = dot( wo, wh );
1108
+ if ( totalInternalReflection( dotHV, eta ) ) {
1109
+
1110
+ return 1.0;
1111
+
1112
+ }
1113
+
1114
+ float dotHL = dot( wi, wh );
1115
+ float dielectricFresnel = dielectricFresnel( abs( dotHV ), eta );
1116
+ float metallicFresnel = schlickFresnel( dotHL, f0 );
1117
+
1118
+ return mix( dielectricFresnel, metallicFresnel, metalness );
1119
+
1120
+ }
1121
+
1122
+ `,qo=`
1123
+
1124
+ // Fast arccos approximation used to remove banding artifacts caused by numerical errors in acos.
1125
+ // This is a cubic Lagrange interpolating polynomial for x = [-1, -1/2, 0, 1/2, 1].
1126
+ // For more information see: https://github.com/gkjohnson/three-gpu-pathtracer/pull/171#issuecomment-1152275248
1127
+ float acosApprox( float x ) {
1128
+
1129
+ x = clamp( x, -1.0, 1.0 );
1130
+ return ( - 0.69813170079773212 * x * x - 0.87266462599716477 ) * x + 1.5707963267948966;
1131
+
1132
+ }
1133
+
1134
+ // An acos with input values bound to the range [-1, 1].
1135
+ float acosSafe( float x ) {
1136
+
1137
+ return acos( clamp( x, -1.0, 1.0 ) );
1138
+
1139
+ }
1140
+
1141
+ float saturateCos( float val ) {
1142
+
1143
+ return clamp( val, 0.001, 1.0 );
1144
+
1145
+ }
1146
+
1147
+ float square( float t ) {
1148
+
1149
+ return t * t;
1150
+
1151
+ }
1152
+
1153
+ vec2 square( vec2 t ) {
1154
+
1155
+ return t * t;
1156
+
1157
+ }
1158
+
1159
+ vec3 square( vec3 t ) {
1160
+
1161
+ return t * t;
1162
+
1163
+ }
1164
+
1165
+ vec4 square( vec4 t ) {
1166
+
1167
+ return t * t;
1168
+
1169
+ }
1170
+
1171
+ vec2 rotateVector( vec2 v, float t ) {
1172
+
1173
+ float ac = cos( t );
1174
+ float as = sin( t );
1175
+ return vec2(
1176
+ v.x * ac - v.y * as,
1177
+ v.x * as + v.y * ac
1178
+ );
1179
+
1180
+ }
1181
+
1182
+ // forms a basis with the normal vector as Z
1183
+ mat3 getBasisFromNormal( vec3 normal ) {
1184
+
1185
+ vec3 other;
1186
+ if ( abs( normal.x ) > 0.5 ) {
1187
+
1188
+ other = vec3( 0.0, 1.0, 0.0 );
1189
+
1190
+ } else {
1191
+
1192
+ other = vec3( 1.0, 0.0, 0.0 );
1193
+
1194
+ }
1195
+
1196
+ vec3 ortho = normalize( cross( normal, other ) );
1197
+ vec3 ortho2 = normalize( cross( normal, ortho ) );
1198
+ return mat3( ortho2, ortho, normal );
1199
+
1200
+ }
1201
+
1202
+ `,jo=`
1203
+
1204
+ // Finds the point where the ray intersects the plane defined by u and v and checks if this point
1205
+ // falls in the bounds of the rectangle on that same plane.
1206
+ // Plane intersection: https://lousodrome.net/blog/light/2020/07/03/intersection-of-a-ray-and-a-plane/
1207
+ bool intersectsRectangle( vec3 center, vec3 normal, vec3 u, vec3 v, vec3 rayOrigin, vec3 rayDirection, inout float dist ) {
1208
+
1209
+ float t = dot( center - rayOrigin, normal ) / dot( rayDirection, normal );
1210
+
1211
+ if ( t > EPSILON ) {
1212
+
1213
+ vec3 p = rayOrigin + rayDirection * t;
1214
+ vec3 vi = p - center;
1215
+
1216
+ // check if p falls inside the rectangle
1217
+ float a1 = dot( u, vi );
1218
+ if ( abs( a1 ) <= 0.5 ) {
1219
+
1220
+ float a2 = dot( v, vi );
1221
+ if ( abs( a2 ) <= 0.5 ) {
1222
+
1223
+ dist = t;
1224
+ return true;
1225
+
1226
+ }
1227
+
1228
+ }
1229
+
1230
+ }
1231
+
1232
+ return false;
1233
+
1234
+ }
1235
+
1236
+ // Finds the point where the ray intersects the plane defined by u and v and checks if this point
1237
+ // falls in the bounds of the circle on that same plane. See above URL for a description of the plane intersection algorithm.
1238
+ bool intersectsCircle( vec3 position, vec3 normal, vec3 u, vec3 v, vec3 rayOrigin, vec3 rayDirection, inout float dist ) {
1239
+
1240
+ float t = dot( position - rayOrigin, normal ) / dot( rayDirection, normal );
1241
+
1242
+ if ( t > EPSILON ) {
1243
+
1244
+ vec3 hit = rayOrigin + rayDirection * t;
1245
+ vec3 vi = hit - position;
1246
+
1247
+ float a1 = dot( u, vi );
1248
+ float a2 = dot( v, vi );
1249
+
1250
+ if( length( vec2( a1, a2 ) ) <= 0.5 ) {
1251
+
1252
+ dist = t;
1253
+ return true;
1254
+
1255
+ }
1256
+
1257
+ }
1258
+
1259
+ return false;
1260
+
1261
+ }
1262
+
1263
+ `,Yo=`
1264
+
1265
+ // add texel fetch functions for texture arrays
1266
+ vec4 texelFetch1D( sampler2DArray tex, int layer, uint index ) {
1267
+
1268
+ uint width = uint( textureSize( tex, 0 ).x );
1269
+ uvec2 uv;
1270
+ uv.x = index % width;
1271
+ uv.y = index / width;
1272
+
1273
+ return texelFetch( tex, ivec3( uv, layer ), 0 );
1274
+
1275
+ }
1276
+
1277
+ vec4 textureSampleBarycoord( sampler2DArray tex, int layer, vec3 barycoord, uvec3 faceIndices ) {
1278
+
1279
+ return
1280
+ barycoord.x * texelFetch1D( tex, layer, faceIndices.x ) +
1281
+ barycoord.y * texelFetch1D( tex, layer, faceIndices.y ) +
1282
+ barycoord.z * texelFetch1D( tex, layer, faceIndices.z );
1283
+
1284
+ }
1285
+
1286
+ `,Tr=`
1287
+
1288
+ // TODO: possibly this should be renamed something related to material or path tracing logic
1289
+
1290
+ #ifndef RAY_OFFSET
1291
+ #define RAY_OFFSET 1e-4
1292
+ #endif
1293
+
1294
+ // adjust the hit point by the surface normal by a factor of some offset and the
1295
+ // maximum component-wise value of the current point to accommodate floating point
1296
+ // error as values increase.
1297
+ vec3 stepRayOrigin( vec3 rayOrigin, vec3 rayDirection, vec3 offset, float dist ) {
1298
+
1299
+ vec3 point = rayOrigin + rayDirection * dist;
1300
+ vec3 absPoint = abs( point );
1301
+ float maxPoint = max( absPoint.x, max( absPoint.y, absPoint.z ) );
1302
+ return point + offset * ( maxPoint + 1.0 ) * RAY_OFFSET;
1303
+
1304
+ }
1305
+
1306
+ // https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md#attenuation
1307
+ vec3 transmissionAttenuation( float dist, vec3 attColor, float attDist ) {
1308
+
1309
+ vec3 ot = - log( attColor ) / attDist;
1310
+ return exp( - ot * dist );
1311
+
1312
+ }
1313
+
1314
+ vec3 getHalfVector( vec3 wi, vec3 wo, float eta ) {
1315
+
1316
+ // get the half vector - assuming if the light incident vector is on the other side
1317
+ // of the that it's transmissive.
1318
+ vec3 h;
1319
+ if ( wi.z > 0.0 ) {
1320
+
1321
+ h = normalize( wi + wo );
1322
+
1323
+ } else {
1324
+
1325
+ // Scale by the ior ratio to retrieve the appropriate half vector
1326
+ // From Section 2.2 on computing the transmission half vector:
1327
+ // https://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf
1328
+ h = normalize( wi + wo * eta );
1329
+
1330
+ }
1331
+
1332
+ h *= sign( h.z );
1333
+ return h;
1334
+
1335
+ }
1336
+
1337
+ vec3 getHalfVector( vec3 a, vec3 b ) {
1338
+
1339
+ return normalize( a + b );
1340
+
1341
+ }
1342
+
1343
+ // The discrepancy between interpolated surface normal and geometry normal can cause issues when a ray
1344
+ // is cast that is on the top side of the geometry normal plane but below the surface normal plane. If
1345
+ // we find a ray like that we ignore it to avoid artifacts.
1346
+ // This function returns if the direction is on the same side of both planes.
1347
+ bool isDirectionValid( vec3 direction, vec3 surfaceNormal, vec3 geometryNormal ) {
1348
+
1349
+ bool aboveSurfaceNormal = dot( direction, surfaceNormal ) > 0.0;
1350
+ bool aboveGeometryNormal = dot( direction, geometryNormal ) > 0.0;
1351
+ return aboveSurfaceNormal == aboveGeometryNormal;
1352
+
1353
+ }
1354
+
1355
+ // ray sampling x and z are swapped to align with expected background view
1356
+ vec2 equirectDirectionToUv( vec3 direction ) {
1357
+
1358
+ // from Spherical.setFromCartesianCoords
1359
+ vec2 uv = vec2( atan( direction.z, direction.x ), acos( direction.y ) );
1360
+ uv /= vec2( 2.0 * PI, PI );
1361
+
1362
+ // apply adjustments to get values in range [0, 1] and y right side up
1363
+ uv.x += 0.5;
1364
+ uv.y = 1.0 - uv.y;
1365
+ return uv;
1366
+
1367
+ }
1368
+
1369
+ vec3 equirectUvToDirection( vec2 uv ) {
1370
+
1371
+ // undo above adjustments
1372
+ uv.x -= 0.5;
1373
+ uv.y = 1.0 - uv.y;
1374
+
1375
+ // from Vector3.setFromSphericalCoords
1376
+ float theta = uv.x * 2.0 * PI;
1377
+ float phi = uv.y * PI;
1378
+
1379
+ float sinPhi = sin( phi );
1380
+
1381
+ return vec3( sinPhi * cos( theta ), cos( phi ), sinPhi * sin( theta ) );
1382
+
1383
+ }
1384
+
1385
+ // power heuristic for multiple importance sampling
1386
+ float misHeuristic( float a, float b ) {
1387
+
1388
+ float aa = a * a;
1389
+ float bb = b * b;
1390
+ return aa / ( aa + bb );
1391
+
1392
+ }
1393
+
1394
+ // tentFilter from Peter Shirley's 'Realistic Ray Tracing (2nd Edition)' book, pg. 60
1395
+ // erichlof/THREE.js-PathTracing-Renderer/
1396
+ float tentFilter( float x ) {
1397
+
1398
+ return x < 0.5 ? sqrt( 2.0 * x ) - 1.0 : 1.0 - sqrt( 2.0 - ( 2.0 * x ) );
1399
+
1400
+ }
1401
+ `,qs=`
1402
+
1403
+ // https://www.shadertoy.com/view/wltcRS
1404
+ uvec4 WHITE_NOISE_SEED;
1405
+
1406
+ void rng_initialize( vec2 p, int frame ) {
1407
+
1408
+ // white noise seed
1409
+ WHITE_NOISE_SEED = uvec4( p, uint( frame ), uint( p.x ) + uint( p.y ) );
1410
+
1411
+ }
1412
+
1413
+ // https://www.pcg-random.org/
1414
+ void pcg4d( inout uvec4 v ) {
1415
+
1416
+ v = v * 1664525u + 1013904223u;
1417
+ v.x += v.y * v.w;
1418
+ v.y += v.z * v.x;
1419
+ v.z += v.x * v.y;
1420
+ v.w += v.y * v.z;
1421
+ v = v ^ ( v >> 16u );
1422
+ v.x += v.y*v.w;
1423
+ v.y += v.z*v.x;
1424
+ v.z += v.x*v.y;
1425
+ v.w += v.y*v.z;
1426
+
1427
+ }
1428
+
1429
+ // returns [ 0, 1 ]
1430
+ float pcgRand() {
1431
+
1432
+ pcg4d( WHITE_NOISE_SEED );
1433
+ return float( WHITE_NOISE_SEED.x ) / float( 0xffffffffu );
1434
+
1435
+ }
1436
+
1437
+ vec2 pcgRand2() {
1438
+
1439
+ pcg4d( WHITE_NOISE_SEED );
1440
+ return vec2( WHITE_NOISE_SEED.xy ) / float(0xffffffffu);
1441
+
1442
+ }
1443
+
1444
+ vec3 pcgRand3() {
1445
+
1446
+ pcg4d( WHITE_NOISE_SEED );
1447
+ return vec3( WHITE_NOISE_SEED.xyz ) / float( 0xffffffffu );
1448
+
1449
+ }
1450
+
1451
+ vec4 pcgRand4() {
1452
+
1453
+ pcg4d( WHITE_NOISE_SEED );
1454
+ return vec4( WHITE_NOISE_SEED ) / float( 0xffffffffu );
1455
+
1456
+ }
1457
+ `,Qo=`
1458
+
1459
+ uniform sampler2D stratifiedTexture;
1460
+ uniform sampler2D stratifiedOffsetTexture;
1461
+
1462
+ uint sobolPixelIndex = 0u;
1463
+ uint sobolPathIndex = 0u;
1464
+ uint sobolBounceIndex = 0u;
1465
+ vec4 pixelSeed = vec4( 0 );
1466
+
1467
+ vec4 rand4( int v ) {
1468
+
1469
+ ivec2 uv = ivec2( v, sobolBounceIndex );
1470
+ vec4 stratifiedSample = texelFetch( stratifiedTexture, uv, 0 );
1471
+ return fract( stratifiedSample + pixelSeed.r ); // blue noise + stratified samples
1472
+
1473
+ }
1474
+
1475
+ vec3 rand3( int v ) {
1476
+
1477
+ return rand4( v ).xyz;
1478
+
1479
+ }
1480
+
1481
+ vec2 rand2( int v ) {
1482
+
1483
+ return rand4( v ).xy;
1484
+
1485
+ }
1486
+
1487
+ float rand( int v ) {
1488
+
1489
+ return rand4( v ).x;
1490
+
1491
+ }
1492
+
1493
+ void rng_initialize( vec2 screenCoord, int frame ) {
1494
+
1495
+ // tile the small noise texture across the entire screen
1496
+ ivec2 noiseSize = ivec2( textureSize( stratifiedOffsetTexture, 0 ) );
1497
+ ivec2 pixel = ivec2( screenCoord.xy ) % noiseSize;
1498
+ vec2 pixelWidth = 1.0 / vec2( noiseSize );
1499
+ vec2 uv = vec2( pixel ) * pixelWidth + pixelWidth * 0.5;
1500
+
1501
+ // note that using "texelFetch" here seems to break Android for some reason
1502
+ pixelSeed = texture( stratifiedOffsetTexture, uv );
1503
+
1504
+ }
1505
+
1506
+ `,Xo=`
1507
+
1508
+ // diffuse
1509
+ float diffuseEval( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf, inout vec3 color ) {
1510
+
1511
+ // https://schuttejoe.github.io/post/disneybsdf/
1512
+ float fl = schlickFresnel( wi.z, 0.0 );
1513
+ float fv = schlickFresnel( wo.z, 0.0 );
1514
+
1515
+ float metalFactor = ( 1.0 - surf.metalness );
1516
+ float transFactor = ( 1.0 - surf.transmission );
1517
+ float rr = 0.5 + 2.0 * surf.roughness * fl * fl;
1518
+ float retro = rr * ( fl + fv + fl * fv * ( rr - 1.0f ) );
1519
+ float lambert = ( 1.0f - 0.5f * fl ) * ( 1.0f - 0.5f * fv );
1520
+
1521
+ // TODO: subsurface approx?
1522
+
1523
+ // float F = evaluateFresnelWeight( dot( wo, wh ), surf.eta, surf.f0 );
1524
+ float F = disneyFresnel( wo, wi, wh, surf.f0, surf.eta, surf.metalness );
1525
+ color = ( 1.0 - F ) * transFactor * metalFactor * wi.z * surf.color * ( retro + lambert ) / PI;
1526
+
1527
+ return wi.z / PI;
1528
+
1529
+ }
1530
+
1531
+ vec3 diffuseDirection( vec3 wo, SurfaceRecord surf ) {
1532
+
1533
+ vec3 lightDirection = sampleSphere( rand2( 11 ) );
1534
+ lightDirection.z += 1.0;
1535
+ lightDirection = normalize( lightDirection );
1536
+
1537
+ return lightDirection;
1538
+
1539
+ }
1540
+
1541
+ // specular
1542
+ float specularEval( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf, inout vec3 color ) {
1543
+
1544
+ // if roughness is set to 0 then D === NaN which results in black pixels
1545
+ float metalness = surf.metalness;
1546
+ float roughness = surf.filteredRoughness;
1547
+
1548
+ float eta = surf.eta;
1549
+ float f0 = surf.f0;
1550
+
1551
+ vec3 f0Color = mix( f0 * surf.specularColor * surf.specularIntensity, surf.color, surf.metalness );
1552
+ vec3 f90Color = vec3( mix( surf.specularIntensity, 1.0, surf.metalness ) );
1553
+ vec3 F = evaluateFresnel( dot( wo, wh ), eta, f0Color, f90Color );
1554
+
1555
+ vec3 iridescenceF = evalIridescence( 1.0, surf.iridescenceIor, dot( wi, wh ), surf.iridescenceThickness, f0Color );
1556
+ F = mix( F, iridescenceF, surf.iridescence );
1557
+
1558
+ // PDF
1559
+ // See 14.1.1 Microfacet BxDFs in https://www.pbr-book.org/
1560
+ float incidentTheta = acos( wo.z );
1561
+ float G = ggxShadowMaskG2( wi, wo, roughness );
1562
+ float D = ggxDistribution( wh, roughness );
1563
+ float G1 = ggxShadowMaskG1( incidentTheta, roughness );
1564
+ float ggxPdf = D * G1 * max( 0.0, abs( dot( wo, wh ) ) ) / abs ( wo.z );
1565
+
1566
+ color = wi.z * F * G * D / ( 4.0 * abs( wi.z * wo.z ) );
1567
+ return ggxPdf / ( 4.0 * dot( wo, wh ) );
1568
+
1569
+ }
1570
+
1571
+ vec3 specularDirection( vec3 wo, SurfaceRecord surf ) {
1572
+
1573
+ // sample ggx vndf distribution which gives a new normal
1574
+ float roughness = surf.filteredRoughness;
1575
+ vec3 halfVector = ggxDirection(
1576
+ wo,
1577
+ vec2( roughness ),
1578
+ rand2( 12 )
1579
+ );
1580
+
1581
+ // apply to new ray by reflecting off the new normal
1582
+ return - reflect( wo, halfVector );
1583
+
1584
+ }
1585
+
1586
+
1587
+ // transmission
1588
+ /*
1589
+ float transmissionEval( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf, inout vec3 color ) {
1590
+
1591
+ // See section 4.2 in https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
1592
+
1593
+ float filteredRoughness = surf.filteredRoughness;
1594
+ float eta = surf.eta;
1595
+ bool frontFace = surf.frontFace;
1596
+ bool thinFilm = surf.thinFilm;
1597
+
1598
+ color = surf.transmission * surf.color;
1599
+
1600
+ float denom = pow( eta * dot( wi, wh ) + dot( wo, wh ), 2.0 );
1601
+ return ggxPDF( wo, wh, filteredRoughness ) / denom;
1602
+
1603
+ }
1604
+
1605
+ vec3 transmissionDirection( vec3 wo, SurfaceRecord surf ) {
1606
+
1607
+ float filteredRoughness = surf.filteredRoughness;
1608
+ float eta = surf.eta;
1609
+ bool frontFace = surf.frontFace;
1610
+
1611
+ // sample ggx vndf distribution which gives a new normal
1612
+ vec3 halfVector = ggxDirection(
1613
+ wo,
1614
+ vec2( filteredRoughness ),
1615
+ rand2( 13 )
1616
+ );
1617
+
1618
+ vec3 lightDirection = refract( normalize( - wo ), halfVector, eta );
1619
+ if ( surf.thinFilm ) {
1620
+
1621
+ lightDirection = - refract( normalize( - lightDirection ), - vec3( 0.0, 0.0, 1.0 ), 1.0 / eta );
1622
+
1623
+ }
1624
+
1625
+ return normalize( lightDirection );
1626
+
1627
+ }
1628
+ */
1629
+
1630
+ // TODO: This is just using a basic cosine-weighted specular distribution with an
1631
+ // incorrect PDF value at the moment. Update it to correctly use a GGX distribution
1632
+ float transmissionEval( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf, inout vec3 color ) {
1633
+
1634
+ color = surf.transmission * surf.color;
1635
+
1636
+ // PDF
1637
+ // float F = evaluateFresnelWeight( dot( wo, wh ), surf.eta, surf.f0 );
1638
+ // float F = disneyFresnel( wo, wi, wh, surf.f0, surf.eta, surf.metalness );
1639
+ // if ( F >= 1.0 ) {
1640
+
1641
+ // return 0.0;
1642
+
1643
+ // }
1644
+
1645
+ // return 1.0 / ( 1.0 - F );
1646
+
1647
+ // reverted to previous to transmission. The above was causing black pixels
1648
+ float eta = surf.eta;
1649
+ float f0 = surf.f0;
1650
+ float cosTheta = min( wo.z, 1.0 );
1651
+ float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
1652
+ float reflectance = schlickFresnel( cosTheta, f0 );
1653
+ bool cannotRefract = eta * sinTheta > 1.0;
1654
+ if ( cannotRefract ) {
1655
+
1656
+ return 0.0;
1657
+
1658
+ }
1659
+
1660
+ return 1.0 / ( 1.0 - reflectance );
1661
+
1662
+ }
1663
+
1664
+ vec3 transmissionDirection( vec3 wo, SurfaceRecord surf ) {
1665
+
1666
+ float roughness = surf.filteredRoughness;
1667
+ float eta = surf.eta;
1668
+ vec3 halfVector = normalize( vec3( 0.0, 0.0, 1.0 ) + sampleSphere( rand2( 13 ) ) * roughness );
1669
+ vec3 lightDirection = refract( normalize( - wo ), halfVector, eta );
1670
+
1671
+ if ( surf.thinFilm ) {
1672
+
1673
+ lightDirection = - refract( normalize( - lightDirection ), - vec3( 0.0, 0.0, 1.0 ), 1.0 / eta );
1674
+
1675
+ }
1676
+ return normalize( lightDirection );
1677
+
1678
+ }
1679
+
1680
+ // clearcoat
1681
+ float clearcoatEval( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf, inout vec3 color ) {
1682
+
1683
+ float ior = 1.5;
1684
+ float f0 = iorRatioToF0( ior );
1685
+ bool frontFace = surf.frontFace;
1686
+ float roughness = surf.filteredClearcoatRoughness;
1687
+
1688
+ float eta = frontFace ? 1.0 / ior : ior;
1689
+ float G = ggxShadowMaskG2( wi, wo, roughness );
1690
+ float D = ggxDistribution( wh, roughness );
1691
+ float F = schlickFresnel( dot( wi, wh ), f0 );
1692
+
1693
+ float fClearcoat = F * D * G / ( 4.0 * abs( wi.z * wo.z ) );
1694
+ color = color * ( 1.0 - surf.clearcoat * F ) + fClearcoat * surf.clearcoat * wi.z;
1695
+
1696
+ // PDF
1697
+ // See equation (27) in http://jcgt.org/published/0003/02/03/
1698
+ return ggxPDF( wo, wh, roughness ) / ( 4.0 * dot( wi, wh ) );
1699
+
1700
+ }
1701
+
1702
+ vec3 clearcoatDirection( vec3 wo, SurfaceRecord surf ) {
1703
+
1704
+ // sample ggx vndf distribution which gives a new normal
1705
+ float roughness = surf.filteredClearcoatRoughness;
1706
+ vec3 halfVector = ggxDirection(
1707
+ wo,
1708
+ vec2( roughness ),
1709
+ rand2( 14 )
1710
+ );
1711
+
1712
+ // apply to new ray by reflecting off the new normal
1713
+ return - reflect( wo, halfVector );
1714
+
1715
+ }
1716
+
1717
+ // sheen
1718
+ vec3 sheenColor( vec3 wo, vec3 wi, vec3 wh, SurfaceRecord surf ) {
1719
+
1720
+ float cosThetaO = saturateCos( wo.z );
1721
+ float cosThetaI = saturateCos( wi.z );
1722
+ float cosThetaH = wh.z;
1723
+
1724
+ float D = velvetD( cosThetaH, surf.sheenRoughness );
1725
+ float G = velvetG( cosThetaO, cosThetaI, surf.sheenRoughness );
1726
+
1727
+ // See equation (1) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
1728
+ vec3 color = surf.sheenColor;
1729
+ color *= D * G / ( 4.0 * abs( cosThetaO * cosThetaI ) );
1730
+ color *= wi.z;
1731
+
1732
+ return color;
1733
+
1734
+ }
1735
+
1736
+ // bsdf
1737
+ void getLobeWeights(
1738
+ vec3 wo, vec3 wi, vec3 wh, vec3 clearcoatWo, SurfaceRecord surf,
1739
+ inout float diffuseWeight, inout float specularWeight, inout float transmissionWeight, inout float clearcoatWeight
1740
+ ) {
1741
+
1742
+ float metalness = surf.metalness;
1743
+ float transmission = surf.transmission;
1744
+ // float fEstimate = evaluateFresnelWeight( dot( wo, wh ), surf.eta, surf.f0 );
1745
+ float fEstimate = disneyFresnel( wo, wi, wh, surf.f0, surf.eta, surf.metalness );
1746
+
1747
+ float transSpecularProb = mix( max( 0.25, fEstimate ), 1.0, metalness );
1748
+ float diffSpecularProb = 0.5 + 0.5 * metalness;
1749
+
1750
+ diffuseWeight = ( 1.0 - transmission ) * ( 1.0 - diffSpecularProb );
1751
+ specularWeight = transmission * transSpecularProb + ( 1.0 - transmission ) * diffSpecularProb;
1752
+ transmissionWeight = transmission * ( 1.0 - transSpecularProb );
1753
+ clearcoatWeight = surf.clearcoat * schlickFresnel( clearcoatWo.z, 0.04 );
1754
+
1755
+ float totalWeight = diffuseWeight + specularWeight + transmissionWeight + clearcoatWeight;
1756
+ diffuseWeight /= totalWeight;
1757
+ specularWeight /= totalWeight;
1758
+ transmissionWeight /= totalWeight;
1759
+ clearcoatWeight /= totalWeight;
1760
+ }
1761
+
1762
+ float bsdfEval(
1763
+ vec3 wo, vec3 clearcoatWo, vec3 wi, vec3 clearcoatWi, SurfaceRecord surf,
1764
+ float diffuseWeight, float specularWeight, float transmissionWeight, float clearcoatWeight, inout float specularPdf, inout vec3 color
1765
+ ) {
1766
+
1767
+ float metalness = surf.metalness;
1768
+ float transmission = surf.transmission;
1769
+
1770
+ float spdf = 0.0;
1771
+ float dpdf = 0.0;
1772
+ float tpdf = 0.0;
1773
+ float cpdf = 0.0;
1774
+ color = vec3( 0.0 );
1775
+
1776
+ vec3 halfVector = getHalfVector( wi, wo, surf.eta );
1777
+
1778
+ // diffuse
1779
+ if ( diffuseWeight > 0.0 && wi.z > 0.0 ) {
1780
+
1781
+ dpdf = diffuseEval( wo, wi, halfVector, surf, color );
1782
+ color *= 1.0 - surf.transmission;
1783
+
1784
+ }
1785
+
1786
+ // ggx specular
1787
+ if ( specularWeight > 0.0 && wi.z > 0.0 ) {
1788
+
1789
+ vec3 outColor;
1790
+ spdf = specularEval( wo, wi, getHalfVector( wi, wo ), surf, outColor );
1791
+ color += outColor;
1792
+
1793
+ }
1794
+
1795
+ // transmission
1796
+ if ( transmissionWeight > 0.0 && wi.z < 0.0 ) {
1797
+
1798
+ tpdf = transmissionEval( wo, wi, halfVector, surf, color );
1799
+
1800
+ }
1801
+
1802
+ // sheen
1803
+ color *= mix( 1.0, sheenAlbedoScaling( wo, wi, surf ), surf.sheen );
1804
+ color += sheenColor( wo, wi, halfVector, surf ) * surf.sheen;
1805
+
1806
+ // clearcoat
1807
+ if ( clearcoatWi.z >= 0.0 && clearcoatWeight > 0.0 ) {
1808
+
1809
+ vec3 clearcoatHalfVector = getHalfVector( clearcoatWo, clearcoatWi );
1810
+ cpdf = clearcoatEval( clearcoatWo, clearcoatWi, clearcoatHalfVector, surf, color );
1811
+
1812
+ }
1813
+
1814
+ float pdf =
1815
+ dpdf * diffuseWeight
1816
+ + spdf * specularWeight
1817
+ + tpdf * transmissionWeight
1818
+ + cpdf * clearcoatWeight;
1819
+
1820
+ // retrieve specular rays for the shadows flag
1821
+ specularPdf = spdf * specularWeight + cpdf * clearcoatWeight;
1822
+
1823
+ return pdf;
1824
+
1825
+ }
1826
+
1827
+ float bsdfResult( vec3 worldWo, vec3 worldWi, SurfaceRecord surf, inout vec3 color ) {
1828
+
1829
+ if ( surf.volumeParticle ) {
1830
+
1831
+ color = surf.color / ( 4.0 * PI );
1832
+ return 1.0 / ( 4.0 * PI );
1833
+
1834
+ }
1835
+
1836
+ vec3 wo = normalize( surf.normalInvBasis * worldWo );
1837
+ vec3 wi = normalize( surf.normalInvBasis * worldWi );
1838
+
1839
+ vec3 clearcoatWo = normalize( surf.clearcoatInvBasis * worldWo );
1840
+ vec3 clearcoatWi = normalize( surf.clearcoatInvBasis * worldWi );
1841
+
1842
+ vec3 wh = getHalfVector( wo, wi, surf.eta );
1843
+ float diffuseWeight;
1844
+ float specularWeight;
1845
+ float transmissionWeight;
1846
+ float clearcoatWeight;
1847
+ getLobeWeights( wo, wi, wh, clearcoatWo, surf, diffuseWeight, specularWeight, transmissionWeight, clearcoatWeight );
1848
+
1849
+ float specularPdf;
1850
+ return bsdfEval( wo, clearcoatWo, wi, clearcoatWi, surf, diffuseWeight, specularWeight, transmissionWeight, clearcoatWeight, specularPdf, color );
1851
+
1852
+ }
1853
+
1854
+ ScatterRecord bsdfSample( vec3 worldWo, SurfaceRecord surf ) {
1855
+
1856
+ if ( surf.volumeParticle ) {
1857
+
1858
+ ScatterRecord sampleRec;
1859
+ sampleRec.specularPdf = 0.0;
1860
+ sampleRec.pdf = 1.0 / ( 4.0 * PI );
1861
+ sampleRec.direction = sampleSphere( rand2( 16 ) );
1862
+ sampleRec.color = surf.color / ( 4.0 * PI );
1863
+ return sampleRec;
1864
+
1865
+ }
1866
+
1867
+ vec3 wo = normalize( surf.normalInvBasis * worldWo );
1868
+ vec3 clearcoatWo = normalize( surf.clearcoatInvBasis * worldWo );
1869
+ mat3 normalBasis = surf.normalBasis;
1870
+ mat3 invBasis = surf.normalInvBasis;
1871
+ mat3 clearcoatNormalBasis = surf.clearcoatBasis;
1872
+ mat3 clearcoatInvBasis = surf.clearcoatInvBasis;
1873
+
1874
+ float diffuseWeight;
1875
+ float specularWeight;
1876
+ float transmissionWeight;
1877
+ float clearcoatWeight;
1878
+ // using normal and basically-reflected ray since we don't have proper half vector here
1879
+ getLobeWeights( wo, wo, vec3( 0, 0, 1 ), clearcoatWo, surf, diffuseWeight, specularWeight, transmissionWeight, clearcoatWeight );
1880
+
1881
+ float pdf[4];
1882
+ pdf[0] = diffuseWeight;
1883
+ pdf[1] = specularWeight;
1884
+ pdf[2] = transmissionWeight;
1885
+ pdf[3] = clearcoatWeight;
1886
+
1887
+ float cdf[4];
1888
+ cdf[0] = pdf[0];
1889
+ cdf[1] = pdf[1] + cdf[0];
1890
+ cdf[2] = pdf[2] + cdf[1];
1891
+ cdf[3] = pdf[3] + cdf[2];
1892
+
1893
+ if( cdf[3] != 0.0 ) {
1894
+
1895
+ float invMaxCdf = 1.0 / cdf[3];
1896
+ cdf[0] *= invMaxCdf;
1897
+ cdf[1] *= invMaxCdf;
1898
+ cdf[2] *= invMaxCdf;
1899
+ cdf[3] *= invMaxCdf;
1900
+
1901
+ } else {
1902
+
1903
+ cdf[0] = 1.0;
1904
+ cdf[1] = 0.0;
1905
+ cdf[2] = 0.0;
1906
+ cdf[3] = 0.0;
1907
+
1908
+ }
1909
+
1910
+ vec3 wi;
1911
+ vec3 clearcoatWi;
1912
+
1913
+ float r = rand( 15 );
1914
+ if ( r <= cdf[0] ) { // diffuse
1915
+
1916
+ wi = diffuseDirection( wo, surf );
1917
+ clearcoatWi = normalize( clearcoatInvBasis * normalize( normalBasis * wi ) );
1918
+
1919
+ } else if ( r <= cdf[1] ) { // specular
1920
+
1921
+ wi = specularDirection( wo, surf );
1922
+ clearcoatWi = normalize( clearcoatInvBasis * normalize( normalBasis * wi ) );
1923
+
1924
+ } else if ( r <= cdf[2] ) { // transmission / refraction
1925
+
1926
+ wi = transmissionDirection( wo, surf );
1927
+ clearcoatWi = normalize( clearcoatInvBasis * normalize( normalBasis * wi ) );
1928
+
1929
+ } else if ( r <= cdf[3] ) { // clearcoat
1930
+
1931
+ clearcoatWi = clearcoatDirection( clearcoatWo, surf );
1932
+ wi = normalize( invBasis * normalize( clearcoatNormalBasis * clearcoatWi ) );
1933
+
1934
+ }
1935
+
1936
+ ScatterRecord result;
1937
+ result.pdf = bsdfEval( wo, clearcoatWo, wi, clearcoatWi, surf, diffuseWeight, specularWeight, transmissionWeight, clearcoatWeight, result.specularPdf, result.color );
1938
+ result.direction = normalize( surf.normalBasis * wi );
1939
+
1940
+ return result;
1941
+
1942
+ }
1943
+
1944
+ `,Zo=`
1945
+
1946
+ // returns the hit distance given the material density
1947
+ float intersectFogVolume( Material material, float u ) {
1948
+
1949
+ // https://raytracing.github.io/books/RayTracingTheNextWeek.html#volumes/constantdensitymediums
1950
+ return material.opacity == 0.0 ? INFINITY : ( - 1.0 / material.opacity ) * log( u );
1951
+
1952
+ }
1953
+
1954
+ ScatterRecord sampleFogVolume( SurfaceRecord surf, vec2 uv ) {
1955
+
1956
+ ScatterRecord sampleRec;
1957
+ sampleRec.specularPdf = 0.0;
1958
+ sampleRec.pdf = 1.0 / ( 2.0 * PI );
1959
+ sampleRec.direction = sampleSphere( uv );
1960
+ sampleRec.color = surf.color;
1961
+ return sampleRec;
1962
+
1963
+ }
1964
+
1965
+ `,Ko=`
1966
+
1967
+ // The GGX functions provide sampling and distribution information for normals as output so
1968
+ // in order to get probability of scatter direction the half vector must be computed and provided.
1969
+ // [0] https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
1970
+ // [1] https://hal.archives-ouvertes.fr/hal-01509746/document
1971
+ // [2] http://jcgt.org/published/0007/04/01/
1972
+ // [4] http://jcgt.org/published/0003/02/03/
1973
+
1974
+ // trowbridge-reitz === GGX === GTR
1975
+
1976
+ vec3 ggxDirection( vec3 incidentDir, vec2 roughness, vec2 uv ) {
1977
+
1978
+ // TODO: try GGXVNDF implementation from reference [2], here. Needs to update ggxDistribution
1979
+ // function below, as well
1980
+
1981
+ // Implementation from reference [1]
1982
+ // stretch view
1983
+ vec3 V = normalize( vec3( roughness * incidentDir.xy, incidentDir.z ) );
1984
+
1985
+ // orthonormal basis
1986
+ vec3 T1 = ( V.z < 0.9999 ) ? normalize( cross( V, vec3( 0.0, 0.0, 1.0 ) ) ) : vec3( 1.0, 0.0, 0.0 );
1987
+ vec3 T2 = cross( T1, V );
1988
+
1989
+ // sample point with polar coordinates (r, phi)
1990
+ float a = 1.0 / ( 1.0 + V.z );
1991
+ float r = sqrt( uv.x );
1992
+ float phi = ( uv.y < a ) ? uv.y / a * PI : PI + ( uv.y - a ) / ( 1.0 - a ) * PI;
1993
+ float P1 = r * cos( phi );
1994
+ float P2 = r * sin( phi ) * ( ( uv.y < a ) ? 1.0 : V.z );
1995
+
1996
+ // compute normal
1997
+ vec3 N = P1 * T1 + P2 * T2 + V * sqrt( max( 0.0, 1.0 - P1 * P1 - P2 * P2 ) );
1998
+
1999
+ // unstretch
2000
+ N = normalize( vec3( roughness * N.xy, max( 0.0, N.z ) ) );
2001
+
2002
+ return N;
2003
+
2004
+ }
2005
+
2006
+ // Below are PDF and related functions for use in a Monte Carlo path tracer
2007
+ // as specified in Appendix B of the following paper
2008
+ // See equation (34) from reference [0]
2009
+ float ggxLamda( float theta, float roughness ) {
2010
+
2011
+ float tanTheta = tan( theta );
2012
+ float tanTheta2 = tanTheta * tanTheta;
2013
+ float alpha2 = roughness * roughness;
2014
+
2015
+ float numerator = - 1.0 + sqrt( 1.0 + alpha2 * tanTheta2 );
2016
+ return numerator / 2.0;
2017
+
2018
+ }
2019
+
2020
+ // See equation (34) from reference [0]
2021
+ float ggxShadowMaskG1( float theta, float roughness ) {
2022
+
2023
+ return 1.0 / ( 1.0 + ggxLamda( theta, roughness ) );
2024
+
2025
+ }
2026
+
2027
+ // See equation (125) from reference [4]
2028
+ float ggxShadowMaskG2( vec3 wi, vec3 wo, float roughness ) {
2029
+
2030
+ float incidentTheta = acos( wi.z );
2031
+ float scatterTheta = acos( wo.z );
2032
+ return 1.0 / ( 1.0 + ggxLamda( incidentTheta, roughness ) + ggxLamda( scatterTheta, roughness ) );
2033
+
2034
+ }
2035
+
2036
+ // See equation (33) from reference [0]
2037
+ float ggxDistribution( vec3 halfVector, float roughness ) {
2038
+
2039
+ float a2 = roughness * roughness;
2040
+ a2 = max( EPSILON, a2 );
2041
+ float cosTheta = halfVector.z;
2042
+ float cosTheta4 = pow( cosTheta, 4.0 );
2043
+
2044
+ if ( cosTheta == 0.0 ) return 0.0;
2045
+
2046
+ float theta = acosSafe( halfVector.z );
2047
+ float tanTheta = tan( theta );
2048
+ float tanTheta2 = pow( tanTheta, 2.0 );
2049
+
2050
+ float denom = PI * cosTheta4 * pow( a2 + tanTheta2, 2.0 );
2051
+ return ( a2 / denom );
2052
+
2053
+ }
2054
+
2055
+ // See equation (3) from reference [2]
2056
+ float ggxPDF( vec3 wi, vec3 halfVector, float roughness ) {
2057
+
2058
+ float incidentTheta = acos( wi.z );
2059
+ float D = ggxDistribution( halfVector, roughness );
2060
+ float G1 = ggxShadowMaskG1( incidentTheta, roughness );
2061
+
2062
+ return D * G1 * max( 0.0, dot( wi, halfVector ) ) / wi.z;
2063
+
2064
+ }
2065
+
2066
+ `,$o=`
2067
+
2068
+ // XYZ to sRGB color space
2069
+ const mat3 XYZ_TO_REC709 = mat3(
2070
+ 3.2404542, -0.9692660, 0.0556434,
2071
+ -1.5371385, 1.8760108, -0.2040259,
2072
+ -0.4985314, 0.0415560, 1.0572252
2073
+ );
2074
+
2075
+ vec3 fresnel0ToIor( vec3 fresnel0 ) {
2076
+
2077
+ vec3 sqrtF0 = sqrt( fresnel0 );
2078
+ return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );
2079
+
2080
+ }
2081
+
2082
+ // Conversion FO/IOR
2083
+ vec3 iorToFresnel0( vec3 transmittedIor, float incidentIor ) {
2084
+
2085
+ return square( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );
2086
+
2087
+ }
2088
+
2089
+ // ior is a value between 1.0 and 3.0. 1.0 is air interface
2090
+ float iorToFresnel0( float transmittedIor, float incidentIor ) {
2091
+
2092
+ return square( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ) );
2093
+
2094
+ }
2095
+
2096
+ // Fresnel equations for dielectric/dielectric interfaces. See https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
2097
+ vec3 evalSensitivity( float OPD, vec3 shift ) {
2098
+
2099
+ float phase = 2.0 * PI * OPD * 1.0e-9;
2100
+
2101
+ vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );
2102
+ vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );
2103
+ vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );
2104
+
2105
+ vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - square( phase ) * var );
2106
+ xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * square( phase ) );
2107
+ xyz /= 1.0685e-7;
2108
+
2109
+ vec3 srgb = XYZ_TO_REC709 * xyz;
2110
+ return srgb;
2111
+
2112
+ }
2113
+
2114
+ // See Section 4. Analytic Spectral Integration, A Practical Extension to Microfacet Theory for the Modeling of Varying Iridescence, https://hal.archives-ouvertes.fr/hal-01518344/document
2115
+ vec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {
2116
+
2117
+ vec3 I;
2118
+
2119
+ // Force iridescenceIor -> outsideIOR when thinFilmThickness -> 0.0
2120
+ float iridescenceIor = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );
2121
+
2122
+ // Evaluate the cosTheta on the base layer (Snell law)
2123
+ float sinTheta2Sq = square( outsideIOR / iridescenceIor ) * ( 1.0 - square( cosTheta1 ) );
2124
+
2125
+ // Handle TIR:
2126
+ float cosTheta2Sq = 1.0 - sinTheta2Sq;
2127
+ if ( cosTheta2Sq < 0.0 ) {
2128
+
2129
+ return vec3( 1.0 );
2130
+
2131
+ }
2132
+
2133
+ float cosTheta2 = sqrt( cosTheta2Sq );
2134
+
2135
+ // First interface
2136
+ float R0 = iorToFresnel0( iridescenceIor, outsideIOR );
2137
+ float R12 = schlickFresnel( cosTheta1, R0 );
2138
+ float R21 = R12;
2139
+ float T121 = 1.0 - R12;
2140
+ float phi12 = 0.0;
2141
+ if ( iridescenceIor < outsideIOR ) {
2142
+
2143
+ phi12 = PI;
2144
+
2145
+ }
2146
+
2147
+ float phi21 = PI - phi12;
2148
+
2149
+ // Second interface
2150
+ vec3 baseIOR = fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); // guard against 1.0
2151
+ vec3 R1 = iorToFresnel0( baseIOR, iridescenceIor );
2152
+ vec3 R23 = schlickFresnel( cosTheta2, R1 );
2153
+ vec3 phi23 = vec3( 0.0 );
2154
+ if ( baseIOR[0] < iridescenceIor ) {
2155
+
2156
+ phi23[ 0 ] = PI;
2157
+
2158
+ }
2159
+
2160
+ if ( baseIOR[1] < iridescenceIor ) {
2161
+
2162
+ phi23[ 1 ] = PI;
2163
+
2164
+ }
2165
+
2166
+ if ( baseIOR[2] < iridescenceIor ) {
2167
+
2168
+ phi23[ 2 ] = PI;
2169
+
2170
+ }
2171
+
2172
+ // Phase shift
2173
+ float OPD = 2.0 * iridescenceIor * thinFilmThickness * cosTheta2;
2174
+ vec3 phi = vec3( phi21 ) + phi23;
2175
+
2176
+ // Compound terms
2177
+ vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );
2178
+ vec3 r123 = sqrt( R123 );
2179
+ vec3 Rs = square( T121 ) * R23 / ( vec3( 1.0 ) - R123 );
2180
+
2181
+ // Reflectance term for m = 0 (DC term amplitude)
2182
+ vec3 C0 = R12 + Rs;
2183
+ I = C0;
2184
+
2185
+ // Reflectance term for m > 0 (pairs of diracs)
2186
+ vec3 Cm = Rs - T121;
2187
+ for ( int m = 1; m <= 2; ++ m ) {
2188
+
2189
+ Cm *= r123;
2190
+ vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );
2191
+ I += Cm * Sm;
2192
+
2193
+ }
2194
+
2195
+ // Since out of gamut colors might be produced, negative color values are clamped to 0.
2196
+ return max( I, vec3( 0.0 ) );
2197
+
2198
+ }
2199
+
2200
+ `,Jo=`
2201
+
2202
+ // See equation (2) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
2203
+ float velvetD( float cosThetaH, float roughness ) {
2204
+
2205
+ float alpha = max( roughness, 0.07 );
2206
+ alpha = alpha * alpha;
2207
+
2208
+ float invAlpha = 1.0 / alpha;
2209
+
2210
+ float sqrCosThetaH = cosThetaH * cosThetaH;
2211
+ float sinThetaH = max( 1.0 - sqrCosThetaH, 0.001 );
2212
+
2213
+ return ( 2.0 + invAlpha ) * pow( sinThetaH, 0.5 * invAlpha ) / ( 2.0 * PI );
2214
+
2215
+ }
2216
+
2217
+ float velvetParamsInterpolate( int i, float oneMinusAlphaSquared ) {
2218
+
2219
+ const float p0[5] = float[5]( 25.3245, 3.32435, 0.16801, -1.27393, -4.85967 );
2220
+ const float p1[5] = float[5]( 21.5473, 3.82987, 0.19823, -1.97760, -4.32054 );
2221
+
2222
+ return mix( p1[i], p0[i], oneMinusAlphaSquared );
2223
+
2224
+ }
2225
+
2226
+ float velvetL( float x, float alpha ) {
2227
+
2228
+ float oneMinusAlpha = 1.0 - alpha;
2229
+ float oneMinusAlphaSquared = oneMinusAlpha * oneMinusAlpha;
2230
+
2231
+ float a = velvetParamsInterpolate( 0, oneMinusAlphaSquared );
2232
+ float b = velvetParamsInterpolate( 1, oneMinusAlphaSquared );
2233
+ float c = velvetParamsInterpolate( 2, oneMinusAlphaSquared );
2234
+ float d = velvetParamsInterpolate( 3, oneMinusAlphaSquared );
2235
+ float e = velvetParamsInterpolate( 4, oneMinusAlphaSquared );
2236
+
2237
+ return a / ( 1.0 + b * pow( abs( x ), c ) ) + d * x + e;
2238
+
2239
+ }
2240
+
2241
+ // See equation (3) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
2242
+ float velvetLambda( float cosTheta, float alpha ) {
2243
+
2244
+ return abs( cosTheta ) < 0.5 ? exp( velvetL( cosTheta, alpha ) ) : exp( 2.0 * velvetL( 0.5, alpha ) - velvetL( 1.0 - cosTheta, alpha ) );
2245
+
2246
+ }
2247
+
2248
+ // See Section 3, Shadowing Term, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
2249
+ float velvetG( float cosThetaO, float cosThetaI, float roughness ) {
2250
+
2251
+ float alpha = max( roughness, 0.07 );
2252
+ alpha = alpha * alpha;
2253
+
2254
+ return 1.0 / ( 1.0 + velvetLambda( cosThetaO, alpha ) + velvetLambda( cosThetaI, alpha ) );
2255
+
2256
+ }
2257
+
2258
+ float directionalAlbedoSheen( float cosTheta, float alpha ) {
2259
+
2260
+ cosTheta = saturate( cosTheta );
2261
+
2262
+ float c = 1.0 - cosTheta;
2263
+ float c3 = c * c * c;
2264
+
2265
+ return 0.65584461 * c3 + 1.0 / ( 4.16526551 + exp( -7.97291361 * sqrt( alpha ) + 6.33516894 ) );
2266
+
2267
+ }
2268
+
2269
+ float sheenAlbedoScaling( vec3 wo, vec3 wi, SurfaceRecord surf ) {
2270
+
2271
+ float alpha = max( surf.sheenRoughness, 0.07 );
2272
+ alpha = alpha * alpha;
2273
+
2274
+ float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
2275
+
2276
+ float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
2277
+ float eWi = directionalAlbedoSheen( saturateCos( wi.z ), alpha );
2278
+
2279
+ return min( 1.0 - maxSheenColor * eWo, 1.0 - maxSheenColor * eWi );
2280
+
2281
+ }
2282
+
2283
+ // See Section 5, Layering, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
2284
+ float sheenAlbedoScaling( vec3 wo, SurfaceRecord surf ) {
2285
+
2286
+ float alpha = max( surf.sheenRoughness, 0.07 );
2287
+ alpha = alpha * alpha;
2288
+
2289
+ float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
2290
+
2291
+ float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
2292
+
2293
+ return 1.0 - maxSheenColor * eWo;
2294
+
2295
+ }
2296
+
2297
+ `,ea=`
2298
+
2299
+ #ifndef FOG_CHECK_ITERATIONS
2300
+ #define FOG_CHECK_ITERATIONS 30
2301
+ #endif
2302
+
2303
+ // returns whether the given material is a fog material or not
2304
+ bool isMaterialFogVolume( sampler2D materials, uint materialIndex ) {
2305
+
2306
+ uint i = materialIndex * 45u;
2307
+ vec4 s14 = texelFetch1D( materials, i + 14u );
2308
+ return bool( int( s14.b ) & 4 );
2309
+
2310
+ }
2311
+
2312
+ // returns true if we're within the first fog volume we hit
2313
+ bool bvhIntersectFogVolumeHit(
2314
+ vec3 rayOrigin, vec3 rayDirection,
2315
+ usampler2D materialIndexAttribute, sampler2D materials,
2316
+ inout Material material
2317
+ ) {
2318
+
2319
+ material.fogVolume = false;
2320
+
2321
+ for ( int i = 0; i < FOG_CHECK_ITERATIONS; i ++ ) {
2322
+
2323
+ // find nearest hit
2324
+ uvec4 faceIndices = uvec4( 0u );
2325
+ vec3 faceNormal = vec3( 0.0, 0.0, 1.0 );
2326
+ vec3 barycoord = vec3( 0.0 );
2327
+ float side = 1.0;
2328
+ float dist = 0.0;
2329
+ bool hit = bvhIntersectFirstHit( bvh, rayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist );
2330
+ if ( hit ) {
2331
+
2332
+ // if it's a fog volume return whether we hit the front or back face
2333
+ uint materialIndex = uTexelFetch1D( materialIndexAttribute, faceIndices.x ).r;
2334
+ if ( isMaterialFogVolume( materials, materialIndex ) ) {
2335
+
2336
+ material = readMaterialInfo( materials, materialIndex );
2337
+ return side == - 1.0;
2338
+
2339
+ } else {
2340
+
2341
+ // move the ray forward
2342
+ rayOrigin = stepRayOrigin( rayOrigin, rayDirection, - faceNormal, dist );
2343
+
2344
+ }
2345
+
2346
+ } else {
2347
+
2348
+ return false;
2349
+
2350
+ }
2351
+
2352
+ }
2353
+
2354
+ return false;
2355
+
2356
+ }
2357
+
2358
+ `,ta=`
2359
+
2360
+ // step through multiple surface hits and accumulate color attenuation based on transmissive surfaces
2361
+ // returns true if a solid surface was hit
2362
+ bool attenuateHit(
2363
+ RenderState state,
2364
+ Ray ray, float rayDist,
2365
+ out vec3 color
2366
+ ) {
2367
+
2368
+ // store the original bounce index so we can reset it after
2369
+ uint originalBounceIndex = sobolBounceIndex;
2370
+
2371
+ int traversals = state.traversals;
2372
+ int transmissiveTraversals = state.transmissiveTraversals;
2373
+ bool isShadowRay = state.isShadowRay;
2374
+ Material fogMaterial = state.fogMaterial;
2375
+
2376
+ vec3 startPoint = ray.origin;
2377
+
2378
+ // hit results
2379
+ SurfaceHit surfaceHit;
2380
+
2381
+ color = vec3( 1.0 );
2382
+
2383
+ bool result = true;
2384
+ for ( int i = 0; i < traversals; i ++ ) {
2385
+
2386
+ sobolBounceIndex ++;
2387
+
2388
+ int hitType = traceScene( ray, fogMaterial, surfaceHit );
2389
+
2390
+ if ( hitType == FOG_HIT ) {
2391
+
2392
+ result = true;
2393
+ break;
2394
+
2395
+ } else if ( hitType == SURFACE_HIT ) {
2396
+
2397
+ float totalDist = distance( startPoint, ray.origin + ray.direction * surfaceHit.dist );
2398
+ if ( totalDist > rayDist ) {
2399
+
2400
+ result = false;
2401
+ break;
2402
+
2403
+ }
2404
+
2405
+ // TODO: attenuate the contribution based on the PDF of the resulting ray including refraction values
2406
+ // Should be able to work using the material BSDF functions which will take into account specularity, etc.
2407
+ // TODO: should we account for emissive surfaces here?
2408
+
2409
+ uint materialIndex = uTexelFetch1D( materialIndexAttribute, surfaceHit.faceIndices.x ).r;
2410
+ Material material = readMaterialInfo( materials, materialIndex );
2411
+
2412
+ // adjust the ray to the new surface
2413
+ bool isEntering = surfaceHit.side == 1.0;
2414
+ ray.origin = stepRayOrigin( ray.origin, ray.direction, - surfaceHit.faceNormal, surfaceHit.dist );
2415
+
2416
+ #if FEATURE_FOG
2417
+
2418
+ if ( material.fogVolume ) {
2419
+
2420
+ fogMaterial = material;
2421
+ fogMaterial.fogVolume = surfaceHit.side == 1.0;
2422
+ i -= sign( transmissiveTraversals );
2423
+ transmissiveTraversals --;
2424
+ continue;
2425
+
2426
+ }
2427
+
2428
+ #endif
2429
+
2430
+ if ( ! material.castShadow && isShadowRay ) {
2431
+
2432
+ continue;
2433
+
2434
+ }
2435
+
2436
+ vec2 uv = textureSampleBarycoord( attributesArray, ATTR_UV, surfaceHit.barycoord, surfaceHit.faceIndices.xyz ).xy;
2437
+ vec4 vertexColor = textureSampleBarycoord( attributesArray, ATTR_COLOR, surfaceHit.barycoord, surfaceHit.faceIndices.xyz );
2438
+
2439
+ // albedo
2440
+ vec4 albedo = vec4( material.color, material.opacity );
2441
+ if ( material.map != - 1 ) {
2442
+
2443
+ vec3 uvPrime = material.mapTransform * vec3( uv, 1 );
2444
+ albedo *= texture2D( textures, vec3( uvPrime.xy, material.map ) );
2445
+
2446
+ }
2447
+
2448
+ if ( material.vertexColors ) {
2449
+
2450
+ albedo *= vertexColor;
2451
+
2452
+ }
2453
+
2454
+ // alphaMap
2455
+ if ( material.alphaMap != - 1 ) {
2456
+
2457
+ albedo.a *= texture2D( textures, vec3( uv, material.alphaMap ) ).x;
2458
+
2459
+ }
2460
+
2461
+ // transmission
2462
+ float transmission = material.transmission;
2463
+ if ( material.transmissionMap != - 1 ) {
2464
+
2465
+ vec3 uvPrime = material.transmissionMapTransform * vec3( uv, 1 );
2466
+ transmission *= texture2D( textures, vec3( uvPrime.xy, material.transmissionMap ) ).r;
2467
+
2468
+ }
2469
+
2470
+ // metalness
2471
+ float metalness = material.metalness;
2472
+ if ( material.metalnessMap != - 1 ) {
2473
+
2474
+ vec3 uvPrime = material.metalnessMapTransform * vec3( uv, 1 );
2475
+ metalness *= texture2D( textures, vec3( uvPrime.xy, material.metalnessMap ) ).b;
2476
+
2477
+ }
2478
+
2479
+ float alphaTest = material.alphaTest;
2480
+ bool useAlphaTest = alphaTest != 0.0;
2481
+ float transmissionFactor = ( 1.0 - metalness ) * transmission;
2482
+ if (
2483
+ transmissionFactor < rand( 9 ) && ! (
2484
+ // material sidedness
2485
+ material.side != 0.0 && surfaceHit.side == material.side
2486
+
2487
+ // alpha test
2488
+ || useAlphaTest && albedo.a < alphaTest
2489
+
2490
+ // opacity
2491
+ || material.transparent && ! useAlphaTest && albedo.a < rand( 10 )
2492
+ )
2493
+ ) {
2494
+
2495
+ result = true;
2496
+ break;
2497
+
2498
+ }
2499
+
2500
+ if ( surfaceHit.side == 1.0 && isEntering ) {
2501
+
2502
+ // only attenuate by surface color on the way in
2503
+ color *= mix( vec3( 1.0 ), albedo.rgb, transmissionFactor );
2504
+
2505
+ } else if ( surfaceHit.side == - 1.0 ) {
2506
+
2507
+ // attenuate by medium once we hit the opposite side of the model
2508
+ color *= transmissionAttenuation( surfaceHit.dist, material.attenuationColor, material.attenuationDistance );
2509
+
2510
+ }
2511
+
2512
+ bool isTransmissiveRay = dot( ray.direction, surfaceHit.faceNormal * surfaceHit.side ) < 0.0;
2513
+ if ( ( isTransmissiveRay || isEntering ) && transmissiveTraversals > 0 ) {
2514
+
2515
+ i -= sign( transmissiveTraversals );
2516
+ transmissiveTraversals --;
2517
+
2518
+ }
2519
+
2520
+ } else {
2521
+
2522
+ result = false;
2523
+ break;
2524
+
2525
+ }
2526
+
2527
+ }
2528
+
2529
+ // reset the bounce index
2530
+ sobolBounceIndex = originalBounceIndex;
2531
+ return result;
2532
+
2533
+ }
2534
+
2535
+ `,ia=`
2536
+
2537
+ vec3 ndcToRayOrigin( vec2 coord ) {
2538
+
2539
+ vec4 rayOrigin4 = cameraWorldMatrix * invProjectionMatrix * vec4( coord, - 1.0, 1.0 );
2540
+ return rayOrigin4.xyz / rayOrigin4.w;
2541
+ }
2542
+
2543
+ Ray getCameraRay() {
2544
+
2545
+ vec2 ssd = vec2( 1.0 ) / resolution;
2546
+
2547
+ // Jitter the camera ray by finding a uv coordinate at a random sample
2548
+ // around this pixel's UV coordinate for AA
2549
+ vec2 ruv = rand2( 0 );
2550
+ vec2 jitteredUv = vUv + vec2( tentFilter( ruv.x ) * ssd.x, tentFilter( ruv.y ) * ssd.y );
2551
+ Ray ray;
2552
+
2553
+ #if CAMERA_TYPE == 2
2554
+
2555
+ // Equirectangular projection
2556
+ vec4 rayDirection4 = vec4( equirectUvToDirection( jitteredUv ), 0.0 );
2557
+ vec4 rayOrigin4 = vec4( 0.0, 0.0, 0.0, 1.0 );
2558
+
2559
+ rayDirection4 = cameraWorldMatrix * rayDirection4;
2560
+ rayOrigin4 = cameraWorldMatrix * rayOrigin4;
2561
+
2562
+ ray.direction = normalize( rayDirection4.xyz );
2563
+ ray.origin = rayOrigin4.xyz / rayOrigin4.w;
2564
+
2565
+ #else
2566
+
2567
+ // get [- 1, 1] normalized device coordinates
2568
+ vec2 ndc = 2.0 * jitteredUv - vec2( 1.0 );
2569
+ ray.origin = ndcToRayOrigin( ndc );
2570
+
2571
+ #if CAMERA_TYPE == 1
2572
+
2573
+ // Orthographic projection
2574
+ ray.direction = ( cameraWorldMatrix * vec4( 0.0, 0.0, - 1.0, 0.0 ) ).xyz;
2575
+ ray.direction = normalize( ray.direction );
2576
+
2577
+ #else
2578
+
2579
+ // Perspective projection
2580
+ ray.direction = normalize( mat3( cameraWorldMatrix ) * ( invProjectionMatrix * vec4( ndc, 0.0, 1.0 ) ).xyz );
2581
+
2582
+ #endif
2583
+
2584
+ #endif
2585
+
2586
+ #if FEATURE_DOF
2587
+ {
2588
+
2589
+ // depth of field
2590
+ vec3 focalPoint = ray.origin + normalize( ray.direction ) * physicalCamera.focusDistance;
2591
+
2592
+ // get the aperture sample
2593
+ // if blades === 0 then we assume a circle
2594
+ vec3 shapeUVW= rand3( 1 );
2595
+ int blades = physicalCamera.apertureBlades;
2596
+ float anamorphicRatio = physicalCamera.anamorphicRatio;
2597
+ vec2 apertureSample = blades == 0 ? sampleCircle( shapeUVW.xy ) : sampleRegularPolygon( blades, shapeUVW );
2598
+ apertureSample *= physicalCamera.bokehSize * 0.5 * 1e-3;
2599
+
2600
+ // rotate the aperture shape
2601
+ apertureSample =
2602
+ rotateVector( apertureSample, physicalCamera.apertureRotation ) *
2603
+ saturate( vec2( anamorphicRatio, 1.0 / anamorphicRatio ) );
2604
+
2605
+ // create the new ray
2606
+ ray.origin += ( cameraWorldMatrix * vec4( apertureSample, 0.0, 0.0 ) ).xyz;
2607
+ ray.direction = focalPoint - ray.origin;
2608
+
2609
+ }
2610
+ #endif
2611
+
2612
+ ray.direction = normalize( ray.direction );
2613
+
2614
+ return ray;
2615
+
2616
+ }
2617
+
2618
+ `,sa=`
2619
+
2620
+ vec3 directLightContribution( vec3 worldWo, SurfaceRecord surf, RenderState state, vec3 rayOrigin ) {
2621
+
2622
+ vec3 result = vec3( 0.0 );
2623
+
2624
+ // uniformly pick a light or environment map
2625
+ if( lightsDenom != 0.0 && rand( 5 ) < float( lights.count ) / lightsDenom ) {
2626
+
2627
+ // sample a light or environment
2628
+ LightRecord lightRec = randomLightSample( lights.tex, iesProfiles, lights.count, rayOrigin, rand3( 6 ) );
2629
+
2630
+ bool isSampleBelowSurface = ! surf.volumeParticle && dot( surf.faceNormal, lightRec.direction ) < 0.0;
2631
+ if ( isSampleBelowSurface ) {
2632
+
2633
+ lightRec.pdf = 0.0;
2634
+
2635
+ }
2636
+
2637
+ // check if a ray could even reach the light area
2638
+ Ray lightRay;
2639
+ lightRay.origin = rayOrigin;
2640
+ lightRay.direction = lightRec.direction;
2641
+ vec3 attenuatedColor;
2642
+ if (
2643
+ lightRec.pdf > 0.0 &&
2644
+ isDirectionValid( lightRec.direction, surf.normal, surf.faceNormal ) &&
2645
+ ! attenuateHit( state, lightRay, lightRec.dist, attenuatedColor )
2646
+ ) {
2647
+
2648
+ // get the material pdf
2649
+ vec3 sampleColor;
2650
+ float lightMaterialPdf = bsdfResult( worldWo, lightRec.direction, surf, sampleColor );
2651
+ bool isValidSampleColor = all( greaterThanEqual( sampleColor, vec3( 0.0 ) ) );
2652
+ if ( lightMaterialPdf > 0.0 && isValidSampleColor ) {
2653
+
2654
+ // weight the direct light contribution
2655
+ float lightPdf = lightRec.pdf / lightsDenom;
2656
+ float misWeight = lightRec.type == SPOT_LIGHT_TYPE || lightRec.type == DIR_LIGHT_TYPE || lightRec.type == POINT_LIGHT_TYPE ? 1.0 : misHeuristic( lightPdf, lightMaterialPdf );
2657
+ result = attenuatedColor * lightRec.emission * state.throughputColor * sampleColor * misWeight / lightPdf;
2658
+
2659
+ }
2660
+
2661
+ }
2662
+
2663
+ } else if ( envMapInfo.totalSum != 0.0 && environmentIntensity != 0.0 ) {
2664
+
2665
+ // find a sample in the environment map to include in the contribution
2666
+ vec3 envColor, envDirection;
2667
+ float envPdf = sampleEquirectProbability( rand2( 7 ), envColor, envDirection );
2668
+ envDirection = invEnvRotation3x3 * envDirection;
2669
+
2670
+ // this env sampling is not set up for transmissive sampling and yields overly bright
2671
+ // results so we ignore the sample in this case.
2672
+ // TODO: this should be improved but how? The env samples could traverse a few layers?
2673
+ bool isSampleBelowSurface = ! surf.volumeParticle && dot( surf.faceNormal, envDirection ) < 0.0;
2674
+ if ( isSampleBelowSurface ) {
2675
+
2676
+ envPdf = 0.0;
2677
+
2678
+ }
2679
+
2680
+ // check if a ray could even reach the surface
2681
+ Ray envRay;
2682
+ envRay.origin = rayOrigin;
2683
+ envRay.direction = envDirection;
2684
+ vec3 attenuatedColor;
2685
+ if (
2686
+ envPdf > 0.0 &&
2687
+ isDirectionValid( envDirection, surf.normal, surf.faceNormal ) &&
2688
+ ! attenuateHit( state, envRay, INFINITY, attenuatedColor )
2689
+ ) {
2690
+
2691
+ // get the material pdf
2692
+ vec3 sampleColor;
2693
+ float envMaterialPdf = bsdfResult( worldWo, envDirection, surf, sampleColor );
2694
+ bool isValidSampleColor = all( greaterThanEqual( sampleColor, vec3( 0.0 ) ) );
2695
+ if ( envMaterialPdf > 0.0 && isValidSampleColor ) {
2696
+
2697
+ // weight the direct light contribution
2698
+ envPdf /= lightsDenom;
2699
+ float misWeight = misHeuristic( envPdf, envMaterialPdf );
2700
+ result = attenuatedColor * environmentIntensity * envColor * state.throughputColor * sampleColor * misWeight / envPdf;
2701
+
2702
+ }
2703
+
2704
+ }
2705
+
2706
+ }
2707
+
2708
+ // Function changed to have a single return statement to potentially help with crashes on Mac OS.
2709
+ // See issue #470
2710
+ return result;
2711
+
2712
+ }
2713
+
2714
+ `,ra=`
2715
+
2716
+ #define SKIP_SURFACE 0
2717
+ #define HIT_SURFACE 1
2718
+ int getSurfaceRecord(
2719
+ Material material, SurfaceHit surfaceHit, sampler2DArray attributesArray,
2720
+ float accumulatedRoughness,
2721
+ inout SurfaceRecord surf
2722
+ ) {
2723
+
2724
+ if ( material.fogVolume ) {
2725
+
2726
+ vec3 normal = vec3( 0, 0, 1 );
2727
+
2728
+ SurfaceRecord fogSurface;
2729
+ fogSurface.volumeParticle = true;
2730
+ fogSurface.color = material.color;
2731
+ fogSurface.emission = material.emissiveIntensity * material.emissive;
2732
+ fogSurface.normal = normal;
2733
+ fogSurface.faceNormal = normal;
2734
+ fogSurface.clearcoatNormal = normal;
2735
+
2736
+ surf = fogSurface;
2737
+ return HIT_SURFACE;
2738
+
2739
+ }
2740
+
2741
+ // uv coord for textures
2742
+ vec2 uv = textureSampleBarycoord( attributesArray, ATTR_UV, surfaceHit.barycoord, surfaceHit.faceIndices.xyz ).xy;
2743
+ vec4 vertexColor = textureSampleBarycoord( attributesArray, ATTR_COLOR, surfaceHit.barycoord, surfaceHit.faceIndices.xyz );
2744
+
2745
+ // albedo
2746
+ vec4 albedo = vec4( material.color, material.opacity );
2747
+ if ( material.map != - 1 ) {
2748
+
2749
+ vec3 uvPrime = material.mapTransform * vec3( uv, 1 );
2750
+ albedo *= texture2D( textures, vec3( uvPrime.xy, material.map ) );
2751
+
2752
+ }
2753
+
2754
+ if ( material.vertexColors ) {
2755
+
2756
+ albedo *= vertexColor;
2757
+
2758
+ }
2759
+
2760
+ // alphaMap
2761
+ if ( material.alphaMap != - 1 ) {
2762
+
2763
+ albedo.a *= texture2D( textures, vec3( uv, material.alphaMap ) ).x;
2764
+
2765
+ }
2766
+
2767
+ // possibly skip this sample if it's transparent, alpha test is enabled, or we hit the wrong material side
2768
+ // and it's single sided.
2769
+ // - alpha test is disabled when it === 0
2770
+ // - the material sidedness test is complicated because we want light to pass through the back side but still
2771
+ // be able to see the front side. This boolean checks if the side we hit is the front side on the first ray
2772
+ // and we're rendering the other then we skip it. Do the opposite on subsequent bounces to get incoming light.
2773
+ float alphaTest = material.alphaTest;
2774
+ bool useAlphaTest = alphaTest != 0.0;
2775
+ if (
2776
+ // material sidedness
2777
+ material.side != 0.0 && surfaceHit.side != material.side
2778
+
2779
+ // alpha test
2780
+ || useAlphaTest && albedo.a < alphaTest
2781
+
2782
+ // opacity
2783
+ || material.transparent && ! useAlphaTest && albedo.a < rand( 3 )
2784
+ ) {
2785
+
2786
+ return SKIP_SURFACE;
2787
+
2788
+ }
2789
+
2790
+ // fetch the interpolated smooth normal
2791
+ vec3 normal = normalize( textureSampleBarycoord(
2792
+ attributesArray,
2793
+ ATTR_NORMAL,
2794
+ surfaceHit.barycoord,
2795
+ surfaceHit.faceIndices.xyz
2796
+ ).xyz );
2797
+
2798
+ // roughness
2799
+ float roughness = material.roughness;
2800
+ if ( material.roughnessMap != - 1 ) {
2801
+
2802
+ vec3 uvPrime = material.roughnessMapTransform * vec3( uv, 1 );
2803
+ roughness *= texture2D( textures, vec3( uvPrime.xy, material.roughnessMap ) ).g;
2804
+
2805
+ }
2806
+
2807
+ // metalness
2808
+ float metalness = material.metalness;
2809
+ if ( material.metalnessMap != - 1 ) {
2810
+
2811
+ vec3 uvPrime = material.metalnessMapTransform * vec3( uv, 1 );
2812
+ metalness *= texture2D( textures, vec3( uvPrime.xy, material.metalnessMap ) ).b;
2813
+
2814
+ }
2815
+
2816
+ // emission
2817
+ vec3 emission = material.emissiveIntensity * material.emissive;
2818
+ if ( material.emissiveMap != - 1 ) {
2819
+
2820
+ vec3 uvPrime = material.emissiveMapTransform * vec3( uv, 1 );
2821
+ emission *= texture2D( textures, vec3( uvPrime.xy, material.emissiveMap ) ).xyz;
2822
+
2823
+ }
2824
+
2825
+ // transmission
2826
+ float transmission = material.transmission;
2827
+ if ( material.transmissionMap != - 1 ) {
2828
+
2829
+ vec3 uvPrime = material.transmissionMapTransform * vec3( uv, 1 );
2830
+ transmission *= texture2D( textures, vec3( uvPrime.xy, material.transmissionMap ) ).r;
2831
+
2832
+ }
2833
+
2834
+ // normal
2835
+ if ( material.flatShading ) {
2836
+
2837
+ // if we're rendering a flat shaded object then use the face normals - the face normal
2838
+ // is provided based on the side the ray hits the mesh so flip it to align with the
2839
+ // interpolated vertex normals.
2840
+ normal = surfaceHit.faceNormal * surfaceHit.side;
2841
+
2842
+ }
2843
+
2844
+ vec3 baseNormal = normal;
2845
+ if ( material.normalMap != - 1 ) {
2846
+
2847
+ vec4 tangentSample = textureSampleBarycoord(
2848
+ attributesArray,
2849
+ ATTR_TANGENT,
2850
+ surfaceHit.barycoord,
2851
+ surfaceHit.faceIndices.xyz
2852
+ );
2853
+
2854
+ // some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate
2855
+ // resulting in NaNs and slow path tracing.
2856
+ if ( length( tangentSample.xyz ) > 0.0 ) {
2857
+
2858
+ vec3 tangent = normalize( tangentSample.xyz );
2859
+ vec3 bitangent = normalize( cross( normal, tangent ) * tangentSample.w );
2860
+ mat3 vTBN = mat3( tangent, bitangent, normal );
2861
+
2862
+ vec3 uvPrime = material.normalMapTransform * vec3( uv, 1 );
2863
+ vec3 texNormal = texture2D( textures, vec3( uvPrime.xy, material.normalMap ) ).xyz * 2.0 - 1.0;
2864
+ texNormal.xy *= material.normalScale;
2865
+ normal = vTBN * texNormal;
2866
+
2867
+ }
2868
+
2869
+ }
2870
+
2871
+ normal *= surfaceHit.side;
2872
+
2873
+ // clearcoat
2874
+ float clearcoat = material.clearcoat;
2875
+ if ( material.clearcoatMap != - 1 ) {
2876
+
2877
+ vec3 uvPrime = material.clearcoatMapTransform * vec3( uv, 1 );
2878
+ clearcoat *= texture2D( textures, vec3( uvPrime.xy, material.clearcoatMap ) ).r;
2879
+
2880
+ }
2881
+
2882
+ // clearcoatRoughness
2883
+ float clearcoatRoughness = material.clearcoatRoughness;
2884
+ if ( material.clearcoatRoughnessMap != - 1 ) {
2885
+
2886
+ vec3 uvPrime = material.clearcoatRoughnessMapTransform * vec3( uv, 1 );
2887
+ clearcoatRoughness *= texture2D( textures, vec3( uvPrime.xy, material.clearcoatRoughnessMap ) ).g;
2888
+
2889
+ }
2890
+
2891
+ // clearcoatNormal
2892
+ vec3 clearcoatNormal = baseNormal;
2893
+ if ( material.clearcoatNormalMap != - 1 ) {
2894
+
2895
+ vec4 tangentSample = textureSampleBarycoord(
2896
+ attributesArray,
2897
+ ATTR_TANGENT,
2898
+ surfaceHit.barycoord,
2899
+ surfaceHit.faceIndices.xyz
2900
+ );
2901
+
2902
+ // some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate
2903
+ // resulting in NaNs and slow path tracing.
2904
+ if ( length( tangentSample.xyz ) > 0.0 ) {
2905
+
2906
+ vec3 tangent = normalize( tangentSample.xyz );
2907
+ vec3 bitangent = normalize( cross( clearcoatNormal, tangent ) * tangentSample.w );
2908
+ mat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );
2909
+
2910
+ vec3 uvPrime = material.clearcoatNormalMapTransform * vec3( uv, 1 );
2911
+ vec3 texNormal = texture2D( textures, vec3( uvPrime.xy, material.clearcoatNormalMap ) ).xyz * 2.0 - 1.0;
2912
+ texNormal.xy *= material.clearcoatNormalScale;
2913
+ clearcoatNormal = vTBN * texNormal;
2914
+
2915
+ }
2916
+
2917
+ }
2918
+
2919
+ clearcoatNormal *= surfaceHit.side;
2920
+
2921
+ // sheenColor
2922
+ vec3 sheenColor = material.sheenColor;
2923
+ if ( material.sheenColorMap != - 1 ) {
2924
+
2925
+ vec3 uvPrime = material.sheenColorMapTransform * vec3( uv, 1 );
2926
+ sheenColor *= texture2D( textures, vec3( uvPrime.xy, material.sheenColorMap ) ).rgb;
2927
+
2928
+ }
2929
+
2930
+ // sheenRoughness
2931
+ float sheenRoughness = material.sheenRoughness;
2932
+ if ( material.sheenRoughnessMap != - 1 ) {
2933
+
2934
+ vec3 uvPrime = material.sheenRoughnessMapTransform * vec3( uv, 1 );
2935
+ sheenRoughness *= texture2D( textures, vec3( uvPrime.xy, material.sheenRoughnessMap ) ).a;
2936
+
2937
+ }
2938
+
2939
+ // iridescence
2940
+ float iridescence = material.iridescence;
2941
+ if ( material.iridescenceMap != - 1 ) {
2942
+
2943
+ vec3 uvPrime = material.iridescenceMapTransform * vec3( uv, 1 );
2944
+ iridescence *= texture2D( textures, vec3( uvPrime.xy, material.iridescenceMap ) ).r;
2945
+
2946
+ }
2947
+
2948
+ // iridescence thickness
2949
+ float iridescenceThickness = material.iridescenceThicknessMaximum;
2950
+ if ( material.iridescenceThicknessMap != - 1 ) {
2951
+
2952
+ vec3 uvPrime = material.iridescenceThicknessMapTransform * vec3( uv, 1 );
2953
+ float iridescenceThicknessSampled = texture2D( textures, vec3( uvPrime.xy, material.iridescenceThicknessMap ) ).g;
2954
+ iridescenceThickness = mix( material.iridescenceThicknessMinimum, material.iridescenceThicknessMaximum, iridescenceThicknessSampled );
2955
+
2956
+ }
2957
+
2958
+ iridescence = iridescenceThickness == 0.0 ? 0.0 : iridescence;
2959
+
2960
+ // specular color
2961
+ vec3 specularColor = material.specularColor;
2962
+ if ( material.specularColorMap != - 1 ) {
2963
+
2964
+ vec3 uvPrime = material.specularColorMapTransform * vec3( uv, 1 );
2965
+ specularColor *= texture2D( textures, vec3( uvPrime.xy, material.specularColorMap ) ).rgb;
2966
+
2967
+ }
2968
+
2969
+ // specular intensity
2970
+ float specularIntensity = material.specularIntensity;
2971
+ if ( material.specularIntensityMap != - 1 ) {
2972
+
2973
+ vec3 uvPrime = material.specularIntensityMapTransform * vec3( uv, 1 );
2974
+ specularIntensity *= texture2D( textures, vec3( uvPrime.xy, material.specularIntensityMap ) ).a;
2975
+
2976
+ }
2977
+
2978
+ surf.volumeParticle = false;
2979
+
2980
+ surf.faceNormal = surfaceHit.faceNormal;
2981
+ surf.normal = normal;
2982
+
2983
+ surf.metalness = metalness;
2984
+ surf.color = albedo.rgb;
2985
+ surf.emission = emission;
2986
+
2987
+ surf.ior = material.ior;
2988
+ surf.transmission = transmission;
2989
+ surf.thinFilm = material.thinFilm;
2990
+ surf.attenuationColor = material.attenuationColor;
2991
+ surf.attenuationDistance = material.attenuationDistance;
2992
+
2993
+ surf.clearcoatNormal = clearcoatNormal;
2994
+ surf.clearcoat = clearcoat;
2995
+
2996
+ surf.sheen = material.sheen;
2997
+ surf.sheenColor = sheenColor;
2998
+
2999
+ surf.iridescence = iridescence;
3000
+ surf.iridescenceIor = material.iridescenceIor;
3001
+ surf.iridescenceThickness = iridescenceThickness;
3002
+
3003
+ surf.specularColor = specularColor;
3004
+ surf.specularIntensity = specularIntensity;
3005
+
3006
+ // apply perceptual roughness factor from gltf. sheen perceptual roughness is
3007
+ // applied by its brdf function
3008
+ // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#microfacet-surfaces
3009
+ surf.roughness = roughness * roughness;
3010
+ surf.clearcoatRoughness = clearcoatRoughness * clearcoatRoughness;
3011
+ surf.sheenRoughness = sheenRoughness;
3012
+
3013
+ // frontFace is used to determine transmissive properties and PDF. If no transmission is used
3014
+ // then we can just always assume this is a front face.
3015
+ surf.frontFace = surfaceHit.side == 1.0 || transmission == 0.0;
3016
+ surf.eta = material.thinFilm || surf.frontFace ? 1.0 / material.ior : material.ior;
3017
+ surf.f0 = iorRatioToF0( surf.eta );
3018
+
3019
+ // Compute the filtered roughness value to use during specular reflection computations.
3020
+ // The accumulated roughness value is scaled by a user setting and a "magic value" of 5.0.
3021
+ // If we're exiting something transmissive then scale the factor down significantly so we can retain
3022
+ // sharp internal reflections
3023
+ surf.filteredRoughness = applyFilteredGlossy( surf.roughness, accumulatedRoughness );
3024
+ surf.filteredClearcoatRoughness = applyFilteredGlossy( surf.clearcoatRoughness, accumulatedRoughness );
3025
+
3026
+ // get the normal frames
3027
+ surf.normalBasis = getBasisFromNormal( surf.normal );
3028
+ surf.normalInvBasis = inverse( surf.normalBasis );
3029
+
3030
+ surf.clearcoatBasis = getBasisFromNormal( surf.clearcoatNormal );
3031
+ surf.clearcoatInvBasis = inverse( surf.clearcoatBasis );
3032
+
3033
+ return HIT_SURFACE;
3034
+
3035
+ }
3036
+ `,na=`
3037
+
3038
+ struct Ray {
3039
+
3040
+ vec3 origin;
3041
+ vec3 direction;
3042
+
3043
+ };
3044
+
3045
+ struct SurfaceHit {
3046
+
3047
+ uvec4 faceIndices;
3048
+ vec3 barycoord;
3049
+ vec3 faceNormal;
3050
+ float side;
3051
+ float dist;
3052
+
3053
+ };
3054
+
3055
+ struct RenderState {
3056
+
3057
+ bool firstRay;
3058
+ bool transmissiveRay;
3059
+ bool isShadowRay;
3060
+ float accumulatedRoughness;
3061
+ int transmissiveTraversals;
3062
+ int traversals;
3063
+ uint depth;
3064
+ vec3 throughputColor;
3065
+ Material fogMaterial;
3066
+
3067
+ };
3068
+
3069
+ RenderState initRenderState() {
3070
+
3071
+ RenderState result;
3072
+ result.firstRay = true;
3073
+ result.transmissiveRay = true;
3074
+ result.isShadowRay = false;
3075
+ result.accumulatedRoughness = 0.0;
3076
+ result.transmissiveTraversals = 0;
3077
+ result.traversals = 0;
3078
+ result.throughputColor = vec3( 1.0 );
3079
+ result.depth = 0u;
3080
+ result.fogMaterial.fogVolume = false;
3081
+ return result;
3082
+
3083
+ }
3084
+
3085
+ `,oa=`
3086
+
3087
+ #define NO_HIT 0
3088
+ #define SURFACE_HIT 1
3089
+ #define LIGHT_HIT 2
3090
+ #define FOG_HIT 3
3091
+
3092
+ // Passing the global variable 'lights' into this function caused shader program errors.
3093
+ // So global variables like 'lights' and 'bvh' were moved out of the function parameters.
3094
+ // For more information, refer to: https://github.com/gkjohnson/three-gpu-pathtracer/pull/457
3095
+ int traceScene(
3096
+ Ray ray, Material fogMaterial, inout SurfaceHit surfaceHit
3097
+ ) {
3098
+
3099
+ int result = NO_HIT;
3100
+ bool hit = bvhIntersectFirstHit( bvh, ray.origin, ray.direction, surfaceHit.faceIndices, surfaceHit.faceNormal, surfaceHit.barycoord, surfaceHit.side, surfaceHit.dist );
3101
+
3102
+ #if FEATURE_FOG
3103
+
3104
+ if ( fogMaterial.fogVolume ) {
3105
+
3106
+ // offset the distance so we don't run into issues with particles on the same surface
3107
+ // as other objects
3108
+ float particleDist = intersectFogVolume( fogMaterial, rand( 1 ) );
3109
+ if ( particleDist + RAY_OFFSET < surfaceHit.dist ) {
3110
+
3111
+ surfaceHit.side = 1.0;
3112
+ surfaceHit.faceNormal = normalize( - ray.direction );
3113
+ surfaceHit.dist = particleDist;
3114
+ return FOG_HIT;
3115
+
3116
+ }
3117
+
3118
+ }
3119
+
3120
+ #endif
3121
+
3122
+ if ( hit ) {
3123
+
3124
+ result = SURFACE_HIT;
3125
+
3126
+ }
3127
+
3128
+ return result;
3129
+
3130
+ }
3131
+
3132
+ `;class aa extends ms{onBeforeRender(){this.setDefine("FEATURE_DOF",this.physicalCamera.bokehSize===0?0:1),this.setDefine("FEATURE_BACKGROUND_MAP",this.backgroundMap?1:0),this.setDefine("FEATURE_FOG",this.materials.features.isUsed("FOG")?1:0)}constructor(e){super({transparent:!0,depthWrite:!1,defines:{FEATURE_MIS:1,FEATURE_RUSSIAN_ROULETTE:1,FEATURE_DOF:1,FEATURE_BACKGROUND_MAP:0,FEATURE_FOG:1,RANDOM_TYPE:2,CAMERA_TYPE:0,DEBUG_MODE:0,ATTR_NORMAL:0,ATTR_TANGENT:1,ATTR_UV:2,ATTR_COLOR:3},uniforms:{resolution:{value:new f.Vector2},opacity:{value:1},bounces:{value:10},transmissiveBounces:{value:10},filterGlossyFactor:{value:0},physicalCamera:{value:new io},cameraWorldMatrix:{value:new f.Matrix4},invProjectionMatrix:{value:new f.Matrix4},bvh:{value:new Be.MeshBVHUniformStruct},attributesArray:{value:new mo},materialIndexAttribute:{value:new Be.UIntVertexAttributeTexture},materials:{value:new wo},textures:{value:new Ns().texture},lights:{value:new fo},iesProfiles:{value:new Ns(360,180,{type:f.HalfFloatType,wrapS:f.ClampToEdgeWrapping,wrapT:f.ClampToEdgeWrapping}).texture},environmentIntensity:{value:1},environmentRotation:{value:new f.Matrix4},envMapInfo:{value:new no},backgroundBlur:{value:0},backgroundMap:{value:null},backgroundAlpha:{value:1},backgroundIntensity:{value:1},backgroundRotation:{value:new f.Matrix4},seed:{value:0},sobolTexture:{value:null},stratifiedTexture:{value:new Io},stratifiedOffsetTexture:{value:new Bo(64,1)}},vertexShader:`
3133
+
3134
+ varying vec2 vUv;
3135
+ void main() {
3136
+
3137
+ vec4 mvPosition = vec4( position, 1.0 );
3138
+ mvPosition = modelViewMatrix * mvPosition;
3139
+ gl_Position = projectionMatrix * mvPosition;
3140
+
3141
+ vUv = uv;
3142
+
3143
+ }
3144
+
3145
+ `,fragmentShader:`
3146
+ #define RAY_OFFSET 1e-4
3147
+ #define INFINITY 1e20
3148
+
3149
+ precision highp isampler2D;
3150
+ precision highp usampler2D;
3151
+ precision highp sampler2DArray;
3152
+ vec4 envMapTexelToLinear( vec4 a ) { return a; }
3153
+ #include <common>
3154
+
3155
+ // bvh intersection
3156
+ ${Be.BVHShaderGLSL.common_functions}
3157
+ ${Be.BVHShaderGLSL.bvh_struct_definitions}
3158
+ ${Be.BVHShaderGLSL.bvh_ray_functions}
3159
+
3160
+ // uniform structs
3161
+ ${ko}
3162
+ ${zo}
3163
+ ${Oo}
3164
+ ${Vo}
3165
+ ${Uo}
3166
+
3167
+ // random
3168
+ #if RANDOM_TYPE == 2 // Stratified List
3169
+
3170
+ ${Qo}
3171
+
3172
+ #elif RANDOM_TYPE == 1 // Sobol
3173
+
3174
+ ${qs}
3175
+ ${br}
3176
+ ${$n}
3177
+
3178
+ #define rand(v) sobol(v)
3179
+ #define rand2(v) sobol2(v)
3180
+ #define rand3(v) sobol3(v)
3181
+ #define rand4(v) sobol4(v)
3182
+
3183
+ #else // PCG
3184
+
3185
+ ${qs}
3186
+
3187
+ // Using the sobol functions seems to break the the compiler on MacOS
3188
+ // - specifically the "sobolReverseBits" function.
3189
+ uint sobolPixelIndex = 0u;
3190
+ uint sobolPathIndex = 0u;
3191
+ uint sobolBounceIndex = 0u;
3192
+
3193
+ #define rand(v) pcgRand()
3194
+ #define rand2(v) pcgRand2()
3195
+ #define rand3(v) pcgRand3()
3196
+ #define rand4(v) pcgRand4()
3197
+
3198
+ #endif
3199
+
3200
+ // common
3201
+ ${Yo}
3202
+ ${Go}
3203
+ ${Tr}
3204
+ ${qo}
3205
+ ${jo}
3206
+
3207
+ // environment
3208
+ uniform EquirectHdrInfo envMapInfo;
3209
+ uniform mat4 environmentRotation;
3210
+ uniform float environmentIntensity;
3211
+
3212
+ // lighting
3213
+ uniform sampler2DArray iesProfiles;
3214
+ uniform LightsInfo lights;
3215
+
3216
+ // background
3217
+ uniform float backgroundBlur;
3218
+ uniform float backgroundAlpha;
3219
+ #if FEATURE_BACKGROUND_MAP
3220
+
3221
+ uniform sampler2D backgroundMap;
3222
+ uniform mat4 backgroundRotation;
3223
+ uniform float backgroundIntensity;
3224
+
3225
+ #endif
3226
+
3227
+ // camera
3228
+ uniform mat4 cameraWorldMatrix;
3229
+ uniform mat4 invProjectionMatrix;
3230
+ #if FEATURE_DOF
3231
+
3232
+ uniform PhysicalCamera physicalCamera;
3233
+
3234
+ #endif
3235
+
3236
+ // geometry
3237
+ uniform sampler2DArray attributesArray;
3238
+ uniform usampler2D materialIndexAttribute;
3239
+ uniform sampler2D materials;
3240
+ uniform sampler2DArray textures;
3241
+ uniform BVH bvh;
3242
+
3243
+ // path tracer
3244
+ uniform int bounces;
3245
+ uniform int transmissiveBounces;
3246
+ uniform float filterGlossyFactor;
3247
+ uniform int seed;
3248
+
3249
+ // image
3250
+ uniform vec2 resolution;
3251
+ uniform float opacity;
3252
+
3253
+ varying vec2 vUv;
3254
+
3255
+ // globals
3256
+ mat3 envRotation3x3;
3257
+ mat3 invEnvRotation3x3;
3258
+ float lightsDenom;
3259
+
3260
+ // sampling
3261
+ ${No}
3262
+ ${Ho}
3263
+ ${Wo}
3264
+
3265
+ ${ea}
3266
+ ${Ko}
3267
+ ${Jo}
3268
+ ${$o}
3269
+ ${Zo}
3270
+ ${Xo}
3271
+
3272
+ float applyFilteredGlossy( float roughness, float accumulatedRoughness ) {
3273
+
3274
+ return clamp(
3275
+ max(
3276
+ roughness,
3277
+ accumulatedRoughness * filterGlossyFactor * 5.0 ),
3278
+ 0.0,
3279
+ 1.0
3280
+ );
3281
+
3282
+ }
3283
+
3284
+ vec3 sampleBackground( vec3 direction, vec2 uv ) {
3285
+
3286
+ vec3 sampleDir = sampleHemisphere( direction, uv ) * 0.5 * backgroundBlur;
3287
+
3288
+ #if FEATURE_BACKGROUND_MAP
3289
+
3290
+ sampleDir = normalize( mat3( backgroundRotation ) * direction + sampleDir );
3291
+ return backgroundIntensity * sampleEquirectColor( backgroundMap, sampleDir );
3292
+
3293
+ #else
3294
+
3295
+ sampleDir = normalize( envRotation3x3 * direction + sampleDir );
3296
+ return environmentIntensity * sampleEquirectColor( envMapInfo.map, sampleDir );
3297
+
3298
+ #endif
3299
+
3300
+ }
3301
+
3302
+ ${na}
3303
+ ${ia}
3304
+ ${oa}
3305
+ ${ta}
3306
+ ${sa}
3307
+ ${ra}
3308
+
3309
+ void main() {
3310
+
3311
+ // init
3312
+ rng_initialize( gl_FragCoord.xy, seed );
3313
+ sobolPixelIndex = ( uint( gl_FragCoord.x ) << 16 ) | uint( gl_FragCoord.y );
3314
+ sobolPathIndex = uint( seed );
3315
+
3316
+ // get camera ray
3317
+ Ray ray = getCameraRay();
3318
+
3319
+ // inverse environment rotation
3320
+ envRotation3x3 = mat3( environmentRotation );
3321
+ invEnvRotation3x3 = inverse( envRotation3x3 );
3322
+ lightsDenom =
3323
+ ( environmentIntensity == 0.0 || envMapInfo.totalSum == 0.0 ) && lights.count != 0u ?
3324
+ float( lights.count ) :
3325
+ float( lights.count + 1u );
3326
+
3327
+ // final color
3328
+ gl_FragColor = vec4( 0, 0, 0, 1 );
3329
+
3330
+ // surface results
3331
+ SurfaceHit surfaceHit;
3332
+ ScatterRecord scatterRec;
3333
+
3334
+ // path tracing state
3335
+ RenderState state = initRenderState();
3336
+ state.transmissiveTraversals = transmissiveBounces;
3337
+ #if FEATURE_FOG
3338
+
3339
+ state.fogMaterial.fogVolume = bvhIntersectFogVolumeHit(
3340
+ ray.origin, - ray.direction,
3341
+ materialIndexAttribute, materials,
3342
+ state.fogMaterial
3343
+ );
3344
+
3345
+ #endif
3346
+
3347
+ for ( int i = 0; i < bounces; i ++ ) {
3348
+
3349
+ sobolBounceIndex ++;
3350
+
3351
+ state.depth ++;
3352
+ state.traversals = bounces - i;
3353
+ state.firstRay = i == 0 && state.transmissiveTraversals == transmissiveBounces;
3354
+
3355
+ int hitType = traceScene( ray, state.fogMaterial, surfaceHit );
3356
+
3357
+ // check if we intersect any lights and accumulate the light contribution
3358
+ // TODO: we can add support for light surface rendering in the else condition if we
3359
+ // add the ability to toggle visibility of the the light
3360
+ if ( ! state.firstRay && ! state.transmissiveRay ) {
3361
+
3362
+ LightRecord lightRec;
3363
+ float lightDist = hitType == NO_HIT ? INFINITY : surfaceHit.dist;
3364
+ for ( uint i = 0u; i < lights.count; i ++ ) {
3365
+
3366
+ if (
3367
+ intersectLightAtIndex( lights.tex, ray.origin, ray.direction, i, lightRec ) &&
3368
+ lightRec.dist < lightDist
3369
+ ) {
3370
+
3371
+ #if FEATURE_MIS
3372
+
3373
+ // weight the contribution
3374
+ // NOTE: Only area lights are supported for forward sampling and can be hit
3375
+ float misWeight = misHeuristic( scatterRec.pdf, lightRec.pdf / lightsDenom );
3376
+ gl_FragColor.rgb += lightRec.emission * state.throughputColor * misWeight;
3377
+
3378
+ #else
3379
+
3380
+ gl_FragColor.rgb += lightRec.emission * state.throughputColor;
3381
+
3382
+ #endif
3383
+
3384
+ }
3385
+
3386
+ }
3387
+
3388
+ }
3389
+
3390
+ if ( hitType == NO_HIT ) {
3391
+
3392
+ if ( state.firstRay || state.transmissiveRay ) {
3393
+
3394
+ gl_FragColor.rgb += sampleBackground( ray.direction, rand2( 2 ) ) * state.throughputColor;
3395
+ gl_FragColor.a = backgroundAlpha;
3396
+
3397
+ } else {
3398
+
3399
+ #if FEATURE_MIS
3400
+
3401
+ // get the PDF of the hit envmap point
3402
+ vec3 envColor;
3403
+ float envPdf = sampleEquirect( envRotation3x3 * ray.direction, envColor );
3404
+ envPdf /= lightsDenom;
3405
+
3406
+ // and weight the contribution
3407
+ float misWeight = misHeuristic( scatterRec.pdf, envPdf );
3408
+ gl_FragColor.rgb += environmentIntensity * envColor * state.throughputColor * misWeight;
3409
+
3410
+ #else
3411
+
3412
+ gl_FragColor.rgb +=
3413
+ environmentIntensity *
3414
+ sampleEquirectColor( envMapInfo.map, envRotation3x3 * ray.direction ) *
3415
+ state.throughputColor;
3416
+
3417
+ #endif
3418
+
3419
+ }
3420
+ break;
3421
+
3422
+ }
3423
+
3424
+ uint materialIndex = uTexelFetch1D( materialIndexAttribute, surfaceHit.faceIndices.x ).r;
3425
+ Material material = readMaterialInfo( materials, materialIndex );
3426
+
3427
+ #if FEATURE_FOG
3428
+
3429
+ if ( hitType == FOG_HIT ) {
3430
+
3431
+ material = state.fogMaterial;
3432
+ state.accumulatedRoughness += 0.2;
3433
+
3434
+ } else if ( material.fogVolume ) {
3435
+
3436
+ state.fogMaterial = material;
3437
+ state.fogMaterial.fogVolume = surfaceHit.side == 1.0;
3438
+
3439
+ ray.origin = stepRayOrigin( ray.origin, ray.direction, - surfaceHit.faceNormal, surfaceHit.dist );
3440
+
3441
+ i -= sign( state.transmissiveTraversals );
3442
+ state.transmissiveTraversals -= sign( state.transmissiveTraversals );
3443
+ continue;
3444
+
3445
+ }
3446
+
3447
+ #endif
3448
+
3449
+ // early out if this is a matte material
3450
+ if ( material.matte && state.firstRay ) {
3451
+
3452
+ gl_FragColor = vec4( 0.0 );
3453
+ break;
3454
+
3455
+ }
3456
+
3457
+ // if we've determined that this is a shadow ray and we've hit an item with no shadow casting
3458
+ // then skip it
3459
+ if ( ! material.castShadow && state.isShadowRay ) {
3460
+
3461
+ ray.origin = stepRayOrigin( ray.origin, ray.direction, - surfaceHit.faceNormal, surfaceHit.dist );
3462
+ continue;
3463
+
3464
+ }
3465
+
3466
+ SurfaceRecord surf;
3467
+ if (
3468
+ getSurfaceRecord(
3469
+ material, surfaceHit, attributesArray, state.accumulatedRoughness,
3470
+ surf
3471
+ ) == SKIP_SURFACE
3472
+ ) {
3473
+
3474
+ // only allow a limited number of transparency discards otherwise we could
3475
+ // crash the context with too long a loop.
3476
+ i -= sign( state.transmissiveTraversals );
3477
+ state.transmissiveTraversals -= sign( state.transmissiveTraversals );
3478
+
3479
+ ray.origin = stepRayOrigin( ray.origin, ray.direction, - surfaceHit.faceNormal, surfaceHit.dist );
3480
+ continue;
3481
+
3482
+ }
3483
+
3484
+ scatterRec = bsdfSample( - ray.direction, surf );
3485
+ state.isShadowRay = scatterRec.specularPdf < rand( 4 );
3486
+
3487
+ bool isBelowSurface = ! surf.volumeParticle && dot( scatterRec.direction, surf.faceNormal ) < 0.0;
3488
+ vec3 hitPoint = stepRayOrigin( ray.origin, ray.direction, isBelowSurface ? - surf.faceNormal : surf.faceNormal, surfaceHit.dist );
3489
+
3490
+ // next event estimation
3491
+ #if FEATURE_MIS
3492
+
3493
+ gl_FragColor.rgb += directLightContribution( - ray.direction, surf, state, hitPoint );
3494
+
3495
+ #endif
3496
+
3497
+ // accumulate a roughness value to offset diffuse, specular, diffuse rays that have high contribution
3498
+ // to a single pixel resulting in fireflies
3499
+ // TODO: handle transmissive surfaces
3500
+ if ( ! surf.volumeParticle && ! isBelowSurface ) {
3501
+
3502
+ // determine if this is a rough normal or not by checking how far off straight up it is
3503
+ vec3 halfVector = normalize( - ray.direction + scatterRec.direction );
3504
+ state.accumulatedRoughness += max(
3505
+ sin( acosApprox( dot( halfVector, surf.normal ) ) ),
3506
+ sin( acosApprox( dot( halfVector, surf.clearcoatNormal ) ) )
3507
+ );
3508
+
3509
+ state.transmissiveRay = false;
3510
+
3511
+ }
3512
+
3513
+ // accumulate emissive color
3514
+ gl_FragColor.rgb += ( surf.emission * state.throughputColor );
3515
+
3516
+ // skip the sample if our PDF or ray is impossible
3517
+ if ( scatterRec.pdf <= 0.0 || ! isDirectionValid( scatterRec.direction, surf.normal, surf.faceNormal ) ) {
3518
+
3519
+ break;
3520
+
3521
+ }
3522
+
3523
+ // if we're bouncing around the inside a transmissive material then decrement
3524
+ // perform this separate from a bounce
3525
+ bool isTransmissiveRay = ! surf.volumeParticle && dot( scatterRec.direction, surf.faceNormal * surfaceHit.side ) < 0.0;
3526
+ if ( ( isTransmissiveRay || isBelowSurface ) && state.transmissiveTraversals > 0 ) {
3527
+
3528
+ state.transmissiveTraversals --;
3529
+ i --;
3530
+
3531
+ }
3532
+
3533
+ //
3534
+
3535
+ // handle throughput color transformation
3536
+ // attenuate the throughput color by the medium color
3537
+ if ( ! surf.frontFace ) {
3538
+
3539
+ state.throughputColor *= transmissionAttenuation( surfaceHit.dist, surf.attenuationColor, surf.attenuationDistance );
3540
+
3541
+ }
3542
+
3543
+ #if FEATURE_RUSSIAN_ROULETTE
3544
+
3545
+ // russian roulette path termination
3546
+ // https://www.arnoldrenderer.com/research/physically_based_shader_design_in_arnold.pdf
3547
+ uint minBounces = 3u;
3548
+ float depthProb = float( state.depth < minBounces );
3549
+
3550
+ float rrProb = luminance( state.throughputColor * scatterRec.color / scatterRec.pdf );
3551
+ rrProb /= luminance( state.throughputColor );
3552
+ rrProb = sqrt( rrProb );
3553
+ rrProb = max( rrProb, depthProb );
3554
+ rrProb = min( rrProb, 1.0 );
3555
+ if ( rand( 8 ) > rrProb ) {
3556
+
3557
+ break;
3558
+
3559
+ }
3560
+
3561
+ // perform sample clamping here to avoid bright pixels
3562
+ state.throughputColor *= min( 1.0 / rrProb, 20.0 );
3563
+
3564
+ #endif
3565
+
3566
+ // adjust the throughput and discard and exit if we find discard the sample if there are any NaNs
3567
+ state.throughputColor *= scatterRec.color / scatterRec.pdf;
3568
+ if ( any( isnan( state.throughputColor ) ) || any( isinf( state.throughputColor ) ) ) {
3569
+
3570
+ break;
3571
+
3572
+ }
3573
+
3574
+ //
3575
+
3576
+ // prepare for next ray
3577
+ ray.direction = scatterRec.direction;
3578
+ ray.origin = hitPoint;
3579
+
3580
+ }
3581
+
3582
+ gl_FragColor.a *= opacity;
3583
+
3584
+ #if DEBUG_MODE == 1
3585
+
3586
+ // output the number of rays checked in the path and number of
3587
+ // transmissive rays encountered.
3588
+ gl_FragColor.rgb = vec3(
3589
+ float( state.depth ),
3590
+ transmissiveBounces - state.transmissiveTraversals,
3591
+ 0.0
3592
+ );
3593
+ gl_FragColor.a = 1.0;
3594
+
3595
+ #endif
3596
+
3597
+ }
3598
+
3599
+ `}),this.setValues(e)}}function*la(){const{_renderer:n,_fsQuad:e,_blendQuad:t,_primaryTarget:i,_blendTargets:s,_sobolTarget:a,_subframe:o,alpha:c,material:u}=this,m=new f.Vector4,d=new f.Vector4,r=t.material;let[l,h]=s;for(;;){c?(r.opacity=this._opacityFactor/(this.samples+1),u.blending=f.NoBlending,u.opacity=1):(u.opacity=this._opacityFactor/(this.samples+1),u.blending=f.NormalBlending);const[g,_,p,v]=o,y=i.width,x=i.height;u.resolution.set(y*p,x*v),u.sobolTexture=a.texture,u.stratifiedTexture.init(20,u.bounces+u.transmissiveBounces+5),u.stratifiedTexture.next(),u.seed++;const w=this.tiles.x||1,b=this.tiles.y||1,T=w*b,M=Math.ceil(y*p),S=Math.ceil(x*v),C=Math.floor(g*y),I=Math.floor(_*x),D=Math.ceil(M/w),A=Math.ceil(S/b);for(let P=0;P<b;P++)for(let R=0;R<w;R++){const E=n.getRenderTarget(),F=n.autoClear,k=n.getScissorTest();n.getScissor(m),n.getViewport(d);let H=R,W=P;if(!this.stableTiles){const X=this._currentTile%(w*b);H=X%w,W=~~(X/w),this._currentTile=X+1}const Q=b-W-1;i.scissor.set(C+H*D,I+Q*A,Math.min(D,M-H*D),Math.min(A,S-Q*A)),i.viewport.set(C,I,M,S),n.setRenderTarget(i),n.setScissorTest(!0),n.autoClear=!1,e.render(n),n.setViewport(d),n.setScissor(m),n.setScissorTest(k),n.setRenderTarget(E),n.autoClear=F,c&&(r.target1=l.texture,r.target2=i.texture,n.setRenderTarget(h),t.render(n),n.setRenderTarget(E)),this.samples+=1/T,R===w-1&&P===b-1&&(this.samples=Math.round(this.samples)),yield}[l,h]=[h,l]}}const js=new f.Color;class Ys{get material(){return this._fsQuad.material}set material(e){this._fsQuad.material.removeEventListener("recompilation",this._compileFunction),e.addEventListener("recompilation",this._compileFunction),this._fsQuad.material=e}get target(){return this._alpha?this._blendTargets[1]:this._primaryTarget}set alpha(e){this._alpha!==e&&(e||(this._blendTargets[0].dispose(),this._blendTargets[1].dispose()),this._alpha=e,this.reset())}get alpha(){return this._alpha}get isCompiling(){return!!this._compilePromise}constructor(e){this.camera=null,this.tiles=new f.Vector2(3,3),this.stableNoise=!1,this.stableTiles=!0,this.samples=0,this._subframe=new f.Vector4(0,0,1,1),this._opacityFactor=1,this._renderer=e,this._alpha=!1,this._fsQuad=new gt.FullScreenQuad(new aa),this._blendQuad=new gt.FullScreenQuad(new Zn),this._task=null,this._currentTile=0,this._compilePromise=null,this._sobolTarget=new eo().generate(e),this._primaryTarget=new f.WebGLRenderTarget(1,1,{format:f.RGBAFormat,type:f.FloatType,magFilter:f.NearestFilter,minFilter:f.NearestFilter}),this._blendTargets=[new f.WebGLRenderTarget(1,1,{format:f.RGBAFormat,type:f.FloatType,magFilter:f.NearestFilter,minFilter:f.NearestFilter}),new f.WebGLRenderTarget(1,1,{format:f.RGBAFormat,type:f.FloatType,magFilter:f.NearestFilter,minFilter:f.NearestFilter})],this._compileFunction=()=>{const t=this.compileMaterial(this._fsQuad._mesh);t.then(()=>{this._compilePromise===t&&(this._compilePromise=null)}),this._compilePromise=t},this.material.addEventListener("recompilation",this._compileFunction)}compileMaterial(){return this._renderer.compileAsync(this._fsQuad._mesh)}setCamera(e){const{material:t}=this;t.cameraWorldMatrix.copy(e.matrixWorld),t.invProjectionMatrix.copy(e.projectionMatrixInverse),t.physicalCamera.updateFrom(e);let i=0;e.projectionMatrix.elements[15]>0&&(i=1),e.isEquirectCamera&&(i=2),t.setDefine("CAMERA_TYPE",i),this.camera=e}setSize(e,t){e=Math.ceil(e),t=Math.ceil(t),!(this._primaryTarget.width===e&&this._primaryTarget.height===t)&&(this._primaryTarget.setSize(e,t),this._blendTargets[0].setSize(e,t),this._blendTargets[1].setSize(e,t),this.reset())}getSize(e){e.x=this._primaryTarget.width,e.y=this._primaryTarget.height}dispose(){this._primaryTarget.dispose(),this._blendTargets[0].dispose(),this._blendTargets[1].dispose(),this._sobolTarget.dispose(),this._fsQuad.dispose(),this._blendQuad.dispose(),this._task=null}reset(){const{_renderer:e,_primaryTarget:t,_blendTargets:i}=this,s=e.getRenderTarget(),a=e.getClearAlpha();e.getClearColor(js),e.setRenderTarget(t),e.setClearColor(0,0),e.clearColor(),e.setRenderTarget(i[0]),e.setClearColor(0,0),e.clearColor(),e.setRenderTarget(i[1]),e.setClearColor(0,0),e.clearColor(),e.setClearColor(js,a),e.setRenderTarget(s),this.samples=0,this._task=null,this.material.stratifiedTexture.stableNoise=this.stableNoise,this.stableNoise&&(this.material.seed=0,this.material.stratifiedTexture.reset())}update(){this.material.onBeforeRender(),!this.isCompiling&&(this._task||(this._task=la.call(this)),this._task.next())}}const We=new f.Vector2,Qs=new f.Vector2,qt=new f.Spherical,jt=new f.Color;class ca extends f.DataTexture{constructor(e=512,t=512){super(new Float32Array(e*t*4),e,t,f.RGBAFormat,f.FloatType,f.EquirectangularReflectionMapping,f.RepeatWrapping,f.ClampToEdgeWrapping,f.LinearFilter,f.LinearFilter),this.generationCallback=null}update(){this.dispose(),this.needsUpdate=!0;const{data:e,width:t,height:i}=this.image;for(let s=0;s<t;s++)for(let a=0;a<i;a++){Qs.set(t,i),We.set(s/t,a/i),We.x-=.5,We.y=1-We.y,qt.theta=We.x*2*Math.PI,qt.phi=We.y*Math.PI,qt.radius=1,this.generationCallback(qt,We,Qs,jt);const c=4*(a*t+s);e[c+0]=jt.r,e[c+1]=jt.g,e[c+2]=jt.b,e[c+3]=1}}copy(e){return super.copy(e),this.generationCallback=e.generationCallback,this}}const Xs=new f.Vector3;class ua extends ca{constructor(e=512){super(e,e),this.topColor=new f.Color().set(16777215),this.bottomColor=new f.Color().set(0),this.exponent=2,this.generationCallback=(t,i,s,a)=>{Xs.setFromSpherical(t);const o=Xs.y*.5+.5;a.lerpColors(this.bottomColor,this.topColor,o**this.exponent)}}copy(e){return super.copy(e),this.topColor.copy(e.topColor),this.bottomColor.copy(e.bottomColor),this}}class ha extends f.ShaderMaterial{get map(){return this.uniforms.map.value}set map(e){this.uniforms.map.value=e}get opacity(){return this.uniforms.opacity.value}set opacity(e){this.uniforms&&(this.uniforms.opacity.value=e)}constructor(e){super({uniforms:{map:{value:null},opacity:{value:1}},vertexShader:`
3600
+ varying vec2 vUv;
3601
+ void main() {
3602
+
3603
+ vUv = uv;
3604
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
3605
+
3606
+ }
3607
+ `,fragmentShader:`
3608
+ uniform sampler2D map;
3609
+ uniform float opacity;
3610
+ varying vec2 vUv;
3611
+
3612
+ vec4 clampedTexelFatch( sampler2D map, ivec2 px, int lod ) {
3613
+
3614
+ vec4 res = texelFetch( map, ivec2( px.x, px.y ), 0 );
3615
+
3616
+ #if defined( TONE_MAPPING )
3617
+
3618
+ res.xyz = toneMapping( res.xyz );
3619
+
3620
+ #endif
3621
+
3622
+ return linearToOutputTexel( res );
3623
+
3624
+ }
3625
+
3626
+ void main() {
3627
+
3628
+ vec2 size = vec2( textureSize( map, 0 ) );
3629
+ vec2 pxUv = vUv * size;
3630
+ vec2 pxCurr = floor( pxUv );
3631
+ vec2 pxFrac = fract( pxUv ) - 0.5;
3632
+ vec2 pxOffset;
3633
+ pxOffset.x = pxFrac.x > 0.0 ? 1.0 : - 1.0;
3634
+ pxOffset.y = pxFrac.y > 0.0 ? 1.0 : - 1.0;
3635
+
3636
+ vec2 pxNext = clamp( pxOffset + pxCurr, vec2( 0.0 ), size - 1.0 );
3637
+ vec2 alpha = abs( pxFrac );
3638
+
3639
+ vec4 p1 = mix(
3640
+ clampedTexelFatch( map, ivec2( pxCurr.x, pxCurr.y ), 0 ),
3641
+ clampedTexelFatch( map, ivec2( pxNext.x, pxCurr.y ), 0 ),
3642
+ alpha.x
3643
+ );
3644
+
3645
+ vec4 p2 = mix(
3646
+ clampedTexelFatch( map, ivec2( pxCurr.x, pxNext.y ), 0 ),
3647
+ clampedTexelFatch( map, ivec2( pxNext.x, pxNext.y ), 0 ),
3648
+ alpha.x
3649
+ );
3650
+
3651
+ gl_FragColor = mix( p1, p2, alpha.y );
3652
+ gl_FragColor.a *= opacity;
3653
+ #include <premultiplied_alpha_fragment>
3654
+
3655
+ }
3656
+ `}),this.setValues(e)}}class fa extends f.ShaderMaterial{constructor(){super({uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:`
3657
+ varying vec2 vUv;
3658
+ void main() {
3659
+
3660
+ vUv = uv;
3661
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
3662
+
3663
+ }`,fragmentShader:`
3664
+ #define ENVMAP_TYPE_CUBE_UV
3665
+
3666
+ uniform samplerCube envMap;
3667
+ uniform float flipEnvMap;
3668
+ varying vec2 vUv;
3669
+
3670
+ #include <common>
3671
+ #include <cube_uv_reflection_fragment>
3672
+
3673
+ ${Tr}
3674
+
3675
+ void main() {
3676
+
3677
+ vec3 rayDirection = equirectUvToDirection( vUv );
3678
+ rayDirection.x *= flipEnvMap;
3679
+ gl_FragColor = textureCube( envMap, rayDirection );
3680
+
3681
+ }`}),this.depthWrite=!1,this.depthTest=!1}}class Zs{constructor(e){this._renderer=e,this._quad=new gt.FullScreenQuad(new fa)}generate(e,t=null,i=null){if(!e.isCubeTexture)throw new Error("CubeToEquirectMaterial: Source can only be cube textures.");const s=e.images[0],a=this._renderer,o=this._quad;t===null&&(t=4*s.height),i===null&&(i=2*s.height);const c=new f.WebGLRenderTarget(t,i,{type:f.FloatType,colorSpace:s.colorSpace}),u=s.height,m=Math.log2(u)-2,d=1/u,r=1/(3*Math.max(Math.pow(2,m),7*16));o.material.defines.CUBEUV_MAX_MIP=`${m}.0`,o.material.defines.CUBEUV_TEXEL_WIDTH=r,o.material.defines.CUBEUV_TEXEL_HEIGHT=d,o.material.uniforms.envMap.value=e,o.material.uniforms.flipEnvMap.value=e.isRenderTargetTexture?1:-1,o.material.needsUpdate=!0;const l=a.getRenderTarget(),h=a.autoClear;a.autoClear=!0,a.setRenderTarget(c),o.render(a),a.setRenderTarget(l),a.autoClear=h;const g=new Uint16Array(t*i*4),_=new Float32Array(t*i*4);a.readRenderTargetPixels(c,0,0,t,i,_),c.dispose();for(let v=0,y=_.length;v<y;v++)g[v]=f.DataUtils.toHalfFloat(_[v]);const p=new f.DataTexture(g,t,i,f.RGBAFormat,f.HalfFloatType);return p.minFilter=f.LinearMipMapLinearFilter,p.magFilter=f.LinearFilter,p.wrapS=f.RepeatWrapping,p.wrapT=f.RepeatWrapping,p.mapping=f.EquirectangularReflectionMapping,p.needsUpdate=!0,p}dispose(){this._quad.dispose()}}function da(n){return n.extensions.get("EXT_float_blend")}const $e=new f.Vector2;class pa{get multipleImportanceSampling(){return!!this._pathTracer.material.defines.FEATURE_MIS}set multipleImportanceSampling(e){this._pathTracer.material.setDefine("FEATURE_MIS",e?1:0)}get transmissiveBounces(){return this._pathTracer.material.transmissiveBounces}set transmissiveBounces(e){this._pathTracer.material.transmissiveBounces=e}get bounces(){return this._pathTracer.material.bounces}set bounces(e){this._pathTracer.material.bounces=e}get filterGlossyFactor(){return this._pathTracer.material.filterGlossyFactor}set filterGlossyFactor(e){this._pathTracer.material.filterGlossyFactor=e}get samples(){return this._pathTracer.samples}get target(){return this._pathTracer.target}get tiles(){return this._pathTracer.tiles}get stableNoise(){return this._pathTracer.stableNoise}set stableNoise(e){this._pathTracer.stableNoise=e}get isCompiling(){return!!this._pathTracer.isCompiling}constructor(e){this._renderer=e,this._generator=new Xn,this._pathTracer=new Ys(e),this._queueReset=!1,this._clock=new f.Clock,this._compilePromise=null,this._lowResPathTracer=new Ys(e),this._lowResPathTracer.tiles.set(1,1),this._quad=new gt.FullScreenQuad(new ha({map:null,transparent:!0,blending:f.NoBlending,premultipliedAlpha:e.getContextAttributes().premultipliedAlpha})),this._materials=null,this._previousEnvironment=null,this._previousBackground=null,this._internalBackground=null,this.renderDelay=100,this.minSamples=5,this.fadeDuration=500,this.enablePathTracing=!0,this.pausePathTracing=!1,this.dynamicLowRes=!1,this.lowResScale=.25,this.renderScale=1,this.synchronizeRenderSize=!0,this.rasterizeScene=!0,this.renderToCanvas=!0,this.textureSize=new f.Vector2(1024,1024),this.rasterizeSceneCallback=(t,i)=>{this._renderer.render(t,i)},this.renderToCanvasCallback=(t,i,s)=>{const a=i.autoClear;i.autoClear=!1,s.render(i),i.autoClear=a},this.setScene(new f.Scene,new f.PerspectiveCamera)}setBVHWorker(e){this._generator.setBVHWorker(e)}setScene(e,t,i={}){e.updateMatrixWorld(!0),t.updateMatrixWorld();const s=this._generator;if(s.setObjects(e),this._buildAsync)return s.generateAsync(i.onProgress).then(a=>this._updateFromResults(e,t,a));{const a=s.generate();return this._updateFromResults(e,t,a)}}setSceneAsync(...e){this._buildAsync=!0;const t=this.setScene(...e);return this._buildAsync=!1,t}setCamera(e){this.camera=e,this.updateCamera()}updateCamera(){const e=this.camera;e.updateMatrixWorld(),this._pathTracer.setCamera(e),this._lowResPathTracer.setCamera(e),this.reset()}updateMaterials(){const e=this._pathTracer.material,t=this._renderer,i=this._materials,s=this.textureSize,a=_o(i);e.textures.setTextures(t,a,s.x,s.y),e.materials.updateFrom(i,a),this.reset()}updateLights(){const e=this.scene,t=this._renderer,i=this._pathTracer.material,s=yo(e),a=vo(s);i.lights.updateFrom(s,a),i.iesProfiles.setTextures(t,a),this.reset()}updateEnvironment(){const e=this.scene,t=this._pathTracer.material;if(this._internalBackground&&(this._internalBackground.dispose(),this._internalBackground=null),t.backgroundBlur=e.backgroundBlurriness,t.backgroundIntensity=e.backgroundIntensity??1,t.backgroundRotation.makeRotationFromEuler(e.backgroundRotation).invert(),e.background===null)t.backgroundMap=null,t.backgroundAlpha=0;else if(e.background.isColor){this._colorBackground=this._colorBackground||new ua(16);const i=this._colorBackground;i.topColor.equals(e.background)||(i.topColor.set(e.background),i.bottomColor.set(e.background),i.update()),t.backgroundMap=i,t.backgroundAlpha=1}else if(e.background.isCubeTexture){if(e.background!==this._previousBackground){const i=new Zs(this._renderer).generate(e.background);this._internalBackground=i,t.backgroundMap=i,t.backgroundAlpha=1}}else t.backgroundMap=e.background,t.backgroundAlpha=1;if(t.environmentIntensity=e.environmentIntensity??1,t.environmentRotation.makeRotationFromEuler(e.environmentRotation).invert(),this._previousEnvironment!==e.environment)if(e.environment!==null)if(e.environment.isCubeTexture){const i=new Zs(this._renderer).generate(e.environment);t.envMapInfo.updateFrom(i)}else t.envMapInfo.updateFrom(e.environment);else t.environmentIntensity=0;this._previousEnvironment=e.environment,this._previousBackground=e.background,this.reset()}_updateFromResults(e,t,i){const{materials:s,geometry:a,bvh:o,bvhChanged:c}=i;this._materials=s;const m=this._pathTracer.material;return c&&(m.bvh.updateFrom(o),m.attributesArray.updateFrom(a.attributes.normal,a.attributes.tangent,a.attributes.uv,a.attributes.color),m.materialIndexAttribute.updateFrom(a.attributes.materialIndex)),this._previousScene=e,this.scene=e,this.camera=t,this.updateCamera(),this.updateMaterials(),this.updateEnvironment(),this.updateLights(),i}renderSample(){const e=this._lowResPathTracer,t=this._pathTracer,i=this._renderer,s=this._clock,a=this._quad;this._updateScale(),this._queueReset&&(t.reset(),e.reset(),this._queueReset=!1,a.material.opacity=0,s.start());const o=s.getDelta()*1e3,c=s.getElapsedTime()*1e3;if(!this.pausePathTracing&&this.enablePathTracing&&this.renderDelay<=c&&!this.isCompiling&&t.update(),t.alpha=t.material.backgroundAlpha!==1||!da(i),e.alpha=t.alpha,this.renderToCanvas){const u=this._renderer,m=this.minSamples;if(c>=this.renderDelay&&this.samples>=this.minSamples&&(this.fadeDuration!==0?a.material.opacity=Math.min(a.material.opacity+o/this.fadeDuration,1):a.material.opacity=1),!this.enablePathTracing||this.samples<m||a.material.opacity<1){if(this.dynamicLowRes&&!this.isCompiling){e.samples<1&&(e.material=t.material,e.update());const d=a.material.opacity;a.material.opacity=1-a.material.opacity,a.material.map=e.target.texture,a.render(u),a.material.opacity=d}(!this.dynamicLowRes&&this.rasterizeScene||this.dynamicLowRes&&this.isCompiling)&&this.rasterizeSceneCallback(this.scene,this.camera)}this.enablePathTracing&&a.material.opacity>0&&(a.material.opacity<1&&(a.material.blending=this.dynamicLowRes?f.AdditiveBlending:f.NormalBlending),a.material.map=t.target.texture,this.renderToCanvasCallback(t.target,u,a),a.material.blending=f.NoBlending)}}reset(){this._queueReset=!0,this._pathTracer.samples=0}dispose(){this._renderQuad.dispose(),this._renderQuad.material.dispose(),this._pathTracer.dispose()}_updateScale(){if(this.synchronizeRenderSize){this._renderer.getDrawingBufferSize($e);const e=Math.floor(this.renderScale*$e.x),t=Math.floor(this.renderScale*$e.y);if(this._pathTracer.getSize($e),$e.x!==e||$e.y!==t){const i=this.lowResScale;this._pathTracer.setSize(e,t),this._lowResPathTracer.setSize(Math.floor(e*i),Math.floor(t*i))}}}}const Sr="3.3.5";globalThis.GLTF_PROGRESSIVE_VERSION=Sr;console.debug(`[gltf-progressive] version ${Sr}`);let pe="https://www.gstatic.com/draco/versioned/decoders/1.5.7/",qe="https://cdn.needle.tools/static/three/0.179.1/basis2/";const ma=pe,ga=qe,Mr=new URL(pe+"draco_decoder.js");Mr.searchParams.append("range","true");fetch(Mr,{method:"GET",headers:{Range:"bytes=0-1"}}).catch(n=>{console.debug(`Failed to fetch remote Draco decoder from ${pe} (offline: ${typeof navigator<"u"?navigator.onLine:"unknown"})`),pe===ma&&_a("./include/draco/"),qe===ga&&ya("./include/ktx2/")}).finally(()=>{Pr()});const va=()=>({dracoDecoderPath:pe,ktx2TranscoderPath:qe});function _a(n){pe=n,re&&re[Yi]!=pe?(console.debug("Updating Draco decoder path to "+n),re[Yi]=pe,re.setDecoderPath(pe),re.preload()):console.debug("Setting Draco decoder path to "+n)}function ya(n){qe=n,me&&me.transcoderPath!=qe?(console.debug("Updating KTX2 transcoder path to "+n),me.setTranscoderPath(qe),me.init()):console.debug("Setting KTX2 transcoder path to "+n)}function vs(n){return Pr(),n?me.detectSupport(n):n!==null&&console.warn("No renderer provided to detect ktx2 support - loading KTX2 textures might fail"),{dracoLoader:re,ktx2Loader:me,meshoptDecoder:fi}}function Cr(n){n.dracoLoader||n.setDRACOLoader(re),n.ktx2Loader||n.setKTX2Loader(me),n.meshoptDecoder||n.setMeshoptDecoder(fi)}const Yi=Symbol("dracoDecoderPath");let re,fi,me;function Pr(){re||(re=new xn.DRACOLoader,re[Yi]=pe,re.setDecoderPath(pe),re.setDecoderConfig({type:"js"}),re.preload()),me||(me=new wn.KTX2Loader,me.setTranscoderPath(qe),me.init()),fi||(fi=yn.MeshoptDecoder)}const Qi=new WeakMap;function Ir(n,e){let t=Qi.get(n);t?t=Object.assign(t,e):t=e,Qi.set(n,t)}const Ii=ds.GLTFLoader.prototype.load;function xa(...n){const e=Qi.get(this);let t=n[0];const i=new URL(t,window.location.href);if(i.hostname.endsWith("needle.tools")){const a=(e==null?void 0:e.progressive)!==void 0?e.progressive:!0,o=e!=null&&e.usecase?e.usecase:"default";a?this.requestHeader.Accept=`*/*;progressive=allowed;usecase=${o}`:this.requestHeader.Accept=`*/*;usecase=${o}`,t=i.toString()}return n[0]=t,Ii==null?void 0:Ii.call(this,...n)}ds.GLTFLoader.prototype.load=xa;je("debugprogressive");function je(n){if(typeof window>"u")return!1;const t=new URL(window.location.href).searchParams.get(n);return t==null||t==="0"||t==="false"?!1:t===""?!0:t}function wa(n,e){if(e===void 0||n===void 0||e.startsWith("./")||e.startsWith("http")||e.startsWith("data:")||e.startsWith("blob:"))return e;const t=n.lastIndexOf("/");if(t>=0){const i=n.substring(0,t+1);for(;i.endsWith("/")&&e.startsWith("/");)e=e.substring(1);return i+e}return e}function Rr(){return Tt!==void 0||(Tt=/iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent),je("debugprogressive")&&console.log("[glTF Progressive]: isMobileDevice",Tt)),Tt}let Tt;function Ks(){if(typeof window>"u")return!1;const n=new URL(window.location.href),e=n.hostname==="localhost"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(n.hostname);return n.hostname==="127.0.0.1"||e}class ba{constructor(e=100,t={}){L(this,"maxConcurrent");L(this,"_running",new Map);L(this,"_queue",[]);L(this,"debug",!1);L(this,"tick",()=>{this.internalUpdate(),setTimeout(this.tick,10)});this.maxConcurrent=e,this.debug=t.debug??!1,window.requestAnimationFrame(this.tick)}slot(e){return this.debug&&console.debug(`[PromiseQueue]: Requesting slot for key ${e}, running: ${this._running.size}, waiting: ${this._queue.length}`),new Promise(t=>{this._queue.push({key:e,resolve:t})})}add(e,t){this._running.has(e)||(this._running.set(e,t),t.finally(()=>{this._running.delete(e),this.debug&&console.debug(`[PromiseQueue]: Promise finished now running: ${this._running.size}, waiting: ${this._queue.length}. (finished ${e})`)}),this.debug&&console.debug(`[PromiseQueue]: Added new promise, now running: ${this._running.size}, waiting: ${this._queue.length}. (added ${e})`))}internalUpdate(){const e=this.maxConcurrent-this._running.size;for(let t=0;t<e&&this._queue.length>0;t++){this.debug&&console.debug(`[PromiseQueue]: Running ${this._running.size} promises, waiting for ${this._queue.length} more.`);const{key:i,resolve:s}=this._queue.shift();s({use:a=>this.add(i,a)})}}}const Aa=typeof window>"u"&&typeof document>"u",Xi=Symbol("needle:raycast-mesh");function Ut(n){return(n==null?void 0:n[Xi])instanceof f.BufferGeometry?n[Xi]:null}function Ta(n,e){if((n.type==="Mesh"||n.type==="SkinnedMesh")&&!Ut(n)){const i=Ma(e);i.userData={isRaycastMesh:!0},n[Xi]=i}}function Sa(n=!0){if(n){if(St)return;const e=St=f.Mesh.prototype.raycast;f.Mesh.prototype.raycast=function(t,i){const s=this,a=Ut(s);let o;a&&s.isMesh&&(o=s.geometry,s.geometry=a),e.call(this,t,i),o&&(s.geometry=o)}}else{if(!St)return;f.Mesh.prototype.raycast=St,St=null}}let St=null;function Ma(n){const e=new f.BufferGeometry;for(const t in n.attributes)e.setAttribute(t,n.getAttribute(t));return e.setIndex(n.getIndex()),e}const Ee=new Array,V=je("debugprogressive");let kt,Ne=-1;if(V){let e=function(){Ne+=1,Ne>=n&&(Ne=-1),console.log(`Toggle LOD level [${Ne}]`)},n=6;window.addEventListener("keyup",t=>{t.key==="p"&&e(),t.key==="w"&&(kt=!kt,console.log(`Toggle wireframe [${kt}]`));const i=parseInt(t.key);!isNaN(i)&&i>=0&&(Ne=i,console.log(`Set LOD level to [${Ne}]`))})}function Dr(n){if(V&&kt!==void 0)if(Array.isArray(n))for(const e of n)Dr(e);else n&&"wireframe"in n&&(n.wireframe=kt===!0)}const Mt=new Array;let Ca=0;const Pa=Rr()?2:10;function Ia(n){if(Mt.length<Pa){const i=Mt.length;V&&console.warn(`[Worker] Creating new worker #${i}`);const s=_s.createWorker(n||{});return Mt.push(s),s}const e=Ca++%Mt.length;return Mt[e]}class _s{constructor(e,t){L(this,"worker");L(this,"_running",[]);L(this,"_webglRenderer",null);L(this,"_debug",!1);this.worker=e,this._debug=t.debug??!1,e.onmessage=i=>{const s=i.data;switch(this._debug&&console.log("[Worker] EVENT",s),s.type){case"loaded-gltf":for(const a of this._running)if(a.url===s.result.url){Ra(s.result),a.resolve(s.result);const o=a.url;o.startsWith("blob:")&&URL.revokeObjectURL(o)}}},e.onerror=i=>{console.error("[Worker] Error in gltf-progressive worker:",i)},e.postMessage({type:"init"})}static async createWorker(e){const t=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/loader.worker-fysOIq2s.js").href:new URL("assets/loader.worker-fysOIq2s.js",document.currentScript&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:vt&&vt.src||new URL("scene-Ibg8IbTP.js",document.baseURI).href),{type:"module"});return new _s(t,e)}async load(e,t){const i=va();let s=t==null?void 0:t.renderer;s||(this._webglRenderer??(this._webglRenderer=(async()=>{const{WebGLRenderer:m}=await import("three");return new m})()),s=await this._webglRenderer);const c=vs(s).ktx2Loader.workerConfig;e instanceof URL?e=e.toString():e.startsWith("file:")?e=URL.createObjectURL(new Blob([e])):!e.startsWith("blob:")&&!e.startsWith("http:")&&!e.startsWith("https:")&&(e=new URL(e,window.location.href).toString());const u={type:"load",url:e,dracoDecoderPath:i.dracoDecoderPath,ktx2TranscoderPath:i.ktx2TranscoderPath,ktx2LoaderConfig:c};return this._debug&&console.debug("[Worker] Sending load request",u),this.worker.postMessage(u),new Promise(m=>{this._running.push({url:e.toString(),resolve:m})})}}function Ra(n){var e,t,i,s,a,o,c,u,m,d,r,l,h,g,_,p;for(const v of n.geometries){const y=v.geometry,x=new f.BufferGeometry;if(x.name=y.name||"",y.index){const w=y.index;x.setIndex(Ri(w))}for(const w in y.attributes){const b=y.attributes[w],T=Ri(b);x.setAttribute(w,T)}if(y.morphAttributes)for(const w in y.morphAttributes){const T=y.morphAttributes[w].map(M=>Ri(M));x.morphAttributes[w]=T}if(x.morphTargetsRelative=y.morphTargetsRelative??!1,x.boundingBox=new f.Box3,x.boundingBox.min=new f.Vector3((e=y.boundingBox)==null?void 0:e.min.x,(t=y.boundingBox)==null?void 0:t.min.y,(i=y.boundingBox)==null?void 0:i.min.z),x.boundingBox.max=new f.Vector3((s=y.boundingBox)==null?void 0:s.max.x,(a=y.boundingBox)==null?void 0:a.max.y,(o=y.boundingBox)==null?void 0:o.max.z),x.boundingSphere=new f.Sphere(new f.Vector3((c=y.boundingSphere)==null?void 0:c.center.x,(u=y.boundingSphere)==null?void 0:u.center.y,(m=y.boundingSphere)==null?void 0:m.center.z),(d=y.boundingSphere)==null?void 0:d.radius),y.groups)for(const w of y.groups)x.addGroup(w.start,w.count,w.materialIndex);y.userData&&(x.userData=y.userData),v.geometry=x}for(const v of n.textures){const y=v.texture;let x=null;if(y.isCompressedTexture){const w=y.mipmaps,b=((r=y.image)==null?void 0:r.width)||((h=(l=y.source)==null?void 0:l.data)==null?void 0:h.width)||-1,T=((g=y.image)==null?void 0:g.height)||((p=(_=y.source)==null?void 0:_.data)==null?void 0:p.height)||-1;x=new f.CompressedTexture(w,b,T,y.format,y.type,y.mapping,y.wrapS,y.wrapT,y.magFilter,y.minFilter,y.anisotropy,y.colorSpace)}else x=new f.Texture(y.image,y.mapping,y.wrapS,y.wrapT,y.magFilter,y.minFilter,y.format,y.type,y.anisotropy,y.colorSpace),x.mipmaps=y.mipmaps,x.channel=y.channel,x.source.data=y.source.data,x.flipY=y.flipY,x.premultiplyAlpha=y.premultiplyAlpha,x.unpackAlignment=y.unpackAlignment,x.matrix=new f.Matrix3(...y.matrix.elements);if(!x){console.error("[Worker] Failed to create new texture from received data. Texture is not a CompressedTexture or Texture.");continue}v.texture=x}return n}function Ri(n){let e=n;if("isInterleavedBufferAttribute"in n&&n.isInterleavedBufferAttribute){const t=n.data,i=t.array,s=new f.InterleavedBuffer(i,t.stride);e=new f.InterleavedBufferAttribute(s,n.itemSize,i.byteOffset,n.normalized),e.offset=n.offset}else"isBufferAttribute"in n&&n.isBufferAttribute&&(e=new f.BufferAttribute(n.array,n.itemSize,n.normalized),e.usage=n.usage,e.gpuType=n.gpuType,e.updateRanges=n.updateRanges);return e}const Da=je("gltf-progressive-worker"),La=je("gltf-progressive-reduce-mipmaps"),Di=Symbol("needle-progressive-texture"),Te="NEEDLE_progressive",z=class z{constructor(e){L(this,"parser");L(this,"url");L(this,"_isLoadingMesh");L(this,"loadMesh",e=>{var i,s;if(this._isLoadingMesh)return null;const t=(s=(i=this.parser.json.meshes[e])==null?void 0:i.extensions)==null?void 0:s[Te];return t?(this._isLoadingMesh=!0,this.parser.getDependency("mesh",e).then(a=>{var o;return this._isLoadingMesh=!1,a&&z.registerMesh(this.url,t.guid,a,(o=t.lods)==null?void 0:o.length,0,t),a})):null});const t=e.options.path;V&&console.log("Progressive extension registered for",t),this.parser=e,this.url=t}get name(){return Te}static getMeshLODExtension(e){const t=this.getAssignedLODInformation(e);return t!=null&&t.key?this.lodInfos.get(t.key):null}static getPrimitiveIndex(e){var i;const t=(i=this.getAssignedLODInformation(e))==null?void 0:i.index;return t??-1}static getMaterialMinMaxLODsCount(e,t){const i=this,s="LODS:minmax",a=e[s];if(a!=null)return a;if(t||(t={min_count:1/0,max_count:0,lods:[]}),Array.isArray(e)){for(const c of e)this.getMaterialMinMaxLODsCount(c,t);return e[s]=t,t}if(V==="verbose"&&console.log("getMaterialMinMaxLODsCount",e),e.type==="ShaderMaterial"||e.type==="RawShaderMaterial"){const c=e;for(const u of Object.keys(c.uniforms)){const m=c.uniforms[u].value;(m==null?void 0:m.isTexture)===!0&&o(m,t)}}else if(e.isMaterial)for(const c of Object.keys(e)){const u=e[c];(u==null?void 0:u.isTexture)===!0&&o(u,t)}else V&&console.warn(`[getMaterialMinMaxLODsCount] Unsupported material type: ${e.type}`);return e[s]=t,t;function o(c,u){const m=i.getAssignedLODInformation(c);if(m){const d=i.lodInfos.get(m.key);if(d&&d.lods){u.min_count=Math.min(u.min_count,d.lods.length),u.max_count=Math.max(u.max_count,d.lods.length);for(let r=0;r<d.lods.length;r++){const l=d.lods[r];l.width&&(u.lods[r]=u.lods[r]||{min_height:1/0,max_height:0},u.lods[r].min_height=Math.min(u.lods[r].min_height,l.height),u.lods[r].max_height=Math.max(u.lods[r].max_height,l.height))}}}}}static hasLODLevelAvailable(e,t){var a;if(Array.isArray(e)){for(const o of e)if(this.hasLODLevelAvailable(o,t))return!0;return!1}if(e.isMaterial===!0){for(const o of Object.keys(e)){const c=e[o];if(c&&c.isTexture&&this.hasLODLevelAvailable(c,t))return!0}return!1}else if(e.isGroup===!0){for(const o of e.children)if(o.isMesh===!0&&this.hasLODLevelAvailable(o,t))return!0}let i,s;if(e.isMesh?i=e.geometry:(e.isBufferGeometry||e.isTexture)&&(i=e),i&&(a=i==null?void 0:i.userData)!=null&&a.LODS){const o=i.userData.LODS;if(s=this.lodInfos.get(o.key),t===void 0)return s!=null;if(s)return Array.isArray(s.lods)?t<s.lods.length:t===0}return!1}static assignMeshLOD(e,t){var i;if(!e)return Promise.resolve(null);if(e instanceof f.Mesh||e.isMesh===!0){const s=e.geometry,a=this.getAssignedLODInformation(s);if(!a)return Promise.resolve(null);for(const o of Ee)(i=o.onBeforeGetLODMesh)==null||i.call(o,e,t);return e["LOD:requested level"]=t,z.getOrLoadLOD(s,t).then(o=>{if(Array.isArray(o)){const c=a.index||0;o=o[c]}return e["LOD:requested level"]===t&&(delete e["LOD:requested level"],o&&s!=o&&((o==null?void 0:o.isBufferGeometry)?e.geometry=o:V&&console.error("Invalid LOD geometry",o))),o}).catch(o=>(console.error("Error loading mesh LOD",e,o),null))}else V&&console.error("Invalid call to assignMeshLOD: Request mesh LOD but the object is not a mesh",e);return Promise.resolve(null)}static assignTextureLOD(e,t=0){if(!e)return Promise.resolve(null);if(e.isMesh===!0){const i=e;if(Array.isArray(i.material)){const s=new Array;for(const a of i.material){const o=this.assignTextureLOD(a,t);s.push(o)}return Promise.all(s).then(a=>{const o=new Array;for(const c of a)Array.isArray(c)&&o.push(...c);return o})}else return this.assignTextureLOD(i.material,t)}if(e.isMaterial===!0){const i=e,s=[],a=new Array;if(i.uniforms&&(i.isRawShaderMaterial||i.isShaderMaterial===!0)){const o=i;for(const c of Object.keys(o.uniforms)){const u=o.uniforms[c].value;if((u==null?void 0:u.isTexture)===!0){const m=this.assignTextureLODForSlot(u,t,i,c).then(d=>(d&&o.uniforms[c].value!=d&&(o.uniforms[c].value=d,o.uniformsNeedUpdate=!0),d));s.push(m),a.push(c)}}}else for(const o of Object.keys(i)){const c=i[o];if((c==null?void 0:c.isTexture)===!0){const u=this.assignTextureLODForSlot(c,t,i,o);s.push(u),a.push(o)}}return Promise.all(s).then(o=>{const c=new Array;for(let u=0;u<o.length;u++){const m=o[u],d=a[u];m&&m.isTexture===!0?c.push({material:i,slot:d,texture:m,level:t}):c.push({material:i,slot:d,texture:null,level:t})}return c})}if(e instanceof f.Texture||e.isTexture===!0){const i=e;return this.assignTextureLODForSlot(i,t,null,null)}return Promise.resolve(null)}static assignTextureLODForSlot(e,t,i,s){return(e==null?void 0:e.isTexture)!==!0?Promise.resolve(null):s==="glyphMap"?Promise.resolve(e):z.getOrLoadLOD(e,t).then(a=>{var o,c;if(Array.isArray(a))return console.warn("Progressive: Got an array of textures for a texture slot, this should not happen..."),null;if((a==null?void 0:a.isTexture)===!0){if(a!=e&&i&&s){const u=i[s];if(u&&!V){const m=this.getAssignedLODInformation(u);if(m&&(m==null?void 0:m.level)<t)return V==="verbose"&&console.warn("Assigned texture level is already higher: ",m.level,t,i,u,a),null}if(La&&a.mipmaps){const m=a.mipmaps.length;a.mipmaps.length=Math.min(a.mipmaps.length,3),m!==a.mipmaps.length&&V&&console.debug(`Reduced mipmap count from ${m} to ${a.mipmaps.length} for ${a.uuid}: ${(o=a.image)==null?void 0:o.width}x${(c=a.image)==null?void 0:c.height}.`)}i[s]=a}return a}else V=="verbose"&&console.warn("No LOD found for",e,t);return null}).catch(a=>(console.error("Error loading LOD",e,a),null))}afterRoot(e){var t,i;return V&&console.log("AFTER",this.url,e),(t=this.parser.json.textures)==null||t.forEach((s,a)=>{var o;if(s!=null&&s.extensions){const c=s==null?void 0:s.extensions[Te];if(c){if(!c.lods){V&&console.warn("Texture has no LODs",c);return}let u=!1;for(const m of this.parser.associations.keys())if(m.isTexture===!0){const d=this.parser.associations.get(m);(d==null?void 0:d.textures)===a&&(u=!0,z.registerTexture(this.url,m,(o=c.lods)==null?void 0:o.length,a,c))}u||this.parser.getDependency("texture",a).then(m=>{var d;m&&z.registerTexture(this.url,m,(d=c.lods)==null?void 0:d.length,a,c)})}}}),(i=this.parser.json.meshes)==null||i.forEach((s,a)=>{if(s!=null&&s.extensions){const o=s==null?void 0:s.extensions[Te];if(o&&o.lods){for(const c of this.parser.associations.keys())if(c.isMesh){const u=this.parser.associations.get(c);(u==null?void 0:u.meshes)===a&&z.registerMesh(this.url,o.guid,c,o.lods.length,u.primitives,o)}}}}),null}static async getOrLoadLOD(e,t){var u,m,d,r;const i=V=="verbose",s=this.getAssignedLODInformation(e);if(!s)return V&&console.warn(`[gltf-progressive] No LOD information found: ${e.name}, uuid: ${e.uuid}, type: ${e.type}`,e),null;const a=s==null?void 0:s.key;let o;if(e.isTexture===!0){const l=e;l.source&&l.source[Di]&&(o=l.source[Di])}if(o||(o=z.lodInfos.get(a)),!o)V&&console.warn(`Can not load LOD ${t}: no LOD info found for "${a}" ${e.name}`,e.type,z.lodInfos);else{if(t>0){let g=!1;const _=Array.isArray(o.lods);if(_&&t>=o.lods.length?g=!0:_||(g=!0),g)return this.lowresCache.get(a)}const l=Array.isArray(o.lods)?(u=o.lods[t])==null?void 0:u.path:o.lods;if(!l)return V&&!o["missing:uri"]&&(o["missing:uri"]=!0,console.warn("Missing uri for progressive asset for LOD "+t,o)),null;const h=wa(s.url,l);if(h.endsWith(".glb")||h.endsWith(".gltf")){if(!o.guid)return console.warn("missing pointer for glb/gltf texture",o),null;const g=h+"_"+o.guid,_=await this.queue.slot(h),p=this.previouslyLoaded.get(g);if(p!==void 0){i&&console.log(`LOD ${t} was already loading/loaded: ${g}`);let w=await p.catch(T=>(console.error(`Error loading LOD ${t} from ${h}
3682
+ `,T),null)),b=!1;if(w==null||(w instanceof f.Texture&&e instanceof f.Texture?(m=w.image)!=null&&m.data||(d=w.source)!=null&&d.data?w=this.copySettings(e,w):(b=!0,this.previouslyLoaded.delete(g)):w instanceof f.BufferGeometry&&e instanceof f.BufferGeometry&&((r=w.attributes.position)!=null&&r.array||(b=!0,this.previouslyLoaded.delete(g)))),!b)return w}if(!_.use)return V&&console.log(`LOD ${t} was aborted: ${h}`),null;const v=o,y=new Promise(async(w,b)=>{if(Da){const A=await(await Ia({})).load(h);if(A.textures.length>0)for(const P of A.textures){let R=P.texture;return z.assignLODInformation(s.url,R,a,t,void 0),e instanceof f.Texture&&(R=this.copySettings(e,R)),R&&(R.guid=v.guid),w(R)}if(A.geometries.length>0){const P=new Array;for(const R of A.geometries){const E=R.geometry;z.assignLODInformation(s.url,E,a,t,R.primitiveIndex),P.push(E)}return w(P)}return w(null)}const T=new ds.GLTFLoader;Cr(T),V&&(await new Promise(D=>setTimeout(D,1e3)),i&&console.warn("Start loading (delayed) "+h,v.guid));let M=h;if(v&&Array.isArray(v.lods)){const D=v.lods[t];D.hash&&(M+="?v="+D.hash)}const S=await T.loadAsync(M).catch(D=>(console.error(`Error loading LOD ${t} from ${h}
3683
+ `,D),w(null)));if(!S)return w(null);const C=S.parser;i&&console.log("Loading finished "+h,v.guid);let I=0;if(S.parser.json.textures){let D=!1;for(const A of S.parser.json.textures){if(A!=null&&A.extensions){const P=A==null?void 0:A.extensions[Te];if(P!=null&&P.guid&&P.guid===v.guid){D=!0;break}}I++}if(D){let A=await C.getDependency("texture",I);return A&&z.assignLODInformation(s.url,A,a,t,void 0),i&&console.log('change "'+e.name+'" → "'+A.name+'"',h,I,A,g),e instanceof f.Texture&&(A=this.copySettings(e,A)),A&&(A.guid=v.guid),w(A)}else V&&console.warn("Could not find texture with guid",v.guid,S.parser.json)}if(I=0,S.parser.json.meshes){let D=!1;for(const A of S.parser.json.meshes){if(A!=null&&A.extensions){const P=A==null?void 0:A.extensions[Te];if(P!=null&&P.guid&&P.guid===v.guid){D=!0;break}}I++}if(D){const A=await C.getDependency("mesh",I);if(i&&console.log(`Loaded Mesh "${A.name}"`,h,I,A,g),A.isMesh===!0){const P=A.geometry;return z.assignLODInformation(s.url,P,a,t,0),w(P)}else{const P=new Array;for(let R=0;R<A.children.length;R++){const E=A.children[R];if(E.isMesh===!0){const F=E.geometry;z.assignLODInformation(s.url,F,a,t,R),P.push(F)}}return w(P)}}else V&&console.warn("Could not find mesh with guid",v.guid,S.parser.json)}return w(null)});return this.previouslyLoaded.set(g,y),_.use(y),await y}else if(e instanceof f.Texture){i&&console.log("Load texture from uri: "+h);const _=await new f.TextureLoader().loadAsync(h);return _?(_.guid=o.guid,_.flipY=!1,_.needsUpdate=!0,_.colorSpace=e.colorSpace,i&&console.log(o,_)):V&&console.warn("failed loading",h),_}}return null}static assignLODInformation(e,t,i,s,a){if(!t)return;t.userData||(t.userData={});const o=new Ea(e,i,s,a);t.userData.LODS=o,"source"in t&&typeof t.source=="object"&&(t.source.LODS=o)}static getAssignedLODInformation(e){var t,i;return e?(t=e.userData)!=null&&t.LODS?e.userData.LODS:"source"in e&&((i=e.source)!=null&&i.LODS)?e.source.LODS:null:null}static copySettings(e,t){return t?(V==="verbose"&&console.debug(`Copy texture settings
3684
+ `,e.uuid,`
3685
+ `,t.uuid),t=t.clone(),t.offset=e.offset,t.repeat=e.repeat,t.colorSpace=e.colorSpace,t.magFilter=e.magFilter,t.minFilter=e.minFilter,t.wrapS=e.wrapS,t.wrapT=e.wrapT,t.flipY=e.flipY,t.anisotropy=e.anisotropy,t.mipmaps||(t.generateMipmaps=e.generateMipmaps),t):e}};L(z,"registerTexture",(e,t,i,s,a)=>{var c,u,m,d,r,l,h,g;if(!t){V&&console.error("!! gltf-progressive: Called register texture without texture");return}if(V){const _=((c=t.image)==null?void 0:c.width)||((m=(u=t.source)==null?void 0:u.data)==null?void 0:m.width)||0,p=((d=t.image)==null?void 0:d.height)||((l=(r=t.source)==null?void 0:r.data)==null?void 0:l.height)||0;console.log(`> gltf-progressive: register texture[${s}] "${t.name||t.uuid}", Current: ${_}x${p}, Max: ${(h=a.lods[0])==null?void 0:h.width}x${(g=a.lods[0])==null?void 0:g.height}, uuid: ${t.uuid}`,a,t)}t.source&&(t.source[Di]=a);const o=a.guid;z.assignLODInformation(e,t,o,i,s),z.lodInfos.set(o,a),z.lowresCache.set(o,t)}),L(z,"registerMesh",(e,t,i,s,a,o)=>{var m;const c=i.geometry;if(!c){V&&console.warn("gltf-progressive: Register mesh without geometry");return}c.userData||(c.userData={}),V&&console.log("> Progressive: register mesh "+i.name,{index:a,uuid:i.uuid},o,i),z.assignLODInformation(e,c,t,s,a),z.lodInfos.set(t,o);let u=z.lowresCache.get(t);u?u.push(i.geometry):u=[i.geometry],z.lowresCache.set(t,u),s>0&&!Ut(i)&&Ta(i,c);for(const d of Ee)(m=d.onRegisteredNewMesh)==null||m.call(d,i,o)}),L(z,"lodInfos",new Map),L(z,"previouslyLoaded",new Map),L(z,"lowresCache",new Map),L(z,"workers",[]),L(z,"_workersIndex",0),L(z,"maxConcurrent",50),L(z,"queue",new ba(z.maxConcurrent,{debug:V!=!1}));let xe=z;class Ea{constructor(e,t,i,s){L(this,"url");L(this,"key");L(this,"level");L(this,"index");this.url=e,this.key=t,this.level=i,s!=null&&(this.index=s)}}class li{constructor(e,t){L(this,"ready");L(this,"_resolve");L(this,"_signal");L(this,"_frame_start");L(this,"_frames_to_capture");L(this,"_resolved",!1);L(this,"_addedCount",0);L(this,"_resolvedCount",0);L(this,"_awaiting",[]);L(this,"_maxPromisesPerObject",1);L(this,"_currentFrame",0);L(this,"_seen",new WeakMap);var a;const s=Math.max(t.frames??2,2);this._frame_start=t.waitForFirstCapture?void 0:e,this._frames_to_capture=s,this.ready=new Promise(o=>{this._resolve=o}),this.ready.finally(()=>{this._resolved=!0,this._awaiting.length=0}),this._signal=t.signal,(a=this._signal)==null||a.addEventListener("abort",()=>{this.resolveNow()}),this._maxPromisesPerObject=Math.max(1,t.maxPromisesPerObject??1)}get awaitedCount(){return this._addedCount}get resolvedCount(){return this._resolvedCount}get currentlyAwaiting(){return this._awaiting.length}update(e){var t;this._currentFrame=e,this._frame_start===void 0&&this._addedCount>0&&(this._frame_start=e),((t=this._signal)!=null&&t.aborted||this._awaiting.length===0&&this._frame_start!==void 0&&e>this._frame_start+this._frames_to_capture)&&this.resolveNow()}add(e,t,i){if(this._resolved){V&&console.warn("PromiseGroup: Trying to add a promise to a resolved group, ignoring.");return}if(!(this._frame_start!==void 0&&this._currentFrame>this._frame_start+this._frames_to_capture)){if(this._maxPromisesPerObject>=1)if(this._seen.has(t)){let s=this._seen.get(t);if(s>=this._maxPromisesPerObject){V&&console.warn("PromiseGroup: Already awaiting object ignoring new promise for it.");return}this._seen.set(t,s+1)}else this._seen.set(t,1);this._awaiting.push(i),this._addedCount++,i.finally(()=>{this._resolvedCount++,this._awaiting.splice(this._awaiting.indexOf(i),1)})}}resolveNow(){var e,t;this._resolved||(t=this._resolve)==null||t.call(this,{awaited_count:this._addedCount,resolved_count:this._resolvedCount,cancelled:((e=this._signal)==null?void 0:e.aborted)??!1})}}L(li,"addPromise",(e,t,i,s)=>{s.forEach(a=>{a.add(e,t,i)})});const fe=je("debugprogressive"),Fa=je("noprogressive"),Li=Symbol("Needle:LODSManager"),Ei=Symbol("Needle:LODState"),De=Symbol("Needle:CurrentLOD"),te={mesh_lod:-1,texture_lod:-1};var se,Se,gi,ke,mt,vi,Me;const N=class N{constructor(e,t){L(this,"renderer");L(this,"context");L(this,"projectionScreenMatrix",new f.Matrix4);L(this,"overrideLodLevel");L(this,"targetTriangleDensity",2e5);L(this,"skinnedMeshAutoUpdateBoundsInterval",30);L(this,"updateInterval","auto");Re(this,se,1);L(this,"pause",!1);L(this,"manual",!1);L(this,"_newPromiseGroups",[]);L(this,"_promiseGroupIds",0);L(this,"_lodchangedlisteners",[]);Re(this,Se,void 0);Re(this,gi,new f.Clock);Re(this,ke,0);Re(this,mt,0);Re(this,vi,0);Re(this,Me,0);L(this,"_fpsBuffer",[60,60,60,60,60]);L(this,"_sphere",new f.Sphere);L(this,"_tempBox",new f.Box3);L(this,"_tempBox2",new f.Box3);L(this,"tempMatrix",new f.Matrix4);L(this,"_tempWorldPosition",new f.Vector3);L(this,"_tempBoxSize",new f.Vector3);L(this,"_tempBox2Size",new f.Vector3);this.renderer=e,this.context={...t}}static getObjectLODState(e){return e[Ei]}static addPlugin(e){Ee.push(e)}static removePlugin(e){const t=Ee.indexOf(e);t>=0&&Ee.splice(t,1)}static get(e,t){if(e[Li])return console.debug("[gltf-progressive] LODsManager already exists for this renderer"),e[Li];const i=new N(e,{engine:"unknown",...t});return e[Li]=i,i}get plugins(){return Ee}awaitLoading(e){const t=this._promiseGroupIds++,i=new li(U(this,ke),{...e});this._newPromiseGroups.push(i);const s=performance.now();return i.ready.finally(()=>{const a=this._newPromiseGroups.indexOf(i);a>=0&&(this._newPromiseGroups.splice(a,1),Ks()&&performance.measure("LODsManager:awaitLoading",{start:s,detail:{id:t,name:e==null?void 0:e.name,awaited:i.awaitedCount,resolved:i.resolvedCount}}))}),i.ready}_postprocessPromiseGroups(){if(this._newPromiseGroups.length!==0)for(let e=this._newPromiseGroups.length-1;e>=0;e--)this._newPromiseGroups[e].update(U(this,ke))}addEventListener(e,t){e==="changed"&&this._lodchangedlisteners.push(t)}removeEventListener(e,t){if(e==="changed"){const i=this._lodchangedlisteners.indexOf(t);i>=0&&this._lodchangedlisteners.splice(i,1)}}enable(){if(U(this,Se))return;console.debug("[gltf-progressive] Enabling LODsManager for renderer");let e=0;_e(this,Se,this.renderer.render);const t=this;vs(this.renderer),this.renderer.render=function(i,s){const a=t.renderer.getRenderTarget();(a==null||"isXRRenderTarget"in a&&a.isXRRenderTarget)&&(e=0,_e(t,ke,U(t,ke)+1),_e(t,mt,U(t,gi).getDelta()),_e(t,vi,U(t,vi)+U(t,mt)),t._fpsBuffer.shift(),t._fpsBuffer.push(1/U(t,mt)),_e(t,Me,t._fpsBuffer.reduce((c,u)=>c+u)/t._fpsBuffer.length),fe&&U(t,ke)%200===0&&console.log("FPS",Math.round(U(t,Me)),"Interval:",U(t,se)));const o=e++;U(t,Se).call(this,i,s),t.onAfterRender(i,s,o)}}disable(){U(this,Se)&&(console.debug("[gltf-progressive] Disabling LODsManager for renderer"),this.renderer.render=U(this,Se),_e(this,Se,void 0))}update(e,t){this.internalUpdate(e,t)}onAfterRender(e,t,i){if(this.pause)return;const a=this.renderer.renderLists.get(e,0).opaque;let o=!0;if(a.length===1){const c=a[0].material;(c.name==="EffectMaterial"||c.name==="CopyShader")&&(o=!1)}if((t.parent&&t.parent.type==="CubeCamera"||i>=1&&t.type==="OrthographicCamera")&&(o=!1),o){if(Fa||(this.updateInterval==="auto"?U(this,Me)<40&&U(this,se)<10?(_e(this,se,U(this,se)+1),fe&&console.warn("↓ Reducing LOD updates",U(this,se),U(this,Me).toFixed(0))):U(this,Me)>=60&&U(this,se)>1&&(_e(this,se,U(this,se)-1),fe&&console.warn("↑ Increasing LOD updates",U(this,se),U(this,Me).toFixed(0))):_e(this,se,this.updateInterval),U(this,se)>0&&U(this,ke)%U(this,se)!=0))return;this.internalUpdate(e,t),this._postprocessPromiseGroups()}}internalUpdate(e,t){var u,m;const i=this.renderer.renderLists.get(e,0),s=i.opaque;this.projectionScreenMatrix.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse);const a=this.targetTriangleDensity;for(const d of s){if(d.material&&(((u=d.geometry)==null?void 0:u.type)==="BoxGeometry"||((m=d.geometry)==null?void 0:m.type)==="BufferGeometry")&&(d.material.name==="SphericalGaussianBlur"||d.material.name=="BackgroundCubeMaterial"||d.material.name==="CubemapFromEquirect"||d.material.name==="EquirectangularToCubeUV")){fe&&(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]||(d.material["NEEDLE_PROGRESSIVE:IGNORE-WARNING"]=!0,console.warn("Ignoring skybox or BLIT object",d,d.material.name,d.material.type)));continue}switch(d.material.type){case"LineBasicMaterial":case"LineDashedMaterial":case"PointsMaterial":case"ShadowMaterial":case"MeshDistanceMaterial":case"MeshDepthMaterial":continue}if(fe==="color"&&d.material&&!d.object.progressive_debug_color){d.object.progressive_debug_color=!0;const l=Math.random()*16777215,h=new f.MeshStandardMaterial({color:l});d.object.material=h}const r=d.object;(r instanceof f.Mesh||r.isMesh)&&this.updateLODs(e,t,r,a)}const o=i.transparent;for(const d of o){const r=d.object;(r instanceof f.Mesh||r.isMesh)&&this.updateLODs(e,t,r,a)}const c=i.transmissive;for(const d of c){const r=d.object;(r instanceof f.Mesh||r.isMesh)&&this.updateLODs(e,t,r,a)}}updateLODs(e,t,i,s){var c,u;i.userData||(i.userData={});let a=i[Ei];if(a||(a=new Ba,i[Ei]=a),a.frames++<2)return;for(const m of Ee)(c=m.onBeforeUpdateLOD)==null||c.call(m,this.renderer,e,t,i);const o=this.overrideLodLevel!==void 0?this.overrideLodLevel:Ne;o>=0?(te.mesh_lod=o,te.texture_lod=o):(this.calculateLodLevel(t,i,a,s,te),te.mesh_lod=Math.round(te.mesh_lod),te.texture_lod=Math.round(te.texture_lod)),te.mesh_lod>=0&&this.loadProgressiveMeshes(i,te.mesh_lod),i.material&&te.texture_lod>=0&&this.loadProgressiveTextures(i.material,te.texture_lod,o),V&&i.material&&!i.isGizmo&&Dr(i.material);for(const m of Ee)(u=m.onAfterUpdatedLOD)==null||u.call(m,this.renderer,e,t,i,te);a.lastLodLevel_Mesh=te.mesh_lod,a.lastLodLevel_Texture=te.texture_lod}loadProgressiveTextures(e,t,i){if(!e)return;if(Array.isArray(e)){for(const a of e)this.loadProgressiveTextures(a,t);return}let s=!1;if((e[De]===void 0||t<e[De])&&(s=!0),i!==void 0&&i>=0&&(s=e[De]!=i,t=i),s){e[De]=t;const a=xe.assignTextureLOD(e,t).then(o=>{this._lodchangedlisteners.forEach(c=>c({type:"texture",level:t,object:e}))});li.addPromise("texture",e,a,this._newPromiseGroups)}}loadProgressiveMeshes(e,t){if(!e)return Promise.resolve(null);let i=e[De]!==t;const s=e["DEBUG:LOD"];if(s!=null&&(i=e[De]!=s,t=s),i){e[De]=t;const a=e.geometry,o=xe.assignMeshLOD(e,t).then(c=>(c&&e[De]==t&&a!=e.geometry&&this._lodchangedlisteners.forEach(u=>u({type:"mesh",level:t,object:e})),c));return li.addPromise("mesh",e,o,this._newPromiseGroups),o}return Promise.resolve(null)}static isInside(e,t){const i=e.min,s=e.max,a=(i.x+s.x)*.5,o=(i.y+s.y)*.5;return this._tempPtInside.set(a,o,i.z).applyMatrix4(t).z<0}calculateLodLevel(e,t,i,s,a){var p,v,y,x;if(!t){a.mesh_lod=-1,a.texture_lod=-1;return}if(!e){a.mesh_lod=-1,a.texture_lod=-1;return}let c=10+1,u=!1;if(fe&&t["DEBUG:LOD"]!=null)return t["DEBUG:LOD"];const m=(p=xe.getMeshLODExtension(t.geometry))==null?void 0:p.lods,d=xe.getPrimitiveIndex(t.geometry),r=m&&m.length>0,l=xe.getMaterialMinMaxLODsCount(t.material),h=l.min_count!==1/0&&l.min_count>=0&&l.max_count>=0;if(!r&&!h){a.mesh_lod=0,a.texture_lod=0;return}r||(u=!0,c=0);const g=this.renderer.domElement.clientHeight||this.renderer.domElement.height;let _=t.geometry.boundingBox;if(t.type==="SkinnedMesh"){const w=t;if(!w.boundingBox)w.computeBoundingBox();else if(this.skinnedMeshAutoUpdateBoundsInterval>0){if(!w[N.$skinnedMeshBoundsOffset]){const T=N.skinnedMeshBoundsFrameOffsetCounter++;w[N.$skinnedMeshBoundsOffset]=T}const b=w[N.$skinnedMeshBoundsOffset];if((i.frames+b)%this.skinnedMeshAutoUpdateBoundsInterval===0){const T=Ut(w),M=w.geometry;T&&(w.geometry=T),w.computeBoundingBox(),w.geometry=M}}_=w.boundingBox}if(_){const w=e;if(t.geometry.attributes.color&&t.geometry.attributes.color.count<100&&t.geometry.boundingSphere){this._sphere.copy(t.geometry.boundingSphere),this._sphere.applyMatrix4(t.matrixWorld);const P=e.getWorldPosition(this._tempWorldPosition);if(this._sphere.containsPoint(P)){a.mesh_lod=0,a.texture_lod=0;return}}if(this._tempBox.copy(_),this._tempBox.applyMatrix4(t.matrixWorld),w.isPerspectiveCamera&&N.isInside(this._tempBox,this.projectionScreenMatrix)){a.mesh_lod=0,a.texture_lod=0;return}if(this._tempBox.applyMatrix4(this.projectionScreenMatrix),this.renderer.xr.enabled&&w.isPerspectiveCamera&&w.fov>70){const P=this._tempBox.min,R=this._tempBox.max;let E=P.x,F=P.y,k=R.x,H=R.y;const W=2,Q=1.5,X=(P.x+R.x)*.5,O=(P.y+R.y)*.5;E=(E-X)*W+X,F=(F-O)*W+O,k=(k-X)*W+X,H=(H-O)*W+O;const ve=E<0&&k>0?0:Math.min(Math.abs(P.x),Math.abs(R.x)),Ie=F<0&&H>0?0:Math.min(Math.abs(P.y),Math.abs(R.y)),ue=Math.max(ve,Ie);i.lastCentrality=(Q-ue)*(Q-ue)*(Q-ue)}else i.lastCentrality=1;const b=this._tempBox.getSize(this._tempBoxSize);b.multiplyScalar(.5),screen.availHeight>0&&g>0&&b.multiplyScalar(g/screen.availHeight),e.isPerspectiveCamera?b.x*=e.aspect:e.isOrthographicCamera;const T=e.matrixWorldInverse,M=this._tempBox2;M.copy(_),M.applyMatrix4(t.matrixWorld),M.applyMatrix4(T);const S=M.getSize(this._tempBox2Size),C=Math.max(S.x,S.y);if(Math.max(b.x,b.y)!=0&&C!=0&&(b.z=S.z/Math.max(S.x,S.y)*Math.max(b.x,b.y)),i.lastScreenCoverage=Math.max(b.x,b.y,b.z),i.lastScreenspaceVolume.copy(b),i.lastScreenCoverage*=i.lastCentrality,fe&&N.debugDrawLine){const P=this.tempMatrix.copy(this.projectionScreenMatrix);P.invert();const R=N.corner0,E=N.corner1,F=N.corner2,k=N.corner3;R.copy(this._tempBox.min),E.copy(this._tempBox.max),E.x=R.x,F.copy(this._tempBox.max),F.y=R.y,k.copy(this._tempBox.max);const H=(R.z+k.z)*.5;R.z=E.z=F.z=k.z=H,R.applyMatrix4(P),E.applyMatrix4(P),F.applyMatrix4(P),k.applyMatrix4(P),N.debugDrawLine(R,E,255),N.debugDrawLine(R,F,255),N.debugDrawLine(E,k,255),N.debugDrawLine(F,k,255)}let D=999;if(m&&i.lastScreenCoverage>0)for(let P=0;P<m.length;P++){const R=m[P],F=(((v=R.densities)==null?void 0:v[d])||R.density||1e-5)/i.lastScreenCoverage;if(d>0&&Ks()&&!R.densities&&!globalThis["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]&&(window["NEEDLE:MISSING_LOD_PRIMITIVE_DENSITIES"]=!0,console.warn("[Needle Progressive] Detected usage of mesh without primitive densities. This might cause incorrect LOD level selection: Consider re-optimizing your model by updating your Needle Integration, Needle glTF Pipeline or running optimization again on Needle Cloud.")),F<s){D=P;break}}D<c&&(c=D,u=!0)}if(u?a.mesh_lod=c:a.mesh_lod=i.lastLodLevel_Mesh,fe&&a.mesh_lod!=i.lastLodLevel_Mesh){const b=m==null?void 0:m[a.mesh_lod];b&&console.log(`Mesh LOD changed: ${i.lastLodLevel_Mesh} → ${a.mesh_lod} (density: ${(y=b.densities)==null?void 0:y[d].toFixed(0)}) | ${t.name}`)}if(h){const w="saveData"in globalThis.navigator&&globalThis.navigator.saveData===!0;if(i.lastLodLevel_Texture<0){if(a.texture_lod=l.max_count-1,fe){const b=l.lods[l.max_count-1];fe&&console.log(`First Texture LOD ${a.texture_lod} (${b.max_height}px) - ${t.name}`)}}else{const b=i.lastScreenspaceVolume.x+i.lastScreenspaceVolume.y+i.lastScreenspaceVolume.z;let T=i.lastScreenCoverage*4;((x=this.context)==null?void 0:x.engine)==="model-viewer"&&(T*=1.5);const S=g/window.devicePixelRatio*T;let C=!1;for(let I=l.lods.length-1;I>=0;I--){const D=l.lods[I];if(!(w&&D.max_height>=2048)&&!(Rr()&&D.max_height>4096)&&(D.max_height>S||!C&&I===0)){if(C=!0,a.texture_lod=I,fe&&a.texture_lod<i.lastLodLevel_Texture){const A=D.max_height;console.log(`Texture LOD changed: ${i.lastLodLevel_Texture} → ${a.texture_lod} = ${A}px
3686
+ Screensize: ${S.toFixed(0)}px, Coverage: ${(100*i.lastScreenCoverage).toFixed(2)}%, Volume ${b.toFixed(1)}
3687
+ ${t.name}`)}break}}}}else a.texture_lod=0}};se=new WeakMap,Se=new WeakMap,gi=new WeakMap,ke=new WeakMap,mt=new WeakMap,vi=new WeakMap,Me=new WeakMap,L(N,"debugDrawLine"),L(N,"corner0",new f.Vector3),L(N,"corner1",new f.Vector3),L(N,"corner2",new f.Vector3),L(N,"corner3",new f.Vector3),L(N,"_tempPtInside",new f.Vector3),L(N,"skinnedMeshBoundsFrameOffsetCounter",0),L(N,"$skinnedMeshBoundsOffset",Symbol("gltf-progressive-skinnedMeshBoundsOffset"));let _t=N;class Ba{constructor(){L(this,"frames",0);L(this,"lastLodLevel_Mesh",-1);L(this,"lastLodLevel_Texture",-1);L(this,"lastScreenCoverage",0);L(this,"lastScreenspaceVolume",new f.Vector3);L(this,"lastCentrality",0)}}const $s=Symbol("NEEDLE_mesh_lod"),Yt=Symbol("NEEDLE_texture_lod");let Ct=null;function Lr(){const n=ka();n&&(n.mapURLs(function(e){return Js(),e}),Js(),Ct==null||Ct.disconnect(),Ct=new MutationObserver(e=>{e.forEach(t=>{t.addedNodes.forEach(i=>{i instanceof HTMLElement&&i.tagName.toLowerCase()==="model-viewer"&&Er(i)})})}),Ct.observe(document,{childList:!0,subtree:!0}))}function ka(){if(typeof customElements>"u")return null;const n=customElements.get("model-viewer");return n||(customElements.whenDefined("model-viewer").then(()=>{console.debug("[gltf-progressive] model-viewer defined"),Lr()}),null)}function Js(){if(typeof document>"u")return;document.querySelectorAll("model-viewer").forEach(e=>{Er(e)})}const er=new WeakSet;let Oa=0;function Er(n){if(!n||er.has(n))return null;er.add(n),console.debug("[gltf-progressive] found new model-viewer..."+ ++Oa+`
3688
+ `,n.getAttribute("src"));let e=null,t=null,i=null;for(let s=n;s!=null;s=Object.getPrototypeOf(s)){const a=Object.getOwnPropertySymbols(s),o=a.find(m=>m.toString()=="Symbol(renderer)"),c=a.find(m=>m.toString()=="Symbol(scene)"),u=a.find(m=>m.toString()=="Symbol(needsRender)");!e&&o!=null&&(e=n[o].threeRenderer),!t&&c!=null&&(t=n[c]),!i&&u!=null&&(i=n[u])}if(e&&t){let a=function(){if(i){let o=0,c=setInterval(()=>{if(o++>5){clearInterval(c);return}i==null||i.call(n)},300)}};console.debug("[gltf-progressive] setup model-viewer");const s=_t.get(e,{engine:"model-viewer"});return _t.addPlugin(new za),s.enable(),s.addEventListener("changed",()=>{i==null||i.call(n)}),n.addEventListener("model-visibility",o=>{o.detail.visible&&(i==null||i.call(n))}),n.addEventListener("load",()=>{a()}),()=>{s.disable()}}return null}class za{constructor(){L(this,"_didWarnAboutMissingUrl",!1)}onBeforeUpdateLOD(e,t,i,s){this.tryParseMeshLOD(t,s),this.tryParseTextureLOD(t,s)}getUrl(e){if(!e)return null;let t=e.getAttribute("src");return t||(t=e.src),t||(this._didWarnAboutMissingUrl||console.warn("No url found in modelviewer",e),this._didWarnAboutMissingUrl=!0),t}tryGetCurrentGLTF(e){return e._currentGLTF}tryGetCurrentModelViewer(e){return e.element}tryParseTextureLOD(e,t){if(t[Yt]==!0)return;t[Yt]=!0;const i=this.tryGetCurrentGLTF(e),s=this.tryGetCurrentModelViewer(e),a=this.getUrl(s);if(a&&i&&t.material){let c=function(u){var d,r,l;if(u[Yt]==!0)return;u[Yt]=!0,u.userData&&(u.userData.LOD=-1);const m=Object.keys(u);for(let h=0;h<m.length;h++){const g=m[h],_=u[g];if((_==null?void 0:_.isTexture)===!0){const p=(r=(d=_.userData)==null?void 0:d.associations)==null?void 0:r.textures;if(p==null)continue;const v=i.parser.json.textures[p];if(!v){console.warn("Texture data not found for texture index "+p);continue}if((l=v==null?void 0:v.extensions)!=null&&l[Te]){const y=v.extensions[Te];y&&a&&xe.registerTexture(a,_,y.lods.length,p,y)}}}};const o=t.material;if(Array.isArray(o))for(const u of o)c(u);else c(o)}}tryParseMeshLOD(e,t){var o,c;if(t[$s]==!0)return;t[$s]=!0;const i=this.tryGetCurrentModelViewer(e),s=this.getUrl(i);if(!s)return;const a=(c=(o=t.userData)==null?void 0:o.gltfExtensions)==null?void 0:c[Te];if(a&&s){const u=t.uuid;xe.registerMesh(s,u,t,0,a.lods.length,a)}}}function Fr(...n){let e,t,i,s;switch(n.length){case 2:[i,t]=n,s={};break;case 3:[i,t,s]=n;break;case 4:[e,t,i,s]=n;break;default:throw new Error("Invalid arguments")}vs(t),Cr(i),Ir(i,{progressive:!0,...s==null?void 0:s.hints}),i.register(o=>new xe(o));const a=_t.get(t);return(s==null?void 0:s.enableLODsManager)!==!1&&a.enable(),a}Lr();if(!Aa){const n={gltfProgressive:{useNeedleProgressive:Fr,LODsManager:_t,configureLoader:Ir,getRaycastMesh:Ut,useRaycastMeshes:Sa}};if(!globalThis.Needle)globalThis.Needle=n;else for(const e in n)globalThis.Needle[e]=n[e]}var pt=Object.freeze({Linear:Object.freeze({None:function(n){return n},In:function(n){return n},Out:function(n){return n},InOut:function(n){return n}}),Quadratic:Object.freeze({In:function(n){return n*n},Out:function(n){return n*(2-n)},InOut:function(n){return(n*=2)<1?.5*n*n:-.5*(--n*(n-2)-1)}}),Cubic:Object.freeze({In:function(n){return n*n*n},Out:function(n){return--n*n*n+1},InOut:function(n){return(n*=2)<1?.5*n*n*n:.5*((n-=2)*n*n+2)}}),Quartic:Object.freeze({In:function(n){return n*n*n*n},Out:function(n){return 1- --n*n*n*n},InOut:function(n){return(n*=2)<1?.5*n*n*n*n:-.5*((n-=2)*n*n*n-2)}}),Quintic:Object.freeze({In:function(n){return n*n*n*n*n},Out:function(n){return--n*n*n*n*n+1},InOut:function(n){return(n*=2)<1?.5*n*n*n*n*n:.5*((n-=2)*n*n*n*n+2)}}),Sinusoidal:Object.freeze({In:function(n){return 1-Math.sin((1-n)*Math.PI/2)},Out:function(n){return Math.sin(n*Math.PI/2)},InOut:function(n){return .5*(1-Math.sin(Math.PI*(.5-n)))}}),Exponential:Object.freeze({In:function(n){return n===0?0:Math.pow(1024,n-1)},Out:function(n){return n===1?1:1-Math.pow(2,-10*n)},InOut:function(n){return n===0?0:n===1?1:(n*=2)<1?.5*Math.pow(1024,n-1):.5*(-Math.pow(2,-10*(n-1))+2)}}),Circular:Object.freeze({In:function(n){return 1-Math.sqrt(1-n*n)},Out:function(n){return Math.sqrt(1- --n*n)},InOut:function(n){return(n*=2)<1?-.5*(Math.sqrt(1-n*n)-1):.5*(Math.sqrt(1-(n-=2)*n)+1)}}),Elastic:Object.freeze({In:function(n){return n===0?0:n===1?1:-Math.pow(2,10*(n-1))*Math.sin((n-1.1)*5*Math.PI)},Out:function(n){return n===0?0:n===1?1:Math.pow(2,-10*n)*Math.sin((n-.1)*5*Math.PI)+1},InOut:function(n){return n===0?0:n===1?1:(n*=2,n<1?-.5*Math.pow(2,10*(n-1))*Math.sin((n-1.1)*5*Math.PI):.5*Math.pow(2,-10*(n-1))*Math.sin((n-1.1)*5*Math.PI)+1)}}),Back:Object.freeze({In:function(n){var e=1.70158;return n===1?1:n*n*((e+1)*n-e)},Out:function(n){var e=1.70158;return n===0?0:--n*n*((e+1)*n+e)+1},InOut:function(n){var e=2.5949095;return(n*=2)<1?.5*(n*n*((e+1)*n-e)):.5*((n-=2)*n*((e+1)*n+e)+2)}}),Bounce:Object.freeze({In:function(n){return 1-pt.Bounce.Out(1-n)},Out:function(n){return n<1/2.75?7.5625*n*n:n<2/2.75?7.5625*(n-=1.5/2.75)*n+.75:n<2.5/2.75?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375},InOut:function(n){return n<.5?pt.Bounce.In(n*2)*.5:pt.Bounce.Out(n*2-1)*.5+.5}}),generatePow:function(n){return n===void 0&&(n=4),n=n<Number.EPSILON?Number.EPSILON:n,n=n>1e4?1e4:n,{In:function(e){return Math.pow(e,n)},Out:function(e){return 1-Math.pow(1-e,n)},InOut:function(e){return e<.5?Math.pow(e*2,n)/2:(1-Math.pow(2-e*2,n))/2+.5}}}}),ft=function(){return performance.now()},Br=function(){function n(){this._tweens={},this._tweensAddedDuringUpdate={}}return n.prototype.getAll=function(){var e=this;return Object.keys(this._tweens).map(function(t){return e._tweens[t]})},n.prototype.removeAll=function(){this._tweens={}},n.prototype.add=function(e){this._tweens[e.getId()]=e,this._tweensAddedDuringUpdate[e.getId()]=e},n.prototype.remove=function(e){delete this._tweens[e.getId()],delete this._tweensAddedDuringUpdate[e.getId()]},n.prototype.update=function(e,t){e===void 0&&(e=ft()),t===void 0&&(t=!1);var i=Object.keys(this._tweens);if(i.length===0)return!1;for(;i.length>0;){this._tweensAddedDuringUpdate={};for(var s=0;s<i.length;s++){var a=this._tweens[i[s]],o=!t;a&&a.update(e,o)===!1&&!t&&delete this._tweens[i[s]]}i=Object.keys(this._tweensAddedDuringUpdate)}return!0},n}(),Ge={Linear:function(n,e){var t=n.length-1,i=t*e,s=Math.floor(i),a=Ge.Utils.Linear;return e<0?a(n[0],n[1],i):e>1?a(n[t],n[t-1],t-i):a(n[s],n[s+1>t?t:s+1],i-s)},Bezier:function(n,e){for(var t=0,i=n.length-1,s=Math.pow,a=Ge.Utils.Bernstein,o=0;o<=i;o++)t+=s(1-e,i-o)*s(e,o)*n[o]*a(i,o);return t},CatmullRom:function(n,e){var t=n.length-1,i=t*e,s=Math.floor(i),a=Ge.Utils.CatmullRom;return n[0]===n[t]?(e<0&&(s=Math.floor(i=t*(1+e))),a(n[(s-1+t)%t],n[s],n[(s+1)%t],n[(s+2)%t],i-s)):e<0?n[0]-(a(n[0],n[0],n[1],n[1],-i)-n[0]):e>1?n[t]-(a(n[t],n[t],n[t-1],n[t-1],i-t)-n[t]):a(n[s?s-1:0],n[s],n[t<s+1?t:s+1],n[t<s+2?t:s+2],i-s)},Utils:{Linear:function(n,e,t){return(e-n)*t+n},Bernstein:function(n,e){var t=Ge.Utils.Factorial;return t(n)/t(e)/t(n-e)},Factorial:function(){var n=[1];return function(e){var t=1;if(n[e])return n[e];for(var i=e;i>1;i--)t*=i;return n[e]=t,t}}(),CatmullRom:function(n,e,t,i,s){var a=(t-n)*.5,o=(i-e)*.5,c=s*s,u=s*c;return(2*e-2*t+a+o)*u+(-3*e+3*t-2*a-o)*c+a*s+e}}},ys=function(){function n(){}return n.nextId=function(){return n._nextId++},n._nextId=0,n}(),Zi=new Br,di=function(){function n(e,t){t===void 0&&(t=Zi),this._object=e,this._group=t,this._isPaused=!1,this._pauseStart=0,this._valuesStart={},this._valuesEnd={},this._valuesStartRepeat={},this._duration=1e3,this._isDynamic=!1,this._initialRepeat=0,this._repeat=0,this._yoyo=!1,this._isPlaying=!1,this._reversed=!1,this._delayTime=0,this._startTime=0,this._easingFunction=pt.Linear.None,this._interpolationFunction=Ge.Linear,this._chainedTweens=[],this._onStartCallbackFired=!1,this._onEveryStartCallbackFired=!1,this._id=ys.nextId(),this._isChainStopped=!1,this._propertiesAreSetUp=!1,this._goToEnd=!1}return n.prototype.getId=function(){return this._id},n.prototype.isPlaying=function(){return this._isPlaying},n.prototype.isPaused=function(){return this._isPaused},n.prototype.getDuration=function(){return this._duration},n.prototype.to=function(e,t){if(t===void 0&&(t=1e3),this._isPlaying)throw new Error("Can not call Tween.to() while Tween is already started or paused. Stop the Tween first.");return this._valuesEnd=e,this._propertiesAreSetUp=!1,this._duration=t<0?0:t,this},n.prototype.duration=function(e){return e===void 0&&(e=1e3),this._duration=e<0?0:e,this},n.prototype.dynamic=function(e){return e===void 0&&(e=!1),this._isDynamic=e,this},n.prototype.start=function(e,t){if(e===void 0&&(e=ft()),t===void 0&&(t=!1),this._isPlaying)return this;if(this._group&&this._group.add(this),this._repeat=this._initialRepeat,this._reversed){this._reversed=!1;for(var i in this._valuesStartRepeat)this._swapEndStartRepeatValues(i),this._valuesStart[i]=this._valuesStartRepeat[i]}if(this._isPlaying=!0,this._isPaused=!1,this._onStartCallbackFired=!1,this._onEveryStartCallbackFired=!1,this._isChainStopped=!1,this._startTime=e,this._startTime+=this._delayTime,!this._propertiesAreSetUp||t){if(this._propertiesAreSetUp=!0,!this._isDynamic){var s={};for(var a in this._valuesEnd)s[a]=this._valuesEnd[a];this._valuesEnd=s}this._setupProperties(this._object,this._valuesStart,this._valuesEnd,this._valuesStartRepeat,t)}return this},n.prototype.startFromCurrentValues=function(e){return this.start(e,!0)},n.prototype._setupProperties=function(e,t,i,s,a){for(var o in i){var c=e[o],u=Array.isArray(c),m=u?"array":typeof c,d=!u&&Array.isArray(i[o]);if(!(m==="undefined"||m==="function")){if(d){var r=i[o];if(r.length===0)continue;for(var l=[c],h=0,g=r.length;h<g;h+=1){var _=this._handleRelativeValue(c,r[h]);if(isNaN(_)){d=!1,console.warn("Found invalid interpolation list. Skipping.");break}l.push(_)}d&&(i[o]=l)}if((m==="object"||u)&&c&&!d){t[o]=u?[]:{};var p=c;for(var v in p)t[o][v]=p[v];s[o]=u?[]:{};var r=i[o];if(!this._isDynamic){var y={};for(var v in r)y[v]=r[v];i[o]=r=y}this._setupProperties(p,t[o],r,s[o],a)}else(typeof t[o]>"u"||a)&&(t[o]=c),u||(t[o]*=1),d?s[o]=i[o].slice().reverse():s[o]=t[o]||0}}},n.prototype.stop=function(){return this._isChainStopped||(this._isChainStopped=!0,this.stopChainedTweens()),this._isPlaying?(this._group&&this._group.remove(this),this._isPlaying=!1,this._isPaused=!1,this._onStopCallback&&this._onStopCallback(this._object),this):this},n.prototype.end=function(){return this._goToEnd=!0,this.update(1/0),this},n.prototype.pause=function(e){return e===void 0&&(e=ft()),this._isPaused||!this._isPlaying?this:(this._isPaused=!0,this._pauseStart=e,this._group&&this._group.remove(this),this)},n.prototype.resume=function(e){return e===void 0&&(e=ft()),!this._isPaused||!this._isPlaying?this:(this._isPaused=!1,this._startTime+=e-this._pauseStart,this._pauseStart=0,this._group&&this._group.add(this),this)},n.prototype.stopChainedTweens=function(){for(var e=0,t=this._chainedTweens.length;e<t;e++)this._chainedTweens[e].stop();return this},n.prototype.group=function(e){return e===void 0&&(e=Zi),this._group=e,this},n.prototype.delay=function(e){return e===void 0&&(e=0),this._delayTime=e,this},n.prototype.repeat=function(e){return e===void 0&&(e=0),this._initialRepeat=e,this._repeat=e,this},n.prototype.repeatDelay=function(e){return this._repeatDelayTime=e,this},n.prototype.yoyo=function(e){return e===void 0&&(e=!1),this._yoyo=e,this},n.prototype.easing=function(e){return e===void 0&&(e=pt.Linear.None),this._easingFunction=e,this},n.prototype.interpolation=function(e){return e===void 0&&(e=Ge.Linear),this._interpolationFunction=e,this},n.prototype.chain=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return this._chainedTweens=e,this},n.prototype.onStart=function(e){return this._onStartCallback=e,this},n.prototype.onEveryStart=function(e){return this._onEveryStartCallback=e,this},n.prototype.onUpdate=function(e){return this._onUpdateCallback=e,this},n.prototype.onRepeat=function(e){return this._onRepeatCallback=e,this},n.prototype.onComplete=function(e){return this._onCompleteCallback=e,this},n.prototype.onStop=function(e){return this._onStopCallback=e,this},n.prototype.update=function(e,t){var i=this,s;if(e===void 0&&(e=ft()),t===void 0&&(t=!0),this._isPaused)return!0;var a,o=this._startTime+this._duration;if(!this._goToEnd&&!this._isPlaying){if(e>o)return!1;t&&this.start(e,!0)}if(this._goToEnd=!1,e<this._startTime)return!0;this._onStartCallbackFired===!1&&(this._onStartCallback&&this._onStartCallback(this._object),this._onStartCallbackFired=!0),this._onEveryStartCallbackFired===!1&&(this._onEveryStartCallback&&this._onEveryStartCallback(this._object),this._onEveryStartCallbackFired=!0);var c=e-this._startTime,u=this._duration+((s=this._repeatDelayTime)!==null&&s!==void 0?s:this._delayTime),m=this._duration+this._repeat*u,d=function(){if(i._duration===0||c>m)return 1;var p=Math.trunc(c/u),v=c-p*u,y=Math.min(v/i._duration,1);return y===0&&c===i._duration?1:y},r=d(),l=this._easingFunction(r);if(this._updateProperties(this._object,this._valuesStart,this._valuesEnd,l),this._onUpdateCallback&&this._onUpdateCallback(this._object,r),this._duration===0||c>=this._duration)if(this._repeat>0){var h=Math.min(Math.trunc((c-this._duration)/u)+1,this._repeat);isFinite(this._repeat)&&(this._repeat-=h);for(a in this._valuesStartRepeat)!this._yoyo&&typeof this._valuesEnd[a]=="string"&&(this._valuesStartRepeat[a]=this._valuesStartRepeat[a]+parseFloat(this._valuesEnd[a])),this._yoyo&&this._swapEndStartRepeatValues(a),this._valuesStart[a]=this._valuesStartRepeat[a];return this._yoyo&&(this._reversed=!this._reversed),this._startTime+=u*h,this._onRepeatCallback&&this._onRepeatCallback(this._object),this._onEveryStartCallbackFired=!1,!0}else{this._onCompleteCallback&&this._onCompleteCallback(this._object);for(var g=0,_=this._chainedTweens.length;g<_;g++)this._chainedTweens[g].start(this._startTime+this._duration,!1);return this._isPlaying=!1,!1}return!0},n.prototype._updateProperties=function(e,t,i,s){for(var a in i)if(t[a]!==void 0){var o=t[a]||0,c=i[a],u=Array.isArray(e[a]),m=Array.isArray(c),d=!u&&m;d?e[a]=this._interpolationFunction(c,s):typeof c=="object"&&c?this._updateProperties(e[a],o,c,s):(c=this._handleRelativeValue(o,c),typeof c=="number"&&(e[a]=o+(c-o)*s))}},n.prototype._handleRelativeValue=function(e,t){return typeof t!="string"?t:t.charAt(0)==="+"||t.charAt(0)==="-"?e+parseFloat(t):parseFloat(t)},n.prototype._swapEndStartRepeatValues=function(e){var t=this._valuesStartRepeat[e],i=this._valuesEnd[e];typeof i=="string"?this._valuesStartRepeat[e]=this._valuesStartRepeat[e]+parseFloat(i):this._valuesStartRepeat[e]=this._valuesEnd[e],this._valuesEnd[e]=t},n}(),Va="23.1.3",Ua=ys.nextId,be=Zi,Ha=be.getAll.bind(be),Wa=be.removeAll.bind(be),Na=be.add.bind(be),Ga=be.remove.bind(be),qa=be.update.bind(be),ye={Easing:pt,Group:Br,Interpolation:Ge,now:ft,Sequence:ys,nextId:Ua,Tween:di,VERSION:Va,getAll:Ha,removeAll:Wa,add:Na,remove:Ga,update:qa},kr={exports:{}};(function(n){var e=Object.prototype.hasOwnProperty,t="~";function i(){}Object.create&&(i.prototype=Object.create(null),new i().__proto__||(t=!1));function s(u,m,d){this.fn=u,this.context=m,this.once=d||!1}function a(u,m,d,r,l){if(typeof d!="function")throw new TypeError("The listener must be a function");var h=new s(d,r||u,l),g=t?t+m:m;return u._events[g]?u._events[g].fn?u._events[g]=[u._events[g],h]:u._events[g].push(h):(u._events[g]=h,u._eventsCount++),u}function o(u,m){--u._eventsCount===0?u._events=new i:delete u._events[m]}function c(){this._events=new i,this._eventsCount=0}c.prototype.eventNames=function(){var m=[],d,r;if(this._eventsCount===0)return m;for(r in d=this._events)e.call(d,r)&&m.push(t?r.slice(1):r);return Object.getOwnPropertySymbols?m.concat(Object.getOwnPropertySymbols(d)):m},c.prototype.listeners=function(m){var d=t?t+m:m,r=this._events[d];if(!r)return[];if(r.fn)return[r.fn];for(var l=0,h=r.length,g=new Array(h);l<h;l++)g[l]=r[l].fn;return g},c.prototype.listenerCount=function(m){var d=t?t+m:m,r=this._events[d];return r?r.fn?1:r.length:0},c.prototype.emit=function(m,d,r,l,h,g){var _=t?t+m:m;if(!this._events[_])return!1;var p=this._events[_],v=arguments.length,y,x;if(p.fn){switch(p.once&&this.removeListener(m,p.fn,void 0,!0),v){case 1:return p.fn.call(p.context),!0;case 2:return p.fn.call(p.context,d),!0;case 3:return p.fn.call(p.context,d,r),!0;case 4:return p.fn.call(p.context,d,r,l),!0;case 5:return p.fn.call(p.context,d,r,l,h),!0;case 6:return p.fn.call(p.context,d,r,l,h,g),!0}for(x=1,y=new Array(v-1);x<v;x++)y[x-1]=arguments[x];p.fn.apply(p.context,y)}else{var w=p.length,b;for(x=0;x<w;x++)switch(p[x].once&&this.removeListener(m,p[x].fn,void 0,!0),v){case 1:p[x].fn.call(p[x].context);break;case 2:p[x].fn.call(p[x].context,d);break;case 3:p[x].fn.call(p[x].context,d,r);break;case 4:p[x].fn.call(p[x].context,d,r,l);break;default:if(!y)for(b=1,y=new Array(v-1);b<v;b++)y[b-1]=arguments[b];p[x].fn.apply(p[x].context,y)}}return!0},c.prototype.on=function(m,d,r){return a(this,m,d,r,!1)},c.prototype.once=function(m,d,r){return a(this,m,d,r,!0)},c.prototype.removeListener=function(m,d,r,l){var h=t?t+m:m;if(!this._events[h])return this;if(!d)return o(this,h),this;var g=this._events[h];if(g.fn)g.fn===d&&(!l||g.once)&&(!r||g.context===r)&&o(this,h);else{for(var _=0,p=[],v=g.length;_<v;_++)(g[_].fn!==d||l&&!g[_].once||r&&g[_].context!==r)&&p.push(g[_]);p.length?this._events[h]=p.length===1?p[0]:p:o(this,h)}return this},c.prototype.removeAllListeners=function(m){var d;return m?(d=t?t+m:m,this._events[d]&&o(this,d)):(this._events=new i,this._eventsCount=0),this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prefixed=t,c.EventEmitter=c,n.exports=c})(kr);var ja=kr.exports;const xt=B.getDefaultExportFromCjs(ja);var Ot=function(){var n=0,e=document.createElement("div");e.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000",e.addEventListener("click",function(r){r.preventDefault(),i(++n%e.children.length)},!1);function t(r){return e.appendChild(r.dom),r}function i(r){for(var l=0;l<e.children.length;l++)e.children[l].style.display=l===r?"block":"none";n=r}var s=(performance||Date).now(),a=s,o=0,c=t(new Ot.Panel("FPS","#0ff","#002")),u=t(new Ot.Panel("MS","#0f0","#020"));if(self.performance&&self.performance.memory)var m=t(new Ot.Panel("MB","#f08","#201"));i(0);var d=0;return{REVISION:16,dom:e,fps:function(){return d&&parseInt(d.toFixed(0))},addPanel:t,showPanel:i,begin:function(){s=(performance||Date).now()},end:function(){o++;var r=(performance||Date).now();if(u.update(r-s,200),r>=a+1e3&&(d=o*1e3/(r-a),c.update(d,100),a=r,o=0,m)){var l=performance.memory;m.update(l.usedJSHeapSize/1048576,l.jsHeapSizeLimit/1048576)}return r},update:function(){s=this.end()},domElement:e,setMode:i}};Ot.Panel=function(n,e,t){var i=1/0,s=0,a=Math.round,o=a(window.devicePixelRatio||1),c=80*o,u=48*o,m=3*o,d=2*o,r=3*o,l=15*o,h=74*o,g=30*o,_=document.createElement("canvas");_.width=c,_.height=u,_.style.cssText="width:80px;height:48px";var p=_.getContext("2d");return p.font="bold "+9*o+"px Helvetica,Arial,sans-serif",p.textBaseline="top",p.fillStyle=t,p.fillRect(0,0,c,u),p.fillStyle=e,p.fillText(n,m,d),p.fillRect(r,l,h,g),p.fillStyle=t,p.globalAlpha=.9,p.fillRect(r,l,h,g),{dom:_,update:function(v,y){i=Math.min(i,v),s=Math.max(s,v),p.fillStyle=t,p.globalAlpha=1,p.fillRect(0,0,c,l),p.fillStyle=e,p.fillText(a(v)+" "+n+" ("+a(i)+"-"+a(s)+")",m,d),p.drawImage(_,r+o,l,h-o,g,r,l,h-o,g),p.fillRect(r+h-o,l,o,g),p.fillStyle=t,p.globalAlpha=.9,p.fillRect(r+h-o,l,o,a((1-v/y)*g))}}};function Ya(n,e){const t=URL.createObjectURL(n),i=document.createElement("a");i.href=t,i.download=e,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(t)}function Or(n){return n.length===0?0:n.reduce((t,i)=>t+i,0)/n.length}function Ki(n,e){const t=new Blob([n],{type:e});return URL.createObjectURL(t)}function zr(){return/Mac|iPod|iPhone|iPad/.test(navigator==null?void 0:navigator.platform)||/Mac OS|iOS/.test(navigator==null?void 0:navigator.userAgent)}function $i(n){let e=document.createElement("canvas");const t=e.getContext("2d");return e.width=n.width,e.height=n.height,t?(t.drawImage(n,0,0),e.toDataURL("image/png",.75)):void 0}function Qa(n,e=43){const t=n*Math.PI/180;return e/(2*Math.tan(t/2))}var Vr={};/*!
3689
+ * howler.js v2.2.4
3690
+ * howlerjs.com
3691
+ *
3692
+ * (c) 2013-2020, James Simpson of GoldFire Studios
3693
+ * goldfirestudios.com
3694
+ *
3695
+ * MIT License
3696
+ */(function(n){(function(){var e=function(){this.init()};e.prototype={init:function(){var r=this||t;return r._counter=1e3,r._html5AudioPool=[],r.html5PoolSize=10,r._codecs={},r._howls=[],r._muted=!1,r._volume=1,r._canPlayEvent="canplaythrough",r._navigator=typeof window<"u"&&window.navigator?window.navigator:null,r.masterGain=null,r.noAudio=!1,r.usingWebAudio=!0,r.autoSuspend=!0,r.ctx=null,r.autoUnlock=!0,r._setup(),r},volume:function(r){var l=this||t;if(r=parseFloat(r),l.ctx||d(),typeof r<"u"&&r>=0&&r<=1){if(l._volume=r,l._muted)return l;l.usingWebAudio&&l.masterGain.gain.setValueAtTime(r,t.ctx.currentTime);for(var h=0;h<l._howls.length;h++)if(!l._howls[h]._webAudio)for(var g=l._howls[h]._getSoundIds(),_=0;_<g.length;_++){var p=l._howls[h]._soundById(g[_]);p&&p._node&&(p._node.volume=p._volume*r)}return l}return l._volume},mute:function(r){var l=this||t;l.ctx||d(),l._muted=r,l.usingWebAudio&&l.masterGain.gain.setValueAtTime(r?0:l._volume,t.ctx.currentTime);for(var h=0;h<l._howls.length;h++)if(!l._howls[h]._webAudio)for(var g=l._howls[h]._getSoundIds(),_=0;_<g.length;_++){var p=l._howls[h]._soundById(g[_]);p&&p._node&&(p._node.muted=r?!0:p._muted)}return l},stop:function(){for(var r=this||t,l=0;l<r._howls.length;l++)r._howls[l].stop();return r},unload:function(){for(var r=this||t,l=r._howls.length-1;l>=0;l--)r._howls[l].unload();return r.usingWebAudio&&r.ctx&&typeof r.ctx.close<"u"&&(r.ctx.close(),r.ctx=null,d()),r},codecs:function(r){return(this||t)._codecs[r.replace(/^x-/,"")]},_setup:function(){var r=this||t;if(r.state=r.ctx&&r.ctx.state||"suspended",r._autoSuspend(),!r.usingWebAudio)if(typeof Audio<"u")try{var l=new Audio;typeof l.oncanplaythrough>"u"&&(r._canPlayEvent="canplay")}catch{r.noAudio=!0}else r.noAudio=!0;try{var l=new Audio;l.muted&&(r.noAudio=!0)}catch{}return r.noAudio||r._setupCodecs(),r},_setupCodecs:function(){var r=this||t,l=null;try{l=typeof Audio<"u"?new Audio:null}catch{return r}if(!l||typeof l.canPlayType!="function")return r;var h=l.canPlayType("audio/mpeg;").replace(/^no$/,""),g=r._navigator?r._navigator.userAgent:"",_=g.match(/OPR\/(\d+)/g),p=_&&parseInt(_[0].split("/")[1],10)<33,v=g.indexOf("Safari")!==-1&&g.indexOf("Chrome")===-1,y=g.match(/Version\/(.*?) /),x=v&&y&&parseInt(y[1],10)<15;return r._codecs={mp3:!!(!p&&(h||l.canPlayType("audio/mp3;").replace(/^no$/,""))),mpeg:!!h,opus:!!l.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!l.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!l.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!(l.canPlayType('audio/wav; codecs="1"')||l.canPlayType("audio/wav")).replace(/^no$/,""),aac:!!l.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!l.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(l.canPlayType("audio/x-m4a;")||l.canPlayType("audio/m4a;")||l.canPlayType("audio/aac;")).replace(/^no$/,""),m4b:!!(l.canPlayType("audio/x-m4b;")||l.canPlayType("audio/m4b;")||l.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(l.canPlayType("audio/x-mp4;")||l.canPlayType("audio/mp4;")||l.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!(!x&&l.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),webm:!!(!x&&l.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),dolby:!!l.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(l.canPlayType("audio/x-flac;")||l.canPlayType("audio/flac;")).replace(/^no$/,"")},r},_unlockAudio:function(){var r=this||t;if(!(r._audioUnlocked||!r.ctx)){r._audioUnlocked=!1,r.autoUnlock=!1,!r._mobileUnloaded&&r.ctx.sampleRate!==44100&&(r._mobileUnloaded=!0,r.unload()),r._scratchBuffer=r.ctx.createBuffer(1,1,22050);var l=function(h){for(;r._html5AudioPool.length<r.html5PoolSize;)try{var g=new Audio;g._unlocked=!0,r._releaseHtml5Audio(g)}catch{r.noAudio=!0;break}for(var _=0;_<r._howls.length;_++)if(!r._howls[_]._webAudio)for(var p=r._howls[_]._getSoundIds(),v=0;v<p.length;v++){var y=r._howls[_]._soundById(p[v]);y&&y._node&&!y._node._unlocked&&(y._node._unlocked=!0,y._node.load())}r._autoResume();var x=r.ctx.createBufferSource();x.buffer=r._scratchBuffer,x.connect(r.ctx.destination),typeof x.start>"u"?x.noteOn(0):x.start(0),typeof r.ctx.resume=="function"&&r.ctx.resume(),x.onended=function(){x.disconnect(0),r._audioUnlocked=!0,document.removeEventListener("touchstart",l,!0),document.removeEventListener("touchend",l,!0),document.removeEventListener("click",l,!0),document.removeEventListener("keydown",l,!0);for(var w=0;w<r._howls.length;w++)r._howls[w]._emit("unlock")}};return document.addEventListener("touchstart",l,!0),document.addEventListener("touchend",l,!0),document.addEventListener("click",l,!0),document.addEventListener("keydown",l,!0),r}},_obtainHtml5Audio:function(){var r=this||t;if(r._html5AudioPool.length)return r._html5AudioPool.pop();var l=new Audio().play();return l&&typeof Promise<"u"&&(l instanceof Promise||typeof l.then=="function")&&l.catch(function(){console.warn("HTML5 Audio pool exhausted, returning potentially locked audio object.")}),new Audio},_releaseHtml5Audio:function(r){var l=this||t;return r._unlocked&&l._html5AudioPool.push(r),l},_autoSuspend:function(){var r=this;if(!(!r.autoSuspend||!r.ctx||typeof r.ctx.suspend>"u"||!t.usingWebAudio)){for(var l=0;l<r._howls.length;l++)if(r._howls[l]._webAudio){for(var h=0;h<r._howls[l]._sounds.length;h++)if(!r._howls[l]._sounds[h]._paused)return r}return r._suspendTimer&&clearTimeout(r._suspendTimer),r._suspendTimer=setTimeout(function(){if(r.autoSuspend){r._suspendTimer=null,r.state="suspending";var g=function(){r.state="suspended",r._resumeAfterSuspend&&(delete r._resumeAfterSuspend,r._autoResume())};r.ctx.suspend().then(g,g)}},3e4),r}},_autoResume:function(){var r=this;if(!(!r.ctx||typeof r.ctx.resume>"u"||!t.usingWebAudio))return r.state==="running"&&r.ctx.state!=="interrupted"&&r._suspendTimer?(clearTimeout(r._suspendTimer),r._suspendTimer=null):r.state==="suspended"||r.state==="running"&&r.ctx.state==="interrupted"?(r.ctx.resume().then(function(){r.state="running";for(var l=0;l<r._howls.length;l++)r._howls[l]._emit("resume")}),r._suspendTimer&&(clearTimeout(r._suspendTimer),r._suspendTimer=null)):r.state==="suspending"&&(r._resumeAfterSuspend=!0),r}};var t=new e,i=function(r){var l=this;if(!r.src||r.src.length===0){console.error("An array of source files must be passed with any new Howl.");return}l.init(r)};i.prototype={init:function(r){var l=this;return t.ctx||d(),l._autoplay=r.autoplay||!1,l._format=typeof r.format!="string"?r.format:[r.format],l._html5=r.html5||!1,l._muted=r.mute||!1,l._loop=r.loop||!1,l._pool=r.pool||5,l._preload=typeof r.preload=="boolean"||r.preload==="metadata"?r.preload:!0,l._rate=r.rate||1,l._sprite=r.sprite||{},l._src=typeof r.src!="string"?r.src:[r.src],l._volume=r.volume!==void 0?r.volume:1,l._xhr={method:r.xhr&&r.xhr.method?r.xhr.method:"GET",headers:r.xhr&&r.xhr.headers?r.xhr.headers:null,withCredentials:r.xhr&&r.xhr.withCredentials?r.xhr.withCredentials:!1},l._duration=0,l._state="unloaded",l._sounds=[],l._endTimers={},l._queue=[],l._playLock=!1,l._onend=r.onend?[{fn:r.onend}]:[],l._onfade=r.onfade?[{fn:r.onfade}]:[],l._onload=r.onload?[{fn:r.onload}]:[],l._onloaderror=r.onloaderror?[{fn:r.onloaderror}]:[],l._onplayerror=r.onplayerror?[{fn:r.onplayerror}]:[],l._onpause=r.onpause?[{fn:r.onpause}]:[],l._onplay=r.onplay?[{fn:r.onplay}]:[],l._onstop=r.onstop?[{fn:r.onstop}]:[],l._onmute=r.onmute?[{fn:r.onmute}]:[],l._onvolume=r.onvolume?[{fn:r.onvolume}]:[],l._onrate=r.onrate?[{fn:r.onrate}]:[],l._onseek=r.onseek?[{fn:r.onseek}]:[],l._onunlock=r.onunlock?[{fn:r.onunlock}]:[],l._onresume=[],l._webAudio=t.usingWebAudio&&!l._html5,typeof t.ctx<"u"&&t.ctx&&t.autoUnlock&&t._unlockAudio(),t._howls.push(l),l._autoplay&&l._queue.push({event:"play",action:function(){l.play()}}),l._preload&&l._preload!=="none"&&l.load(),l},load:function(){var r=this,l=null;if(t.noAudio){r._emit("loaderror",null,"No audio support.");return}typeof r._src=="string"&&(r._src=[r._src]);for(var h=0;h<r._src.length;h++){var g,_;if(r._format&&r._format[h])g=r._format[h];else{if(_=r._src[h],typeof _!="string"){r._emit("loaderror",null,"Non-string found in selected audio sources - ignoring.");continue}g=/^data:audio\/([^;,]+);/i.exec(_),g||(g=/\.([^.]+)$/.exec(_.split("?",1)[0])),g&&(g=g[1].toLowerCase())}if(g||console.warn('No file extension was found. Consider using the "format" property or specify an extension.'),g&&t.codecs(g)){l=r._src[h];break}}if(!l){r._emit("loaderror",null,"No codec support for selected audio sources.");return}return r._src=l,r._state="loading",window.location.protocol==="https:"&&l.slice(0,5)==="http:"&&(r._html5=!0,r._webAudio=!1),new s(r),r._webAudio&&o(r),r},play:function(r,l){var h=this,g=null;if(typeof r=="number")g=r,r=null;else{if(typeof r=="string"&&h._state==="loaded"&&!h._sprite[r])return null;if(typeof r>"u"&&(r="__default",!h._playLock)){for(var _=0,p=0;p<h._sounds.length;p++)h._sounds[p]._paused&&!h._sounds[p]._ended&&(_++,g=h._sounds[p]._id);_===1?r=null:g=null}}var v=g?h._soundById(g):h._inactiveSound();if(!v)return null;if(g&&!r&&(r=v._sprite||"__default"),h._state!=="loaded"){v._sprite=r,v._ended=!1;var y=v._id;return h._queue.push({event:"play",action:function(){h.play(y)}}),y}if(g&&!v._paused)return l||h._loadQueue("play"),v._id;h._webAudio&&t._autoResume();var x=Math.max(0,v._seek>0?v._seek:h._sprite[r][0]/1e3),w=Math.max(0,(h._sprite[r][0]+h._sprite[r][1])/1e3-x),b=w*1e3/Math.abs(v._rate),T=h._sprite[r][0]/1e3,M=(h._sprite[r][0]+h._sprite[r][1])/1e3;v._sprite=r,v._ended=!1;var S=function(){v._paused=!1,v._seek=x,v._start=T,v._stop=M,v._loop=!!(v._loop||h._sprite[r][2])};if(x>=M){h._ended(v);return}var C=v._node;if(h._webAudio){var I=function(){h._playLock=!1,S(),h._refreshBuffer(v);var R=v._muted||h._muted?0:v._volume;C.gain.setValueAtTime(R,t.ctx.currentTime),v._playStart=t.ctx.currentTime,typeof C.bufferSource.start>"u"?v._loop?C.bufferSource.noteGrainOn(0,x,86400):C.bufferSource.noteGrainOn(0,x,w):v._loop?C.bufferSource.start(0,x,86400):C.bufferSource.start(0,x,w),b!==1/0&&(h._endTimers[v._id]=setTimeout(h._ended.bind(h,v),b)),l||setTimeout(function(){h._emit("play",v._id),h._loadQueue()},0)};t.state==="running"&&t.ctx.state!=="interrupted"?I():(h._playLock=!0,h.once("resume",I),h._clearTimer(v._id))}else{var D=function(){C.currentTime=x,C.muted=v._muted||h._muted||t._muted||C.muted,C.volume=v._volume*t.volume(),C.playbackRate=v._rate;try{var R=C.play();if(R&&typeof Promise<"u"&&(R instanceof Promise||typeof R.then=="function")?(h._playLock=!0,S(),R.then(function(){h._playLock=!1,C._unlocked=!0,l?h._loadQueue():h._emit("play",v._id)}).catch(function(){h._playLock=!1,h._emit("playerror",v._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction."),v._ended=!0,v._paused=!0})):l||(h._playLock=!1,S(),h._emit("play",v._id)),C.playbackRate=v._rate,C.paused){h._emit("playerror",v._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.");return}r!=="__default"||v._loop?h._endTimers[v._id]=setTimeout(h._ended.bind(h,v),b):(h._endTimers[v._id]=function(){h._ended(v),C.removeEventListener("ended",h._endTimers[v._id],!1)},C.addEventListener("ended",h._endTimers[v._id],!1))}catch(E){h._emit("playerror",v._id,E)}};C.src==="data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA"&&(C.src=h._src,C.load());var A=window&&window.ejecta||!C.readyState&&t._navigator.isCocoonJS;if(C.readyState>=3||A)D();else{h._playLock=!0,h._state="loading";var P=function(){h._state="loaded",D(),C.removeEventListener(t._canPlayEvent,P,!1)};C.addEventListener(t._canPlayEvent,P,!1),h._clearTimer(v._id)}}return v._id},pause:function(r){var l=this;if(l._state!=="loaded"||l._playLock)return l._queue.push({event:"pause",action:function(){l.pause(r)}}),l;for(var h=l._getSoundIds(r),g=0;g<h.length;g++){l._clearTimer(h[g]);var _=l._soundById(h[g]);if(_&&!_._paused&&(_._seek=l.seek(h[g]),_._rateSeek=0,_._paused=!0,l._stopFade(h[g]),_._node))if(l._webAudio){if(!_._node.bufferSource)continue;typeof _._node.bufferSource.stop>"u"?_._node.bufferSource.noteOff(0):_._node.bufferSource.stop(0),l._cleanBuffer(_._node)}else(!isNaN(_._node.duration)||_._node.duration===1/0)&&_._node.pause();arguments[1]||l._emit("pause",_?_._id:null)}return l},stop:function(r,l){var h=this;if(h._state!=="loaded"||h._playLock)return h._queue.push({event:"stop",action:function(){h.stop(r)}}),h;for(var g=h._getSoundIds(r),_=0;_<g.length;_++){h._clearTimer(g[_]);var p=h._soundById(g[_]);p&&(p._seek=p._start||0,p._rateSeek=0,p._paused=!0,p._ended=!0,h._stopFade(g[_]),p._node&&(h._webAudio?p._node.bufferSource&&(typeof p._node.bufferSource.stop>"u"?p._node.bufferSource.noteOff(0):p._node.bufferSource.stop(0),h._cleanBuffer(p._node)):(!isNaN(p._node.duration)||p._node.duration===1/0)&&(p._node.currentTime=p._start||0,p._node.pause(),p._node.duration===1/0&&h._clearSound(p._node))),l||h._emit("stop",p._id))}return h},mute:function(r,l){var h=this;if(h._state!=="loaded"||h._playLock)return h._queue.push({event:"mute",action:function(){h.mute(r,l)}}),h;if(typeof l>"u")if(typeof r=="boolean")h._muted=r;else return h._muted;for(var g=h._getSoundIds(l),_=0;_<g.length;_++){var p=h._soundById(g[_]);p&&(p._muted=r,p._interval&&h._stopFade(p._id),h._webAudio&&p._node?p._node.gain.setValueAtTime(r?0:p._volume,t.ctx.currentTime):p._node&&(p._node.muted=t._muted?!0:r),h._emit("mute",p._id))}return h},volume:function(){var r=this,l=arguments,h,g;if(l.length===0)return r._volume;if(l.length===1||l.length===2&&typeof l[1]>"u"){var _=r._getSoundIds(),p=_.indexOf(l[0]);p>=0?g=parseInt(l[0],10):h=parseFloat(l[0])}else l.length>=2&&(h=parseFloat(l[0]),g=parseInt(l[1],10));var v;if(typeof h<"u"&&h>=0&&h<=1){if(r._state!=="loaded"||r._playLock)return r._queue.push({event:"volume",action:function(){r.volume.apply(r,l)}}),r;typeof g>"u"&&(r._volume=h),g=r._getSoundIds(g);for(var y=0;y<g.length;y++)v=r._soundById(g[y]),v&&(v._volume=h,l[2]||r._stopFade(g[y]),r._webAudio&&v._node&&!v._muted?v._node.gain.setValueAtTime(h,t.ctx.currentTime):v._node&&!v._muted&&(v._node.volume=h*t.volume()),r._emit("volume",v._id))}else return v=g?r._soundById(g):r._sounds[0],v?v._volume:0;return r},fade:function(r,l,h,g){var _=this;if(_._state!=="loaded"||_._playLock)return _._queue.push({event:"fade",action:function(){_.fade(r,l,h,g)}}),_;r=Math.min(Math.max(0,parseFloat(r)),1),l=Math.min(Math.max(0,parseFloat(l)),1),h=parseFloat(h),_.volume(r,g);for(var p=_._getSoundIds(g),v=0;v<p.length;v++){var y=_._soundById(p[v]);if(y){if(g||_._stopFade(p[v]),_._webAudio&&!y._muted){var x=t.ctx.currentTime,w=x+h/1e3;y._volume=r,y._node.gain.setValueAtTime(r,x),y._node.gain.linearRampToValueAtTime(l,w)}_._startFadeInterval(y,r,l,h,p[v],typeof g>"u")}}return _},_startFadeInterval:function(r,l,h,g,_,p){var v=this,y=l,x=h-l,w=Math.abs(x/.01),b=Math.max(4,w>0?g/w:g),T=Date.now();r._fadeTo=h,r._interval=setInterval(function(){var M=(Date.now()-T)/g;T=Date.now(),y+=x*M,y=Math.round(y*100)/100,x<0?y=Math.max(h,y):y=Math.min(h,y),v._webAudio?r._volume=y:v.volume(y,r._id,!0),p&&(v._volume=y),(h<l&&y<=h||h>l&&y>=h)&&(clearInterval(r._interval),r._interval=null,r._fadeTo=null,v.volume(h,r._id),v._emit("fade",r._id))},b)},_stopFade:function(r){var l=this,h=l._soundById(r);return h&&h._interval&&(l._webAudio&&h._node.gain.cancelScheduledValues(t.ctx.currentTime),clearInterval(h._interval),h._interval=null,l.volume(h._fadeTo,r),h._fadeTo=null,l._emit("fade",r)),l},loop:function(){var r=this,l=arguments,h,g,_;if(l.length===0)return r._loop;if(l.length===1)if(typeof l[0]=="boolean")h=l[0],r._loop=h;else return _=r._soundById(parseInt(l[0],10)),_?_._loop:!1;else l.length===2&&(h=l[0],g=parseInt(l[1],10));for(var p=r._getSoundIds(g),v=0;v<p.length;v++)_=r._soundById(p[v]),_&&(_._loop=h,r._webAudio&&_._node&&_._node.bufferSource&&(_._node.bufferSource.loop=h,h&&(_._node.bufferSource.loopStart=_._start||0,_._node.bufferSource.loopEnd=_._stop,r.playing(p[v])&&(r.pause(p[v],!0),r.play(p[v],!0)))));return r},rate:function(){var r=this,l=arguments,h,g;if(l.length===0)g=r._sounds[0]._id;else if(l.length===1){var _=r._getSoundIds(),p=_.indexOf(l[0]);p>=0?g=parseInt(l[0],10):h=parseFloat(l[0])}else l.length===2&&(h=parseFloat(l[0]),g=parseInt(l[1],10));var v;if(typeof h=="number"){if(r._state!=="loaded"||r._playLock)return r._queue.push({event:"rate",action:function(){r.rate.apply(r,l)}}),r;typeof g>"u"&&(r._rate=h),g=r._getSoundIds(g);for(var y=0;y<g.length;y++)if(v=r._soundById(g[y]),v){r.playing(g[y])&&(v._rateSeek=r.seek(g[y]),v._playStart=r._webAudio?t.ctx.currentTime:v._playStart),v._rate=h,r._webAudio&&v._node&&v._node.bufferSource?v._node.bufferSource.playbackRate.setValueAtTime(h,t.ctx.currentTime):v._node&&(v._node.playbackRate=h);var x=r.seek(g[y]),w=(r._sprite[v._sprite][0]+r._sprite[v._sprite][1])/1e3-x,b=w*1e3/Math.abs(v._rate);(r._endTimers[g[y]]||!v._paused)&&(r._clearTimer(g[y]),r._endTimers[g[y]]=setTimeout(r._ended.bind(r,v),b)),r._emit("rate",v._id)}}else return v=r._soundById(g),v?v._rate:r._rate;return r},seek:function(){var r=this,l=arguments,h,g;if(l.length===0)r._sounds.length&&(g=r._sounds[0]._id);else if(l.length===1){var _=r._getSoundIds(),p=_.indexOf(l[0]);p>=0?g=parseInt(l[0],10):r._sounds.length&&(g=r._sounds[0]._id,h=parseFloat(l[0]))}else l.length===2&&(h=parseFloat(l[0]),g=parseInt(l[1],10));if(typeof g>"u")return 0;if(typeof h=="number"&&(r._state!=="loaded"||r._playLock))return r._queue.push({event:"seek",action:function(){r.seek.apply(r,l)}}),r;var v=r._soundById(g);if(v)if(typeof h=="number"&&h>=0){var y=r.playing(g);y&&r.pause(g,!0),v._seek=h,v._ended=!1,r._clearTimer(g),!r._webAudio&&v._node&&!isNaN(v._node.duration)&&(v._node.currentTime=h);var x=function(){y&&r.play(g,!0),r._emit("seek",g)};if(y&&!r._webAudio){var w=function(){r._playLock?setTimeout(w,0):x()};setTimeout(w,0)}else x()}else if(r._webAudio){var b=r.playing(g)?t.ctx.currentTime-v._playStart:0,T=v._rateSeek?v._rateSeek-v._seek:0;return v._seek+(T+b*Math.abs(v._rate))}else return v._node.currentTime;return r},playing:function(r){var l=this;if(typeof r=="number"){var h=l._soundById(r);return h?!h._paused:!1}for(var g=0;g<l._sounds.length;g++)if(!l._sounds[g]._paused)return!0;return!1},duration:function(r){var l=this,h=l._duration,g=l._soundById(r);return g&&(h=l._sprite[g._sprite][1]/1e3),h},state:function(){return this._state},unload:function(){for(var r=this,l=r._sounds,h=0;h<l.length;h++)l[h]._paused||r.stop(l[h]._id),r._webAudio||(r._clearSound(l[h]._node),l[h]._node.removeEventListener("error",l[h]._errorFn,!1),l[h]._node.removeEventListener(t._canPlayEvent,l[h]._loadFn,!1),l[h]._node.removeEventListener("ended",l[h]._endFn,!1),t._releaseHtml5Audio(l[h]._node)),delete l[h]._node,r._clearTimer(l[h]._id);var g=t._howls.indexOf(r);g>=0&&t._howls.splice(g,1);var _=!0;for(h=0;h<t._howls.length;h++)if(t._howls[h]._src===r._src||r._src.indexOf(t._howls[h]._src)>=0){_=!1;break}return a&&_&&delete a[r._src],t.noAudio=!1,r._state="unloaded",r._sounds=[],r=null,null},on:function(r,l,h,g){var _=this,p=_["_on"+r];return typeof l=="function"&&p.push(g?{id:h,fn:l,once:g}:{id:h,fn:l}),_},off:function(r,l,h){var g=this,_=g["_on"+r],p=0;if(typeof l=="number"&&(h=l,l=null),l||h)for(p=0;p<_.length;p++){var v=h===_[p].id;if(l===_[p].fn&&v||!l&&v){_.splice(p,1);break}}else if(r)g["_on"+r]=[];else{var y=Object.keys(g);for(p=0;p<y.length;p++)y[p].indexOf("_on")===0&&Array.isArray(g[y[p]])&&(g[y[p]]=[])}return g},once:function(r,l,h){var g=this;return g.on(r,l,h,1),g},_emit:function(r,l,h){for(var g=this,_=g["_on"+r],p=_.length-1;p>=0;p--)(!_[p].id||_[p].id===l||r==="load")&&(setTimeout((function(v){v.call(this,l,h)}).bind(g,_[p].fn),0),_[p].once&&g.off(r,_[p].fn,_[p].id));return g._loadQueue(r),g},_loadQueue:function(r){var l=this;if(l._queue.length>0){var h=l._queue[0];h.event===r&&(l._queue.shift(),l._loadQueue()),r||h.action()}return l},_ended:function(r){var l=this,h=r._sprite;if(!l._webAudio&&r._node&&!r._node.paused&&!r._node.ended&&r._node.currentTime<r._stop)return setTimeout(l._ended.bind(l,r),100),l;var g=!!(r._loop||l._sprite[h][2]);if(l._emit("end",r._id),!l._webAudio&&g&&l.stop(r._id,!0).play(r._id),l._webAudio&&g){l._emit("play",r._id),r._seek=r._start||0,r._rateSeek=0,r._playStart=t.ctx.currentTime;var _=(r._stop-r._start)*1e3/Math.abs(r._rate);l._endTimers[r._id]=setTimeout(l._ended.bind(l,r),_)}return l._webAudio&&!g&&(r._paused=!0,r._ended=!0,r._seek=r._start||0,r._rateSeek=0,l._clearTimer(r._id),l._cleanBuffer(r._node),t._autoSuspend()),!l._webAudio&&!g&&l.stop(r._id,!0),l},_clearTimer:function(r){var l=this;if(l._endTimers[r]){if(typeof l._endTimers[r]!="function")clearTimeout(l._endTimers[r]);else{var h=l._soundById(r);h&&h._node&&h._node.removeEventListener("ended",l._endTimers[r],!1)}delete l._endTimers[r]}return l},_soundById:function(r){for(var l=this,h=0;h<l._sounds.length;h++)if(r===l._sounds[h]._id)return l._sounds[h];return null},_inactiveSound:function(){var r=this;r._drain();for(var l=0;l<r._sounds.length;l++)if(r._sounds[l]._ended)return r._sounds[l].reset();return new s(r)},_drain:function(){var r=this,l=r._pool,h=0,g=0;if(!(r._sounds.length<l)){for(g=0;g<r._sounds.length;g++)r._sounds[g]._ended&&h++;for(g=r._sounds.length-1;g>=0;g--){if(h<=l)return;r._sounds[g]._ended&&(r._webAudio&&r._sounds[g]._node&&r._sounds[g]._node.disconnect(0),r._sounds.splice(g,1),h--)}}},_getSoundIds:function(r){var l=this;if(typeof r>"u"){for(var h=[],g=0;g<l._sounds.length;g++)h.push(l._sounds[g]._id);return h}else return[r]},_refreshBuffer:function(r){var l=this;return r._node.bufferSource=t.ctx.createBufferSource(),r._node.bufferSource.buffer=a[l._src],r._panner?r._node.bufferSource.connect(r._panner):r._node.bufferSource.connect(r._node),r._node.bufferSource.loop=r._loop,r._loop&&(r._node.bufferSource.loopStart=r._start||0,r._node.bufferSource.loopEnd=r._stop||0),r._node.bufferSource.playbackRate.setValueAtTime(r._rate,t.ctx.currentTime),l},_cleanBuffer:function(r){var l=this,h=t._navigator&&t._navigator.vendor.indexOf("Apple")>=0;if(!r.bufferSource)return l;if(t._scratchBuffer&&r.bufferSource&&(r.bufferSource.onended=null,r.bufferSource.disconnect(0),h))try{r.bufferSource.buffer=t._scratchBuffer}catch{}return r.bufferSource=null,l},_clearSound:function(r){var l=/MSIE |Trident\//.test(t._navigator&&t._navigator.userAgent);l||(r.src="data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA")}};var s=function(r){this._parent=r,this.init()};s.prototype={init:function(){var r=this,l=r._parent;return r._muted=l._muted,r._loop=l._loop,r._volume=l._volume,r._rate=l._rate,r._seek=0,r._paused=!0,r._ended=!0,r._sprite="__default",r._id=++t._counter,l._sounds.push(r),r.create(),r},create:function(){var r=this,l=r._parent,h=t._muted||r._muted||r._parent._muted?0:r._volume;return l._webAudio?(r._node=typeof t.ctx.createGain>"u"?t.ctx.createGainNode():t.ctx.createGain(),r._node.gain.setValueAtTime(h,t.ctx.currentTime),r._node.paused=!0,r._node.connect(t.masterGain)):t.noAudio||(r._node=t._obtainHtml5Audio(),r._errorFn=r._errorListener.bind(r),r._node.addEventListener("error",r._errorFn,!1),r._loadFn=r._loadListener.bind(r),r._node.addEventListener(t._canPlayEvent,r._loadFn,!1),r._endFn=r._endListener.bind(r),r._node.addEventListener("ended",r._endFn,!1),r._node.src=l._src,r._node.preload=l._preload===!0?"auto":l._preload,r._node.volume=h*t.volume(),r._node.load()),r},reset:function(){var r=this,l=r._parent;return r._muted=l._muted,r._loop=l._loop,r._volume=l._volume,r._rate=l._rate,r._seek=0,r._rateSeek=0,r._paused=!0,r._ended=!0,r._sprite="__default",r._id=++t._counter,r},_errorListener:function(){var r=this;r._parent._emit("loaderror",r._id,r._node.error?r._node.error.code:0),r._node.removeEventListener("error",r._errorFn,!1)},_loadListener:function(){var r=this,l=r._parent;l._duration=Math.ceil(r._node.duration*10)/10,Object.keys(l._sprite).length===0&&(l._sprite={__default:[0,l._duration*1e3]}),l._state!=="loaded"&&(l._state="loaded",l._emit("load"),l._loadQueue()),r._node.removeEventListener(t._canPlayEvent,r._loadFn,!1)},_endListener:function(){var r=this,l=r._parent;l._duration===1/0&&(l._duration=Math.ceil(r._node.duration*10)/10,l._sprite.__default[1]===1/0&&(l._sprite.__default[1]=l._duration*1e3),l._ended(r)),r._node.removeEventListener("ended",r._endFn,!1)}};var a={},o=function(r){var l=r._src;if(a[l]){r._duration=a[l].duration,m(r);return}if(/^data:[^;]+;base64,/.test(l)){for(var h=atob(l.split(",")[1]),g=new Uint8Array(h.length),_=0;_<h.length;++_)g[_]=h.charCodeAt(_);u(g.buffer,r)}else{var p=new XMLHttpRequest;p.open(r._xhr.method,l,!0),p.withCredentials=r._xhr.withCredentials,p.responseType="arraybuffer",r._xhr.headers&&Object.keys(r._xhr.headers).forEach(function(v){p.setRequestHeader(v,r._xhr.headers[v])}),p.onload=function(){var v=(p.status+"")[0];if(v!=="0"&&v!=="2"&&v!=="3"){r._emit("loaderror",null,"Failed loading audio file with status: "+p.status+".");return}u(p.response,r)},p.onerror=function(){r._webAudio&&(r._html5=!0,r._webAudio=!1,r._sounds=[],delete a[l],r.load())},c(p)}},c=function(r){try{r.send()}catch{r.onerror()}},u=function(r,l){var h=function(){l._emit("loaderror",null,"Decoding audio data failed.")},g=function(_){_&&l._sounds.length>0?(a[l._src]=_,m(l,_)):h()};typeof Promise<"u"&&t.ctx.decodeAudioData.length===1?t.ctx.decodeAudioData(r).then(g).catch(h):t.ctx.decodeAudioData(r,g,h)},m=function(r,l){l&&!r._duration&&(r._duration=l.duration),Object.keys(r._sprite).length===0&&(r._sprite={__default:[0,r._duration*1e3]}),r._state!=="loaded"&&(r._state="loaded",r._emit("load"),r._loadQueue())},d=function(){if(t.usingWebAudio){try{typeof AudioContext<"u"?t.ctx=new AudioContext:typeof webkitAudioContext<"u"?t.ctx=new webkitAudioContext:t.usingWebAudio=!1}catch{t.usingWebAudio=!1}t.ctx||(t.usingWebAudio=!1);var r=/iP(hone|od|ad)/.test(t._navigator&&t._navigator.platform),l=t._navigator&&t._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),h=l?parseInt(l[1],10):null;if(r&&h&&h<9){var g=/safari/.test(t._navigator&&t._navigator.userAgent.toLowerCase());t._navigator&&!g&&(t.usingWebAudio=!1)}t.usingWebAudio&&(t.masterGain=typeof t.ctx.createGain>"u"?t.ctx.createGainNode():t.ctx.createGain(),t.masterGain.gain.setValueAtTime(t._muted?0:t._volume,t.ctx.currentTime),t.masterGain.connect(t.ctx.destination)),t._setup()}};n.Howler=t,n.Howl=i,typeof B.commonjsGlobal<"u"?(B.commonjsGlobal.HowlerGlobal=e,B.commonjsGlobal.Howler=t,B.commonjsGlobal.Howl=i,B.commonjsGlobal.Sound=s):typeof window<"u"&&(window.HowlerGlobal=e,window.Howler=t,window.Howl=i,window.Sound=s)})();/*!
3697
+ * Spatial Plugin - Adds support for stereo and 3D audio where Web Audio is supported.
3698
+ *
3699
+ * howler.js v2.2.4
3700
+ * howlerjs.com
3701
+ *
3702
+ * (c) 2013-2020, James Simpson of GoldFire Studios
3703
+ * goldfirestudios.com
3704
+ *
3705
+ * MIT License
3706
+ */(function(){HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(t){var i=this;if(!i.ctx||!i.ctx.listener)return i;for(var s=i._howls.length-1;s>=0;s--)i._howls[s].stereo(t);return i},HowlerGlobal.prototype.pos=function(t,i,s){var a=this;if(!a.ctx||!a.ctx.listener)return a;if(i=typeof i!="number"?a._pos[1]:i,s=typeof s!="number"?a._pos[2]:s,typeof t=="number")a._pos=[t,i,s],typeof a.ctx.listener.positionX<"u"?(a.ctx.listener.positionX.setTargetAtTime(a._pos[0],Howler.ctx.currentTime,.1),a.ctx.listener.positionY.setTargetAtTime(a._pos[1],Howler.ctx.currentTime,.1),a.ctx.listener.positionZ.setTargetAtTime(a._pos[2],Howler.ctx.currentTime,.1)):a.ctx.listener.setPosition(a._pos[0],a._pos[1],a._pos[2]);else return a._pos;return a},HowlerGlobal.prototype.orientation=function(t,i,s,a,o,c){var u=this;if(!u.ctx||!u.ctx.listener)return u;var m=u._orientation;if(i=typeof i!="number"?m[1]:i,s=typeof s!="number"?m[2]:s,a=typeof a!="number"?m[3]:a,o=typeof o!="number"?m[4]:o,c=typeof c!="number"?m[5]:c,typeof t=="number")u._orientation=[t,i,s,a,o,c],typeof u.ctx.listener.forwardX<"u"?(u.ctx.listener.forwardX.setTargetAtTime(t,Howler.ctx.currentTime,.1),u.ctx.listener.forwardY.setTargetAtTime(i,Howler.ctx.currentTime,.1),u.ctx.listener.forwardZ.setTargetAtTime(s,Howler.ctx.currentTime,.1),u.ctx.listener.upX.setTargetAtTime(a,Howler.ctx.currentTime,.1),u.ctx.listener.upY.setTargetAtTime(o,Howler.ctx.currentTime,.1),u.ctx.listener.upZ.setTargetAtTime(c,Howler.ctx.currentTime,.1)):u.ctx.listener.setOrientation(t,i,s,a,o,c);else return m;return u},Howl.prototype.init=function(t){return function(i){var s=this;return s._orientation=i.orientation||[1,0,0],s._stereo=i.stereo||null,s._pos=i.pos||null,s._pannerAttr={coneInnerAngle:typeof i.coneInnerAngle<"u"?i.coneInnerAngle:360,coneOuterAngle:typeof i.coneOuterAngle<"u"?i.coneOuterAngle:360,coneOuterGain:typeof i.coneOuterGain<"u"?i.coneOuterGain:0,distanceModel:typeof i.distanceModel<"u"?i.distanceModel:"inverse",maxDistance:typeof i.maxDistance<"u"?i.maxDistance:1e4,panningModel:typeof i.panningModel<"u"?i.panningModel:"HRTF",refDistance:typeof i.refDistance<"u"?i.refDistance:1,rolloffFactor:typeof i.rolloffFactor<"u"?i.rolloffFactor:1},s._onstereo=i.onstereo?[{fn:i.onstereo}]:[],s._onpos=i.onpos?[{fn:i.onpos}]:[],s._onorientation=i.onorientation?[{fn:i.onorientation}]:[],t.call(this,i)}}(Howl.prototype.init),Howl.prototype.stereo=function(t,i){var s=this;if(!s._webAudio)return s;if(s._state!=="loaded")return s._queue.push({event:"stereo",action:function(){s.stereo(t,i)}}),s;var a=typeof Howler.ctx.createStereoPanner>"u"?"spatial":"stereo";if(typeof i>"u")if(typeof t=="number")s._stereo=t,s._pos=[t,0,0];else return s._stereo;for(var o=s._getSoundIds(i),c=0;c<o.length;c++){var u=s._soundById(o[c]);if(u)if(typeof t=="number")u._stereo=t,u._pos=[t,0,0],u._node&&(u._pannerAttr.panningModel="equalpower",(!u._panner||!u._panner.pan)&&e(u,a),a==="spatial"?typeof u._panner.positionX<"u"?(u._panner.positionX.setValueAtTime(t,Howler.ctx.currentTime),u._panner.positionY.setValueAtTime(0,Howler.ctx.currentTime),u._panner.positionZ.setValueAtTime(0,Howler.ctx.currentTime)):u._panner.setPosition(t,0,0):u._panner.pan.setValueAtTime(t,Howler.ctx.currentTime)),s._emit("stereo",u._id);else return u._stereo}return s},Howl.prototype.pos=function(t,i,s,a){var o=this;if(!o._webAudio)return o;if(o._state!=="loaded")return o._queue.push({event:"pos",action:function(){o.pos(t,i,s,a)}}),o;if(i=typeof i!="number"?0:i,s=typeof s!="number"?-.5:s,typeof a>"u")if(typeof t=="number")o._pos=[t,i,s];else return o._pos;for(var c=o._getSoundIds(a),u=0;u<c.length;u++){var m=o._soundById(c[u]);if(m)if(typeof t=="number")m._pos=[t,i,s],m._node&&((!m._panner||m._panner.pan)&&e(m,"spatial"),typeof m._panner.positionX<"u"?(m._panner.positionX.setValueAtTime(t,Howler.ctx.currentTime),m._panner.positionY.setValueAtTime(i,Howler.ctx.currentTime),m._panner.positionZ.setValueAtTime(s,Howler.ctx.currentTime)):m._panner.setPosition(t,i,s)),o._emit("pos",m._id);else return m._pos}return o},Howl.prototype.orientation=function(t,i,s,a){var o=this;if(!o._webAudio)return o;if(o._state!=="loaded")return o._queue.push({event:"orientation",action:function(){o.orientation(t,i,s,a)}}),o;if(i=typeof i!="number"?o._orientation[1]:i,s=typeof s!="number"?o._orientation[2]:s,typeof a>"u")if(typeof t=="number")o._orientation=[t,i,s];else return o._orientation;for(var c=o._getSoundIds(a),u=0;u<c.length;u++){var m=o._soundById(c[u]);if(m)if(typeof t=="number")m._orientation=[t,i,s],m._node&&(m._panner||(m._pos||(m._pos=o._pos||[0,0,-.5]),e(m,"spatial")),typeof m._panner.orientationX<"u"?(m._panner.orientationX.setValueAtTime(t,Howler.ctx.currentTime),m._panner.orientationY.setValueAtTime(i,Howler.ctx.currentTime),m._panner.orientationZ.setValueAtTime(s,Howler.ctx.currentTime)):m._panner.setOrientation(t,i,s)),o._emit("orientation",m._id);else return m._orientation}return o},Howl.prototype.pannerAttr=function(){var t=this,i=arguments,s,a,o;if(!t._webAudio)return t;if(i.length===0)return t._pannerAttr;if(i.length===1)if(typeof i[0]=="object")s=i[0],typeof a>"u"&&(s.pannerAttr||(s.pannerAttr={coneInnerAngle:s.coneInnerAngle,coneOuterAngle:s.coneOuterAngle,coneOuterGain:s.coneOuterGain,distanceModel:s.distanceModel,maxDistance:s.maxDistance,refDistance:s.refDistance,rolloffFactor:s.rolloffFactor,panningModel:s.panningModel}),t._pannerAttr={coneInnerAngle:typeof s.pannerAttr.coneInnerAngle<"u"?s.pannerAttr.coneInnerAngle:t._coneInnerAngle,coneOuterAngle:typeof s.pannerAttr.coneOuterAngle<"u"?s.pannerAttr.coneOuterAngle:t._coneOuterAngle,coneOuterGain:typeof s.pannerAttr.coneOuterGain<"u"?s.pannerAttr.coneOuterGain:t._coneOuterGain,distanceModel:typeof s.pannerAttr.distanceModel<"u"?s.pannerAttr.distanceModel:t._distanceModel,maxDistance:typeof s.pannerAttr.maxDistance<"u"?s.pannerAttr.maxDistance:t._maxDistance,refDistance:typeof s.pannerAttr.refDistance<"u"?s.pannerAttr.refDistance:t._refDistance,rolloffFactor:typeof s.pannerAttr.rolloffFactor<"u"?s.pannerAttr.rolloffFactor:t._rolloffFactor,panningModel:typeof s.pannerAttr.panningModel<"u"?s.pannerAttr.panningModel:t._panningModel});else return o=t._soundById(parseInt(i[0],10)),o?o._pannerAttr:t._pannerAttr;else i.length===2&&(s=i[0],a=parseInt(i[1],10));for(var c=t._getSoundIds(a),u=0;u<c.length;u++)if(o=t._soundById(c[u]),o){var m=o._pannerAttr;m={coneInnerAngle:typeof s.coneInnerAngle<"u"?s.coneInnerAngle:m.coneInnerAngle,coneOuterAngle:typeof s.coneOuterAngle<"u"?s.coneOuterAngle:m.coneOuterAngle,coneOuterGain:typeof s.coneOuterGain<"u"?s.coneOuterGain:m.coneOuterGain,distanceModel:typeof s.distanceModel<"u"?s.distanceModel:m.distanceModel,maxDistance:typeof s.maxDistance<"u"?s.maxDistance:m.maxDistance,refDistance:typeof s.refDistance<"u"?s.refDistance:m.refDistance,rolloffFactor:typeof s.rolloffFactor<"u"?s.rolloffFactor:m.rolloffFactor,panningModel:typeof s.panningModel<"u"?s.panningModel:m.panningModel};var d=o._panner;d||(o._pos||(o._pos=t._pos||[0,0,-.5]),e(o,"spatial"),d=o._panner),d.coneInnerAngle=m.coneInnerAngle,d.coneOuterAngle=m.coneOuterAngle,d.coneOuterGain=m.coneOuterGain,d.distanceModel=m.distanceModel,d.maxDistance=m.maxDistance,d.refDistance=m.refDistance,d.rolloffFactor=m.rolloffFactor,d.panningModel=m.panningModel}return t},Sound.prototype.init=function(t){return function(){var i=this,s=i._parent;i._orientation=s._orientation,i._stereo=s._stereo,i._pos=s._pos,i._pannerAttr=s._pannerAttr,t.call(this),i._stereo?s.stereo(i._stereo):i._pos&&s.pos(i._pos[0],i._pos[1],i._pos[2],i._id)}}(Sound.prototype.init),Sound.prototype.reset=function(t){return function(){var i=this,s=i._parent;return i._orientation=s._orientation,i._stereo=s._stereo,i._pos=s._pos,i._pannerAttr=s._pannerAttr,i._stereo?s.stereo(i._stereo):i._pos?s.pos(i._pos[0],i._pos[1],i._pos[2],i._id):i._panner&&(i._panner.disconnect(0),i._panner=void 0,s._refreshBuffer(i)),t.call(this)}}(Sound.prototype.reset);var e=function(t,i){i=i||"spatial",i==="spatial"?(t._panner=Howler.ctx.createPanner(),t._panner.coneInnerAngle=t._pannerAttr.coneInnerAngle,t._panner.coneOuterAngle=t._pannerAttr.coneOuterAngle,t._panner.coneOuterGain=t._pannerAttr.coneOuterGain,t._panner.distanceModel=t._pannerAttr.distanceModel,t._panner.maxDistance=t._pannerAttr.maxDistance,t._panner.refDistance=t._pannerAttr.refDistance,t._panner.rolloffFactor=t._pannerAttr.rolloffFactor,t._panner.panningModel=t._pannerAttr.panningModel,typeof t._panner.positionX<"u"?(t._panner.positionX.setValueAtTime(t._pos[0],Howler.ctx.currentTime),t._panner.positionY.setValueAtTime(t._pos[1],Howler.ctx.currentTime),t._panner.positionZ.setValueAtTime(t._pos[2],Howler.ctx.currentTime)):t._panner.setPosition(t._pos[0],t._pos[1],t._pos[2]),typeof t._panner.orientationX<"u"?(t._panner.orientationX.setValueAtTime(t._orientation[0],Howler.ctx.currentTime),t._panner.orientationY.setValueAtTime(t._orientation[1],Howler.ctx.currentTime),t._panner.orientationZ.setValueAtTime(t._orientation[2],Howler.ctx.currentTime)):t._panner.setOrientation(t._orientation[0],t._orientation[1],t._orientation[2])):(t._panner=Howler.ctx.createStereoPanner(),t._panner.pan.setValueAtTime(t._stereo,Howler.ctx.currentTime)),t._panner.connect(t._node),t._paused||t._parent.pause(t._id,!0).play(t._id,!0)}})()})(Vr);const Xa="data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjQxLjEwMAAAAAAAAAAAAAAA//NwwAAAAAAAAAAAAEluZm8AAAAPAAAAFAAACOAAICAgICwsLCwsNzc3NzdDQ0NDQ09PT09PW1tbW1tmZmZmZnJycnJyfn5+fn6KioqKipWVlZWVoaGhoaGtra2trbm5ubm5xcXFxcXQ0NDQ0Nzc3Nzc6Ojo6Oj09PT09P//////AAAAAExhdmM1OC43NQAAAAAAAAAAAAAAACQCwAAAAAAAAAjgTZykiAAAAAAAAAAAAAAAAAD/80DEABJhFmQCwwYUIDsKrsHAWBMRyeJYliQJBg5RYsWU/W3z/8OLc/3AAAQiIAIjv+7vUCJXd4jucQABAE3lwffiDBD+JC58oCH8H/1h/WH//1HPwTUMFrULH9ELKxULyTodFKYbO//zQsQRFFkScKDSRhyGWpIFpG91I7Fi/F6D2RWwN6TN/t9CiVSG5wMw74ogYcHoEwTFyMmTf4KkxEwmRfjXIYv1tpIOZRv/3O9ibtjR6gYmbGCgQ+Fk0mfSmybOX1cf78g7D6nP6qxCgf/zQMQbF+EacktaSABfy+3JKszHdMgcwwcl/kNFIuAo0I0DD1fWVs/crTSTTRInof3cmIwyLBwGQqCSLq7hyvtRPBB4aFyyXHov9X///7UXKqoIIcgcHict89/0y+n+nf/C0DIjB/+P//NCxBYZU9q0AYpoAHNyXSLn/+EjEbJclC4eJT//8e5aMAWeE4////wvAyAvYjZLjAD0Lg9D0kCU/////zwwBdJcYAehKBIwtYyx6FyXC4XP//////x7l83NDpfqd6gAcA/+wu9A2FGg//NAxAwXCnsq/5M4AhQKAOwmRvQRhjhOe5S8UkAmVHpU8IVU3lwejjIcayXOOceGwjf+D05I8oAu2x382o1ZHHV//31NU4441lmqcv///+RNGrUJKImnTf//iVYK1UZquoZESSy3egH/80LEChchBtMfyzAAk191v20qimbuNqavb211BthJKSJAG2aucbdLeVFVmRjZEVvzOggIwuUFDgvEZA7UeuUqNMLOraDQ5CVCk5m9BsmT3kbNrBdolcFSsqXGwQTWyYUX2wEDEgKkvZb/80DECRYRUpWsikYY1HXLbDZksYxtCHBShdHt/DgYCOM6r8AmUSpfGZYzH7ARMBCj1JtmY/hmwoGio0XBUShoklC5GsNeDR38RQ6d01DyrENtqp6mCJ5GJUckmpUBaIgYK6C0fPjmUf/zQsQLFil+cajTBhydxPRO4mLMWWSGQF2qa1f3PPlHQDJdzCxnwgkzB1SQohrpNRYRgtobv07tBLUFc27jQdWoQY0JNpiMJy654enBVoqnQR571uq/i9rpL1oAqAupJATLLk5L+QT3Kf/zQMQOE9D2bWFaGACZyWQZdt1rd3OVY8s/y2dBlg0m12PFzdFSlYrboY6gMOE1hJp7iFqmDcopF8F2OKEPnktdThRLoy9iuyj//0vD4+qf///++38OsIIFFhpEFZMC4s+gZmilJz1X//NCxBkaW8allZI4AWPWKBoLFWrwfuYvukbk4Rt9tBuJYOBoWpfzfjQaNMp//+OGEzzzDIif3+n/4PBIEt5hjDc9zxv/////nseeNDHGg0MQwxBEFn//////4TpB9d/s9thcHddpssFg//NAxAsVCT8GX5BAAigUAPBBdOBaKEIpaajR1VyCNH/gAwAfjRX8G7B4zfx0HANA8BpjQ6FhfqKxRBQURleGbrufzJywVGVfRdOzp5///ERCxhb//8wqijBAwUYMBCjVWZsv26uwYU3/80LEERRTIuTLwxABmdQgEBGKFNo9amfRWcpnayOUsKJ/UpWo/qyL////sj1b+pc3oarStSWpf/VP+hlotDN/0MVjKMKDAZGL/Ar8QWpCR0msAoVgrMoeT3xHIZd3qARkQge7hzlejQD/80DEGxPQ5sryeYYUBCI58AEvohe5nAMDcPxAbUxN6VCB4xCid97iaTyonF0l4upInmIpD//V0f/OllFls0vEBipVlYYRWhuzlHgpEiJSRmYJQaiptezfqvKm1PBRJKiq7M3s1yoqKv/zQsQmFBEGuojBkAQdCzTSpHY0FSwdboEQKi7pZN986g7UVOkf5ZR6VdbbQwZ+79PW6VoWdwZqA4VT2QGoxuuO0VZgbATjSNkSqqresUZ4lDGM5tfbuZzGHYfri5YKg0eDjgQjhm0Wpf/zQMQxE1jyoqhoxFD16D4jzQUUULEB1QXZhRIdIbHFtSlSvX5anFh11QTHaABkiBXOXoXxGW9galRr4fRiew3yOag/4HjxOydOM9ZyyokPlRKdFBa0CjY1luBiKXXwLw6oeMWEhjoS//NCxD4TUNKKIJpMJNTRh7nf/3kekmjdSWypy9UZXQgZMDh3pnAWB4O2M6nAaelR4r1OmVPFSwoksiWRUE1zc+f1lPc0ZudtdFDr4LLpoSwwGkpVO+oD6Tlb3HsYL7d+R1//td2LQMNF//NAxEwTaP5xYqJMCFlqIwAbEoCJNDEp9/3itYVbV6Yx/v0nuLdzyy50qHQw3cafmKlb6zBo0yXeRMnQG5J4jE7j4PFAkTSpQ9pexojMMsL0PIqP/Z1Xp/TpnVZZ27eWtNWRSSSyWyz/80LEWRSo1nDhWhgAlsstlkskgADyNOHqG5rlhLnSyI0a5oClU7uw0JnJQq2kTMBUYADEskGQ9wdHohh2xMKnCubKTIdyRgT83NEIrcfJpJOL3fV7l9cyXXJwJRDGpJLTZJF1+3OPUX3/80DEYiVyorJfmlgDRVRdYm21rHJXTVH0+ajd35ouiSF1tVcmLGnFummxbrhsXfHNzcf/2qgd/7XhppiSaYkmmQGRpnCsAMAEB4tQrXVA0VOiINSMWfljtMTHsRdZ3iL/V1neW6zvLf/zQsQnDSAiMFXMGADWd4i6zvEX+W/yzud5ZUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==";let Za=class{constructor(){this.sound=new Vr.Howl({src:[Xa]})}play(){this.sound.play()}};const Ce=n=>{var e,t;if(typeof n.destroy=="function"){n.destroy();return}for(;n.children.length>0;)Ce(n.children[0]),(e=n.children[0])==null||e.removeFromParent();if(n instanceof f.Mesh)try{(t=n.geometry)==null||t.dispose()}catch{}};function Ka(n){return new f.Vector3(n[0],n[1],n[2])}function $a(){let n=3,e=Math.max(1/window.devicePixelRatio,.5);return window.innerWidth/window.innerHeight<.65&&(n=4,e=1/window.devicePixelRatio),{tiles:n,renderScale:e}}function Ja(n){let e=!1,t=!1,i=!1,s=1/0,a=1/0,o=1/0,c=-1/0,u=-1/0,m=-1/0,d=0,r=0;return n.traverse(h=>{if(h.isMesh&&h.geometry){const g=h;if(g.userData.ignoreSize||g.material.userData.isLOGO)return;g.geometry.computeBoundingBox();let _=g.geometry.attributes.position;const p=g.geometry.morphAttributes.position;let v=g.morphTargetInfluences;const y=Object.keys(g.morphTargetDictionary||{});y.includes("width")&&(t=!0),y.includes("length")&&(e=!0),y.includes("height")&&(i=!0);for(let x=0;x<_.count;x++){let w=_.getX(x),b=_.getY(x),T=_.getZ(x);r=Math.max(b,r),p&&v&&p.forEach((S,C)=>{const I=v&&v[C]||0;w+=S.getX(x)*I,b+=S.getY(x)*I,T+=S.getZ(x)*I}),w<s&&(s=w),b<a&&(a=b),T<o&&(o=T),w>c&&(c=w),b>u&&(u=b),T>m&&(m=T);const M=Math.sqrt(w*w+b*b);M>d&&(d=M)}}}),{box:new f.Box3(new f.Vector3(s,a,o),new f.Vector3(c,u,m)),maxRadius:d,height:r,hasWidth:t,hasLength:e,hasHeight:i}}function el(n,e,t=null){let i=0;return function(){let s=t||this,a=arguments;clearTimeout(i),i=window.setTimeout(function(){n.apply(s,a)},e)}}class tl{constructor(e,t,i){this.length=e,this.width=t,this.height=i}}const tr=n=>{var i;let e=0,t=0;if(n.geometry){n.geometry.computeBoundingBox();const s=new f.Vector3;(i=n.geometry.boundingBox)==null||i.getSize(s),s.y?(t=s.y,!s.x&&s.z?e=s.z:s.x&&!s.z?e=s.x:s.x&&s.z&&(e=s.z)):(e=s.z,t=s.x)}return{width:e,height:t}};function xs(){var e;if(typeof navigator>"u")return!1;if(il())return!0;const n=(e=navigator.userAgent)==null?void 0:e.toLowerCase();return/iphone|ipad|ipod|android|mobile|blackberry|iemobile|opera mini/.test(n)}function il(){try{if(typeof wx<"u"&&wx.getSystemInfo||typeof my<"u"&&my.alert||typeof tt<"u"&&tt.getSystemInfo||typeof swan<"u"&&swan.getSystemInfo)return!0}catch{}return!1}const Ur=new Sn.GLTFExporter,yt=new bn.GLTFLoader,Hr=new An.DRACOLoader;let Ji="./draco/";try{Ji=new URL("./draco/",typeof document>"u"?require("url").pathToFileURL(__filename).href:vt&&vt.src||new URL("scene-Ibg8IbTP.js",document.baseURI).href).href}catch{Ji="./draco/"}typeof window<"u"&&window.dracoPath&&(Ji=window.dracoPath);Hr.setDecoderConfig({type:"wasm"});yt.setDRACOLoader(Hr);const sl=new Tn.DRACOExporter,ir=[115,103,108,98];function rl(n,e,t){const i=JSON.stringify(e),s=new TextEncoder().encode(i),a=new Uint8Array([115,103,108,98]),o=new Uint8Array(2);o[0]=t>>8,o[1]=t&255;const c=new Uint8Array(4);c[0]=s.length>>24,c[1]=s.length>>16&255,c[2]=s.length>>8&255,c[3]=s.length&255;const u=new Uint8Array(n),m=a.length+o.length+c.length+s.length+u.length,d=new Uint8Array(m);let r=0;return d.set(a,r),r+=a.length,d.set(o,r),r+=o.length,d.set(c,r),r+=c.length,d.set(s,r),r+=s.length,d.set(u,r),d.buffer}function nl(n){const e=new Uint8Array(n.slice(0,4));let t=!0;for(let r=0;r<ir.length;r++)if(e[r]!==ir[r]){t=!1;break}if(!t)throw new Error("Invalid file format");const s=new DataView(n,4,2).getUint16(0,!1),o=new DataView(n,6,4).getUint32(0,!1),c=new Uint8Array(n.slice(10,10+o)),u=new TextDecoder().decode(c),m=JSON.parse(u),d=n.slice(10+o);return{version:s,jsonDescription:m,glbContent:d}}class pi{constructor(e){this.props=e,this.cache=new Map}load(e,t,i,s){if(this.props.useCache&&this.cache.has(e)){t(this.cache.get(e));return}const a=this;fetch(e).then(o=>{if(!o.ok){s==null||s(new ErrorEvent("NetworkError",{message:"NetworkError for "+e+": "+o.statusText}));return}return o.arrayBuffer()}).then(async o=>{o||s==null||s(new ErrorEvent("Error",{message:"Not a valid sglb file."}));try{const c=a.parse(o);if(!c.glbContent){s==null||s(new ErrorEvent("Error",{message:"No glb content."}));return}const u=Ki(c.glbContent,"model/gltf-binary"),m=await yt.loadAsync(u);URL.revokeObjectURL(u),c.glbContent=void 0,c.glb=m.scene,o=void 0,this.cache.set(e,c),t(c)}catch(c){s==null||s(new ErrorEvent("Error",{message:c==null?void 0:c.message}))}}).catch(o=>{s==null||s(new ErrorEvent("Error",{message:o.message}))})}async loadAsync(e){if(this.props.useCache&&this.cache.has(e))return this.cache.get(e);try{const t=await fetch(e);if(!t.ok)throw new Error(`NetworkError for ${e}: ${t.statusText}`);const i=await t.arrayBuffer();if(!i)throw new Error("Not a valid sglb file.");const s=this.parse(i);if(!s.glbContent)throw new Error("No GLB content.");const a=Ki(s.glbContent,"model/gltf-binary"),o=await yt.loadAsync(a);return URL.revokeObjectURL(a),s.glbContent=void 0,s.glb=o.scene,this.cache.set(e,s),s}catch(t){throw t}}parse(e){return nl(e)}clear(){[...this.cache.values()]}}const ol=`*{box-sizing:border-box}.slot-item-container.is-mobile .main{pointer-events:none;border-width:1px;opacity:.8}.slot-item-container.is-mobile .main.focus{width:18px!important;height:18px!important;border-width:2px;opacity:1}.slot-item-container.is-mobile .main.filled{opacity:1;border-width:1px;width:14px!important;height:14px!important;background-image:none;border-radius:50%}.slot-item-container.is-mobile .main.to-be-installed{opacity:1;pointer-events:auto;width:38px!important;height:38px!important;border-color:#000;border-width:1px;background-image:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20fill='none'%20version='1.1'%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%3e%3cg%3e%3cg%3e%3cpath%20d='M20,10.75L0,10.75L0,9.25L20,9.25L20,10.75Z'%20fill-rule='evenodd'%20fill='%23000000'%20fill-opacity='1'/%3e%3c/g%3e%3cg%20transform='matrix(0,1,1,0,10,-10)'%3e%3cpath%20d='M30,0.75L10,0.75L10,-0.75L30,-0.75L30,0.75Z'%20fill-rule='evenodd'%20fill='%23000000'%20fill-opacity='1'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e");background-size:20px auto;background-repeat:no-repeat;background-position:center;background-color:#fff9}.slot-item-container.is-mobile .main.to-be-installed+.info{pointer-events:auto;overflow:visible;width:auto}.slot-item-container.is-mobile .main.to-be-installed.filled{opacity:1;border-width:2px;width:18px!important;height:18px!important;background-image:none;border-radius:50%;border-color:#00ff95}.slot-item-container.is-mobile .main.to-be-installed.to-be-replaced{opacity:1;border-width:1px;pointer-events:auto;width:38px!important;height:38px!important;border-radius:50%;background-image:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20fill='none'%20version='1.1'%20width='40'%20height='40'%20viewBox='0%200%2040%2040'%3e%3cdefs%3e%3cclipPath%20id='master_svg0_504_014299'%3e%3crect%20x='0'%20y='0'%20width='40'%20height='40'%20rx='20'/%3e%3c/clipPath%3e%3c/defs%3e%3cg%20clip-path='url(%23master_svg0_504_014299)'%3e%3cg%3e%3cg%3e%3cpath%20d='M31.695414,17L26.009501,10.74549544L24.899591,11.75450456L28.304586,15.5L8.75,15.5L8.75,17L31.695414,17Z'%20fill-rule='evenodd'%20fill='%23000000'%20fill-opacity='1'/%3e%3c/g%3e%3cg%3e%3cpath%20d='M8.3045862,23L13.9904997,29.2545042L15.10041,28.2454953L11.6954139,24.5L31.25,24.5L31.25,23L8.3045862,23Z'%20fill-rule='evenodd'%20fill='%23000000'%20fill-opacity='1'/%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/svg%3e");background-size:38px auto;border-color:#000}.slot-item-container.is-mobile .info{left:100%;margin-top:0;margin-left:4px}.slot-item-container.is-mobile .info .name-wrapper{margin-top:0;border-radius:0;background:#000;color:#fff}.slot-item-container.is-mobile .info>img{display:none}.slot-item-container .main{pointer-events:auto;cursor:pointer;font-size:12px;color:#fff;width:22px;height:22px;background:#fff0;border:2px solid #fff;border-radius:0;transition:background .2s,width .14s,height .14s,border .14s}.slot-item-container .main.disable{cursor:not-allowed}.slot-item-container .main.drag-over{border-color:red}.slot-item-container .main.can-install{position:relative;width:44px;height:44px;background:#0066ff1a;border-color:#06f}.slot-item-container .main.filled{border-color:#00ff95;border-radius:50%}.slot-item-container .main.selected{border-width:4px}.slot-item-container .main.selected+.info{pointer-events:auto;overflow:visible;width:auto}.slot-item-container .main.focus{border-color:#000}.slot-item-container .main.focus+.info{pointer-events:auto;overflow:visible;width:auto}.slot-item-container .main.has-error{border-color:red}.slot-item-container .main.hidden{display:none}.slot-item-container .main.hidden+.info{display:none}.slot-item-container .main:after{pointer-events:none;content:attr(data-name);transition:all .2s .3s;opacity:0;position:absolute;left:50%;bottom:100%;transform:translate3d(-50%,5px,0);white-space:nowrap;font-size:12px;color:#000;padding:2px 8px;border-radius:2px;background:#fff}.slot-item-container .main:hover{background:#ffffff80}.slot-item-container .main:hover+.info{pointer-events:auto;overflow:visible;width:auto}.slot-item-container .name{position:relative}.slot-item-container .name-wrapper{margin-top:-10px;white-space:nowrap;font-size:12px;color:#fff;padding:2px 8px;background:#000}.slot-item-container .functions-wrapper{z-index:20000;position:absolute;left:0;top:100%}.slot-item-container .functions-wrapper>.functions{display:inline-block;min-width:100px;padding:6px 0;border-left:1px solid #00ff95;border-radius:0 2px 2px 0;background:#0003;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}.slot-item-container .functions-wrapper>.functions .btn-add{cursor:pointer;padding:2px 0;margin:0 8px;display:flex;justify-content:center;align-content:center;align-items:center;border:1px dashed #eee;font-size:12px;color:#eee;border-radius:2px;-webkit-backdrop-filter:none;backdrop-filter:none;background:#00050a80}.slot-item-container .functions-wrapper>.functions .btn-add.btn-not-allowed{cursor:not-allowed}.slot-item-container .functions-wrapper>.functions .function{display:flex;justify-content:space-between;white-space:nowrap;margin-bottom:6px;padding:0 8px;font-size:12px;color:#fff}.slot-item-container .functions-wrapper>.functions .function span{margin-right:4px}.slot-item-container .functions-wrapper>.functions .function .btn-remove{pointer-events:none;opacity:0;cursor:pointer;align-self:center;margin-right:0;height:14px;width:14px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAACnSURBVEiJxZaxFcMgDETPTuUtWCWTM4pZAq5RojRpnOfEyEKxSnh3HySeBEhNjZJJTRgUG89GyZWilbKOgJCaKmWtFG2UvFnwQr56jYAcengg3dozELPGIjh96x6hu26/DIa9vD0jq/nUA3nikQEkAOW9nACUGbf7skxlX2mIj1Ob0jK76QdxbYpGFNlk3rPnNndDQltFaLMLbdehAyd8ZP5l6Ed+W17xG7oN9QkytAAAAABJRU5ErkJggg==) center no-repeat;background-size:10px 10px}.slot-item-container .functions-wrapper>.functions .function:hover .btn-remove{pointer-events:auto;opacity:1;transform:scale(1.2)}.slot-item-container .device-name{position:relative;margin:2px 0;display:flex;min-width:120px;align-items:center;align-content:center;justify-content:space-between;white-space:nowrap;height:30px;padding:0 8px;font-size:14px;font-weight:700;color:#000;background:#fff}.slot-item-container .device-name .device-logo{margin-left:-8px;margin-right:4px;width:30px;height:30px;object-fit:contain}.slot-item-container .device-name span{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:250px}.slot-item-container .device-name .btn-close{margin-left:8px;cursor:pointer;height:20px;width:20px;background:url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20fill='none'%20version='1.1'%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%3e%3cdefs%3e%3cclipPath%20id='master_svg0_504_017509'%3e%3crect%20x='0'%20y='0'%20width='20'%20height='20'%20rx='0'/%3e%3c/clipPath%3e%3c/defs%3e%3cg%20clip-path='url(%23master_svg0_504_017509)'%3e%3cg%3e%3cpath%20d='M4.375,16.875L4.375,4.375L15.625,4.375L15.625,16.875L4.375,16.875ZM14.375,5.625L5.625,5.625L5.625,15.625L14.375,15.625L14.375,5.625Z'%20fill-rule='evenodd'%20fill='%23999999'%20fill-opacity='1'/%3e%3c/g%3e%3cg%3e%3cpath%20d='M8.125,12.1875L8.125,8.125L9.375,8.125L9.375,12.1875L8.125,12.1875Z'%20fill-rule='evenodd'%20fill='%23999999'%20fill-opacity='1'/%3e%3c/g%3e%3cg%3e%3cpath%20d='M10.625,12.1875L10.625,8.125L11.875,8.125L11.875,12.1875L10.625,12.1875Z'%20fill-rule='evenodd'%20fill='%23999999'%20fill-opacity='1'/%3e%3c/g%3e%3cg%3e%3cpath%20d='M16.875,5.625L3.125,5.625L3.125,4.375L16.875,4.375L16.875,5.625Z'%20fill-rule='evenodd'%20fill='%23999999'%20fill-opacity='1'/%3e%3c/g%3e%3cg%3e%3cpath%20d='M6.4446528999999995,5.625L13.545177899999999,5.625L11.8665838,2.5L8.15767372,2.5L6.4446528999999995,5.625ZM11.4548223,4.3749999L8.5553472,4.3749999L8.8979512,3.75L11.1191032,3.75L11.4548223,4.3749999Z'%20fill-rule='evenodd'%20fill='%23999999'%20fill-opacity='1'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e") center no-repeat;background-size:100% auto}.slot-item-container .device-name.empty{color:#000c;font-weight:400}.slot-item-container .device-name.empty .btn-close{display:none}.slot-item-container .device-name.empty:before{height:0}.slot-item-container .all-functions{opacity:0;pointer-events:none;min-width:80px;position:absolute;left:-10px;margin-left:100%;bottom:0;padding:6px 0;background:#fff;transition:all .3s}.slot-item-container .all-functions.show{opacity:1;pointer-events:auto;left:16px}.slot-item-container .all-functions label{margin-left:8px;margin-bottom:20px;color:#444e69;font-size:14px}.slot-item-container .all-functions .btn-close{cursor:pointer;position:absolute;right:7px;top:7px;height:16px;width:16px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAB4SURBVDiNpZPLEYAgDAUXe6MuoK4UpwdBwQkQJDcyb9+QnxORCOC9jyxE4Y78DiWxAIcmISKnxaSrtZhMNSOB+ZeacAS7ngl3k1JOBSBpk1INPib0YHjH+Du2S1DhlSZOYbPJ1iLtrLKrG2a9yJopYzTD8Jx+ArgAylOzjm1WpDwAAAAASUVORK5CYII=) center no-repeat;background-size:10px 10px}.slot-item-container .all-functions .functions{display:inline-block;max-height:200px;overflow-x:hidden;overflow-y:auto}.slot-item-container .all-functions .functions::-webkit-scrollbar{width:4px}.slot-item-container .all-functions .functions::-webkit-scrollbar-track{background-color:#fff}.slot-item-container .all-functions .functions::-webkit-scrollbar-thumb{background:#787878;border-radius:25px}.slot-item-container .all-functions .function{display:flex;justify-content:space-between;white-space:nowrap;padding:5px 10px;font-size:12px;color:#787878}.slot-item-container .all-functions .function span{display:flex;align-content:center;align-items:center;margin-right:4px}.slot-item-container .all-functions .function:hover{background:#444e6933}.slot-item-container .all-functions .btn-add{cursor:pointer;width:16px;font-size:16px;text-align:center;font-style:normal}.slot-item-container .info{overflow:hidden;margin-left:-2px;margin-top:-19px;position:absolute;left:100%;top:50%;transform:translateY(-50%);width:0;display:flex;align-items:flex-start;transition:all .3s}.slot-item-container .info>img{flex:0 0 auto;width:53px;height:29px}`,al="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGsAAAA7CAYAAAB8MXT7AAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAGTSURBVHic7dxLbQNBEIThnigADGEhxAwcBoZgCIZgBoZgCIZgCIaQMIgZVC4daw/xXPLoqdX/3fbW0milUtfutMCdpCkiLhEx1U6CLkkvkt4k7atnQYekfR7US/Us6JB0yIOaqmfBA5JWks6SrhzUwCRN+TYdq2dBx+ygDtWzoEPSNg9qVz0LOmZBgsQ3sqUkvufqAf6SpFVEnCPiFhHr1tqteCR8hyBhYrY6OlTPgo5cHX1I2lbPgo6lBInFk3Rc+uroqXqAn8ogcc3H19bae+U8eIDEZ0LSJoMEZeHIWB2ZIPEZoCw0QVlogsRnYlYWsjoaGUHCRK6OOKiRfa2OMvWtqufBAwQJE5SFJmZl4aZ6FnSQ+Azk6mjxZeFv+/fycfbDWrTW1pSFgyLxmcjVEWXh6CgLTZD4DMzKwguro4ERJEywOjIhaUdZaIAgYYKy0ABloQkSnwlxKZUHcSmVBxKfgVwdnSgLB8d35iZIfCYoC01QFpog8Y3rftFWrotO+cilVKMiSJigLDSS30hQFhr4BEcKZN0LNhDxAAAAAElFTkSuQmCC";var ll=Object.defineProperty,cl=Object.getOwnPropertyDescriptor,K=(n,e,t,i)=>{for(var s=i>1?void 0:i?cl(e,t):e,a=n.length-1,o;a>=0;a--)(o=n[a])&&(s=(i?o(e,t,s):o(s))||s);return i&&s&&ll(e,t,s),s};let Y=class extends B.s{constructor(n){super(),this.props=n,this._size=12,this._showDialog=!1,this.selected=!1,this.focused=!1,this.toBeInstalled=!1,this.toBeReplaced=!1,this.hasError=!1,this.canInstall=!1,this.hide=!1,this.disable=!1,this.filled=!1,this.allFunctions=[],this.functions=[],this.deviceName="",this.deviceLogo="",this.removeDevice=()=>{this.props.onRemove&&this.props.onRemove()}}get hasMoreFunctions(){return this.allFunctions.length>this.functions.length}onClick(n){n.preventDefault(),n.stopPropagation()}setSize(n=12){this._size=n}addFunction(n){this.dispatchEvent(new CustomEvent("function-added",{detail:n}))}render(){var n;return B.x`
3707
+ <div class="slot-item-container ${this.props.isMobile&&"is-mobile"}">
3708
+ <div class="main
3709
+ ${this.selected?"selected":""}
3710
+ ${this.focused?"focus":""}
3711
+ ${this.toBeInstalled?"to-be-installed":""}
3712
+ ${this.toBeReplaced?"to-be-replaced":""}
3713
+ ${this.hasError?"has-error":""}
3714
+ ${this.canInstall?"can-install":""}
3715
+ ${this.hide?"hidden":""}
3716
+ ${this.disable?"disable":""}
3717
+ ${this.filled?"filled":""}
3718
+ "
3719
+ style="${`width: ${this._size+"px"}; height:${this._size+"px"}`}"
3720
+ ></div>
3721
+ <div class="info" @click="${this.onClick}">
3722
+ <img alt="" src="${al}">
3723
+ <div class="name">
3724
+ <div class="name-wrapper">${(n=this.slot)==null?void 0:n.name}</div>
3725
+ <div class="functions-wrapper">
3726
+ <div class="device-name ${!this.deviceName&&"empty"}">
3727
+ ${this.deviceLogo?B.x`<img class="device-logo" src="${this.deviceLogo}" alt="device logo">`:null}
3728
+ <span>${this.deviceName||"待安装"}</span>
3729
+ <i class="btn btn-close" @click=${this.removeDevice}></i>
3730
+ </div>
3731
+ ${this.allFunctions.length?B.x`
3732
+ <div class="functions">
3733
+ ${this.functions.map(e=>B.x`
3734
+ <div class="function"><span>${e}</span><i class="btn btn-remove"
3735
+ @click=${()=>{this.dispatchEvent(new CustomEvent("function-removed",{detail:e}))}}></i>
3736
+ </div>
3737
+ `)}
3738
+ ${B.x`
3739
+ <div class="btn btn-add ${!this.hasMoreFunctions&&"btn-not-allowed"}" @click=${()=>{this._showDialog=!this._showDialog}}>+添加
3740
+ </div>`}
3741
+ </div>
3742
+ `:B.x``}
3743
+
3744
+ ${this.hasMoreFunctions&&this.allFunctions.length?B.x`
3745
+ <div class="all-functions ${this._showDialog&&"show"}">
3746
+ <label>添加功能
3747
+ <i class="btn btn-close" @click=${()=>{this._showDialog=!1}}></i>
3748
+ </label>
3749
+ <div class="functions">
3750
+ ${this.allFunctions.map(e=>this.functions.includes(e)?B.x``:B.x`
3751
+ <div class="function">
3752
+ <span>${e}</span>
3753
+ <i class="btn btn-add" @click=${()=>this.addFunction(e)}>+</i>
3754
+ </div>
3755
+ `)}
3756
+ </div>
3757
+ </div>`:B.x``}
3758
+ </div>
3759
+ </div>
3760
+ </div>
3761
+ </div>
3762
+ `}};Y.styles=B.i([ol]);K([B.r$1()],Y.prototype,"_size",2);K([B.r$1()],Y.prototype,"_showDialog",2);K([B.n({type:Boolean})],Y.prototype,"selected",2);K([B.n({type:Boolean})],Y.prototype,"focused",2);K([B.n({type:Boolean})],Y.prototype,"toBeInstalled",2);K([B.n({type:Boolean})],Y.prototype,"toBeReplaced",2);K([B.n({type:Boolean})],Y.prototype,"hasError",2);K([B.n({type:Boolean})],Y.prototype,"canInstall",2);K([B.n({type:Boolean})],Y.prototype,"hide",2);K([B.n({type:Boolean})],Y.prototype,"disable",2);K([B.n({type:Boolean})],Y.prototype,"filled",2);K([B.n({type:Object})],Y.prototype,"allFunctions",2);K([B.n({type:Object})],Y.prototype,"functions",2);K([B.n({type:String})],Y.prototype,"deviceName",2);K([B.n({type:String})],Y.prototype,"deviceLogo",2);K([B.n()],Y.prototype,"slot",2);Y=K([B.t("slot-item")],Y);const Z={ON_DROP:"slot-on-drop",ON_DEVICE_DELETED:"slot-on-device-deleted",ON_DEVICE_REPLACED:"slot-on-device-replaced",ON_BEFORE_SELECTED:"slot-on-before-selected",ON_SELECTED:"slot-on-selected",ON_ADD_BUTTON_CLICKED:"slot-add-button-clicked",ON_DEVICE_SELECTED:"slot-on-device-selected",ON_DROP_ERROR:"slot-on-drop-error",ON_ERROR_STATE_CHANGE:"slot-on-error-state-change",ON_FUNCTION_REMOVED:"slot-on-function-removed",ON_FUNCTION_ADDED:"slot-on-function-added"};class es extends we.CSS2DObject{constructor(e){const t=document.createElement("div");super(t),this.props=e,this._emitter=new xt,this._slotContainer=new f.Group,this._bracketSlots=[],this._hasError=!1,this.useBracket=!1,this.addEventListener=this._emitter.addListener.bind(this._emitter),this.removeEventListener=this._emitter.removeListener.bind(this._emitter),this._canInstall=!1,this._loading=!1,this._selected=!1,this._deviceSelected=!1,this._focused=!1,this._toBeInstalled=!1,this._toBeReplaced=!1,this._allFunctions=new Set,this._functions=new Set,this._timer=0,this._parentPos=new f.Vector3,this._wrapper=new f.Group,this._showSlot=!0,this._isMirror=!1,this._preventDefaults=i=>{i.preventDefault(),i.stopPropagation()},this.getWP=this._slotContainer.getWorldPosition.bind(this._slotContainer),this._showSlot=typeof e.show=="boolean"?e.show:!0,this.name=e.name,this._isMirror=e.isMirror,this._slotUI=new Y({name:e.name,isMobile:e.isMobile,onRemove:()=>{this.clearSlot(),this._emitter.emit(Z.ON_DEVICE_DELETED)}}),this._slotUI.slot=this,this._slotUI.hide=!this._showSlot||this.isMirror,t.append(this._slotUI),this._parentPos.copy(this.props.slot.position),this._slotUI.addEventListener("function-removed",({detail:i})=>{this.removeFunction(i)}),this._slotUI.addEventListener("function-added",({detail:i})=>{this.addFunction(i)}),this.add(this._slotContainer),this.props.slot.add(this),setTimeout(()=>{var i;(i=this.props.slot.parent)==null||i.add(this._wrapper),this._wrapper.add(this.props.slot)},10),["dragenter","dragover","dragleave","drop"].forEach(i=>{t.addEventListener(i,this._preventDefaults,!1)}),t.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),this.toBeInstalled?this._emitter.emit(Z.ON_ADD_BUTTON_CLICKED):this.selected=!this.selected}),t.addEventListener("dragover",i=>{if(i.preventDefault(),i.dataTransfer.dropEffect="copy",!this._canInstall){i.dataTransfer&&(i.dataTransfer.dropEffect="none");return}}),t.addEventListener("drop",async i=>{var a;if(i.preventDefault(),i.stopPropagation(),!this._canInstall)return;const s=(a=i.dataTransfer)==null?void 0:a.getData("application/json");if(s){const o=JSON.parse(s);try{await this.install(o),this._emitter.emit(Z.ON_DROP,this)}catch(c){this._emitter.emit(Z.ON_DROP_ERROR,c)}}else this._emitter.emit(Z.ON_DROP_ERROR,new Error("No device info"))})}get hasDevice(){return this._slotContainer.children.length>0}get isMirror(){return this._isMirror}shapeKeyChanged(e,t){var i;if(this.props.follows.has(e)){const s=this.props.follows.get(e);if(s){let a="x";["height","mast"].includes(e)?a="y":["width","liftOuterWidth"].includes(e)&&(a="z");const o=((i=this.props.slot)==null?void 0:i.position[a])>0?1:-1;this._wrapper.position[a]=(t-s.origin)*s.scale*o}}}async loadGlb(e){const i=await new pi({useCache:!0}).loadAsync(e);if(i.glb)return i.glb.clone(!0)}async installBracket(e){const i=await new pi({useCache:!0}).loadAsync(e);if(!i.glb)return;const s=i.glb.clone(!0);s.traverse(a=>{a.userData.isBracket=!0}),this.useBracket=!0,this._slotContainer.add(s)}async install(e){if(!this._loading){this._loading=!0;try{const t=await this.loadGlb(e.url);if(!t)throw new Error(`Fail to load device from: ${e.url}`);if(t.traverse(i=>{i.userData.isDevice=!0}),this.isMirror&&t.scale.set(1,1,-1),e.bracketUrl){const i=await this.loadGlb(e.bracketUrl);if(i)this.clearSlot(),this._emitter.emit(Z.ON_DEVICE_REPLACED),i.traverse(s=>{s.name.startsWith("Slot")&&this._bracketSlots.push(s),s.userData.isBracket=!0}),this._slotContainer.add(i);else throw new Error(`Fail to load bracket from: ${e.bracketUrl}`);this._bracketSlots.forEach(s=>{s.add(t)})}else this.clearSlot(),this._emitter.emit(Z.ON_DEVICE_REPLACED),this._slotContainer.add(t);this.mirrorTarget&&this.mirrorTarget.install(e),this.deviceInfo=e,this._slotUI.deviceLogo=e.logo||"",this._slotUI.deviceName=e.name,this._slotUI.filled=!0,this.holeTarget&&(this.holeTarget.visible=!1)}catch(t){throw t}finally{this._loading=!1}}}get device(){return this._slotContainer.children.length?this._slotContainer.children[0]:null}get allFunctions(){return[...this._allFunctions]}set allFunctions(e){this._functions.forEach(t=>{e.includes(t)||this._functions.delete(t)}),this._allFunctions=new Set(e),this._slotUI.allFunctions=e}get functions(){return[...this._functions]}addFunction(e){this._allFunctions.has(e)&&(this._functions.add(e),this._slotUI.functions=[...this.functions],this._emitter.emit(Z.ON_FUNCTION_ADDED,e))}removeFunction(e){this._functions.has(e)&&(this._functions.delete(e),this._slotUI.functions=[...this.functions],this._emitter.emit(Z.ON_FUNCTION_REMOVED,e))}clearFunctions(){this._functions.forEach(e=>this.removeFunction(e))}addFunctions(e){e.forEach(t=>this.addFunction(t)),this._slotUI.functions=this.functions}changeName(e){var t;this.name=e,this.props.slot.userData.name=e,this.props.name=e,(t=this.element)==null||t.setAttribute("data-name",this.props.name)}clearSlot(){this._bracketSlots=[],this._slotContainer.children.forEach(e=>{e.removeFromParent(),Ce(e)}),this._slotUI.filled=!1,this.deviceInfo=void 0,this._slotUI.deviceName="",this._slotUI.deviceLogo="",this.holeTarget&&(this.holeTarget.visible=!0),this.mirrorTarget&&this.mirrorTarget.clearSlot()}enable(){this._slotUI.disable=!1}disable(){this._slotUI.disable=!0}hide(){this._slotUI.hide=!0}show(){this.isMirror||(this._slotUI.hide=!1)}get selected(){return this._selected}get focused(){return this._focused}set focused(e){this._focused=e,this._slotUI.focused=e}get toBeInstalled(){return this._toBeInstalled}set toBeInstalled(e){this._toBeInstalled=e,this._slotUI.toBeInstalled=e}get toBeReplaced(){return this._toBeReplaced}set toBeReplaced(e){this._toBeReplaced=e,this._slotUI.toBeReplaced=e}set selected(e){e&&this._emitter.emit(Z.ON_BEFORE_SELECTED,e),this._selected=e,this._slotUI.selected=e,this._emitter.emit(Z.ON_SELECTED,e),this.element.style.zIndex="100",this.selected?this.renderOrder=1/0:this.renderOrder=1}get deviceSelected(){return this._deviceSelected}set deviceSelected(e){this._deviceSelected=e,this._emitter.emit(Z.ON_DEVICE_SELECTED,e)}get error(){return this._hasError}set error(e){this._loading&&setTimeout(()=>{this.error=e},100),this._hasError=e,this._slotUI.hasError=e,this._emitter.emit(Z.ON_ERROR_STATE_CHANGE,e)}getCanInstall(){return this._canInstall}canInstall(e){this._canInstall=e,this._slotUI.canInstall=e}dispose(){cancelAnimationFrame(this._timer),["dragenter","dragover","dragleave","drop"].forEach(e=>{this.element.addEventListener(e,this._preventDefaults,!1)}),this.clearSlot(),this._emitter.removeAllListeners(),Ce(this._slotContainer),this.element.remove()}render(e){const t=this.element.style.transform,i=/translate\(-?\d*\.?\d*%?,?\s-?\d*\.?\d*%?\)\s*translate\((-?\d*\.?\d*)px,\s*(-?\d*\.?\d*)px\)/.exec(t);if(!i)return;const s=new f.Vector2(parseFloat(i[1]),parseFloat(i[2])),a=e.mousePos.distanceTo(s);let o=this.props.isMobile?12:18,c=38,u=30;if(this._canInstall&&(o=34,c=60,u=60),a<u){let m=(u-a)*1+o;a<20&&(m=c),m>c&&(m=c),this._slotUI.setSize(m)}else this._slotUI.setSize(o)}clone(e){return new f.Group}}var ul=Object.defineProperty,hl=Object.getOwnPropertyDescriptor,ws=(n,e,t,i)=>{for(var s=i>1?void 0:i?hl(e,t):e,a=n.length-1,o;a>=0;a--)(o=n[a])&&(s=(i?o(e,t,s):o(s))||s);return i&&s&&ul(e,t,s),s};class fl{constructor(e,t,i,s){this.name=e,this.slot=t,this.start=i,this.end=s,this.split="--",this.uuid="",this.valid=!1,this.editable=!1,this.highlight=!1,this.uuid=e+this.split+t}update(e,t){this.start=e.clone(),this.end=t.clone()}}exports.DeviceLines=class extends B.s{constructor(e,t=0){super(),this.offset=e,this.heightOffset=t,this.lines=new Map,this.setOffset(this.offset.x,this.offset.y)}setOffset(e,t){this.offset.set(e,t),this.style.setProperty("--left",this.offset.x+"px"),this.style.setProperty("--top",this.offset.y+"px")}setHeightOffset(e){this.heightOffset=e,this.style.setProperty("--heightOffset",this.heightOffset+"px")}hide(){var e;(e=this.container)==null||e.classList.add("hidden")}show(){var e;(e=this.container)==null||e.classList.remove("hidden")}addLine(e){this.lines.has(e.uuid)||this.lines.set(e.uuid,e)}clear(){this.lines.clear()}removeLine(e){this.lines.delete(e.uuid)}getLineByName(e){const t=[];return this.lines.forEach((i,s)=>{i.name===e&&t.push(i)}),t}getLineBySlot(e){const t=[];return this.lines.forEach((i,s)=>{i.slot===e&&t.push(i)}),t}getPath(e){const t=e.end.clone();t.set(t.x-this.offset.x,t.y-this.offset.y);const i=e.start.clone().add(t).multiplyScalar(.5),s=e.start.clone().add(t).multiplyScalar(.7);return`M${e.start.x} ${e.start.y}
3763
+ C${i.x} ${e.start.y}
3764
+ ${s.x} ${e.end.y}
3765
+ ${t.x} ${t.y}
3766
+ `}updateLine(e){this.lines.set(e.uuid,e)}forceUpdate(){this.requestUpdate()}render(){return B.b`
3767
+ <svg class="container">
3768
+ <g>
3769
+ ${[...this.lines.values()].map(e=>B.b`<path
3770
+ class="${e.valid?"valid":""} ${e.editable?"editable":""} ${e.highlight?"highlight":""}"
3771
+ d="${this.getPath(e)}"></path>`)}
3772
+ </g>
3773
+ </svg>`}};exports.DeviceLines.styles=B.i`
3774
+ :host {
3775
+ --left: 0px;
3776
+ --top: 0px;
3777
+ position: absolute;
3778
+ left: var(--left);
3779
+ top: var(--top);
3780
+ pointer-events: none;
3781
+ width: calc(100% - var(--left));
3782
+ height: calc(100% - var(--top));
3783
+ }
3784
+
3785
+ svg {
3786
+ width: 100%;
3787
+ height: calc(100% + var(--heightOffset));
3788
+ &.hidden {
3789
+ display: none;
3790
+ }
3791
+ }
3792
+
3793
+ path {
3794
+ stroke: #787878;
3795
+ fill: transparent;
3796
+ stroke-width: 0.5px;
3797
+ stroke-dasharray: 4 4;
3798
+
3799
+ &.valid {
3800
+ stroke-width: 1px;
3801
+ stroke: #00FF95;
3802
+ stroke-dasharray: none;
3803
+ &:hover {
3804
+ cursor: pointer;
3805
+ }
3806
+ }
3807
+
3808
+ &.highlight {
3809
+ stroke: #0066FF;
3810
+ cursor: pointer;
3811
+ stroke-width: 2px;
3812
+ }
3813
+
3814
+ &.editable {
3815
+ pointer-events: auto;
3816
+ &:hover {
3817
+ cursor: pointer;
3818
+ stroke: #0066FF;
3819
+ stroke-width: 2px;
3820
+ stroke-dasharray: none;
3821
+ }
3822
+ }
3823
+ }
3824
+ `;ws([B.r$1()],exports.DeviceLines.prototype,"lines",2);ws([B.e$1(".container")],exports.DeviceLines.prototype,"container",2);exports.DeviceLines=ws([B.t("device-lines")],exports.DeviceLines);class dl extends we.CSS2DObject{constructor(e){const t=document.createElement("div");super(t),this._text=document.createElement("div");const i=xs(),s=i?"#ddd":"#eee";this.element.style.pointerEvents="auto",this.element.style.padding=i?"2px 6px":"3px 12px",this.element.style.borderTop=`1px solid ${s}`,this.element.style.borderBottom=this.element.style.borderTop;const a="6px",o=document.createElement("div");o.style.pointerEvents="none",Object.assign(o.style,{pointerEvents:"none",borderLeft:`1px solid ${s}`,borderRight:`1px solid ${s}`,position:"absolute",left:"0",top:"0",boxSizing:"border-box",height:a,width:"100%"}),this.element.append(o);const c=document.createElement("div");c.style.pointerEvents="none",Object.assign(c.style,{pointerEvents:"none",borderLeft:`1px solid ${s}`,borderRight:`1px solid ${s}`,position:"absolute",left:"0",bottom:"0",boxSizing:"border-box",height:a,width:"100%"}),this.element.append(c),this._text.style.fontSize=i?"10px":"14px",this._text.style.font="SF Pro SC,SF Pro Text,SF Pro Icons,PingFang SC,Helvetica Neue,Helvetica,Arial,sans-serif",this._text.style.color="#fff",this._text.style.fontWeight="500",this._text.style.transition="all .16s",this._text.innerText=e,this.element.append(this._text),this._text.addEventListener("pointermove",()=>{var u;o.style.borderColor=c.style.borderColor=this.element.style.borderColor="#666",this._text.style.color="#000",(u=this.onPointMove)==null||u.call(this)}),this._text.addEventListener("pointerleave",()=>{var u;o.style.borderColor=c.style.borderColor=this.element.style.borderColor=s,this._text.style.transform="scale(1)",this._text.style.color="#fff",(u=this.onPointLeave)==null||u.call(this)})}set text(e){this._text.innerText=e}dispose(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element)}}class ci extends f.Group{constructor(e,t=!0,i=!0){super(),this._startWith=e,this._showText=t,this.useStartEnd=i,this._line2Length=.01,this._line=new f.LineSegments(new f.BufferGeometry,new f.LineBasicMaterial({color:"#666",linewidth:2})),this._line2=new f.LineSegments(new f.BufferGeometry,new f.LineBasicMaterial({color:"#666",linewidth:2})),this._text=new dl(""),this._line.frustumCulled=!1,this.add(this._line,this._line2),this._showText&&(this.add(this._text),this._text.onPointMove=()=>{this._line.material.color.set("#000"),this._line2.material.color.set("#000")},this._text.onPointLeave=()=>{this._line.material.color.set("#666"),this._line2.material.color.set("#666")})}updateMaterial(e){this._line.material=e}reset(){var e;(e=this._line.geometry)==null||e.dispose(),this._line.computeLineDistances()}update(e,t,i=0){var h,g;(h=this._line.geometry)==null||h.dispose(),this._line.geometry.setFromPoints([e,t]),this._line.computeLineDistances();const s=this._line2Length+i*.02,a=new f.Vector3().subVectors(t,e).normalize();let o;Math.abs(a.z)>Math.abs(a.x)&&Math.abs(a.z)>Math.abs(a.y)?o=new f.Vector3(-a.y,a.x,0):Math.abs(a.y)>Math.abs(a.x)?o=new f.Vector3(1,0,0):o=new f.Vector3(0,1,0),o.length()<.001&&(Math.abs(a.x)<.9?o=new f.Vector3(1,0,0):o=new f.Vector3(0,1,0)),o.normalize();const c=new f.Vector3().addVectors(e,o.clone().multiplyScalar(s)),u=new f.Vector3().addVectors(e,o.clone().multiplyScalar(-s)),m=new f.Vector3().addVectors(t,o.clone().multiplyScalar(s)),d=new f.Vector3().addVectors(t,o.clone().multiplyScalar(-s));(g=this._line2.geometry)==null||g.dispose(),this._line2.geometry=new f.BufferGeometry,this._line2.geometry.setFromPoints([c,u,m,d]),this._line2.computeLineDistances();const r=e.distanceTo(t);this._startWith?this._text.text=`${this._startWith}${(r*1e3).toFixed(0)} mm`:this._text.text=`${(r*1e3).toFixed(0)} mm`;const l=new f.Vector3;l.addVectors(e,t).multiplyScalar(.5),this._text.position.copy(l),this.useStartEnd||(this._line2.visible=!1)}destroy(){this._text.dispose(),this.children.forEach(e=>Ce(e)),this.removeFromParent()}}class Wr extends f.Object3D{constructor(e,t){super(),this.radius=e,this._text=new pl(""),this._line=new ci(void 0,!1,!1),this._box=new f.Mesh,this._arc=new Pn.Line2,this._previousPosition=null,this._updateTimer=null,this._updateDelay=300,this._accumulatedAngle=0,this._lastAngle=null,this._line.updateMaterial(new f.LineDashedMaterial({color:"#555",dashSize:.06,gapSize:.06})),this._line.renderOrder=0,this._box.geometry=new f.RingGeometry(e,e+.003,128),this._box.material=new f.MeshBasicMaterial({color:"#666",side:f.DoubleSide}),this._arc.geometry=new Is.LineGeometry,this._arc.geometry.setPositions([0,0,0,0,0,0]),this._arc.geometry.instanceCount=0,this._arc.material=new _r.LineMaterial({color:"#eee",linewidth:2,resolution:new f.Vector2(window.innerWidth,window.innerHeight)}),this._arc.visible=!1,this._arc.rotateX(-Math.PI/2),this.position.y=t,this._arc.position.y=.001,this.add(this._box),this.add(this._arc),this.add(this._line),this.add(this._text)}hide(){this._text.hide(),this._line.visible=!1,this._arc.visible=!1}show(){this._text.show(),this._line.visible=!0}dispose(){this._updateTimer&&(clearTimeout(this._updateTimer),this._updateTimer=null),this._box.geometry&&this._box.geometry.dispose(),this._arc.geometry&&this._arc.geometry.dispose(),this._arc.visible=!1,this._previousPosition=null}update(e){var t;this.radius=e,(t=this._box.geometry)==null||t.dispose(),this._box.geometry=new f.RingGeometry(e,e+.003,128),this._line.updateMaterial(new f.LineDashedMaterial({color:"#555",dashSize:.06*e,gapSize:.06*e})),this._text.update((e*1e3).toFixed(0))}change(e){const t=e.clone();t.setZ(0),t.normalize().multiplyScalar(this.radius),this._text.position.set(t.x,t.y,t.z),this._text.updateColor("#eee"),this._line.update(t,new f.Vector3),this._previousPosition&&this._updateArc(this._previousPosition,t),this._updateTimer&&clearTimeout(this._updateTimer),this._updateTimer=setTimeout(()=>{this._previousPosition=null,this._accumulatedAngle=0,this._lastAngle=null,this._clearArc(),this._updateTimer=null},this._updateDelay),this._previousPosition||(this._previousPosition=t.clone(),this._lastAngle=Math.atan2(t.y,t.x),this._accumulatedAngle=0)}_updateArc(e,t){const i=Math.atan2(t.y,t.x);if(this._lastAngle!==null){let u=i-this._lastAngle;u>Math.PI?u-=2*Math.PI:u<-Math.PI&&(u+=2*Math.PI),this._accumulatedAngle+=u}if(this._lastAngle=i,Math.abs(this._accumulatedAngle)<.01){this._arc.visible=!1;return}const s=Math.atan2(e.y,e.x),a=s+this._accumulatedAngle;let o=.006*this.radius;o<.003&&(o=.003),o>.006&&(o=.006);const c=this._createArcGeometry(s,a,this.radius+o);this._arc.geometry&&this._arc.geometry.dispose(),this._arc.geometry=c,this._arc.visible=!0}_clearArc(){this._text.updateColor(),this._arc.geometry&&(this._arc.geometry.setPositions([0,0,0,0,0,0]),this._arc.geometry.instanceCount=0,this._arc.computeLineDistances()),this._arc.visible=!1}_createArcGeometry(e,t,i){const s=[],a=t-e,o=Math.max(128,Math.floor(Math.abs(a)/(Math.PI/128))),c=a/o;for(let m=0;m<=o;m++){const d=e+m*c,r=Math.cos(d),l=Math.sin(d);s.push(i*r,0,i*l)}const u=new Is.LineGeometry;return u.setPositions(s),u.instanceCount=Math.max(0,s.length/3-1),u}}class pl extends we.CSS2DObject{constructor(e){const t=document.createElement("div");super(t),this._wrapper=document.createElement("div"),this._circle=document.createElement("div");const i=xs();this._wrapper.style.fontSize=i?"10px":"11px",this._wrapper.style.color="#fff",this._wrapper.style.whiteSpace="nowrap",this._wrapper.style.position="absolute",this._wrapper.style.transform="translateX(-50%)",this._wrapper.style.top="6px",this._wrapper.style.font="SF Pro SC,SF Pro Text,SF Pro Icons,PingFang SC,Helvetica Neue,Helvetica,Arial,sans-serif";const s=this._circle;s.style.position="relative",s.style.zIndex="10",s.style.width=s.style.height="5px",s.style.borderRadius="50%",s.style.background="#666",t.append(this._wrapper,s),this.update(e)}show(){this.element.style.display="block"}hide(){this.element.style.display="none"}update(e){this._wrapper.innerText="旋转半径:"+e+" mm",this.updateColor("#eee")}updateColor(e="#666"){this._circle.style.background=e}}const ml="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAAUCAYAAADY6P5TAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAEvSURBVFiFzZdbFYMwEEQroRKQgAQkVEIlICEOkFAJlRAJSIgEJNx+sPS0nGxIaOhyv3nM7mTmwOViDHAFesADD+BqrakKQAcMwMQ3AWis9e1C3HLASJoAdNZ6sxG3/MZQMZy1dhWgFbfWRzDGlFjAwFlyyXdh5OD5OIqykBgBy1yiF0aMUQaJugLclOcEoP3nULmFgQgeyCwOoJGBYrijByspDM98ZIszJAt8Ks8dag/VUFYYLtetjHdruRz5JZf8WBg1Ae7KcgOluaSsMAKJwqgJ6Vz2WzcvhZHjVlFh1ESG1DQ67SYtyGs8OwujNpTkUtw4nVtbyLK1XDafF3aKW90Z3EpBbi5lE0u9n3qoNTKk9rHh3heZqqwA8Vw6a11VkVwuPK31HALzb5pfovYC2xSs5LCDIUcAAAAASUVORK5CYII=",gl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAKCAYAAACngj4SAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAChSURBVDiNrdJbFYMwEIRhJFQCEpCAhEqIhDhBAlKQgAQkIOHrSziHpmkbLvua7P4zO9s0FYUeM0b0NT2nC9FnLQho7wQ9MOwgQ3K4ZPDrrtGmFcKKkL0HTAXXw2HX6HYuFnR/hMWC6ykX+W1AzJqq1abDGguux6LoPK9aUGFOm1Y+F+Bh+7DlsSKehRXgnfdDm5od7GdeN8ADnpuKQ3ldqReHZFd3742nZgAAAABJRU5ErkJggg==",sr="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABsCAYAAACPZlfNAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAdzSURBVHic7Z3hlZs6EIUvW4E7CB3EHcQdxB08OngugVTg8yrwSQVOKnBSwW4qsFOB3cF9PxhZQsYYjEAS1neOD7ssCwPXMxoNIGWIDJJLAAsASwCfAOTyey6bLOQDABf5qJ9P8vkry48sy05j2+ySzLcBjyC5QiXOV1kuWv+hPxcAvwD8BvCBSsRL6394JDjBSC4ArFEJtG7Y5ILqwp4A/JHlxfyoC04yN/4vh/bEz9Dim9uY+/8O4EfI4nmFZEFyz1veSe5Iri0BXB13Icfekjxaxz6TPMixXXt2fJDM5WLZF+og63MPNi1IbsQGW7zyJYUToXZyEUxP8iLSPUS80hLvdYQTobbWN3fHKvMLGpKrBq/bzla4htC3C8mbutIg3JnkxrddzhCvil4omwbhDqy6IPEisV5xJFn4tsk1rDJI8wtZ+rapN+JV73PzqnuwSk7MtvkQzflabdUxGsMdIGFSnfuZZFPHPxysELjnXDOoFsTbzAJA6dumRiyxSt/2+Ma6Hlvf9lyRb9QumjAwIZKQqOLAznvEEbFUcvFS7VVXWO/WvHsTLYnVnSBEM8JgEqsDlmi7qQ++TWL1xxKtnOqgKvs5J7H6I6KdJxFNsh5FygafxLqOxVgHme6b8QIYkWqcZoW6Mr13vvMXhboi8u56x+a34eXKTWMhXSO3SQirgqZi5WSniSvS1ChyFztUoTCcetjMoNGnHbqjTQqF42P1z4pnd7IwssKUwo8Mq/uIz2eN1NWMg3vzxoUWvu3pihEa+zU/4l3RJhoRC/ZcAkKdxkfnXUC8ggE1L+tWILbartW45o1D5IIpL+tWq43du4C4BQNqXlY82jB67wJmIdhSTG/vl1FXkaP1LiB+wQCA+m5+Ya5/s7b7V5a/J7Eq0cZ/svza+FcrHEZd1ZiJh5kp/q0e1D3tqMMhMA/BgFodt1DrzJD4jyx/TmpVoo3vsqyHxTmFQ2BWHpY3ngP1Pa9h5f1AmItgQC1bXAE6JKpXVn94sSrRxocsl4AW7Iss/0xuTuIRKqfQ7dic2i9gdiHxWlu0V8yi/QLmJRhQc6jlG3T7lYboCRfVji3eoMda+mjeNhEAJ1ku31ANYQekhCNklDafTA87eTEl0YWTLHNTsNSGhYvSZvEGPWDkyY8t1xt2ua/jd0Uyah/jYinBcvt+2OTIBTgAOHi6GJ3wbKeOfkaOn09sRNM4VGcXF8N1P0wiwNmyMx+63x7HV48dnuHqpJ40ZMNbBovmUrAGsRSTjuB2PRefgokhZcPFGCSaK8FaxCqf3ecAW66Cea8juhbNhWCBiaXridRtSD61IZZRzkQbKlhIYok9ut5rCOY9Q3Ml2hDBQhNLbKoJdpBfVr4MMnEh2rOChSiW2KWeCHg3X4wO5h2woaI9I1ioYolt6gHf/RuMOpU/k+pkWVYC+GatXmCkTit1p9hOvL6JLb7JZXky+0LTjn/UgWc9rY+HhexZCuqXIzZmfAzyAdJnROsqWAxiAbUnp9bmmxJn34bdo69oXQSLRSwAt10veqwndqVFtKJh21bBWD2WHotYuo5orDzIymAyxSbuiEZbtDbBqN8hCF4soGbv3lwZbOJh00W0e4LFJhZQG81hY67UHbMIeCRak2AxigXU2q+V/QdF7sWynrSJ1nFdDGJd2y/axXnqikfhx7z+tIjWhdK3/Y+gbqpuu1yM9IU+Nt8EfUQU00ex4YU+84/m6Df55NYNgPdDXhOFb3u7wLZwaGwUXVhUdBSt8G1nV9hlvBTjpKPIFm0eiFb4tq8P7No3ZkA3NJ/hjmiFb7v6QN3Nuh8OjY3VCQffib6HJVrh256+GN5Vdtk4ZwS1xUeIaIVvO/rSy7uMf9rF7mWx0su7jH9SD31E7WWxwfoI5v0eO6QuOiYvmwgOGcGcLkZ6TnSG+kGb7m1Xw05UtnVMoXE8WJ8hYljZjL4mKXsh6HIE85SAjAvHmCqFabKcUeAYk+UYO1ePWqXpqBxBXWx3f0vLyhpL5wd4MYyoNd7bnKzX6IJ+wipkOOXUlJN8M2YMfUxNaSUh+SQHnQFWszLtfGxME2/3whJr+j4t09T2nbHE8jO1vRiSRHtAMGIZBi2M8HhO2aNGskGVYOy8i2VCXQ+bLvsJGNYfci1929OIZeQ+qG/UREjE2QcvlsIKA0cGMjrBFFjt1ZGx3EcUww/Gt2w7Z2+T890Z5/seZQJmhcjjHBMSVuW6o3GepW+bBsHqfo/pbYc5hMkGrzpG6VX3YPWWyTl24e4IVfi2axRYZVBm+h+NcKxGHdhZtm9n5VX3EOHKBo8rGVByIt5UUFdzKDbvXkIomzvCKfE2PsQzRDpYNh1lfT61TcEhwq3lItniHSX0FGMIKAKtxWveecueAbVRmW8DbESUNaopHpe4HbDrhGqU6Q9UMyao309qgyzLTsa+7E8O4LMsm/YPVPOo/QTwI8uyoMbzD04wE7ngS/l8AbBC8wUeghL/J4CPLMt+Od6/U4IWrAlpQ5aoPOSTLHNoIRfGzxfoMd9P0J74F5VIlyzLopok6H/tVqA8kSYfTwAAAABJRU5ErkJggg==",vl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYwAAACsCAYAAABo4pvIAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAzYSURBVHic7d3hcdtIEobhD05gmYGRgbkRLDKwMjiGoBCUgeoi0F0Evo1AdASiIxAcgbkR9P1Aj9mESIm2QMwAeJ8qlihKomeXwHzsHgCsBBTOzGpJK7+pd7/2r3+ceCw69Vh8nkvt/fbW4/H7vaR//H4bfqeNX6uqij8DilPlHgCWxcxW6ibvNFmn+x/DY/Fn0mHyPXVLE7F0ejKOf3/SpRO1B9c55wJNOg6rfrD1/5v7/31pbN97j7WS9lVVnf3vAoZGYGAwPqHW6ia+tbrJce0/Tj+Lk176+k/4/ui2tAnRA/VUaNbqQjXdr8PvtDoOku/xeyoXDIXAwMXMbK1DGHzUcTikiatVN1l9Uy8YmLiG1wuY2r9+0vHrUuvwOux0/PrseF1wKQIDR06EQvw+TTatunexrXgXOwmh+ku31AJc6xAoMUxaESboITAWyoOhVjdhfAr307vQnbpQ2KlrDe2yDBSj8EBJ20S/Qml12B7S/XZp7UIQGLMX3lk2Og6Gnbqd/1u4zySAI+EghRQmH9VtS7W6bWYrKpLFIDBmJFQNf6nbwdOCc6oYvqqrFrY5xof56AXJJ53e3r5J2hIi80FgTFRoIcRwaP32Vb7TUjFgTCdaW426thYhMgMExgT4u7m1Dm2lxn+UqoatCAcUyrffRodqpPEfbcWbm0khMAoUdrBUPTTyUFC3g7UsQmPKvBJpdNzOiq3TLQFSHgKjAKGM/6xDOb+T9Le6d17bXGMDxmJmjY73g1aHRfX/ESD5ERgZhBbTZx2OOCEggOCVAEn7CQEyMgJjJL2Nv9Hxhr/NNS5gKnr7UK0uQNiHMH1mtjKzGzN7MLNnvz34Rg/gHXz/aszs3vetH75/bbyCB8pmZrVvsI/WeTSzWz8/AsCV+L536/vcj7Dv1bnHBvxkZmt/l/MUqogb3uUAefSqjx++X95R3SOLEBK0moDCER4Y3YmQuKfVBEyLh8dd2I8JDwzD+6J3hAQwP2fCo849LkyI9z/TwnVqNxESwIyF8IgL5qxD4jTfYB786KYvZnaTe0wAxudzQTraivVJdE60nDaUpACkn92GuxAed1QdCxSqCY5wAvCm3pFWj8wZM2eHk+p+VhO5xwRgWrzqSCcIPrHWMTMeFGltgmoCwCB6ax33tLMnzM+biG2nOveYAMxPWAulXTU1vUNiuRAZgFGERfJngqNwrE8AKEVoVz0xHxWEoABQqhAczE85ERQApiIEB62qMREUAKaK4BiJH4nwRFAAmDqC40rCeRQEBYBZ8Y5JumZVnXs8k9U7RO0u93gA4Br6cx2nAvyisE5B6gJYBA+OB684uFr2W3rtpzr3eABgbL31jTr3eIoUTq2/yz0WAMjNugsbPpvZbe6xFMOrimfSFACO+fyYzhhvco8nq1BVkKAAcIZXGz/M7D73WEYXqgoWtQHgAr1qo849nlGEvtwm91gAYGoWsbbBEVAAMIxw5YvH2Z23EVpQy+u/AcAV+Hkb9z63rnOPZxBhsWa+5RMAZDKbFlVIvzr3WABgrsbq4ny4xpOm/pqklaQ/q6pqr/HvAAAkn2P/lLSa1FFUIenuco8FAJYmXMiwzj2WVxEWAJBfCI0yF8PN7MYXtze5xwIASxeu+t3kHsuRMLAy0wwAFsjM1kW9kQ9hUeceCwDgWFgq2OQeSPp4wTrrQAAAZ3lo5Ks0QljQhgKAwmVrT1n3iVCEBQBMSAiNcebuUNrwmbMAMDF+ROv11539Ylf5F08AAL8tXH+qvuY/8sgVZwFg+vzkvqdrPfm9mT1e5ckBAKPz604NWwSM1vMCAIxm8HM0wiI3R0QBwMz4kVPDFAS+bjHtD+YAAJzli+DvW3IY5EkAAMV715XGaUUBwHKEOb/+nT/+wudaAMBy+KG2D7/6R42XJ6srjQsAUCCf+y+/kocvdDfXGxIAoETpIysu/eWGhW4AWK6Lz83w6oILCwLAQl1UZaS1i5HGBAAo1JtrGV5dbMYbEgCgRF5lnF6e8EuX/xh5TACAQvUvGfIh/OxW0n/GHhAAoFhbSS/bUp4kzdijAQCU6eS6dvqM7kxjAgAUKhYTqSW1Fu0oAMBLW3UZ0eHMbgDAKUcnc6ejo7huFACgzzPCpK4lVUvaV1W1zzoqAEBxPBt2ZtZ8UNeb2uYdEgCgYK2k9QdJnyR9yzsWAEDBvkr6mFpSbdahAABKtpNXGGtJrF8AAF6zSudhtDlHAQAo2l4hMAAAOGcvaaV0fC0AAOeYmVFhAAAu8kHSPl7vHACAyDOi/aDUmwIA4BUEBgDgLbV0CAwAAM5ZSdp9kJ/Bl3kwAIBy1fI1jO+S/so7FgBAwT5J+pYqjDrvWAAABWvUZUV3QgYfoAQA6IsfspdO3NuKdQwAwEtrSbuqqvYpMP6W9K+MAwIAlOmzuozo+Id8P+cbDwCgRN6OavoPPr94EACwWP1iIl588N+iLQUAOPgs6b8vHjWzmrYUACBJR0el739WGFVVtZJaM9tkGBcAoCCeBbuqqk5fPsrMbqgyAAAXrWv7L21GGREAoDhePDxe8osbqgwAWC4ze7z4qFmqDABYJj+U9u3qIvwBaxkAsDB+3ahfPyfPzB7M7O4qowIAFMfM7szsy+/8Ye3H4NbDDwsAUBIzW79rzve0oTUFADPnC923+Z8EAFAsM7v9pYXuV56o9kUQPi8DAGbm3a2oE0+48dAY5gkBANmFguBm6Ce+N7OnQZ8UAJCNLzncX+vJnzjUFgCmz4uA969bvPIPpPKFRXAAmKiwzLB6+7ff9w9dp+cFALg6v5LHeOfYhVV1jpwCgIkIc3cz9j+8ITQAYBpCWGxyDWAzamkDAPhl4VJPm9wD4RwNAChUWHfe5B6LJNpTAFAib0OVExaJf+hGeQMDgAUKb+TLPKI1pNld7rEAwFKlK40Xv1QQ+mV3uccCAEszmbBIPDSe/FP7rnsmIQAgfbzqg8+9de7x/DK/Vsl0kg4AJih0dq5zIcGx+AdzcP0pALgCn2N/zGaODYvh97SoAGAYs+3ieH/tcbL9NQAoRGhBPcx6PqVFBQC/L1xdYxlzaDiK6nHW6QgAA/F582GWLahLeP9tPos1AHAFYWH7LvdYsvJLilBtAECPVxWPi60qzmFtAwAO/IxtqopzQpo+2tifCAUABVjMEVBDscNnznJpEQCL0FvU3uQez6T4eRvpIlp3BAeAuWKuG0hI3fwfLwgAAwrnVNB+GpIfTcX6BoDJC0HBlS+uieAAMFUhKFinGBPBAWAqCIpChBeC4ABQFIKiUP7CPBEcAHIjKCYitKo4RA3AaPxUgNjx2OQeEy4UguOHB0ede0wA5qd3wt2Dma1zjwm/yV/MdFVc2lUABuFvSh+sw3kUc+Ll4m1Y57ilXQXgV/XXJwiKmeu1q+6pOgC8JlQTqe3U5B4TRmaH61WldhWL5AAk/Wxnx2qCtVB0wjsI1jqABbPuatlfwtpEk3tMKFRY64hHWDW5xwXgesxsHVpOj15Z0G3A5bwkTZcdfiY8gPnwkLin5YTBecuK8AAm7ERI3HPeBK6qFx4caQUUrHeEEyGBfM6FB/1PIA9fh7wJIfFESKA4vuYRF8wf/fs699iAOfNWU9r3LCxc17nHBrzJDhciS4fqplKY6gMYwIlW04NXFuxfV1LlHsBS+BrHWtJnSbWkVtLfknZVVW1zjQuYit4+1Ejain1oVARGBv4OKG74taSd2PiBn3oBsVb3Jmurw36yzzW2pSIwCuABciPpkwgQLNSZgIj7QZtrbOgQGAXyAGkk/aVux1mr23F2kr5J2rLzYMr8iKVah228UVc97CR9VbeNU0EUhsCYgNDCWqvbwRr/0VZdgOzEDoZChe230SEgpMP2uxUtpkkgMCbKDxds1LWxUpjsddgJW1HGY2Qn3tzUOrRYU/XAdjlRBMaMnAkR6bidtZPU8m4O7+VrDisdt06l43Boq6raZRkgBkdgzJyHSOoXx0X1Vl018l2HxUWCBEe8Yqj9tla3DaX7O3XbTmortVQO80ZgLFCYBFKQfAz39+omgr1obS2GL0KndlLaHtJjMRjSGwuqhgUiMHDkREWyCt+3OoRJqkxa8c6yeP66xttH/5pe3/S67tS9tjtJe4IBEYGBi4UwWek4TFLF0uplhbIPj+9peQ0vhMEqfP0Uvq91/Lq0IhTwGwgMDKb3Lnalw7vY9H0tDw4dqhPpUK1IIVy0wIDxduGpWy3pD70MhpWO/1/uJP2jEA5UfxgKgYFRhQmx1vGk99F/JT6WbvverfXf3aubHJM23E+/27//wqUT6htXPk1jTeoz9//Q6UCIf9/q5X/zd/WqNXGQAkZGYKB4YaLuf43300QsvZy8+9+/9fhrzoVP+8pjMdjiY0eBRiWA0v0fPGR4m68wwtkAAAAASUVORK5CYII=";class rr extends we.CSS2DObject{constructor(e,t){const i=document.createElement("div");super(i),this.props=e,this.amr=t,this._direction=1,this._controllingRotate=!1,this._controlling=!1,this._startAt=0,this._looper=0,this._initial=0,this._canRotate=!1,this._emitter=new xt,this.addListener=this._emitter.addListener.bind(this._emitter),this.removeListener=this._emitter.removeListener.bind(this._emitter),this._update=()=>{if(this._looper=requestAnimationFrame(this._update),this._controlling){let c=(Date.now()-this._startAt)/200;c>4&&(c=4);let u=this._initial+.005*c*this._direction;if(u>this.props.max||u<this.props.min){this.mechanism&&(u<this.props.min?(this.mechanism.position.setZ(this.props.min),this._emitter.emit("change",this.props.min)):u>this.props.max&&(this.mechanism.position.setZ(this.props.max),this._emitter.emit("change",this.props.max)));return}if(this._initial=u,!this.mechanism)return;this.mechanism.position.setZ(u),this._emitter.emit("change",u)}};const s=xs();e.userData&&e.userData.target&&(this.name=e.userData.target.name,t.traverse(c=>{c.name===e.userData.target.name&&(this.mechanism=c)})),i.style.fontSize="30px",i.style.color="#0066FF",i.style.cursor="pointer",i.style.pointerEvents="auto";const a=document.createElement("div");a.style.position="absolute",a.style.left="0",a.style.transform="translateX(-50%) rotate(-180deg)",a.style.marginBottom="5px",a.style.width=a.style.height=s?"34px":"44px",a.style.background=`url(${sr}) center no-repeat`,a.style.backgroundSize="100% auto",a.setAttribute("data-direction","up"),a.style.transition="all .2s";const o=document.createElement("div");if(o.style.position="absolute",o.style.left="0",o.style.transform="translateX(-50%)",a.style.bottom=o.style.top="8px",o.style.width=o.style.height=a.style.width,o.style.background=`url(${sr}) center no-repeat`,o.style.backgroundSize="100% auto",o.style.transition="all .2s",o.setAttribute("data-direction","down"),Array.from([a,o]).forEach(c=>{s||c.addEventListener("mousemove",()=>{c.style.filter="invert(100%)"}),c.addEventListener("mouseleave",()=>{c.style.filter=""}),c.addEventListener("pointerdown",()=>{this.mechanism&&(c.style.filter="invert(100%)",this._controlling=!0,this._startAt=Date.now(),this._initial=this.mechanism.position.z,this._direction=c.getAttribute("data-direction")==="up"?1:-1,this._update())}),c.addEventListener("pointerup",()=>{this._controlling=!1,cancelAnimationFrame(this._looper),c.style.filter=""}),c.addEventListener("pointerleave",()=>{this._controlling=!1,cancelAnimationFrame(this._looper),c.style.filter=""})}),e.userData&&(this._canRotate=e.userData.canRotate,this._canRotate)){const{rotateTarget:c,rotateDuration:u,rotateStep:m,rotateMax:d,rotateMin:r}=e.userData;let l;if(c&&(t.traverse(h=>{h.name===c.name&&(l=h)}),l)){const h=document.createElement("div");h.style.background=`url(${vl}) center no-repeat`,h.style.backgroundSize="100% auto",h.style.position="absolute",h.style.top="-50%",h.style.left="-50%",h.style.width=s?"140px":"160px",h.style.height=s?"70px":"80px",h.style.transform="translateX(-50%) translateY(-50%)",i.append(h);const g=document.createElement("div");g.style.background=`url(${gl}) center no-repeat`,g.style.backgroundSize="100% auto",g.style.width=g.style.height=s?"20px":"26px",g.style.position="absolute",g.style.top="0",g.style.transform="translateY(-50%)",g.style.marginBottom="5px",g.setAttribute("data-direction","left"),i.append(g);const _=document.createElement("div");_.style.background=`url(${ml}) center no-repeat`,_.style.backgroundSize="100% auto",_.style.width=_.style.height=s?"20px":"26px",_.style.position="absolute",g.style.left=_.style.right=s?"62px":"69px",_.style.top="0",_.style.transform="translateY(-50%)",_.style.marginBottom="5px",_.setAttribute("data-direction","right"),i.append(_),Array.from([g,_]).forEach(p=>{s||p.addEventListener("mousemove",()=>{p.style.filter="invert(100%)"}),p.addEventListener("mouseleave",()=>{p.style.filter=""}),p.addEventListener("pointerdown",()=>{if(this._timer&&this._timer.isPlaying())return;p.style.filter="invert(100%)",this._controllingRotate=!0,this._startAt=Date.now(),this._direction=p.getAttribute("data-direction")==="left"?1:-1;let v=m/180*Math.PI*this._direction+l.rotation.z;v>d/180*Math.PI?v=d/180*Math.PI:v<r/180*Math.PI&&(v=r/180*Math.PI),this._timer=new di(l.rotation).to({z:v}).duration(u).start(),this._update()}),p.addEventListener("pointerup",()=>{this._controllingRotate=!1,cancelAnimationFrame(this._looper),p.style.filter=""}),p.addEventListener("pointerleave",()=>{this._controllingRotate=!1,cancelAnimationFrame(this._looper),p.style.filter=""})})}}i.append(a,o),this.scale.set(.01,.01,.01),this.matrixAutoUpdate=!1,this.updateMatrix()}hide(){this.element.style.display="none",this.traverse(e=>{e.visible=!1,e instanceof we.CSS2DObject&&(e.element.style.visibility="hidden")}),this.visible=!1}show(){this.element.style.display="auto",this.traverse(e=>{e.visible=!0,e instanceof we.CSS2DObject&&(e.element.style.visibility="visible")}),this.visible=!0}dispose(){this._emitter.removeAllListeners(),cancelAnimationFrame(this._looper),this.element.remove()}}class _l extends In.CSS3DObject{constructor(e){const t=document.createElement("div");super(t),this.props=e,this._scale=.01,this._emitter=new xt,this.addEventListener=this._emitter.on.bind(this._emitter),this.removeEventListener=this._emitter.on.bind(this._emitter),this._mouseStart=new f.Vector2,this._targetSize=new f.Vector2,this._caches=[],this._sizeFlag="width",this._direction=1,this._lines=[],this._pointerdown=u=>{const{pageX:m,pageY:d}=u;this.endNode.setPointerCapture(u.pointerId),this._mouseStart.set(m,d),this._targetSize.setX(parseFloat(this.endNode.parentElement.style.width)),this._targetSize.setY(parseFloat(this.endNode.parentElement.style.height))},this._pointermove=u=>{if(!this._mouseStart.x)return;const{pageX:m,pageY:d}=u;let r=m-this._mouseStart.x,l=r+this._targetSize.x;this._sizeFlag==="height"&&(r=d-this._mouseStart.y,l=r*this._direction+this._targetSize.y);const h=l%10;l=l-h,r=(l-this._targetSize.x)*this._direction,this._sizeFlag==="height"&&(r=(l-this._targetSize.y)*this._direction),this._textNode.innerText=(l/100).toFixed(2)+" m",this.endNode.parentElement.style[this._sizeFlag]=`${l}px`},this._pointercancel=u=>{this.endNode.releasePointerCapture(u.pointerId),this._mouseStart.set(0,0)};const{start:i,end:s}=e,a=s.distanceTo(i);this.props.axios==="z"?this.props.axios="y":this.props.axios==="y"&&(this.props.axios="z"),this.props.axios==="y"&&(this._sizeFlag="height");const o=document.createElement("div");o.style.position="absolute",o.style.left="0",o.style.bottom="0",t.append(o),this._textNode=document.createElement("div"),this._textNode.innerText=a.toFixed(2)+" m",o.append(this._textNode);const c=document.createElement("div");this.endNode=c,c.style.position="absolute",c.style.left="auto",c.style.right="0",c.style.width="4px",c.style.height="4px",c.style.background="#0066FF",c.style.borderRadius="50%",c.style.margin="-2px -2px 0 0",c.style.cursor="pointer",o.append(c),this.scale.set(this._scale,this._scale,this._scale),t.style.fontSize="6px",t.style.color="#fff",o.style[this._sizeFlag]=a*100+"px",o.style.textAlign="center",this._sizeFlag==="height"?(o.style.borderLeft="0.1px dashed #fff",o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="center",o.style.whiteSpace="nowrap",c.style.top="0",c.style.left="0",c.style.right="auto",c.style.margin="-2px 0 0 -2px"):o.style.borderBottom="0.1px dashed #fff",c.addEventListener("pointerdown",this._pointerdown),c.addEventListener("pointermove",this._pointermove),c.addEventListener("pointerup",this._pointercancel),s[this.props.axios]<i[this.props.axios]?this.rotateY(Math.PI):this._direction=-1}_getIndexByAxios(){return this.props.axios==="y"?1:this.props.axios==="z"?2:0}dispose(){this._lines.forEach(e=>e.dispose()),this._emitter.removeAllListeners(),this.endNode.removeEventListener("pointerdown",this._pointerdown),this.endNode.removeEventListener("pointermove",this._pointermove),this.endNode.removeEventListener("pointerup",this._pointercancel),this.element.remove(),this._caches.forEach(e=>e.clear()),this._caches=[]}}class yl extends f.Object3D{constructor(){super(),this._box3=new f.Box3,this._line11=new ci("长:"),this._line12=new ci("宽:"),this._line13=new ci("高:"),this._outline=new Wr(0,0),this._radius=0,this._hasWidthConfig=!1,this._hasLengthConfig=!1,this._hasHeightConfig=!1,this.follow="",this.followOrigin=0,this.followScale=1,this.originOffset=0,this.translateCache=0,this.head=0,this.tail=0,this._change=()=>{if(!this._app)return;const e=this._app.camera;e&&this._outline.change(e.position)},this.add(this._outline,this._line11,this._line12,this._line13)}get hasSizeConfig(){return{length:this._hasLengthConfig,width:this._hasWidthConfig,height:this._hasHeightConfig}}get size(){return this._box3.clone()}get radius(){return this._radius}init(e){this._app=e,this._app.controls.addEventListener("change",this._change)}reset(){this.hide(),this._line11.reset()}generate(e,t=0){e&&(this._object=e),this.update(t)}show(e=!0){const t=[this._line11,this._line12,this._line13];e&&(this.visible=!0,this._outline.visible=!0,this._outline.show(),t.push(this._outline)),t.forEach(i=>{i.traverse(s=>{s.visible=!0,s instanceof we.CSS2DObject&&(s.element.style.visibility="visible")})})}hide(e=!0){const t=[this._line11,this._line12,this._line13];e&&(this.visible=!1,this._outline.visible=!1,this._outline.hide(),t.push(this._outline)),t.forEach(i=>{i.traverse(s=>{s.visible=!1,s instanceof we.CSS2DObject&&(s.element.style.visibility="hidden")})})}destroy(){var e;(e=this._app)==null||e.controls.removeEventListener("change",this._change),this._line11.destroy(),this._line12.destroy(),this._line13.destroy()}update(e=0){if(!this._object)return;const t=this._object,{box:i,maxRadius:s,hasLength:a,hasHeight:o,hasWidth:c}=Ja(t);this.tail=Math.abs(i.min.x),this.head=Math.abs(i.max.x),this._hasWidthConfig=c,this._hasLengthConfig=a,this._hasHeightConfig=o,this._box3.copy(i),this._radius=s,this.follow&&e&&(this.originOffset=(this.followOrigin-e)*this.followScale),this._outline.update(this._radius),this._change();const u=this._box3.min.x,m=this._box3.max.x,d=this._box3.min.z,r=this._box3.max.z,l=this._box3.min.y,h=this._box3.max.y;let g=.2;const _=new f.Vector3(u,h,0),p=new f.Vector3(m,h,0);this._line11.update(_.clone().sub(new f.Vector3(0,-g/1.8,0)),p.clone().sub(new f.Vector3(0,-g/1.8,0)),this._radius);const v=new f.Vector3(m,l,0);this._line12.update(p.clone().add(new f.Vector3(g,0,0)),v.clone().add(new f.Vector3(g,0,0)),this._radius);const y=new f.Vector3(u,h,d),x=new f.Vector3(u,h,r),w=y.clone();w.y-=g/6;const b=x.clone();b.y-=g/6,this._line13.update(w,b,this._radius)}}class nr extends f.Object3D{constructor(e=.6,t=.4,i=.2){super(),this.isGoods=!0,this._generate(e,t,i)}updateSize(e=.1,t=.1,i=.1){this._generate(e,t,i)}clearAll(){Ce(this)}hide(){this.traverse(e=>e.visible=!1)}show(){this.traverse(e=>e.visible=!0)}_generate(e,t,i){this.clearAll();const s=new f.Mesh(new f.BoxGeometry(e,t,i),new f.MeshBasicMaterial({color:new f.Color("#0f5fd5"),transparent:!0,opacity:.4}));s.geometry.translate(0,0,i/2);const a=new f.EdgesGeometry(s.geometry),o=new f.LineDashedMaterial({color:new f.Color("#000"),dashSize:.015,gapSize:.015}),c=new f.LineSegments(a,o);c.computeLineDistances(),this.add(s,c)}}const xl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAALSURBVAiZY2AAAgAABQABYlUyiAAAAABJRU5ErkJggg==";class ts{constructor(e){this._props=e,this.name="",this.transparentTexture=bs.load(xl),this._offscreen=new OffscreenCanvas(0,0),this._defaults={...e},this.target=e.target,this.parent=this.target.parent,this.reset()}get imageSize(){return this._props.imageSize}get size(){return this._props.size}get defaultConfigs(){return{canvasWidth:200,canvasHeight:200,scaleX:1,scaleY:1,x:0,y:0,ox:0,oy:0,url:this._defaults.imageUrl}}clear(){this.change()}change(e,t=new f.Vector2(1,1),i=new f.Vector2){this.imageUrl=e;let s;if(e){const a=new Image;a.crossOrigin="anonymous",a.src=e,a.onload=async()=>{var m;let o=window.devicePixelRatio*2;this._offscreen.width=a.width+o,this._offscreen.height=a.height+o;const c=this._offscreen.getContext("2d");c==null||c.clearRect(0,0,this._offscreen.width,this._offscreen.height),c==null||c.drawImage(a,o/2,o/2,a.width,a.height),s=new f.Texture(this._offscreen),s.minFilter=1003,s.colorSpace=f.SRGBColorSpace,s.wrapS=s.wrapT=f.ClampToEdgeWrapping,s.repeat.set(1/t.x,1/t.y),s.offset.set(i.x,i.y),s.flipY=!1,s.needsUpdate=!0;const u=this._props.target;u.material&&((m=u.material.map)==null||m.dispose(),s?(u.material.map=s,u.material.opacity=1):(u.material.map=this.transparentTexture,u.material.opacity=0))}}else{const a=this._props.target;a.material&&(a.material.map=this.transparentTexture)}}reset(){this._props=this._defaults,this.name=this._props.name,this.imageUrl=this._props.imageUrl,this.target=this._props.target,this.change(this.imageUrl||"")}dispose(){this._offscreen=null}}function Nr(n){return n.type?n.type==="Mesh":n.isMesh}const wl=n=>{const e=window.performance.now(),t=[];n.updateWorldMatrix(!0,!0),n.traverse(a=>{if(Nr(a)||a.geometry){const o=a.geometry.clone();if(o.applyMatrix4(a.matrixWorld),o.morphTargetsRelative=!1,o.morphAttributes)for(const c in o.morphAttributes)delete o.morphAttributes[c];for(const c in o.attributes)c!=="position"&&o.deleteAttribute(c);t.push(o)}});const i=Rn.mergeGeometries(t,!1),s=window.performance.now()-e;return console.log(`Merge object: ${n.name} time: ${s.toFixed(2)} ms`),i},bs=new f.TextureLoader;bs.crossOrigin="anonymous";class Gr extends f.Object3D{constructor(e){super(),this._props=e,this._emitter=new xt,this.addEventListener=this._emitter.addListener.bind(this._emitter),this._container=new f.Group,this.lines=new f.Group,this.sizeBox=new yl,this._goodsSize=new tl(0,0,0),this._slots=[],this._logos=[],this._skins=[],this._levels=new Map,this._bodyOpacity=1,this._masts=new Map,this._liftMaxHeight=0,this._jackMaxHeight=0,this._forkMaxHeight=0,this.controllers=[],this.goods=[],this._breathLights=[],this._shelves=new Map,this._shelfMaxLevel=1,this._url="",this._showController=!0,this._showSlots=!0,this._shapeKeys=new Map,this._shapeKeyTimer=0,this._shapeKeyCache="",this._materialsCache=new Map,this.opacityCache=void 0,this._pointCloudMode=!1,this._pointClouds=[],this._originalMeshes=new Map,this._pointCloudAnimations=[],this.actions=[],this._url=e.url||"",this._url&&this.load(this._url).then(),this.add(this._container,this.lines),this._props.showSizeBox&&this.add(this.sizeBox),this.showController=typeof e.showController=="boolean"?e.showController:!0,this._showSlots=typeof e.showSlots=="boolean"?e.showSlots:!0}get shapeKeys(){return this._shapeKeys}get size(){const e=this.sizeBox.size.getSize(new f.Vector3);return{width:e.z,length:e.x,height:e.y}}get goodsSize(){return this._goodsSize}get showController(){return this._showController}set showController(e){this._showController=e,this.controllers.forEach(t=>e?t.show():t.hide())}get slots(){return this._slots}get logos(){return this._logos}get skins(){return this._skins}get bodyOpacity(){return this._bodyOpacity}get fork(){return this._fork}get forkHeight(){var e;return((e=this._fork)==null?void 0:e.position.z)||0}get liftHeight(){var e;return((e=this._lift)==null?void 0:e.position.z)||0}get jack(){return this._jack}get jackHeight(){var e;return((e=this._jack)==null?void 0:e.position.z)||0}get lift(){return this._lift}set bodyOpacity(e){this._bodyOpacity=e,e<1?this._materialsCache.forEach(t=>{t.mat.transparent=!0,t.mat.opacity=e,t.mat.metalness=0,t.mat.roughness=1,t.mat.color=new f.Color("#3859be"),t.mat.needsUpdate=!0}):this._materialsCache.forEach(t=>{t.mat.transparent=t.transparent,t.mat.opacity=t.opacity,t.mat.metalness=t.metalness,t.mat.roughness=t.roughness,t.mat.color=t.color,t.mat.needsUpdate=!0})}init(e){this._app=e,this.sizeBox.init(e),this.addEventListener("shape-key-changed",(t,i)=>{this._slots.forEach(s=>s.shapeKeyChanged(t,i)),this.sizeBox.follow===t?(this.sizeBox.generate(this._container,i),this.sizeBox.originOffset&&(this._container.traverse(s=>{s instanceof f.Mesh&&!s.userData.isDevice&&!s.userData.isBracket&&s.geometry.translate(this.sizeBox.originOffset-this.sizeBox.translateCache,0,0),s instanceof es&&!s.props.slot.userData.ignoreOriginChanged&&s.parent&&s.parent.position.add(new f.Vector3(this.sizeBox.originOffset-this.sizeBox.translateCache,0,0))}),this.sizeBox.translateCache=this.sizeBox.originOffset,this.sizeBox.generate(this._container))):this.sizeBox.generate(this._container),["width","length","height"].includes(t)&&this._emitter.emit("size-changed",t,i)})}async load(e,t=""){this._url=e,this.name||(this.name=e.substring(e.lastIndexOf("/")+1,e.lastIndexOf("."))),!e.startsWith("blob")&&e.endsWith(".sglb");let i;if(t==="glb"||e.endsWith(".glb"))i=(await yt.loadAsync(e)).scene;else{const a=await new pi({useCache:!0}).loadAsync(e);if(!a.glb)return;i=a.glb}this._generateAmr(i.clone(!0)),i=null,this._emitter.emit("amr-loaded")}changeSkin(e,t){e&&(e.change(t),this._app&&this._app.usePathTracing&&(this._app.sampleCount=0,this._app.usePathTracing&&(this._app.pathTracer.pausePathTracing=!1,this._app.pathTracer.updateMaterials())))}changeLogo(e,t){e.change(t.url,new f.Vector2(t.scaleX,t.scaleY),new f.Vector2(t.ox,t.oy))}setShapeKey(e,t,i=!0){i&&this._shapeKeyTimer&&e===this._shapeKeyCache&&clearTimeout(this._shapeKeyTimer),this._shapeKeyCache=e,this._shapeKeyTimer=window.setTimeout(()=>{this._container.traverse(s=>{if(!Object.keys(s.morphTargetDictionary||{}).includes(e))return;let a=t;s.userData[`origin_${e}`]&&(a-=s.userData[`origin_${e}`]);const o=s.morphTargetDictionary[e];s.morphTargetInfluences&&(s.morphTargetInfluences[o]=a),s instanceof f.Mesh&&s.geometry.translate(0,0,1e-5)}),i&&this._emitter.emit("shape-key-changed",e,t)},100)}_generateAmr(e){this._mergedGeometry=wl(e),e.traverse(t=>{t.userData.isShelf&&(this._shelf=t),t.userData.isFork&&(this._fork=t),t.userData.isMast&&t.userData.mastLevel&&this._masts.set(t.userData.mastLevel,t),t.userData.isJack&&(this._jack=t),t.userData.isLift&&(this._lift=t),Object.keys(t.morphTargetDictionary||{}).forEach(i=>{let s=t.morphTargetInfluences[t.morphTargetDictionary[i]];t.userData[`origin_${i}`]&&(s+=t.userData[`origin_${i}`]),this._shapeKeys.has(i)||this._shapeKeys.set(i,s)})}),e.traverse(t=>{if(t instanceof f.Mesh){if(t.castShadow=!0,t.receiveShadow=!0,t.material)if(Array.isArray(t.material))t.material.forEach(s=>{s.userData.changeColor&&(this.skins.find(a=>a.name===s.userData.name)||this.skins.push(new hs({name:s.userData.name,target:s})))});else{if(t.material.userData.isBreathLight&&t.material.emissiveIntensity){t.material.emissive||(t.material.emissive=new f.Color(16777215)),t.material.emissiveIntensity=2,t.material.toneMapped=!1;const s=1e3,a=new ye.Tween(t.material).to({emissiveIntensity:.2}).easing(ye.Easing.Quintic.InOut).duration(s),o=new ye.Tween(t.material).to({emissiveIntensity:2}).easing(ye.Easing.Quintic.InOut).duration(s);a.onComplete(()=>o.start()),o.onComplete(()=>a.start()),a.start(),this._breathLights.push(a,o)}t.material.userData.changeColor&&(this.skins.find(s=>s.name===t.material.userData.name)||this.skins.push(new hs({name:t.material.userData.name,target:t.material})))}if(t.material)if(Array.isArray(t.material))t.material.forEach(a=>{if(a.userData.isLOGO){t.material.transparent=!0;let o;const c={width:0,height:0};t.material.map&&t.material.map.image&&(c.width=t.material.map.image.width,c.height=t.material.map.image.height,o=$i(t.material.map.image));const u=new ts({name:a.userData.name,target:t,size:tr(t),imageSize:c,imageUrl:o});this._logos.push(u)}a.userData.isTransparent&&(a.transparent=!0),this._materialsCache.set(a.uuid,{opacity:a.opacity,transparent:a.transparent,roughness:a.roughness,metalness:a.metalness,color:a.color,mat:a})});else{const s=t.material;if(s.userData.isLOGO){t.material.transparent=!0;let a;const o={width:0,height:0};t.material.map&&t.material.map.image&&(o.width=t.material.map.image.width,o.height=t.material.map.image.height,a=$i(t.material.map.image));const c=new ts({name:s.userData.name,target:t,size:tr(t),imageSize:o,imageUrl:a});this._logos.push(c)}s.userData.isTransparent&&(s.transparent=!0),this._materialsCache.set(s.uuid,{opacity:s.opacity,transparent:s.transparent,roughness:s.roughness,metalness:s.metalness,color:s.color,mat:s})}}this.generateController(t,e),this.generateDimension(t,e);const i=this.generateSlot(t,e);i&&this._slots.push(i),t.userData.isOrigin&&Object.keys(t.userData).forEach(a=>{if(a.startsWith("follow_")){const o=a.replace("follow_","");this.shapeKeys.has(o)&&(this.sizeBox.follow=o,this.sizeBox.followOrigin=this._shapeKeys.get(o)||0,this.sizeBox.followScale=t.userData[a])}})}),this.slots.forEach(t=>{t.props.mirrorTarget&&(t.mirrorTarget=this.slots.find(i=>i.props.slot.name===t.props.mirrorTarget))}),e.updateMatrixWorld(!0),this._container.add(e),this.sizeBox.generate(e),this.sizeBox.show()}setHeight(e){this.setShapeKey("height",e)}setWeight(e){this.setShapeKey("width",e)}setLength(e){this.setShapeKey("length",e)}limitValue(e){this.name==="SFL-CDD14"&&(e>1.6?this.setShapeKey("mast",1):this.setShapeKey("mast",0)),["SFL-CDD20","SFL-CDD20-Y"].includes(this.name)&&(e>1.6?this.setShapeKey("mast",1):this.setShapeKey("mast",0)),this.name==="SFL-CDD15"&&(e>2.43?this.setShapeKey("mast",1):this.setShapeKey("mast",0)),["SFL-CPD20-Y","SFL-CPD30-Y"].includes(this.name)&&(e>3.5?this.setShapeKey("mast",2):e>3?this.setShapeKey("mast",1):this.setShapeKey("mast",0))}setForkHeight(e){if(this._fork){if(e>this._forkMaxHeight&&(e=this._forkMaxHeight),this._fork.position.z=e,this._masts.size===1){const t=this._masts.get(2),i=(t==null?void 0:t.userData.startHeight)||.1;t&&(t.position.z=(e-i)*.5)}this._emitter.emit("fork-height-change",e)}}setForkMaxHeight(e){this._fork&&(this._forkMaxHeight=e,this.limitValue(e),this.controllers.forEach(t=>{t.name.toLowerCase().includes("fork")&&(t.props.max=e)}),this._fork&&this.forkHeight>this._forkMaxHeight&&this.setForkHeight(e))}setLiftHeight(e){this._lift&&(e>this._liftMaxHeight&&(e=this._liftMaxHeight),this._lift.position.z=e)}getLiftMaxHeight(){return this._liftMaxHeight}setLiftMaxHeight(e){if(!this._lift)return;this._liftMaxHeight=e,this.limitValue(e),this.controllers.forEach(a=>{a.name.toLowerCase().includes("lift")&&(a.props.max=e)}),this.liftHeight>this._liftMaxHeight&&this.setLiftHeight(e);let t=.46;this.levelOffset&&(t=this.levelOffset+.1);let i=e+t;const s=this.getShelfMinHeight()+t||0;i<s&&(i=s),this.setHeight(i)}setJackMaxHeight(e){this._jack&&(this._jackMaxHeight=e,this.limitValue(e),this.controllers.forEach(t=>{t.name.toLowerCase().includes("jack")&&(t.props.max=e)}),this.jackHeight>this._jackMaxHeight&&this.setJackHeight(e))}setJackHeight(e){this._jack&&(e>this._jackMaxHeight&&(e=this._jackMaxHeight),requestAnimationFrame(()=>{this.setShapeKey("jackHeight",e,!1)}),this._jack.position.z=e)}setLevel(e){}setGoodsSize(e){this._goodsSize.length=e.length,this._goodsSize.width=e.width,this._goodsSize.height=e.height,this.setShelfLevel(this._shelfMaxLevel)}getShelfMinHeight(){const e=this.levelOffset,t=this._shelfMaxLevel,i=this._shelves.get(0);return i?i.position.z+e*t+.1:0}getShelfMaxShelfHeight(){const e=this.levelOffset,t=this._shelfMaxLevel,i=this._shelves.get(0);if(i)return i.position.z+e*(t-1)}get levelOffset(){return this._goodsSize.height+.2}setShapeKeyToMesh(e,t,i){if(!Object.keys(e.morphTargetDictionary||{}).includes(t))return;const s=e.morphTargetDictionary[t];e.morphTargetInfluences&&(e.morphTargetInfluences[s]=i),e.geometry.translate(0,0,1e-5)}setShelfLevel(e=3){var s;if(!this._shelf)return;this._shelfMaxLevel=e;const t=this.levelOffset;this._shelves.delete(0),this._shelves.forEach(a=>{Ce(a),a.parent&&a.removeFromParent()}),this.goods=[],this._shelves.clear(),this._shelves.set(0,this._shelf);for(let a=1;a<e;a++){if(!this._shelf)return;this._shelf.traverse(u=>{Nr(u)&&(this.setShapeKeyToMesh(u,"goodsWidth",this._goodsSize.width),this.setShapeKeyToMesh(u,"goodsLength",this._goodsSize.length))});const o=this._shelf.clone(!0);o.position.z+=t*a,this._shelves.set(a,o),(s=this._shelf.parent)==null||s.add(o);let c;if(o.traverse(u=>{u.userData.isShelfContainer&&(c=u)}),(this.shapeKeys.has("goodsLength")||this.shapeKeys.has("goodsWidth"))&&(c==null||c.position.setX((c==null?void 0:c.position.x)-this._goodsSize.length/2)),c){const u=new nr(this._goodsSize.length,this._goodsSize.width,this._goodsSize.height);if(c.add(u),this.goods.push(u),a===1){const m=new nr(this._goodsSize.length,this._goodsSize.width,this._goodsSize.height);m.position.z-=t,c.add(m),this.goods.push(m)}}}const i=this.getShelfMinHeight()||0;this._liftMaxHeight<i&&this.setLiftMaxHeight(i)}generateOuterLine(){this.traverse(e=>{if(e.userData.isOuterObject){const t=this.sizeBox.radius;this._outline?this._outline.update(t):(this._outline=new Wr(t,0),this.add(this._outline))}})}generateController(e,t){if(this.showController){if(e.userData.isForkController&&e.userData.target){const i=e.userData.target.name,{min:s,max:a}=e.userData;let o;if(t.traverse(u=>{u.name===i&&(o=u)}),!o)return;const c=new rr({name:"",target:i,default:0,min:s,max:a},o);e.add(c)}else if(e.userData.isController&&e.userData.target){const i=e.userData.target.name,{min:s,max:a}=e.userData;let o;if(t.traverse(u=>{u.name===i&&(o=u)}),!o)return;const c=new rr({name:"",userData:e.userData,target:e.userData.key,default:0,min:s||0,max:a||1},o);e.add(c),this.controllers.push(c),(o.userData.isFork||o.userData.isLift||o.userData.isJack)&&(this._forkMaxHeight=a||1,this._liftMaxHeight=a||1,this._jackMaxHeight=a||1,c.addListener("change",u=>{this.setForkHeight(u),this.setLiftHeight(u),this.setJackHeight(u)}))}}}generateDimension(e,t){if(e.userData.isDimension){const i=e.userData.divider,s=Ka(e.userData.startOrigin),a=e.userData.axios;let o,c;if(a==="x"?(o=new f.Vector3(e.userData.start-e.position.x,0,0),c=o.clone().setX(e.userData.end-e.position.x)):a==="z"?(o=new f.Vector3(0,e.userData.start-e.position.y,0),c=o.clone().setY(e.userData.end-e.position.y)):(o=new f.Vector3(0,0,e.userData.start-e.position.z),c=o.clone().setZ(e.userData.end-e.position.z)),!Object.keys(e.userData).flatMap(r=>r.startsWith("target")?e.userData[r].name:[]).length)return;const d=new _l({start:o,end:c,startOrigin:s,axios:a,divider:i});e.add(d)}}generateSlot(e,t){var i,s;if(e.userData.isSlot){const a=e.userData.name,o=e.userData.isMirror,c=(i=e.userData.mirrorSlot)==null?void 0:i.name;if(a){const u=e.userData.holeTarget&&e.userData.holeTarget.name;let m;u&&t.traverse(h=>{h.name===u&&(m=h)});const d=new Map;Object.keys(e.userData).forEach(h=>{if(h.startsWith("follow_")){const g=h.split("_")[1];if(g){let _=e.userData[h];d.set(g,{scale:_,origin:this.shapeKeys.get(g)||0})}}});const r=(s=this._app)==null?void 0:s.props.isMobile,l=new es({name:a,follows:d,slot:e,show:this._showSlots,isMirror:o,mirrorTarget:c,isMobile:r});return l.holeTarget=m,l.addEventListener(Z.ON_DROP,h=>{this._app&&this._app.props.useSound&&this._app.sound.play()}),l.addEventListener(Z.ON_BEFORE_SELECTED,h=>{this._slots.forEach(g=>{g.selected&&(g.selected=!1)})}),l.addEventListener(Z.ON_ERROR_STATE_CHANGE,h=>{if(this._app)if(this._app._outlinePassError.selectedObjects=this._app._outlinePassError.selectedObjects.filter(g=>!!g.parent),h){if(l.device){if(this._app._outlinePassError.selectedObjects.find(_=>{var p;return _.parent==((p=l.device)==null?void 0:p.parent)}))return;this._app._outlinePassError.selectedObjects=[l.device,...this._app._outlinePassError.selectedObjects]}}else l.device&&(this._app._outlinePassError.selectedObjects=this._app._outlinePassError.selectedObjects.filter(g=>{var _;return g.parent!=((_=l.device)==null?void 0:_.parent)}))}),l}}}clean(){this._emitter.removeAllListeners(),this.controllers.forEach(e=>e.dispose()),this.controllers=[],Ce(this._container),this._levels.forEach(e=>e.destroy()),this._levels.clear(),this._slots=[],this._logos=[],this._skins=[],this._materialsCache.clear(),this.opacityCache=void 0,this._breathLights.forEach(e=>e.stop()),this._breathLights=[],this.sizeBox.reset()}destroy(){this._pointCloudMode&&this._clearPointClouds(),this.clean(),this.sizeBox.destroy()}setPointCloudMode(e){this._pointCloudMode=e,e?(this.sizeBox.hide(),this.controllers.forEach(t=>t.hide()),this.slots.forEach(t=>t.hide()),this._createPointClouds()):(this.sizeBox.show(),this.slots.forEach(t=>t.hide()),this.controllers.forEach(t=>t.show()),this._clearPointClouds())}_createPointClouds(){this._clearPointClouds();const e=[],t=[],i=.02,s=.05,a=1e7;new f.Vector3;const o=new f.Vector3(1/0,1/0,1/0),c=new f.Vector3(-1/0,-1/0,-1/0);this._container.traverse(d=>{if(d instanceof f.Mesh&&d.geometry&&d.visible){this._originalMeshes.set(d.uuid,{mesh:d,visible:d.visible}),d.visible=!1,d.geometry.computeBoundingBox();const r=d.geometry.boundingBox.clone();r.applyMatrix4(d.matrixWorld),o.min(r.min),c.max(r.max);const l=d.geometry,h=l.attributes.position,g=l.index;if(h){d.updateMatrixWorld();const _=d.matrixWorld;if(g){const p=g.array;for(let v=0;v<p.length;v+=3){const y=p[v],x=p[v+1],w=p[v+2],b=new f.Vector3(h.getX(y),h.getY(y),h.getZ(y)).applyMatrix4(_),T=new f.Vector3(h.getX(x),h.getY(x),h.getZ(x)).applyMatrix4(_),M=new f.Vector3(h.getX(w),h.getY(w),h.getZ(w)).applyMatrix4(_);e.length<a*3&&this._generatePointsOnTriangle(b,T,M,i,s,e,t)}}else for(let p=0;p<h.count;p++){const v=new f.Vector3(h.getX(p),h.getY(p),h.getZ(p)).applyMatrix4(_);e.push(v.x,v.y,v.z);const y=(v.y-o.y)/(c.y-o.y);t.push(0,y*.5,.5+y*.5)}}}});const u=this._removeDuplicatePoints(e,t,i*.5),m=1e5;if(u.positions.length>m*3){const d=m*3/u.positions.length,r=[],l=[];for(let h=0;h<u.positions.length;h+=3)Math.random()<d&&(r.push(u.positions[h],u.positions[h+1],u.positions[h+2]),l.push(u.colors[h],u.colors[h+1],u.colors[h+2]));u.positions=r,u.colors=l}if(u.positions.length>0){const d=o.clone().add(c).multiplyScalar(.5),r=c.clone().sub(o),l=Math.max(r.x,r.y,r.z);if(l===0||!isFinite(l)){console.warn("Point cloud generation failed: invalid model bounds");return}const h=new Float32Array(u.positions.length),g=new Float32Array(u.positions),_=new Float32Array(u.colors.length),p=new Float32Array(u.colors);for(let S=0;S<u.positions.length;S+=3){const C=S/3;g[S],g[S+1],g[S+2];const D=C/(u.positions.length/3)*Math.PI*4,A=Math.random(),P=Math.sqrt(A),R=.05+Math.random()*.1,E=l*2.2*(R+P*(1-R)),F=3,k=C%F*(Math.PI*2/F)+D,H=Math.random()*.4,W=E*(1+H),Q=P,X=.25+P*.2,ve=(Math.random()<.5?-1:1)*Math.random()*l*X*Q,Ie=(Math.random()-.5)*l*.25*Q,ue=l*.3*(1+P*.5),xi=1.2,wi=.85;h[S]=d.x+Math.cos(k)*W*xi+(Math.random()-.5)*ue,h[S+1]=d.y+ve+Ie,h[S+2]=d.z+Math.sin(k)*W*wi+(Math.random()-.5)*ue;const bi=Math.random(),$=Math.random()<.1?1.5:1,Ai=P>.75?.7:P>.5?.4:0,Ye=bi*(1-Ai);Ye<.7?(_[S]=(.1+Math.random()*.2)*$,_[S+1]=(.6+Math.random()*.4)*$,_[S+2]=(.8+Math.random()*.2)*$):Ye<.8?(_[S]=(.6+Math.random()*.4)*$,_[S+1]=(.1+Math.random()*.3)*$,_[S+2]=(.8+Math.random()*.2)*$):Ye<.92?(_[S]=(.8+Math.random()*.2)*$,_[S+1]=(.2+Math.random()*.3)*$,_[S+2]=(.6+Math.random()*.3)*$):(_[S]=(.9+Math.random()*.1)*$,_[S+1]=(.4+Math.random()*.3)*$,_[S+2]=(.1+Math.random()*.2)*$)}const v=new f.BufferGeometry;v.setAttribute("position",new f.Float32BufferAttribute(h,3)),v.setAttribute("color",new f.Float32BufferAttribute(_,3));const y=new f.PointsMaterial({size:.002,color:"#367BF5",vertexColors:!1,opacity:.1,transparent:!1,depthWrite:!1,sizeAttenuation:!0}),x=new f.Points(v,y);this.add(x),this._pointClouds.push(x);const w=v.attributes.position,b=v.attributes.color,T={progress:0};y.opacity=.3;const M=new ye.Tween(T).to({progress:1},600).easing(ye.Easing.Linear.None).onUpdate(()=>{const S=T.progress,C=w.array,I=b.array,D=.6,A=S<D,P=S<.9,R=A?S/D:1,E=R*R,F=E*Math.PI*1.25,k=A?0:(S-D)/(1-D),W=(1-Math.pow(1-k,3))*Math.PI*.75,Q=A?F:F+W;for(let O=0;O<C.length;O+=3){const ve=h[O],Ie=h[O+1],ue=h[O+2],xi=g[O],wi=g[O+1],bi=g[O+2],$=A?E:1,Ai=ve+(xi-ve)*$,Ye=Ie+(wi-Ie)*$,en=ue+(bi-ue)*$,Qe=Ai-d.x,Xe=en-d.z;if(A){const bt=Math.sqrt(Qe*Qe+Xe*Xe),At=Math.atan2(Xe,Qe)+Q;C[O]=d.x+Math.cos(At)*bt,C[O+1]=Ye,C[O+2]=d.z+Math.sin(At)*bt}else{const bt=Math.sqrt(Qe*Qe+Xe*Xe),At=Math.atan2(Xe,Qe)+Q;C[O]=d.x+Math.cos(At)*bt,C[O+1]=Ye,C[O+2]=d.z+Math.sin(At)*bt}P&&(I[O]=_[O]+(p[O]-_[O])*S,I[O+1]=_[O+1]+(p[O+1]-_[O+1])*S,I[O+2]=_[O+2]+(p[O+2]-_[O+2])*S)}let X=.3;A?X=.3+.4*E:X=.7-.1*k,y.opacity=X,w.needsUpdate=!0,P&&(b.needsUpdate=!0)}).onComplete(()=>{const S=this._pointCloudAnimations.indexOf(M);S>-1&&this._pointCloudAnimations.splice(S,1);const C=new _r.LineMaterial({color:"#222",linewidth:.001,opacity:.1,transparent:!0,depthTest:!0,depthWrite:!1}),I=new f.MeshBasicMaterial({colorWrite:!0,color:"#0000ff",depthWrite:!1,depthTest:!0,transparent:!0,opacity:.12}),D=new f.Mesh(this._mergedGeometry,I);D.renderOrder=0,this.lines.add(D);const A=new f.EdgesGeometry(this._mergedGeometry,15),P=new Cn.LineSegmentsGeometry().fromEdgesGeometry(A),R=new Mn.LineSegments2(P,C);R.renderOrder=1,this.slots.forEach(E=>E.show()),x.visible=!1}).start();this._pointCloudAnimations.push(M)}}_generatePointsOnTriangle(e,t,i,s,a,o,c){const u=e.distanceTo(t),m=t.distanceTo(i),d=i.distanceTo(e),r=Math.max(u,m,d),l=Math.max(2,Math.ceil(r/s));if(r>a)for(let h=0;h<=l;h++)for(let g=0;g<=l-h;g++){const _=h/l,p=g/l,v=1-_-p;if(v>=0){const y=new f.Vector3().addScaledVector(e,_).addScaledVector(t,p).addScaledVector(i,v);o.push(y.x,y.y,y.z),c.push(0,y.y/5,1-y.y/1.4)}}else{o.push(e.x,e.y,e.z),o.push(t.x,t.y,t.z),o.push(i.x,i.y,i.z);for(let h=0;h<3;h++)c.push(0,0,0)}}_removeDuplicatePoints(e,t,i){const s=[],a=[],o=new Map;for(let c=0;c<e.length;c+=3){const u=e[c],m=e[c+1],d=e[c+2],r=`${Math.round(u/i)}_${Math.round(m/i)}_${Math.round(d/i)}`;o.has(r)||(o.set(r,!0),s.push(u,m,d),a.push(t[c],t[c+1],t[c+2]))}return{positions:s,colors:a}}_clearPointClouds(){this._pointCloudAnimations.forEach(e=>{e.stop()}),this._pointCloudAnimations=[],this._pointClouds.forEach(e=>{e.geometry.dispose(),e.material instanceof f.PointsMaterial&&e.material.dispose(),e.removeFromParent()}),this._pointClouds=[],this._originalMeshes.forEach(({mesh:e,visible:t})=>{e.visible=t}),this._originalMeshes.clear()}playAction(e,t=!0){}pauseAction(e){console.log(`Pausing action: ${e}`)}}const qr=0,bl=1,Al=2,or=2,Fi=1.25,ar=1,zt=6*4+4+4,_i=65535,Tl=Math.pow(2,-24),Bi=Symbol("SKIP_GENERATION");function Sl(n){return n.index?n.index.count:n.attributes.position.count}function wt(n){return Sl(n)/3}function Ml(n,e=ArrayBuffer){return n>65535?new Uint32Array(new e(4*n)):new Uint16Array(new e(2*n))}function Cl(n,e){if(!n.index){const t=n.attributes.position.count,i=e.useSharedArrayBuffer?SharedArrayBuffer:ArrayBuffer,s=Ml(t,i);n.setIndex(new f.BufferAttribute(s,1));for(let a=0;a<t;a++)s[a]=a}}function jr(n){const e=wt(n),t=n.drawRange,i=t.start/3,s=(t.start+t.count)/3,a=Math.max(0,i),o=Math.min(e,s)-a;return[{offset:Math.floor(a),count:Math.floor(o)}]}function Yr(n){if(!n.groups||!n.groups.length)return jr(n);const e=[],t=new Set,i=n.drawRange,s=i.start/3,a=(i.start+i.count)/3;for(const c of n.groups){const u=c.start/3,m=(c.start+c.count)/3;t.add(Math.max(s,u)),t.add(Math.min(a,m))}const o=Array.from(t.values()).sort((c,u)=>c-u);for(let c=0;c<o.length-1;c++){const u=o[c],m=o[c+1];e.push({offset:Math.floor(u),count:Math.floor(m-u)})}return e}function Pl(n){if(n.groups.length===0)return!1;const e=wt(n),t=Yr(n).sort((a,o)=>a.offset-o.offset),i=t[t.length-1];i.count=Math.min(e-i.offset,i.count);let s=0;return t.forEach(({count:a})=>s+=a),e!==s}function ki(n,e,t,i,s){let a=1/0,o=1/0,c=1/0,u=-1/0,m=-1/0,d=-1/0,r=1/0,l=1/0,h=1/0,g=-1/0,_=-1/0,p=-1/0;for(let v=e*6,y=(e+t)*6;v<y;v+=6){const x=n[v+0],w=n[v+1],b=x-w,T=x+w;b<a&&(a=b),T>u&&(u=T),x<r&&(r=x),x>g&&(g=x);const M=n[v+2],S=n[v+3],C=M-S,I=M+S;C<o&&(o=C),I>m&&(m=I),M<l&&(l=M),M>_&&(_=M);const D=n[v+4],A=n[v+5],P=D-A,R=D+A;P<c&&(c=P),R>d&&(d=R),D<h&&(h=D),D>p&&(p=D)}i[0]=a,i[1]=o,i[2]=c,i[3]=u,i[4]=m,i[5]=d,s[0]=r,s[1]=l,s[2]=h,s[3]=g,s[4]=_,s[5]=p}function Il(n,e=null,t=null,i=null){const s=n.attributes.position,a=n.index?n.index.array:null,o=wt(n),c=s.normalized;let u;e===null?(u=new Float32Array(o*6*4),t=0,i=o):(u=e,t=t||0,i=i||o);const m=s.array,d=s.offset||0;let r=3;s.isInterleavedBufferAttribute&&(r=s.data.stride);const l=["getX","getY","getZ"];for(let h=t;h<t+i;h++){const g=h*3,_=h*6;let p=g+0,v=g+1,y=g+2;a&&(p=a[p],v=a[v],y=a[y]),c||(p=p*r+d,v=v*r+d,y=y*r+d);for(let x=0;x<3;x++){let w,b,T;c?(w=s[l[x]](p),b=s[l[x]](v),T=s[l[x]](y)):(w=m[p+x],b=m[v+x],T=m[y+x]);let M=w;b<M&&(M=b),T<M&&(M=T);let S=w;b>S&&(S=b),T>S&&(S=T);const C=(S-M)/2,I=x*2;u[_+I+0]=M+C,u[_+I+1]=C+(Math.abs(M)+C)*Tl}}return u}function q(n,e,t){return t.min.x=e[n],t.min.y=e[n+1],t.min.z=e[n+2],t.max.x=e[n+3],t.max.y=e[n+4],t.max.z=e[n+5],t}function lr(n){let e=-1,t=-1/0;for(let i=0;i<3;i++){const s=n[i+3]-n[i];s>t&&(t=s,e=i)}return e}function cr(n,e){e.set(n)}function ur(n,e,t){let i,s;for(let a=0;a<3;a++){const o=a+3;i=n[a],s=e[a],t[a]=i<s?i:s,i=n[o],s=e[o],t[o]=i>s?i:s}}function Qt(n,e,t){for(let i=0;i<3;i++){const s=e[n+2*i],a=e[n+2*i+1],o=s-a,c=s+a;o<t[i]&&(t[i]=o),c>t[i+3]&&(t[i+3]=c)}}function Pt(n){const e=n[3]-n[0],t=n[4]-n[1],i=n[5]-n[2];return 2*(e*t+t*i+i*e)}const Ae=32,Rl=(n,e)=>n.candidate-e.candidate,Le=new Array(Ae).fill().map(()=>({count:0,bounds:new Float32Array(6),rightCacheBounds:new Float32Array(6),leftCacheBounds:new Float32Array(6),candidate:0})),Xt=new Float32Array(6);function Dl(n,e,t,i,s,a){let o=-1,c=0;if(a===qr)o=lr(e),o!==-1&&(c=(e[o]+e[o+3])/2);else if(a===bl)o=lr(n),o!==-1&&(c=Ll(t,i,s,o));else if(a===Al){const u=Pt(n);let m=Fi*s;const d=i*6,r=(i+s)*6;for(let l=0;l<3;l++){const h=e[l],p=(e[l+3]-h)/Ae;if(s<Ae/4){const v=[...Le];v.length=s;let y=0;for(let w=d;w<r;w+=6,y++){const b=v[y];b.candidate=t[w+2*l],b.count=0;const{bounds:T,leftCacheBounds:M,rightCacheBounds:S}=b;for(let C=0;C<3;C++)S[C]=1/0,S[C+3]=-1/0,M[C]=1/0,M[C+3]=-1/0,T[C]=1/0,T[C+3]=-1/0;Qt(w,t,T)}v.sort(Rl);let x=s;for(let w=0;w<x;w++){const b=v[w];for(;w+1<x&&v[w+1].candidate===b.candidate;)v.splice(w+1,1),x--}for(let w=d;w<r;w+=6){const b=t[w+2*l];for(let T=0;T<x;T++){const M=v[T];b>=M.candidate?Qt(w,t,M.rightCacheBounds):(Qt(w,t,M.leftCacheBounds),M.count++)}}for(let w=0;w<x;w++){const b=v[w],T=b.count,M=s-b.count,S=b.leftCacheBounds,C=b.rightCacheBounds;let I=0;T!==0&&(I=Pt(S)/u);let D=0;M!==0&&(D=Pt(C)/u);const A=ar+Fi*(I*T+D*M);A<m&&(o=l,m=A,c=b.candidate)}}else{for(let x=0;x<Ae;x++){const w=Le[x];w.count=0,w.candidate=h+p+x*p;const b=w.bounds;for(let T=0;T<3;T++)b[T]=1/0,b[T+3]=-1/0}for(let x=d;x<r;x+=6){let T=~~((t[x+2*l]-h)/p);T>=Ae&&(T=Ae-1);const M=Le[T];M.count++,Qt(x,t,M.bounds)}const v=Le[Ae-1];cr(v.bounds,v.rightCacheBounds);for(let x=Ae-2;x>=0;x--){const w=Le[x],b=Le[x+1];ur(w.bounds,b.rightCacheBounds,w.rightCacheBounds)}let y=0;for(let x=0;x<Ae-1;x++){const w=Le[x],b=w.count,T=w.bounds,S=Le[x+1].rightCacheBounds;b!==0&&(y===0?cr(T,Xt):ur(T,Xt,Xt)),y+=b;let C=0,I=0;y!==0&&(C=Pt(Xt)/u);const D=s-y;D!==0&&(I=Pt(S)/u);const A=ar+Fi*(C*y+I*D);A<m&&(o=l,m=A,c=w.candidate)}}}}else console.warn(`MeshBVH: Invalid build strategy value ${a} used.`);return{axis:o,pos:c}}function Ll(n,e,t,i){let s=0;for(let a=e,o=e+t;a<o;a++)s+=n[a*6+i*2];return s/t}class Oi{constructor(){this.boundingData=new Float32Array(6)}}function El(n,e,t,i,s,a){let o=i,c=i+s-1;const u=a.pos,m=a.axis*2;for(;;){for(;o<=c&&t[o*6+m]<u;)o++;for(;o<=c&&t[c*6+m]>=u;)c--;if(o<c){for(let d=0;d<3;d++){let r=e[o*3+d];e[o*3+d]=e[c*3+d],e[c*3+d]=r}for(let d=0;d<6;d++){let r=t[o*6+d];t[o*6+d]=t[c*6+d],t[c*6+d]=r}o++,c--}else return o}}function Fl(n,e,t,i,s,a){let o=i,c=i+s-1;const u=a.pos,m=a.axis*2;for(;;){for(;o<=c&&t[o*6+m]<u;)o++;for(;o<=c&&t[c*6+m]>=u;)c--;if(o<c){let d=n[o];n[o]=n[c],n[c]=d;for(let r=0;r<6;r++){let l=t[o*6+r];t[o*6+r]=t[c*6+r],t[c*6+r]=l}o++,c--}else return o}}function ie(n,e){return e[n+15]===65535}function ne(n,e){return e[n+6]}function oe(n,e){return e[n+14]}function ae(n){return n+8}function le(n,e){return e[n+6]}function Qr(n,e){return e[n+7]}let Xr,Bt,ui,Zr;const Bl=Math.pow(2,32);function is(n){return"count"in n?1:1+is(n.left)+is(n.right)}function kl(n,e,t){return Xr=new Float32Array(t),Bt=new Uint32Array(t),ui=new Uint16Array(t),Zr=new Uint8Array(t),ss(n,e)}function ss(n,e){const t=n/4,i=n/2,s="count"in e,a=e.boundingData;for(let o=0;o<6;o++)Xr[t+o]=a[o];if(s)if(e.buffer){const o=e.buffer;Zr.set(new Uint8Array(o),n);for(let c=n,u=n+o.byteLength;c<u;c+=zt){const m=c/2;ie(m,ui)||(Bt[c/4+6]+=t)}return n+o.byteLength}else{const o=e.offset,c=e.count;return Bt[t+6]=o,ui[i+14]=c,ui[i+15]=_i,n+zt}else{const o=e.left,c=e.right,u=e.splitAxis;let m;if(m=ss(n+zt,o),m/4>Bl)throw new Error("MeshBVH: Cannot store child pointer greater than 32 bits.");return Bt[t+6]=m/4,m=ss(m,c),Bt[t+7]=u,m}}function Ol(n,e){const t=(n.index?n.index.count:n.attributes.position.count)/3,i=t>2**16,s=i?4:2,a=e?new SharedArrayBuffer(t*s):new ArrayBuffer(t*s),o=i?new Uint32Array(a):new Uint16Array(a);for(let c=0,u=o.length;c<u;c++)o[c]=c;return o}function zl(n,e,t,i,s){const{maxDepth:a,verbose:o,maxLeafTris:c,strategy:u,onProgress:m,indirect:d}=s,r=n._indirectBuffer,l=n.geometry,h=l.index?l.index.array:null,g=d?Fl:El,_=wt(l),p=new Float32Array(6);let v=!1;const y=new Oi;return ki(e,t,i,y.boundingData,p),w(y,t,i,p),y;function x(b){m&&m(b/_)}function w(b,T,M,S=null,C=0){if(!v&&C>=a&&(v=!0,o&&(console.warn(`MeshBVH: Max depth of ${a} reached when generating BVH. Consider increasing maxDepth.`),console.warn(l))),M<=c||C>=a)return x(T+M),b.offset=T,b.count=M,b;const I=Dl(b.boundingData,S,e,T,M,u);if(I.axis===-1)return x(T+M),b.offset=T,b.count=M,b;const D=g(r,h,e,T,M,I);if(D===T||D===T+M)x(T+M),b.offset=T,b.count=M;else{b.splitAxis=I.axis;const A=new Oi,P=T,R=D-T;b.left=A,ki(e,P,R,A.boundingData,p),w(A,P,R,p,C+1);const E=new Oi,F=D,k=M-R;b.right=E,ki(e,F,k,E.boundingData,p),w(E,F,k,p,C+1)}return b}}function Vl(n,e){const t=n.geometry;e.indirect&&(n._indirectBuffer=Ol(t,e.useSharedArrayBuffer),Pl(t)&&!e.verbose&&console.warn('MeshBVH: Provided geometry contains groups that do not fully span the vertex contents while using the "indirect" option. BVH may incorrectly report intersections on unrendered portions of the geometry.')),n._indirectBuffer||Cl(t,e);const i=e.useSharedArrayBuffer?SharedArrayBuffer:ArrayBuffer,s=Il(t),a=e.indirect?jr(t):Yr(t);n._roots=a.map(o=>{const c=zl(n,s,o.offset,o.count,e),u=is(c),m=new i(zt*u);return kl(0,c,m),m})}class Pe{constructor(){this.min=1/0,this.max=-1/0}setFromPointsField(e,t){let i=1/0,s=-1/0;for(let a=0,o=e.length;a<o;a++){const u=e[a][t];i=u<i?u:i,s=u>s?u:s}this.min=i,this.max=s}setFromPoints(e,t){let i=1/0,s=-1/0;for(let a=0,o=t.length;a<o;a++){const c=t[a],u=e.dot(c);i=u<i?u:i,s=u>s?u:s}this.min=i,this.max=s}isSeparated(e){return this.min>e.max||e.min>this.max}}Pe.prototype.setFromBox=function(){const n=new f.Vector3;return function(t,i){const s=i.min,a=i.max;let o=1/0,c=-1/0;for(let u=0;u<=1;u++)for(let m=0;m<=1;m++)for(let d=0;d<=1;d++){n.x=s.x*u+a.x*(1-u),n.y=s.y*m+a.y*(1-m),n.z=s.z*d+a.z*(1-d);const r=t.dot(n);o=Math.min(r,o),c=Math.max(r,c)}this.min=o,this.max=c}}();const Ul=function(){const n=new f.Vector3,e=new f.Vector3,t=new f.Vector3;return function(s,a,o){const c=s.start,u=n,m=a.start,d=e;t.subVectors(c,m),n.subVectors(s.end,s.start),e.subVectors(a.end,a.start);const r=t.dot(d),l=d.dot(u),h=d.dot(d),g=t.dot(u),p=u.dot(u)*h-l*l;let v,y;p!==0?v=(r*l-g*h)/p:v=0,y=(r+v*l)/h,o.x=v,o.y=y}}(),As=function(){const n=new f.Vector2,e=new f.Vector3,t=new f.Vector3;return function(s,a,o,c){Ul(s,a,n);let u=n.x,m=n.y;if(u>=0&&u<=1&&m>=0&&m<=1){s.at(u,o),a.at(m,c);return}else if(u>=0&&u<=1){m<0?a.at(0,c):a.at(1,c),s.closestPointToPoint(c,!0,o);return}else if(m>=0&&m<=1){u<0?s.at(0,o):s.at(1,o),a.closestPointToPoint(o,!0,c);return}else{let d;u<0?d=s.start:d=s.end;let r;m<0?r=a.start:r=a.end;const l=e,h=t;if(s.closestPointToPoint(r,!0,e),a.closestPointToPoint(d,!0,t),l.distanceToSquared(r)<=h.distanceToSquared(d)){o.copy(l),c.copy(r);return}else{o.copy(d),c.copy(h);return}}}}(),Hl=function(){const n=new f.Vector3,e=new f.Vector3,t=new f.Plane,i=new f.Line3;return function(a,o){const{radius:c,center:u}=a,{a:m,b:d,c:r}=o;if(i.start=m,i.end=d,i.closestPointToPoint(u,!0,n).distanceTo(u)<=c||(i.start=m,i.end=r,i.closestPointToPoint(u,!0,n).distanceTo(u)<=c)||(i.start=d,i.end=r,i.closestPointToPoint(u,!0,n).distanceTo(u)<=c))return!0;const _=o.getPlane(t);if(Math.abs(_.distanceToPoint(u))<=c){const v=_.projectPoint(u,e);if(o.containsPoint(v))return!0}return!1}}(),Wl=1e-15;function zi(n){return Math.abs(n)<Wl}class ge extends f.Triangle{constructor(...e){super(...e),this.isExtendedTriangle=!0,this.satAxes=new Array(4).fill().map(()=>new f.Vector3),this.satBounds=new Array(4).fill().map(()=>new Pe),this.points=[this.a,this.b,this.c],this.sphere=new f.Sphere,this.plane=new f.Plane,this.needsUpdate=!0}intersectsSphere(e){return Hl(e,this)}update(){const e=this.a,t=this.b,i=this.c,s=this.points,a=this.satAxes,o=this.satBounds,c=a[0],u=o[0];this.getNormal(c),u.setFromPoints(c,s);const m=a[1],d=o[1];m.subVectors(e,t),d.setFromPoints(m,s);const r=a[2],l=o[2];r.subVectors(t,i),l.setFromPoints(r,s);const h=a[3],g=o[3];h.subVectors(i,e),g.setFromPoints(h,s),this.sphere.setFromPoints(this.points),this.plane.setFromNormalAndCoplanarPoint(c,e),this.needsUpdate=!1}}ge.prototype.closestPointToSegment=function(){const n=new f.Vector3,e=new f.Vector3,t=new f.Line3;return function(s,a=null,o=null){const{start:c,end:u}=s,m=this.points;let d,r=1/0;for(let l=0;l<3;l++){const h=(l+1)%3;t.start.copy(m[l]),t.end.copy(m[h]),As(t,s,n,e),d=n.distanceToSquared(e),d<r&&(r=d,a&&a.copy(n),o&&o.copy(e))}return this.closestPointToPoint(c,n),d=c.distanceToSquared(n),d<r&&(r=d,a&&a.copy(n),o&&o.copy(c)),this.closestPointToPoint(u,n),d=u.distanceToSquared(n),d<r&&(r=d,a&&a.copy(n),o&&o.copy(u)),Math.sqrt(r)}}();ge.prototype.intersectsTriangle=function(){const n=new ge,e=new Array(3),t=new Array(3),i=new Pe,s=new Pe,a=new f.Vector3,o=new f.Vector3,c=new f.Vector3,u=new f.Vector3,m=new f.Vector3,d=new f.Line3,r=new f.Line3,l=new f.Line3,h=new f.Vector3;function g(_,p,v){const y=_.points;let x=0,w=-1;for(let b=0;b<3;b++){const{start:T,end:M}=d;T.copy(y[b]),M.copy(y[(b+1)%3]),d.delta(o);const S=zi(p.distanceToPoint(T));if(zi(p.normal.dot(o))&&S){v.copy(d),x=2;break}const C=p.intersectLine(d,h);if(!C&&S&&h.copy(T),(C||S)&&!zi(h.distanceTo(M))){if(x<=1)(x===1?v.start:v.end).copy(h),S&&(w=x);else if(x>=2){(w===1?v.start:v.end).copy(h),x=2;break}if(x++,x===2&&w===-1)break}}return x}return function(p,v=null,y=!1){this.needsUpdate&&this.update(),p.isExtendedTriangle?p.needsUpdate&&p.update():(n.copy(p),n.update(),p=n);const x=this.plane,w=p.plane;if(Math.abs(x.normal.dot(w.normal))>1-1e-10){const b=this.satBounds,T=this.satAxes;t[0]=p.a,t[1]=p.b,t[2]=p.c;for(let C=0;C<4;C++){const I=b[C],D=T[C];if(i.setFromPoints(D,t),I.isSeparated(i))return!1}const M=p.satBounds,S=p.satAxes;e[0]=this.a,e[1]=this.b,e[2]=this.c;for(let C=0;C<4;C++){const I=M[C],D=S[C];if(i.setFromPoints(D,e),I.isSeparated(i))return!1}for(let C=0;C<4;C++){const I=T[C];for(let D=0;D<4;D++){const A=S[D];if(a.crossVectors(I,A),i.setFromPoints(a,e),s.setFromPoints(a,t),i.isSeparated(s))return!1}}return v&&(y||console.warn("ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0."),v.start.set(0,0,0),v.end.set(0,0,0)),!0}else{const b=g(this,w,r);if(b===1&&p.containsPoint(r.end))return v&&(v.start.copy(r.end),v.end.copy(r.end)),!0;if(b!==2)return!1;const T=g(p,x,l);if(T===1&&this.containsPoint(l.end))return v&&(v.start.copy(l.end),v.end.copy(l.end)),!0;if(T!==2)return!1;if(r.delta(c),l.delta(u),c.dot(u)<0){let P=l.start;l.start=l.end,l.end=P}const M=r.start.dot(c),S=r.end.dot(c),C=l.start.dot(c),I=l.end.dot(c),D=S<C,A=M<I;return M!==I&&C!==S&&D===A?!1:(v&&(m.subVectors(r.start,l.start),m.dot(c)>0?v.start.copy(r.start):v.start.copy(l.start),m.subVectors(r.end,l.end),m.dot(c)<0?v.end.copy(r.end):v.end.copy(l.end)),!0)}}}();ge.prototype.distanceToPoint=function(){const n=new f.Vector3;return function(t){return this.closestPointToPoint(t,n),t.distanceTo(n)}}();ge.prototype.distanceToTriangle=function(){const n=new f.Vector3,e=new f.Vector3,t=["a","b","c"],i=new f.Line3,s=new f.Line3;return function(o,c=null,u=null){const m=c||u?i:null;if(this.intersectsTriangle(o,m))return(c||u)&&(c&&m.getCenter(c),u&&m.getCenter(u)),0;let d=1/0;for(let r=0;r<3;r++){let l;const h=t[r],g=o[h];this.closestPointToPoint(g,n),l=g.distanceToSquared(n),l<d&&(d=l,c&&c.copy(n),u&&u.copy(g));const _=this[h];o.closestPointToPoint(_,n),l=_.distanceToSquared(n),l<d&&(d=l,c&&c.copy(_),u&&u.copy(n))}for(let r=0;r<3;r++){const l=t[r],h=t[(r+1)%3];i.set(this[l],this[h]);for(let g=0;g<3;g++){const _=t[g],p=t[(g+1)%3];s.set(o[_],o[p]),As(i,s,n,e);const v=n.distanceToSquared(e);v<d&&(d=v,c&&c.copy(n),u&&u.copy(e))}}return Math.sqrt(d)}}();class J{constructor(e,t,i){this.isOrientedBox=!0,this.min=new f.Vector3,this.max=new f.Vector3,this.matrix=new f.Matrix4,this.invMatrix=new f.Matrix4,this.points=new Array(8).fill().map(()=>new f.Vector3),this.satAxes=new Array(3).fill().map(()=>new f.Vector3),this.satBounds=new Array(3).fill().map(()=>new Pe),this.alignedSatBounds=new Array(3).fill().map(()=>new Pe),this.needsUpdate=!1,e&&this.min.copy(e),t&&this.max.copy(t),i&&this.matrix.copy(i)}set(e,t,i){this.min.copy(e),this.max.copy(t),this.matrix.copy(i),this.needsUpdate=!0}copy(e){this.min.copy(e.min),this.max.copy(e.max),this.matrix.copy(e.matrix),this.needsUpdate=!0}}J.prototype.update=function(){return function(){const e=this.matrix,t=this.min,i=this.max,s=this.points;for(let m=0;m<=1;m++)for(let d=0;d<=1;d++)for(let r=0;r<=1;r++){const l=1*m|2*d|4*r,h=s[l];h.x=m?i.x:t.x,h.y=d?i.y:t.y,h.z=r?i.z:t.z,h.applyMatrix4(e)}const a=this.satBounds,o=this.satAxes,c=s[0];for(let m=0;m<3;m++){const d=o[m],r=a[m],l=1<<m,h=s[l];d.subVectors(c,h),r.setFromPoints(d,s)}const u=this.alignedSatBounds;u[0].setFromPointsField(s,"x"),u[1].setFromPointsField(s,"y"),u[2].setFromPointsField(s,"z"),this.invMatrix.copy(this.matrix).invert(),this.needsUpdate=!1}}();J.prototype.intersectsBox=function(){const n=new Pe;return function(t){this.needsUpdate&&this.update();const i=t.min,s=t.max,a=this.satBounds,o=this.satAxes,c=this.alignedSatBounds;if(n.min=i.x,n.max=s.x,c[0].isSeparated(n)||(n.min=i.y,n.max=s.y,c[1].isSeparated(n))||(n.min=i.z,n.max=s.z,c[2].isSeparated(n)))return!1;for(let u=0;u<3;u++){const m=o[u],d=a[u];if(n.setFromBox(m,t),d.isSeparated(n))return!1}return!0}}();J.prototype.intersectsTriangle=function(){const n=new ge,e=new Array(3),t=new Pe,i=new Pe,s=new f.Vector3;return function(o){this.needsUpdate&&this.update(),o.isExtendedTriangle?o.needsUpdate&&o.update():(n.copy(o),n.update(),o=n);const c=this.satBounds,u=this.satAxes;e[0]=o.a,e[1]=o.b,e[2]=o.c;for(let l=0;l<3;l++){const h=c[l],g=u[l];if(t.setFromPoints(g,e),h.isSeparated(t))return!1}const m=o.satBounds,d=o.satAxes,r=this.points;for(let l=0;l<3;l++){const h=m[l],g=d[l];if(t.setFromPoints(g,r),h.isSeparated(t))return!1}for(let l=0;l<3;l++){const h=u[l];for(let g=0;g<4;g++){const _=d[g];if(s.crossVectors(h,_),t.setFromPoints(s,e),i.setFromPoints(s,r),t.isSeparated(i))return!1}}return!0}}();J.prototype.closestPointToPoint=function(){return function(e,t){return this.needsUpdate&&this.update(),t.copy(e).applyMatrix4(this.invMatrix).clamp(this.min,this.max).applyMatrix4(this.matrix),t}}();J.prototype.distanceToPoint=function(){const n=new f.Vector3;return function(t){return this.closestPointToPoint(t,n),t.distanceTo(n)}}();J.prototype.distanceToBox=function(){const n=["x","y","z"],e=new Array(12).fill().map(()=>new f.Line3),t=new Array(12).fill().map(()=>new f.Line3),i=new f.Vector3,s=new f.Vector3;return function(o,c=0,u=null,m=null){if(this.needsUpdate&&this.update(),this.intersectsBox(o))return(u||m)&&(o.getCenter(s),this.closestPointToPoint(s,i),o.closestPointToPoint(i,s),u&&u.copy(i),m&&m.copy(s)),0;const d=c*c,r=o.min,l=o.max,h=this.points;let g=1/0;for(let p=0;p<8;p++){const v=h[p];s.copy(v).clamp(r,l);const y=v.distanceToSquared(s);if(y<g&&(g=y,u&&u.copy(v),m&&m.copy(s),y<d))return Math.sqrt(y)}let _=0;for(let p=0;p<3;p++)for(let v=0;v<=1;v++)for(let y=0;y<=1;y++){const x=(p+1)%3,w=(p+2)%3,b=v<<x|y<<w,T=1<<p|v<<x|y<<w,M=h[b],S=h[T];e[_].set(M,S);const I=n[p],D=n[x],A=n[w],P=t[_],R=P.start,E=P.end;R[I]=r[I],R[D]=v?r[D]:l[D],R[A]=y?r[A]:l[D],E[I]=l[I],E[D]=v?r[D]:l[D],E[A]=y?r[A]:l[D],_++}for(let p=0;p<=1;p++)for(let v=0;v<=1;v++)for(let y=0;y<=1;y++){s.x=p?l.x:r.x,s.y=v?l.y:r.y,s.z=y?l.z:r.z,this.closestPointToPoint(s,i);const x=s.distanceToSquared(i);if(x<g&&(g=x,u&&u.copy(i),m&&m.copy(s),x<d))return Math.sqrt(x)}for(let p=0;p<12;p++){const v=e[p];for(let y=0;y<12;y++){const x=t[y];As(v,x,i,s);const w=i.distanceToSquared(s);if(w<g&&(g=w,u&&u.copy(i),m&&m.copy(s),w<d))return Math.sqrt(w)}}return Math.sqrt(g)}}();class Ts{constructor(e){this._getNewPrimitive=e,this._primitives=[]}getPrimitive(){const e=this._primitives;return e.length===0?this._getNewPrimitive():e.pop()}releasePrimitive(e){this._primitives.push(e)}}class Nl extends Ts{constructor(){super(()=>new ge)}}const ce=new Nl;class Gl{constructor(){this.float32Array=null,this.uint16Array=null,this.uint32Array=null;const e=[];let t=null;this.setBuffer=i=>{t&&e.push(t),t=i,this.float32Array=new Float32Array(i),this.uint16Array=new Uint16Array(i),this.uint32Array=new Uint32Array(i)},this.clearBuffer=()=>{t=null,this.float32Array=null,this.uint16Array=null,this.uint32Array=null,e.length!==0&&this.setBuffer(e.pop())}}}const G=new Gl;let Oe,dt;const Je=[],Zt=new Ts(()=>new f.Box3);function ql(n,e,t,i,s,a){Oe=Zt.getPrimitive(),dt=Zt.getPrimitive(),Je.push(Oe,dt),G.setBuffer(n._roots[e]);const o=rs(0,n.geometry,t,i,s,a);G.clearBuffer(),Zt.releasePrimitive(Oe),Zt.releasePrimitive(dt),Je.pop(),Je.pop();const c=Je.length;return c>0&&(dt=Je[c-1],Oe=Je[c-2]),o}function rs(n,e,t,i,s=null,a=0,o=0){const{float32Array:c,uint16Array:u,uint32Array:m}=G;let d=n*2;if(ie(d,u)){const l=ne(n,m),h=oe(d,u);return q(n,c,Oe),i(l,h,!1,o,a+n,Oe)}else{let I=function(A){const{uint16Array:P,uint32Array:R}=G;let E=A*2;for(;!ie(E,P);)A=ae(A),E=A*2;return ne(A,R)},D=function(A){const{uint16Array:P,uint32Array:R}=G;let E=A*2;for(;!ie(E,P);)A=le(A,R),E=A*2;return ne(A,R)+oe(E,P)};const l=ae(n),h=le(n,m);let g=l,_=h,p,v,y,x;if(s&&(y=Oe,x=dt,q(g,c,y),q(_,c,x),p=s(y),v=s(x),v<p)){g=h,_=l;const A=p;p=v,v=A,y=x}y||(y=Oe,q(g,c,y));const w=ie(g*2,u),b=t(y,w,p,o+1,a+g);let T;if(b===or){const A=I(g),R=D(g)-A;T=i(A,R,!0,o+1,a+g,y)}else T=b&&rs(g,e,t,i,s,a,o+1);if(T)return!0;x=dt,q(_,c,x);const M=ie(_*2,u),S=t(x,M,v,o+1,a+_);let C;if(S===or){const A=I(_),R=D(_)-A;C=i(A,R,!0,o+1,a+_,x)}else C=S&&rs(_,e,t,i,s,a,o+1);return!!C}}const It=new f.Vector3,Vi=new f.Vector3;function jl(n,e,t={},i=0,s=1/0){const a=i*i,o=s*s;let c=1/0,u=null;if(n.shapecast({boundsTraverseOrder:d=>(It.copy(e).clamp(d.min,d.max),It.distanceToSquared(e)),intersectsBounds:(d,r,l)=>l<c&&l<o,intersectsTriangle:(d,r)=>{d.closestPointToPoint(e,It);const l=e.distanceToSquared(It);return l<c&&(Vi.copy(It),c=l,u=r),l<a}}),c===1/0)return null;const m=Math.sqrt(c);return t.point?t.point.copy(Vi):t.point=Vi.clone(),t.distance=m,t.faceIndex=u,t}const et=new f.Vector3,it=new f.Vector3,st=new f.Vector3,Kt=new f.Vector2,$t=new f.Vector2,Jt=new f.Vector2,hr=new f.Vector3,fr=new f.Vector3,dr=new f.Vector3,ei=new f.Vector3;function Yl(n,e,t,i,s,a,o,c){let u;if(a===f.BackSide?u=n.intersectTriangle(i,t,e,!0,s):u=n.intersectTriangle(e,t,i,a!==f.DoubleSide,s),u===null)return null;const m=n.origin.distanceTo(s);return m<o||m>c?null:{distance:m,point:s.clone()}}function Ql(n,e,t,i,s,a,o,c,u,m,d){et.fromBufferAttribute(e,a),it.fromBufferAttribute(e,o),st.fromBufferAttribute(e,c);const r=Yl(n,et,it,st,ei,u,m,d);if(r){i&&(Kt.fromBufferAttribute(i,a),$t.fromBufferAttribute(i,o),Jt.fromBufferAttribute(i,c),r.uv=f.Triangle.getInterpolation(ei,et,it,st,Kt,$t,Jt,new f.Vector2)),s&&(Kt.fromBufferAttribute(s,a),$t.fromBufferAttribute(s,o),Jt.fromBufferAttribute(s,c),r.uv1=f.Triangle.getInterpolation(ei,et,it,st,Kt,$t,Jt,new f.Vector2)),t&&(hr.fromBufferAttribute(t,a),fr.fromBufferAttribute(t,o),dr.fromBufferAttribute(t,c),r.normal=f.Triangle.getInterpolation(ei,et,it,st,hr,fr,dr,new f.Vector3),r.normal.dot(n.direction)>0&&r.normal.multiplyScalar(-1));const l={a,b:o,c,normal:new f.Vector3,materialIndex:0};f.Triangle.getNormal(et,it,st,l.normal),r.face=l,r.faceIndex=a}return r}function yi(n,e,t,i,s,a,o){const c=i*3;let u=c+0,m=c+1,d=c+2;const r=n.index;n.index&&(u=r.getX(u),m=r.getX(m),d=r.getX(d));const{position:l,normal:h,uv:g,uv1:_}=n.attributes,p=Ql(t,l,h,g,_,u,m,d,e,a,o);return p?(p.faceIndex=i,s&&s.push(p),p):null}function j(n,e,t,i){const s=n.a,a=n.b,o=n.c;let c=e,u=e+1,m=e+2;t&&(c=t.getX(c),u=t.getX(u),m=t.getX(m)),s.x=i.getX(c),s.y=i.getY(c),s.z=i.getZ(c),a.x=i.getX(u),a.y=i.getY(u),a.z=i.getZ(u),o.x=i.getX(m),o.y=i.getY(m),o.z=i.getZ(m)}function Xl(n,e,t,i,s,a,o,c){const{geometry:u,_indirectBuffer:m}=n;for(let d=i,r=i+s;d<r;d++)yi(u,e,t,d,a,o,c)}function Zl(n,e,t,i,s,a,o){const{geometry:c,_indirectBuffer:u}=n;let m=1/0,d=null;for(let r=i,l=i+s;r<l;r++){let h;h=yi(c,e,t,r,null,a,o),h&&h.distance<m&&(d=h,m=h.distance)}return d}function Kl(n,e,t,i,s,a,o){const{geometry:c}=t,{index:u}=c,m=c.attributes.position;for(let d=n,r=e+n;d<r;d++){let l;if(l=d,j(o,l*3,u,m),o.needsUpdate=!0,i(o,l,s,a))return!0}return!1}function $l(n,e=null){e&&Array.isArray(e)&&(e=new Set(e));const t=n.geometry,i=t.index?t.index.array:null,s=t.attributes.position;let a,o,c,u,m=0;const d=n._roots;for(let l=0,h=d.length;l<h;l++)a=d[l],o=new Uint32Array(a),c=new Uint16Array(a),u=new Float32Array(a),r(0,m),m+=a.byteLength;function r(l,h,g=!1){const _=l*2;if(c[_+15]===_i){const v=o[l+6],y=c[_+14];let x=1/0,w=1/0,b=1/0,T=-1/0,M=-1/0,S=-1/0;for(let C=3*v,I=3*(v+y);C<I;C++){let D=i[C];const A=s.getX(D),P=s.getY(D),R=s.getZ(D);A<x&&(x=A),A>T&&(T=A),P<w&&(w=P),P>M&&(M=P),R<b&&(b=R),R>S&&(S=R)}return u[l+0]!==x||u[l+1]!==w||u[l+2]!==b||u[l+3]!==T||u[l+4]!==M||u[l+5]!==S?(u[l+0]=x,u[l+1]=w,u[l+2]=b,u[l+3]=T,u[l+4]=M,u[l+5]=S,!0):!1}else{const v=l+8,y=o[l+6],x=v+h,w=y+h;let b=g,T=!1,M=!1;e?b||(T=e.has(x),M=e.has(w),b=!T&&!M):(T=!0,M=!0);const S=b||T,C=b||M;let I=!1;S&&(I=r(v,h,b));let D=!1;C&&(D=r(y,h,b));const A=I||D;if(A)for(let P=0;P<3;P++){const R=v+P,E=y+P,F=u[R],k=u[R+3],H=u[E],W=u[E+3];u[l+P]=F<H?F:H,u[l+P+3]=k>W?k:W}return A}}}function ze(n,e,t,i,s){let a,o,c,u,m,d;const r=1/t.direction.x,l=1/t.direction.y,h=1/t.direction.z,g=t.origin.x,_=t.origin.y,p=t.origin.z;let v=e[n],y=e[n+3],x=e[n+1],w=e[n+3+1],b=e[n+2],T=e[n+3+2];return r>=0?(a=(v-g)*r,o=(y-g)*r):(a=(y-g)*r,o=(v-g)*r),l>=0?(c=(x-_)*l,u=(w-_)*l):(c=(w-_)*l,u=(x-_)*l),a>u||c>o||((c>a||isNaN(a))&&(a=c),(u<o||isNaN(o))&&(o=u),h>=0?(m=(b-p)*h,d=(T-p)*h):(m=(T-p)*h,d=(b-p)*h),a>d||m>o)?!1:((m>a||a!==a)&&(a=m),(d<o||o!==o)&&(o=d),a<=s&&o>=i)}function Jl(n,e,t,i,s,a,o,c){const{geometry:u,_indirectBuffer:m}=n;for(let d=i,r=i+s;d<r;d++){let l=m?m[d]:d;yi(u,e,t,l,a,o,c)}}function ec(n,e,t,i,s,a,o){const{geometry:c,_indirectBuffer:u}=n;let m=1/0,d=null;for(let r=i,l=i+s;r<l;r++){let h;h=yi(c,e,t,u?u[r]:r,null,a,o),h&&h.distance<m&&(d=h,m=h.distance)}return d}function tc(n,e,t,i,s,a,o){const{geometry:c}=t,{index:u}=c,m=c.attributes.position;for(let d=n,r=e+n;d<r;d++){let l;if(l=t.resolveTriangleIndex(d),j(o,l*3,u,m),o.needsUpdate=!0,i(o,l,s,a))return!0}return!1}function ic(n,e,t,i,s,a,o){G.setBuffer(n._roots[e]),ns(0,n,t,i,s,a,o),G.clearBuffer()}function ns(n,e,t,i,s,a,o){const{float32Array:c,uint16Array:u,uint32Array:m}=G,d=n*2;if(ie(d,u)){const l=ne(n,m),h=oe(d,u);Xl(e,t,i,l,h,s,a,o)}else{const l=ae(n);ze(l,c,i,a,o)&&ns(l,e,t,i,s,a,o);const h=le(n,m);ze(h,c,i,a,o)&&ns(h,e,t,i,s,a,o)}}const sc=["x","y","z"];function rc(n,e,t,i,s,a){G.setBuffer(n._roots[e]);const o=os(0,n,t,i,s,a);return G.clearBuffer(),o}function os(n,e,t,i,s,a){const{float32Array:o,uint16Array:c,uint32Array:u}=G;let m=n*2;if(ie(m,c)){const r=ne(n,u),l=oe(m,c);return Zl(e,t,i,r,l,s,a)}else{const r=Qr(n,u),l=sc[r],g=i.direction[l]>=0;let _,p;g?(_=ae(n),p=le(n,u)):(_=le(n,u),p=ae(n));const y=ze(_,o,i,s,a)?os(_,e,t,i,s,a):null;if(y){const b=y.point[l];if(g?b<=o[p+r]:b>=o[p+r+3])return y}const w=ze(p,o,i,s,a)?os(p,e,t,i,s,a):null;return y&&w?y.distance<=w.distance?y:w:y||w||null}}const ti=new f.Box3,rt=new ge,nt=new ge,Rt=new f.Matrix4,pr=new J,ii=new J;function nc(n,e,t,i){G.setBuffer(n._roots[e]);const s=as(0,n,t,i);return G.clearBuffer(),s}function as(n,e,t,i,s=null){const{float32Array:a,uint16Array:o,uint32Array:c}=G;let u=n*2;if(s===null&&(t.boundingBox||t.computeBoundingBox(),pr.set(t.boundingBox.min,t.boundingBox.max,i),s=pr),ie(u,o)){const d=e.geometry,r=d.index,l=d.attributes.position,h=t.index,g=t.attributes.position,_=ne(n,c),p=oe(u,o);if(Rt.copy(i).invert(),t.boundsTree)return q(n,a,ii),ii.matrix.copy(Rt),ii.needsUpdate=!0,t.boundsTree.shapecast({intersectsBounds:y=>ii.intersectsBox(y),intersectsTriangle:y=>{y.a.applyMatrix4(i),y.b.applyMatrix4(i),y.c.applyMatrix4(i),y.needsUpdate=!0;for(let x=_*3,w=(p+_)*3;x<w;x+=3)if(j(nt,x,r,l),nt.needsUpdate=!0,y.intersectsTriangle(nt))return!0;return!1}});for(let v=_*3,y=(p+_)*3;v<y;v+=3){j(rt,v,r,l),rt.a.applyMatrix4(Rt),rt.b.applyMatrix4(Rt),rt.c.applyMatrix4(Rt),rt.needsUpdate=!0;for(let x=0,w=h.count;x<w;x+=3)if(j(nt,x,h,g),nt.needsUpdate=!0,rt.intersectsTriangle(nt))return!0}}else{const d=n+8,r=c[n+6];return q(d,a,ti),!!(s.intersectsBox(ti)&&as(d,e,t,i,s)||(q(r,a,ti),s.intersectsBox(ti)&&as(r,e,t,i,s)))}}const si=new f.Matrix4,Ui=new J,Dt=new J,oc=new f.Vector3,ac=new f.Vector3,lc=new f.Vector3,cc=new f.Vector3;function uc(n,e,t,i={},s={},a=0,o=1/0){e.boundingBox||e.computeBoundingBox(),Ui.set(e.boundingBox.min,e.boundingBox.max,t),Ui.needsUpdate=!0;const c=n.geometry,u=c.attributes.position,m=c.index,d=e.attributes.position,r=e.index,l=ce.getPrimitive(),h=ce.getPrimitive();let g=oc,_=ac,p=null,v=null;s&&(p=lc,v=cc);let y=1/0,x=null,w=null;return si.copy(t).invert(),Dt.matrix.copy(si),n.shapecast({boundsTraverseOrder:b=>Ui.distanceToBox(b),intersectsBounds:(b,T,M)=>M<y&&M<o?(T&&(Dt.min.copy(b.min),Dt.max.copy(b.max),Dt.needsUpdate=!0),!0):!1,intersectsRange:(b,T)=>{if(e.boundsTree)return e.boundsTree.shapecast({boundsTraverseOrder:S=>Dt.distanceToBox(S),intersectsBounds:(S,C,I)=>I<y&&I<o,intersectsRange:(S,C)=>{for(let I=S,D=S+C;I<D;I++){j(h,3*I,r,d),h.a.applyMatrix4(t),h.b.applyMatrix4(t),h.c.applyMatrix4(t),h.needsUpdate=!0;for(let A=b,P=b+T;A<P;A++){j(l,3*A,m,u),l.needsUpdate=!0;const R=l.distanceToTriangle(h,g,p);if(R<y&&(_.copy(g),v&&v.copy(p),y=R,x=A,w=I),R<a)return!0}}}});{const M=wt(e);for(let S=0,C=M;S<C;S++){j(h,3*S,r,d),h.a.applyMatrix4(t),h.b.applyMatrix4(t),h.c.applyMatrix4(t),h.needsUpdate=!0;for(let I=b,D=b+T;I<D;I++){j(l,3*I,m,u),l.needsUpdate=!0;const A=l.distanceToTriangle(h,g,p);if(A<y&&(_.copy(g),v&&v.copy(p),y=A,x=I,w=S),A<a)return!0}}}}}),ce.releasePrimitive(l),ce.releasePrimitive(h),y===1/0?null:(i.point?i.point.copy(_):i.point=_.clone(),i.distance=y,i.faceIndex=x,s&&(s.point?s.point.copy(v):s.point=v.clone(),s.point.applyMatrix4(si),_.applyMatrix4(si),s.distance=_.sub(s.point).length(),s.faceIndex=w),i)}function hc(n,e=null){e&&Array.isArray(e)&&(e=new Set(e));const t=n.geometry,i=t.index?t.index.array:null,s=t.attributes.position;let a,o,c,u,m=0;const d=n._roots;for(let l=0,h=d.length;l<h;l++)a=d[l],o=new Uint32Array(a),c=new Uint16Array(a),u=new Float32Array(a),r(0,m),m+=a.byteLength;function r(l,h,g=!1){const _=l*2;if(c[_+15]===_i){const v=o[l+6],y=c[_+14];let x=1/0,w=1/0,b=1/0,T=-1/0,M=-1/0,S=-1/0;for(let C=v,I=v+y;C<I;C++){const D=3*n.resolveTriangleIndex(C);for(let A=0;A<3;A++){let P=D+A;P=i?i[P]:P;const R=s.getX(P),E=s.getY(P),F=s.getZ(P);R<x&&(x=R),R>T&&(T=R),E<w&&(w=E),E>M&&(M=E),F<b&&(b=F),F>S&&(S=F)}}return u[l+0]!==x||u[l+1]!==w||u[l+2]!==b||u[l+3]!==T||u[l+4]!==M||u[l+5]!==S?(u[l+0]=x,u[l+1]=w,u[l+2]=b,u[l+3]=T,u[l+4]=M,u[l+5]=S,!0):!1}else{const v=l+8,y=o[l+6],x=v+h,w=y+h;let b=g,T=!1,M=!1;e?b||(T=e.has(x),M=e.has(w),b=!T&&!M):(T=!0,M=!0);const S=b||T,C=b||M;let I=!1;S&&(I=r(v,h,b));let D=!1;C&&(D=r(y,h,b));const A=I||D;if(A)for(let P=0;P<3;P++){const R=v+P,E=y+P,F=u[R],k=u[R+3],H=u[E],W=u[E+3];u[l+P]=F<H?F:H,u[l+P+3]=k>W?k:W}return A}}}function fc(n,e,t,i,s,a,o){G.setBuffer(n._roots[e]),ls(0,n,t,i,s,a,o),G.clearBuffer()}function ls(n,e,t,i,s,a,o){const{float32Array:c,uint16Array:u,uint32Array:m}=G,d=n*2;if(ie(d,u)){const l=ne(n,m),h=oe(d,u);Jl(e,t,i,l,h,s,a,o)}else{const l=ae(n);ze(l,c,i,a,o)&&ls(l,e,t,i,s,a,o);const h=le(n,m);ze(h,c,i,a,o)&&ls(h,e,t,i,s,a,o)}}const dc=["x","y","z"];function pc(n,e,t,i,s,a){G.setBuffer(n._roots[e]);const o=cs(0,n,t,i,s,a);return G.clearBuffer(),o}function cs(n,e,t,i,s,a){const{float32Array:o,uint16Array:c,uint32Array:u}=G;let m=n*2;if(ie(m,c)){const r=ne(n,u),l=oe(m,c);return ec(e,t,i,r,l,s,a)}else{const r=Qr(n,u),l=dc[r],g=i.direction[l]>=0;let _,p;g?(_=ae(n),p=le(n,u)):(_=le(n,u),p=ae(n));const y=ze(_,o,i,s,a)?cs(_,e,t,i,s,a):null;if(y){const b=y.point[l];if(g?b<=o[p+r]:b>=o[p+r+3])return y}const w=ze(p,o,i,s,a)?cs(p,e,t,i,s,a):null;return y&&w?y.distance<=w.distance?y:w:y||w||null}}const ri=new f.Box3,ot=new ge,at=new ge,Lt=new f.Matrix4,mr=new J,ni=new J;function mc(n,e,t,i){G.setBuffer(n._roots[e]);const s=us(0,n,t,i);return G.clearBuffer(),s}function us(n,e,t,i,s=null){const{float32Array:a,uint16Array:o,uint32Array:c}=G;let u=n*2;if(s===null&&(t.boundingBox||t.computeBoundingBox(),mr.set(t.boundingBox.min,t.boundingBox.max,i),s=mr),ie(u,o)){const d=e.geometry,r=d.index,l=d.attributes.position,h=t.index,g=t.attributes.position,_=ne(n,c),p=oe(u,o);if(Lt.copy(i).invert(),t.boundsTree)return q(n,a,ni),ni.matrix.copy(Lt),ni.needsUpdate=!0,t.boundsTree.shapecast({intersectsBounds:y=>ni.intersectsBox(y),intersectsTriangle:y=>{y.a.applyMatrix4(i),y.b.applyMatrix4(i),y.c.applyMatrix4(i),y.needsUpdate=!0;for(let x=_,w=p+_;x<w;x++)if(j(at,3*e.resolveTriangleIndex(x),r,l),at.needsUpdate=!0,y.intersectsTriangle(at))return!0;return!1}});for(let v=_,y=p+_;v<y;v++){const x=e.resolveTriangleIndex(v);j(ot,3*x,r,l),ot.a.applyMatrix4(Lt),ot.b.applyMatrix4(Lt),ot.c.applyMatrix4(Lt),ot.needsUpdate=!0;for(let w=0,b=h.count;w<b;w+=3)if(j(at,w,h,g),at.needsUpdate=!0,ot.intersectsTriangle(at))return!0}}else{const d=n+8,r=c[n+6];return q(d,a,ri),!!(s.intersectsBox(ri)&&us(d,e,t,i,s)||(q(r,a,ri),s.intersectsBox(ri)&&us(r,e,t,i,s)))}}const oi=new f.Matrix4,Hi=new J,Et=new J,gc=new f.Vector3,vc=new f.Vector3,_c=new f.Vector3,yc=new f.Vector3;function xc(n,e,t,i={},s={},a=0,o=1/0){e.boundingBox||e.computeBoundingBox(),Hi.set(e.boundingBox.min,e.boundingBox.max,t),Hi.needsUpdate=!0;const c=n.geometry,u=c.attributes.position,m=c.index,d=e.attributes.position,r=e.index,l=ce.getPrimitive(),h=ce.getPrimitive();let g=gc,_=vc,p=null,v=null;s&&(p=_c,v=yc);let y=1/0,x=null,w=null;return oi.copy(t).invert(),Et.matrix.copy(oi),n.shapecast({boundsTraverseOrder:b=>Hi.distanceToBox(b),intersectsBounds:(b,T,M)=>M<y&&M<o?(T&&(Et.min.copy(b.min),Et.max.copy(b.max),Et.needsUpdate=!0),!0):!1,intersectsRange:(b,T)=>{if(e.boundsTree){const M=e.boundsTree;return M.shapecast({boundsTraverseOrder:S=>Et.distanceToBox(S),intersectsBounds:(S,C,I)=>I<y&&I<o,intersectsRange:(S,C)=>{for(let I=S,D=S+C;I<D;I++){const A=M.resolveTriangleIndex(I);j(h,3*A,r,d),h.a.applyMatrix4(t),h.b.applyMatrix4(t),h.c.applyMatrix4(t),h.needsUpdate=!0;for(let P=b,R=b+T;P<R;P++){const E=n.resolveTriangleIndex(P);j(l,3*E,m,u),l.needsUpdate=!0;const F=l.distanceToTriangle(h,g,p);if(F<y&&(_.copy(g),v&&v.copy(p),y=F,x=P,w=I),F<a)return!0}}}})}else{const M=wt(e);for(let S=0,C=M;S<C;S++){j(h,3*S,r,d),h.a.applyMatrix4(t),h.b.applyMatrix4(t),h.c.applyMatrix4(t),h.needsUpdate=!0;for(let I=b,D=b+T;I<D;I++){const A=n.resolveTriangleIndex(I);j(l,3*A,m,u),l.needsUpdate=!0;const P=l.distanceToTriangle(h,g,p);if(P<y&&(_.copy(g),v&&v.copy(p),y=P,x=I,w=S),P<a)return!0}}}}}),ce.releasePrimitive(l),ce.releasePrimitive(h),y===1/0?null:(i.point?i.point.copy(_):i.point=_.clone(),i.distance=y,i.faceIndex=x,s&&(s.point?s.point.copy(v):s.point=v.clone(),s.point.applyMatrix4(oi),_.applyMatrix4(oi),s.distance=_.sub(s.point).length(),s.faceIndex=w),i)}function wc(){return typeof SharedArrayBuffer<"u"}const Vt=new G.constructor,mi=new G.constructor,Fe=new Ts(()=>new f.Box3),lt=new f.Box3,ct=new f.Box3,Wi=new f.Box3,Ni=new f.Box3;let Gi=!1;function bc(n,e,t,i){if(Gi)throw new Error("MeshBVH: Recursive calls to bvhcast not supported.");Gi=!0;const s=n._roots,a=e._roots;let o,c=0,u=0;const m=new f.Matrix4().copy(t).invert();for(let d=0,r=s.length;d<r;d++){Vt.setBuffer(s[d]),u=0;const l=Fe.getPrimitive();q(0,Vt.float32Array,l),l.applyMatrix4(m);for(let h=0,g=a.length;h<g&&(mi.setBuffer(a[d]),o=de(0,0,t,m,i,c,u,0,0,l),mi.clearBuffer(),u+=a[h].length,!o);h++);if(Fe.releasePrimitive(l),Vt.clearBuffer(),c+=s[d].length,o)break}return Gi=!1,o}function de(n,e,t,i,s,a=0,o=0,c=0,u=0,m=null,d=!1){let r,l;d?(r=mi,l=Vt):(r=Vt,l=mi);const h=r.float32Array,g=r.uint32Array,_=r.uint16Array,p=l.float32Array,v=l.uint32Array,y=l.uint16Array,x=n*2,w=e*2,b=ie(x,_),T=ie(w,y);let M=!1;if(T&&b)d?M=s(ne(e,v),oe(e*2,y),ne(n,g),oe(n*2,_),u,o+e,c,a+n):M=s(ne(n,g),oe(n*2,_),ne(e,v),oe(e*2,y),c,a+n,u,o+e);else if(T){const S=Fe.getPrimitive();q(e,p,S),S.applyMatrix4(t);const C=ae(n),I=le(n,g);q(C,h,lt),q(I,h,ct);const D=S.intersectsBox(lt),A=S.intersectsBox(ct);M=D&&de(e,C,i,t,s,o,a,u,c+1,S,!d)||A&&de(e,I,i,t,s,o,a,u,c+1,S,!d),Fe.releasePrimitive(S)}else{const S=ae(e),C=le(e,v);q(S,p,Wi),q(C,p,Ni);const I=m.intersectsBox(Wi),D=m.intersectsBox(Ni);if(I&&D)M=de(n,S,t,i,s,a,o,c,u+1,m,d)||de(n,C,t,i,s,a,o,c,u+1,m,d);else if(I)if(b)M=de(n,S,t,i,s,a,o,c,u+1,m,d);else{const A=Fe.getPrimitive();A.copy(Wi).applyMatrix4(t);const P=ae(n),R=le(n,g);q(P,h,lt),q(R,h,ct);const E=A.intersectsBox(lt),F=A.intersectsBox(ct);M=E&&de(S,P,i,t,s,o,a,u,c+1,A,!d)||F&&de(S,R,i,t,s,o,a,u,c+1,A,!d),Fe.releasePrimitive(A)}else if(D)if(b)M=de(n,C,t,i,s,a,o,c,u+1,m,d);else{const A=Fe.getPrimitive();A.copy(Ni).applyMatrix4(t);const P=ae(n),R=le(n,g);q(P,h,lt),q(R,h,ct);const E=A.intersectsBox(lt),F=A.intersectsBox(ct);M=E&&de(C,P,i,t,s,o,a,u,c+1,A,!d)||F&&de(C,R,i,t,s,o,a,u,c+1,A,!d),Fe.releasePrimitive(A)}}return M}const ai=new J,gr=new f.Box3,Ac={strategy:qr,maxDepth:40,maxLeafTris:10,useSharedArrayBuffer:!1,setBoundingBox:!0,onProgress:null,indirect:!1,verbose:!0};class Ss{static serialize(e,t={}){t={cloneBuffers:!0,...t};const i=e.geometry,s=e._roots,a=e._indirectBuffer,o=i.getIndex();let c;return t.cloneBuffers?c={roots:s.map(u=>u.slice()),index:o?o.array.slice():null,indirectBuffer:a?a.slice():null}:c={roots:s,index:o?o.array:null,indirectBuffer:a},c}static deserialize(e,t,i={}){i={setIndex:!0,indirect:!!e.indirectBuffer,...i};const{index:s,roots:a,indirectBuffer:o}=e,c=new Ss(t,{...i,[Bi]:!0});if(c._roots=a,c._indirectBuffer=o||null,i.setIndex){const u=t.getIndex();if(u===null){const m=new f.BufferAttribute(e.index,1,!1);t.setIndex(m)}else u.array!==s&&(u.array.set(s),u.needsUpdate=!0)}return c}get indirect(){return!!this._indirectBuffer}constructor(e,t={}){if(e.isBufferGeometry){if(e.index&&e.index.isInterleavedBufferAttribute)throw new Error("MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.")}else throw new Error("MeshBVH: Only BufferGeometries are supported.");if(t=Object.assign({...Ac,[Bi]:!1},t),t.useSharedArrayBuffer&&!wc())throw new Error("MeshBVH: SharedArrayBuffer is not available.");this.geometry=e,this._roots=null,this._indirectBuffer=null,t[Bi]||(Vl(this,t),!e.boundingBox&&t.setBoundingBox&&(e.boundingBox=this.getBoundingBox(new f.Box3))),this.resolveTriangleIndex=t.indirect?i=>this._indirectBuffer[i]:i=>i}refit(e=null){return(this.indirect?hc:$l)(this,e)}traverse(e,t=0){const i=this._roots[t],s=new Uint32Array(i),a=new Uint16Array(i);o(0);function o(c,u=0){const m=c*2,d=a[m+15]===_i;if(d){const r=s[c+6],l=a[m+14];e(u,d,new Float32Array(i,c*4,6),r,l)}else{const r=c+zt/4,l=s[c+6],h=s[c+7];e(u,d,new Float32Array(i,c*4,6),h)||(o(r,u+1),o(l,u+1))}}}raycast(e,t=f.FrontSide,i=0,s=1/0){const a=this._roots,o=this.geometry,c=[],u=t.isMaterial,m=Array.isArray(t),d=o.groups,r=u?t.side:t,l=this.indirect?fc:ic;for(let h=0,g=a.length;h<g;h++){const _=m?t[d[h].materialIndex].side:r,p=c.length;if(l(this,h,_,e,c,i,s),m){const v=d[h].materialIndex;for(let y=p,x=c.length;y<x;y++)c[y].face.materialIndex=v}}return c}raycastFirst(e,t=f.FrontSide,i=0,s=1/0){const a=this._roots,o=this.geometry,c=t.isMaterial,u=Array.isArray(t);let m=null;const d=o.groups,r=c?t.side:t,l=this.indirect?pc:rc;for(let h=0,g=a.length;h<g;h++){const _=u?t[d[h].materialIndex].side:r,p=l(this,h,_,e,i,s);p!=null&&(m==null||p.distance<m.distance)&&(m=p,u&&(p.face.materialIndex=d[h].materialIndex))}return m}intersectsGeometry(e,t){let i=!1;const s=this._roots,a=this.indirect?mc:nc;for(let o=0,c=s.length;o<c&&(i=a(this,o,e,t),!i);o++);return i}shapecast(e){const t=ce.getPrimitive(),i=this.indirect?tc:Kl;let{boundsTraverseOrder:s,intersectsBounds:a,intersectsRange:o,intersectsTriangle:c}=e;if(o&&c){const r=o;o=(l,h,g,_,p)=>r(l,h,g,_,p)?!0:i(l,h,this,c,g,_,t)}else o||(c?o=(r,l,h,g)=>i(r,l,this,c,h,g,t):o=(r,l,h)=>h);let u=!1,m=0;const d=this._roots;for(let r=0,l=d.length;r<l;r++){const h=d[r];if(u=ql(this,r,a,o,s,m),u)break;m+=h.byteLength}return ce.releasePrimitive(t),u}bvhcast(e,t,i){let{intersectsRanges:s,intersectsTriangles:a}=i;const o=ce.getPrimitive(),c=this.geometry.index,u=this.geometry.attributes.position,m=this.indirect?g=>{const _=this.resolveTriangleIndex(g);j(o,_*3,c,u)}:g=>{j(o,g*3,c,u)},d=ce.getPrimitive(),r=e.geometry.index,l=e.geometry.attributes.position,h=e.indirect?g=>{const _=e.resolveTriangleIndex(g);j(d,_*3,r,l)}:g=>{j(d,g*3,r,l)};if(a){const g=(_,p,v,y,x,w,b,T)=>{for(let M=v,S=v+y;M<S;M++){h(M),d.a.applyMatrix4(t),d.b.applyMatrix4(t),d.c.applyMatrix4(t),d.needsUpdate=!0;for(let C=_,I=_+p;C<I;C++)if(m(C),o.needsUpdate=!0,a(o,d,C,M,x,w,b,T))return!0}return!1};if(s){const _=s;s=function(p,v,y,x,w,b,T,M){return _(p,v,y,x,w,b,T,M)?!0:g(p,v,y,x,w,b,T,M)}}else s=g}return bc(this,e,t,s)}intersectsBox(e,t){return ai.set(e.min,e.max,t),ai.needsUpdate=!0,this.shapecast({intersectsBounds:i=>ai.intersectsBox(i),intersectsTriangle:i=>ai.intersectsTriangle(i)})}intersectsSphere(e){return this.shapecast({intersectsBounds:t=>e.intersectsBox(t),intersectsTriangle:t=>t.intersectsSphere(e)})}closestPointToGeometry(e,t,i={},s={},a=0,o=1/0){return(this.indirect?xc:uc)(this,e,t,i,s,a,o)}closestPointToPoint(e,t={},i=0,s=1/0){return jl(this,e,t,i,s)}getBoundingBox(e){return e.makeEmpty(),this._roots.forEach(i=>{q(0,new Float32Array(i),gr),e.union(gr)}),e}}class Tc{constructor(e){this.name="WorkerBase",this.running=!1,this.worker=e,this.worker.onerror=t=>{throw t.message?new Error(`${this.name}: Could not create Web Worker with error "${t.message}"`):new Error(`${this.name}: Could not create Web Worker.`)}}runTask(){}generate(...e){if(this.running)throw new Error("GenerateMeshBVHWorker: Already running job.");if(this.worker===null)throw new Error("GenerateMeshBVHWorker: Worker has been disposed.");this.running=!0;const t=this.runTask(this.worker,...e);return t.finally(()=>{this.running=!1}),t}dispose(){this.worker.terminate(),this.worker=null}}class Sc extends Tc{constructor(e){const t=new Worker(e||new URL("data:text/javascript;base64,aW1wb3J0IHsKCUJ1ZmZlckdlb21ldHJ5LAoJQnVmZmVyQXR0cmlidXRlLAp9IGZyb20gJ3RocmVlJzsKaW1wb3J0IHsgTWVzaEJWSCB9IGZyb20gJy4uL2NvcmUvTWVzaEJWSC5qcyc7Cgpvbm1lc3NhZ2UgPSAoIHsgZGF0YSB9ICkgPT4gewoKCWxldCBwcmV2VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpOwoJZnVuY3Rpb24gb25Qcm9ncmVzc0NhbGxiYWNrKCBwcm9ncmVzcyApIHsKCgkJLy8gYWNjb3VudCBmb3IgZXJyb3IKCQlwcm9ncmVzcyA9IE1hdGgubWluKCBwcm9ncmVzcywgMSApOwoKCQljb25zdCBjdXJyVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpOwoJCWlmICggY3VyclRpbWUgLSBwcmV2VGltZSA+PSAxMCAmJiBwcm9ncmVzcyAhPT0gMS4wICkgewoKCQkJcG9zdE1lc3NhZ2UoIHsKCgkJCQllcnJvcjogbnVsbCwKCQkJCXNlcmlhbGl6ZWQ6IG51bGwsCgkJCQlwb3NpdGlvbjogbnVsbCwKCQkJCXByb2dyZXNzLAoKCQkJfSApOwoJCQlwcmV2VGltZSA9IGN1cnJUaW1lOwoKCQl9CgoJfQoKCWNvbnN0IHsgaW5kZXgsIHBvc2l0aW9uLCBvcHRpb25zIH0gPSBkYXRhOwoJdHJ5IHsKCgkJY29uc3QgZ2VvbWV0cnkgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKTsKCQlnZW9tZXRyeS5zZXRBdHRyaWJ1dGUoICdwb3NpdGlvbicsIG5ldyBCdWZmZXJBdHRyaWJ1dGUoIHBvc2l0aW9uLCAzLCBmYWxzZSApICk7CgkJaWYgKCBpbmRleCApIHsKCgkJCWdlb21ldHJ5LnNldEluZGV4KCBuZXcgQnVmZmVyQXR0cmlidXRlKCBpbmRleCwgMSwgZmFsc2UgKSApOwoKCQl9CgoJCWlmICggb3B0aW9ucy5pbmNsdWRlZFByb2dyZXNzQ2FsbGJhY2sgKSB7CgoJCQlvcHRpb25zLm9uUHJvZ3Jlc3MgPSBvblByb2dyZXNzQ2FsbGJhY2s7CgoJCX0KCgkJaWYgKCBvcHRpb25zLmdyb3VwcyApIHsKCgkJCWNvbnN0IGdyb3VwcyA9IG9wdGlvbnMuZ3JvdXBzOwoJCQlmb3IgKCBjb25zdCBpIGluIGdyb3VwcyApIHsKCgkJCQljb25zdCBncm91cCA9IGdyb3Vwc1sgaSBdOwoJCQkJZ2VvbWV0cnkuYWRkR3JvdXAoIGdyb3VwLnN0YXJ0LCBncm91cC5jb3VudCwgZ3JvdXAubWF0ZXJpYWxJbmRleCApOwoKCQkJfQoKCQl9CgoJCWNvbnN0IGJ2aCA9IG5ldyBNZXNoQlZIKCBnZW9tZXRyeSwgb3B0aW9ucyApOwoJCWNvbnN0IHNlcmlhbGl6ZWQgPSBNZXNoQlZILnNlcmlhbGl6ZSggYnZoLCB7IGNvcHlJbmRleEJ1ZmZlcjogZmFsc2UgfSApOwoJCWxldCB0b1RyYW5zZmVyID0gWyBwb3NpdGlvbi5idWZmZXIsIC4uLnNlcmlhbGl6ZWQucm9vdHMgXTsKCQlpZiAoIHNlcmlhbGl6ZWQuaW5kZXggKSB7CgoJCQl0b1RyYW5zZmVyLnB1c2goIHNlcmlhbGl6ZWQuaW5kZXguYnVmZmVyICk7CgoJCX0KCgkJdG9UcmFuc2ZlciA9IHRvVHJhbnNmZXIuZmlsdGVyKCB2ID0+ICggdHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyID09PSAndW5kZWZpbmVkJyApIHx8ICEgKCB2IGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXIgKSApOwoKCQlpZiAoIGJ2aC5faW5kaXJlY3RCdWZmZXIgKSB7CgoJCQl0b1RyYW5zZmVyLnB1c2goIHNlcmlhbGl6ZWQuaW5kaXJlY3RCdWZmZXIuYnVmZmVyICk7CgoJCX0KCgkJcG9zdE1lc3NhZ2UoIHsKCgkJCWVycm9yOiBudWxsLAoJCQlzZXJpYWxpemVkLAoJCQlwb3NpdGlvbiwKCQkJcHJvZ3Jlc3M6IDEsCgoJCX0sIHRvVHJhbnNmZXIgKTsKCgl9IGNhdGNoICggZXJyb3IgKSB7CgoJCXBvc3RNZXNzYWdlKCB7CgoJCQllcnJvciwKCQkJc2VyaWFsaXplZDogbnVsbCwKCQkJcG9zaXRpb246IG51bGwsCgkJCXByb2dyZXNzOiAxLAoKCQl9ICk7CgoJfQoKfTsK",typeof document>"u"?require("url").pathToFileURL(__filename).href:vt&&vt.src||new URL("scene-Ibg8IbTP.js",document.baseURI).href),{type:"module"});super(t),this.name="GenerateMeshBVHWorker"}runTask(e,t,i={}){return new Promise((s,a)=>{if(t.getAttribute("position").isInterleavedBufferAttribute||t.index&&t.index.isInterleavedBufferAttribute)throw new Error("GenerateMeshBVHWorker: InterleavedBufferAttribute are not supported for the geometry attributes.");e.onerror=m=>{a(new Error(`GenerateMeshBVHWorker: ${m.message}`))},e.onmessage=m=>{const{data:d}=m;if(d.error)a(new Error(d.error)),e.onmessage=null;else if(d.serialized){const{serialized:r,position:l}=d,h=Ss.deserialize(r,t,{setIndex:!1}),g=Object.assign({setBoundingBox:!0},i);if(t.attributes.position.array=l,r.index)if(t.index)t.index.array=r.index;else{const _=new f.BufferAttribute(r.index,1,!1);t.setIndex(_)}g.setBoundingBox&&(t.boundingBox=h.getBoundingBox(new f.Box3)),i.onProgress&&i.onProgress(d.progress),s(h),e.onmessage=null}else i.onProgress&&i.onProgress(d.progress)};const o=t.index?t.index.array:null,c=t.attributes.position.array,u=[c];o&&u.push(o),e.postMessage({index:o,position:c,options:{...i,onProgress:null,includedProgressCallback:!!i.onProgress,groups:[...t.groups]}},u.map(m=>m.buffer).filter(m=>typeof SharedArrayBuffer>"u"||!(m instanceof SharedArrayBuffer)))})}}class Mc{constructor(e,t){this.lock=!1,this.lockX=!1,this.lockY=!1,this.invRotMat=new f.Matrix4,this.mouse=new f.Vector3,this.rotateStart=new f.Vector2,this.rotateEnd=new f.Vector2,this.rotateDelta=new f.Vector2,this.selectedAxis=null,this.isDragging=!1,this.context=null,this.orbitState=!0,this._animator=0,this._emitter=new xt,this.addListener=this._emitter.addListener.bind(this._emitter),this.removeAllListeners=this._emitter.removeAllListeners.bind(this._emitter),this._text=document.createElement("div"),this._textTimer=0,this._update=()=>{this.lock||(this._textTimer&&(window.clearTimeout(this._textTimer),this._textTimer=0),this._textTimer=window.setTimeout(()=>{this._text.style.opacity="0"},800),this.camera.updateMatrix(),this.invRotMat.extractRotation(this.camera.matrix).invert(),this.axes.forEach(s=>{this.setAxisPosition(s)}),this.axes.sort((s,a)=>s.position.z>a.position.z?1:-1),this.drawLayers(!0),this._text.style.opacity="1",this._text.innerText=this.camera.position.distanceTo(this.orbit.target).toFixed(2)+" m")},this.updateMouseFromEvent=s=>{this.rect=this.domElement.getBoundingClientRect();const a=this.domElement.width/this.domElement.clientWidth,o=this.domElement.height/this.domElement.clientHeight,{left:c,top:u}=this.rect;this.mouse.set((s.clientX-c)*a,(s.clientY-u)*o,0)},this.updateSelectedAxisUnderMouse=()=>{this.selectedAxis=null,this.axes.forEach(s=>{this.mouse.distanceTo(s.position)<s.size&&(this.selectedAxis=s)})},this.onPointerDown=s=>{this.rotateStart.set(s.clientX,s.clientY),this.updateMouseFromEvent(s),this.updateSelectedAxisUnderMouse(),this.orbitState=this.orbit.enabled,this.orbit.enabled=!1,window.addEventListener("pointermove",this.onDrag,!1),window.addEventListener("pointerup",this.onPointerUp,!1)},this.onPointerUp=()=>{this.domElement.style.backgroundColor="#FFF0",setTimeout(()=>this.isDragging=!1,0),this.domElement.classList.remove("dragging"),this.orbit.enabled=this.orbitState,window.removeEventListener("pointermove",this.onDrag,!1),window.removeEventListener("pointerup",this.onPointerUp,!1)},this.onPointerEnter=()=>{this.domElement.style.backgroundColor="#FFF3",this.rect=this.domElement.getBoundingClientRect()},this.onPointerMove=s=>{if(this.lock||this.isDragging)return;const a=this.selectedAxis;s&&(this.updateMouseFromEvent(s),this.updateSelectedAxisUnderMouse()),a!==this.selectedAxis&&this.drawLayers()},this.onDrag=s=>{this.lock||(this.isDragging||this.domElement.classList.add("dragging"),this.isDragging=!0,this.selectedAxis=null,this.rotateEnd.set(s.clientX,s.clientY),this.rotateDelta.subVectors(this.rotateEnd,this.rotateStart).multiplyScalar(.5),this.rotateStart.copy(this.rotateEnd),this.orbit.update())},this.onMouseClick=s=>{if(this.lock||(this.updateMouseFromEvent(s),this.updateSelectedAxisUnderMouse(),this.isDragging||!this.selectedAxis))return;this._animator&&cancelAnimationFrame(this._animator);const a=this.selectedAxis.direction.clone();this.camera.lookAt(0,0,0);const o=this.camera.position.distanceTo(this.orbit.target);a.multiplyScalar(o),this.selectedAxis.axis==="z"?a.setZ(this.orbit.target.z+o):this.selectedAxis.axis==="-z"?a.setZ(this.orbit.target.z-o):a.setZ(this.orbit.target.z);const c=500,u=performance.now(),m=1,d=this.selectedAxis.axis,r=()=>{const h=performance.now()-u,g=Math.min(h/c,m);if(this.camera.position.lerp(a,g),this.orbit.update(),g!==m){this._animator=window.requestAnimationFrame(r);return}else this._animator=0,this.onPointerMove(void 0),this._emitter.emit("axis-select-end",d);this.onPointerMove(void 0)};this._emitter.emit("axis-select-start",d),r()},this.drawCircle=(s,a=10,o="#FF0000")=>{this.context&&(this.context.beginPath(),this.context.rect(s.x-a,s.y-a,a*2,a*2),this.context.fillStyle=o,this.context.fill(),this.context.closePath())},this.drawLine=(s,a,o=1,c="#FF0000")=>{this.context&&(this.context.beginPath(),this.context.moveTo(s.x,s.y),this.context.lineTo(a.x,a.y),this.context.lineWidth=o,this.context.strokeStyle=c,this.context.stroke(),this.context.closePath())},this.drawLayers=(s=!1)=>{this.context&&(s&&this.context.clearRect(0,0,this.domElement.width,this.domElement.height),this.axes.forEach(a=>{const o=this.selectedAxis===a,c=a.position.z>=-.01?a.color[0]:a.color[1];if(a.line&&this.drawLine(this.center,a.position,a.line,c),this.drawCircle(a.position,a.size,o?"#0066ff":c),a.label){const u=a.axis==="-x"?this.options.fontSize-3:this.options.fontSize;this.context.font=[this.options.fontWeight,u+"px",this.options.fontFamily].join(" "),this.context.fillStyle=this.options.fontColor,this.context.textBaseline="middle",this.context.textAlign="center",this.context.fillText(a.label,a.position.x,a.position.y)}}))},this.setAxisPosition=s=>{const a=s.direction.clone().applyMatrix4(this.invRotMat),o=s.size;s.position.set(a.x*(this.center.x-o/2-this.options.padding)+this.center.x,this.center.y-a.y*(this.center.y-o/2-this.options.padding),a.z)};const i={offset:new f.Vector2,size:90,padding:8,bubbleSizePrimary:8,bubbleSizeSecondary:6,lineWidth:2,fontSize:11,fontFamily:"arial",fontWeight:"normal",fontColor:"#fff",className:"orbit-controls-gizmo",colors:{x:["#f35f5f","#902525"],y:["#78da2f","#71ae45"],z:["#1d92fa","#d0d1d1"]}};this.options={...i,...t},this.orbit=e,this.camera=e.object,this.center=new f.Vector3(this.options.size/2,this.options.size/2,0),this.axes=this.createAxes(),this.domElement=this.createCanvas(this.options),this.orbit.addEventListener("change",this._update),this._text.style.cssText=`
3825
+ transition: all 0.8s ease-in-out;
3826
+ color: rgb(68, 78, 105);
3827
+ position: absolute;
3828
+ left: auto;
3829
+ right: ${this.options.offset.x+this.options.size/4}px;
3830
+ top: ${this.options.offset.y+this.options.size/2+2}px;
3831
+ width: ${this.options.size/2}px;
3832
+ margin-right: ${-this.options.size/4}px;
3833
+ font-size: 12px;
3834
+ text-align:center;
3835
+ `}appendTo(e){e.append(this.domElement),e.append(this._text)}createAxes(){const{colors:e,lineWidth:t,bubbleSizePrimary:i,bubbleSizeSecondary:s}=this.options;return[{axis:"x",direction:new f.Vector3(1,0,0),size:i,color:e.x,line:t,label:"前",position:new f.Vector3},{axis:"y",direction:new f.Vector3(0,1,0),size:i,color:e.y,line:t,label:"左",position:new f.Vector3},{axis:"z",direction:new f.Vector3(0,0,1),size:i,color:e.z,line:t,label:"上",position:new f.Vector3},{axis:"-x",direction:new f.Vector3(-1,0,0),size:s,color:e.x,label:"后",position:new f.Vector3},{axis:"-y",direction:new f.Vector3(0,-1,0),size:s,color:e.y,position:new f.Vector3,label:"右"},{axis:"-z",direction:new f.Vector3(0,0,-1),size:i,color:e.z,label:"下",position:new f.Vector3}]}createCanvas(e){const t=document.createElement("canvas");return t.width=e.size,t.height=e.size,t.classList.add(e.className),t.style.cssText=`
3836
+ position: absolute;
3837
+ left: auto;
3838
+ top: ${this.options.offset.y}px;
3839
+ right: ${this.options.offset.x}px;
3840
+ width: ${e.size/2}px;
3841
+ height: ${e.size/2}px;
3842
+ z-index: 1000;
3843
+ background-color: transparent;
3844
+ border-radius: 100%;
3845
+ transition: background-color .15s linear;
3846
+ cursor: pointer;
3847
+ `,t.addEventListener("pointerdown",this.onPointerDown,!1),t.addEventListener("pointerenter",this.onPointerEnter,!1),t.addEventListener("pointermove",this.onPointerMove,!1),t.addEventListener("click",this.onMouseClick,!1),this.context=t.getContext("2d"),t}destroy(){cancelAnimationFrame(this._animator),this.orbit.removeEventListener("change",this._update),this.orbit.enabled=this.orbitState,window.removeEventListener("pointermove",this.onDrag,!1),window.removeEventListener("pointerup",this.onPointerUp,!1),this._emitter.removeAllListeners(),this.domElement.removeEventListener("pointerdown",this.onPointerDown,!1),this.domElement.removeEventListener("pointerenter",this.onPointerEnter,!1),this.domElement.removeEventListener("pointermove",this.onPointerMove,!1),this.domElement.removeEventListener("click",this.onMouseClick,!1),this.domElement.remove(),window.clearTimeout(this._textTimer),this._text.remove()}}class Cc{get isFinished(){return this.params?this.framesDone>=this.params.frames:!0}set visible(e){this.shadowCatcherMesh.visible=e,this.progShadowGrp.visible=e,e||(this.isRendering=!1)}get paused(){return this.params?this.params.paused:!0}set paused(e){this.params&&(this.params.paused=e,e&&(this.isRendering=!1))}constructor(e,t,{resolution:i=1024,shadowMapRes:s=512,shadowBias:a=.001,lightCount:o=8,size:c=4,frames:u=40,lightRadius:m=2,ambientWeight:d=.5,alphaTest:r=.98,paused:l=!1}={}){this.params={enabled:!0,frames:u,lightRadius:m,ambientWeight:d,alphaTest:r,debugHelpers:!1,size:c,paused:l},this.scene=t,this.renderer=e,this.buffer1Active=!1,this.dirLights=[],this.dirLightsHelpers=[],this.clearColor=new f.Color,this.clearAlpha=0,this.progress=0,this.discardMaterial=new Ic,this.lights=[],this.meshes=[],this.objectsToShow=[],this.autoHiddenObjects=[],this.objectsToShowSet=new Set,this.objectsToShowAncestors=new Set,this.framesDone=0,this.fixedCamera=null,this.isRendering=!1,this.isZUp=f.Object3D.DEFAULT_UP.z===1,this.progShadowGrp=new f.Group,this.progShadowGrp.name="progressive_shadow_assets",this.scene.add(this.progShadowGrp),this.lightOrigin=new f.Group,this.lightOrigin.name="light_origin",this.isZUp?this.lightOrigin.position.set(c,c,c*1.5):this.lightOrigin.position.set(c,c,c),this.progShadowGrp.add(this.lightOrigin),this.lightGroup=new f.Group,this.lightGroup.name="all_dir_lights",this.progShadowGrp.add(this.lightGroup);const h=Math.PI;for(let p=0;p<o;p++){const v=new f.DirectionalLight(16777215,h/o);v.name="dir_light_"+p,v.castShadow=!0,v.shadow.bias=a,v.shadow.camera.near=.1,v.shadow.camera.far=50,v.shadow.camera.right=c/2,v.shadow.camera.left=-c/2,v.shadow.camera.top=c/2,v.shadow.camera.bottom=-c/2,v.shadow.mapSize.width=s,v.shadow.mapSize.height=s,this.dirLights.push(v),this.lightGroup.add(v)}const g=/(Android|iPad|iPhone|iPod)/g.test(navigator==null?void 0:navigator.userAgent)?f.HalfFloatType:f.FloatType;this.progressiveLightMap1=new f.WebGLRenderTarget(i,i,{type:g}),this.progressiveLightMap2=new f.WebGLRenderTarget(i,i,{type:g}),this.progressiveLightMap1.texture.colorSpace=f.NoColorSpace,this.progressiveLightMap2.texture.colorSpace=f.NoColorSpace,this.shadowCatcherMaterial=new Pc({map:this.progressiveLightMap2.texture,transparent:!0,opacity:1});const _=new f.PlaneGeometry(c,c);this.isZUp||_.rotateX(-Math.PI/2),this.shadowCatcherMesh=new f.Mesh(_,this.shadowCatcherMaterial),this.isZUp?this.shadowCatcherMesh.position.z=.001:this.shadowCatcherMesh.position.y=.001,this.shadowCatcherMesh.name="shadowCatcherMesh",this.shadowCatcherMesh.receiveShadow=!0,this.progShadowGrp.add(this.shadowCatcherMesh),this.addObjectToShow(this.progShadowGrp),this.addObjectToShow(this.lightGroup),this.addObjectToShow(this.lightOrigin),this.addObjectToShow(this.shadowCatcherMesh),this.rebuildObjectsToShowAncestors(),this.debugHelpersGroup=new f.Group,this.targetMat=new f.MeshLambertMaterial({fog:!1}),this.previousShadowMap={value:this.progressiveLightMap1.texture},this.averagingWindow={value:u},this.targetMat.onBeforeCompile=p=>{p.vertexShader=`varying vec2 vUv;
3848
+ `+p.vertexShader.slice(0,-1)+"vUv = uv; gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }";const v=p.fragmentShader.indexOf("void main() {");p.fragmentShader=`varying vec2 vUv;
3849
+ `+p.fragmentShader.slice(0,v)+`uniform sampler2D previousShadowMap;
3850
+ uniform float averagingWindow;
3851
+ `+p.fragmentShader.slice(v-1,-1)+`
3852
+ vec3 texelOld = texture2D(previousShadowMap, vUv).rgb;
3853
+ gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/ averagingWindow);
3854
+ }`,p.uniforms.previousShadowMap=this.previousShadowMap,p.uniforms.averagingWindow=this.averagingWindow}}renderOnRenderTargets(e){this.prepare(),this.averagingWindow.value=this.params.frames;const t=this.buffer1Active?this.progressiveLightMap1:this.progressiveLightMap2,i=this.buffer1Active?this.progressiveLightMap2:this.progressiveLightMap1;this.renderer.setRenderTarget(t),this.previousShadowMap.value=i.texture,this.buffer1Active=!this.buffer1Active,this.renderer.render(this.scene,e),this.finish(),this.renderer.setRenderTarget(null)}showDebugHelpers(e){if(!this.debugHelpersGroup.children.length){const t=new f.Mesh(new f.PlaneGeometry(2,2),new f.MeshBasicMaterial({map:this.progressiveLightMap1.texture,side:f.DoubleSide}));this.isZUp?t.position.z=this.params.size/2:t.position.y=this.params.size/2;for(const a of this.dirLights){const o=new f.DirectionalLightHelper(a);this.dirLightsHelpers.push(o)}const i=this.isZUp?new f.Vector3(0,0,1):new f.Vector3(0,1,0),s=new f.PlaneHelper(new f.Plane(i,.001),this.params.size,16776960);this.debugHelpersGroup.add(t,s,...this.dirLightsHelpers)}e?(this.progShadowGrp.add(this.debugHelpersGroup),this.dirLightsHelpers.forEach(t=>{t.update()})):this.progShadowGrp.remove(this.debugHelpersGroup)}randomiseLights(){const e=this.lightOrigin.position.length();for(let t=0;t<this.dirLights.length;t++){if(Math.random()>this.params.ambientWeight)this.dirLights[t].position.set(this.lightOrigin.position.x+f.MathUtils.randFloatSpread(this.params.lightRadius),this.lightOrigin.position.y+f.MathUtils.randFloatSpread(this.params.lightRadius),this.lightOrigin.position.z+f.MathUtils.randFloatSpread(this.params.lightRadius));else{const i=Math.acos(2*Math.random()-1)-1.570795,s=2*3.14159*Math.random();this.isZUp?this.dirLights[t].position.set(Math.cos(i)*Math.cos(s)*e,Math.cos(i)*Math.sin(s)*e,Math.abs(Math.sin(i)*e)):this.dirLights[t].position.set(Math.cos(i)*Math.cos(s)*e,Math.abs(Math.cos(i)*Math.sin(s)*e),Math.sin(i)*e)}this.params.debugHelpers&&this.dirLightsHelpers[t].update()}}async recalculate(){this.params.enabled&&(this.clear(),this.framesDone=0,this.fixedCamera=null,this.isRendering=!1)}prepare(){this.lights.forEach(t=>{t.object.intensity=0}),this.meshes.forEach(t=>{t.object.material=this.discardMaterial}),this.autoHiddenObjects.length=0;const e=t=>this.objectsToShowAncestors.has(t);this.scene.traverse(t=>{t!==this.scene&&(this.isExcludedObject(t)||e(t)||t.isLight||t.isCamera||t.visible&&(this.autoHiddenObjects.push({object:t,visible:t.visible}),t.visible=!1))}),this.lightGroup.visible=!0,this.shadowCatcherMesh.material=this.targetMat,this.params.debugHelpers&&this.showDebugHelpers(!1)}finish(){this.lights.forEach(e=>{e.object.intensity=e.intensity}),this.meshes.forEach(e=>{e.object.material=e.material}),this.autoHiddenObjects.forEach(e=>{e.object.visible=e.visible}),this.autoHiddenObjects.length=0,this.lightGroup.visible=!1,this.shadowCatcherMesh.material=this.shadowCatcherMaterial,this.params.debugHelpers&&this.showDebugHelpers(!0)}clear(){this.renderer.getClearColor(this.clearColor),this.clearAlpha=this.renderer.getClearAlpha(),this.renderer.setClearColor("black",1),this.renderer.setRenderTarget(this.progressiveLightMap1),this.renderer.clear(),this.renderer.setRenderTarget(this.progressiveLightMap2),this.renderer.clear(),this.renderer.setRenderTarget(null),this.renderer.setClearColor(this.clearColor,this.clearAlpha),this.shadowCatcherMesh.material.alphaTest=0,this.updateShadowObjectsList()}updateShadowObjectsList(){this.lights.length=0,this.meshes.length=0,this.objectsToShow.length=0,this.objectsToShowSet.clear(),this.addObjectToShow(this.progShadowGrp),this.addObjectToShow(this.lightGroup),this.addObjectToShow(this.lightOrigin),this.addObjectToShow(this.shadowCatcherMesh),this.scene.traverse(e=>{if(e!==this.scene){if(this.isExcludedObject(e)){this.addObjectToShow(e);return}if(e===this.progShadowGrp||e===this.lightGroup||e===this.lightOrigin){this.addObjectToShow(e);return}if(e===this.shadowCatcherMesh){this.addObjectToShow(e);return}if(e.isLight&&e.parent!==this.lightGroup){this.lights.push({object:e,intensity:e.intensity});return}e.isGoods||e.isTransformControls||e.geometry&&e!==this.shadowCatcherMesh&&e.castShadow&&(this.meshes.push({object:e,material:e.material}),this.addObjectToShow(e))}}),this.rebuildObjectsToShowAncestors()}addObjectToShow(e){e&&(this.objectsToShowSet.has(e)||(this.objectsToShow.push({object:e,visible:e.visible}),this.objectsToShowSet.add(e)))}rebuildObjectsToShowAncestors(){this.objectsToShowAncestors.clear();const e=t=>{let i=t;for(;i&&!this.objectsToShowAncestors.has(i);)this.objectsToShowAncestors.add(i),i=i.parent};this.objectsToShow.forEach(({object:t})=>{e(t)})}isExcludedObject(e){const t=e;return!!(t.isCSS2DObject||t.isCSS3DObject||t.isHelper||typeof e.type=="string"&&e.type.endsWith("Helper")||typeof e.name=="string"&&e.name.toLowerCase().includes("helper"))}update(e){!this.params||!this.shadowCatcherMesh||!this.progressiveLightMap1||!this.progressiveLightMap2||!this.params.enabled||this.framesDone>=this.params.frames||this.params.paused||!this.shadowCatcherMesh.visible||!this.progShadowGrp.visible||(this.framesDone===0&&(this.fixedCamera=e.clone(),this.isRendering=!0),this.shadowCatcherMesh.material.alphaTest=f.MathUtils.clamp(f.MathUtils.mapLinear(this.framesDone,2,this.params.frames-1,0,this.params.alphaTest),0,1),this.renderOnRenderTargets(this.fixedCamera||e),this.randomiseLights(),this.progress=f.MathUtils.mapLinear(this.framesDone,0,this.params.frames-1,0,100),this.framesDone++,this.framesDone>=this.params.frames&&(this.fixedCamera=null,this.isRendering=!1))}destroy(){this.scene&&this.progShadowGrp&&this.scene.remove(this.progShadowGrp),this.progressiveLightMap1&&(this.progressiveLightMap1.dispose(),this.progressiveLightMap1=null),this.progressiveLightMap2&&(this.progressiveLightMap2.dispose(),this.progressiveLightMap2=null),this.shadowCatcherMaterial&&(this.shadowCatcherMaterial.dispose(),this.shadowCatcherMaterial=null),this.targetMat&&(this.targetMat.dispose(),this.targetMat=null),this.discardMaterial&&(this.discardMaterial.dispose(),this.discardMaterial=null),this.shadowCatcherMesh&&(this.shadowCatcherMesh.geometry&&this.shadowCatcherMesh.geometry.dispose(),this.shadowCatcherMesh=null),this.dirLights.forEach(e=>{e.parent&&e.parent.remove(e);const t=e;t.dispose&&typeof t.dispose=="function"&&t.dispose()}),this.dirLights=[],this.dirLightsHelpers.forEach(e=>{e.parent&&e.parent.remove(e);const t=e;t.dispose&&typeof t.dispose=="function"&&t.dispose()}),this.dirLightsHelpers=[],this.debugHelpersGroup&&(this.debugHelpersGroup.children.forEach(e=>{e.geometry&&e.geometry.dispose(),e.material&&e.material.dispose()}),this.debugHelpersGroup.clear(),this.debugHelpersGroup=null),this.progShadowGrp&&(this.progShadowGrp.clear(),this.progShadowGrp=null),this.lightGroup&&(this.lightGroup.clear(),this.lightGroup=null),this.lightOrigin&&(this.lightOrigin.clear(),this.lightOrigin=null),this.lights=[],this.meshes=[],this.objectsToShow=[],this.autoHiddenObjects=[],this.objectsToShowSet=new Set,this.objectsToShowAncestors=new Set,this.scene=null,this.renderer=null,this.fixedCamera=null,this.clearColor=null,this.previousShadowMap=null,this.averagingWindow=null,this.params=null}}function Kr(n={},e,t,i=s=>{}){const s=class extends f.ShaderMaterial{constructor(a={}){const o=Object.entries(n);super({uniforms:o.reduce((c,[u,m])=>{const d=f.UniformsUtils.clone({[u]:{value:m}});return{...c,...d}},{}),vertexShader:e,fragmentShader:t}),o.forEach(([c])=>Object.defineProperty(this,c,{get:()=>this.uniforms[c].value,set:u=>this.uniforms[c].value=u})),Object.assign(this,a),i&&i(this)}};return s.key=f.MathUtils.generateUUID(),s}const Pc=Kr({transparent:!0,color:new f.Color(0,0,0),alphaTest:0,opacity:1,map:null,depthWrite:!1,toneMapped:!1,blend:2},`varying vec2 vUv;
3855
+ void main() {
3856
+ gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);
3857
+ vUv = uv;
3858
+ }`,`varying vec2 vUv;
3859
+ uniform sampler2D map;
3860
+ uniform vec3 color;
3861
+ uniform float opacity;
3862
+ uniform float alphaTest;
3863
+ uniform float blend;
3864
+ void main() {
3865
+ vec4 sampledDiffuseColor = texture2D(map, vUv);
3866
+ gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);
3867
+ #include <tonemapping_fragment>
3868
+ #include <colorspace_fragment>
3869
+ }`),Ic=Kr({},"void main() { }","void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); discard; }");class Rc extends we.CSS2DObject{constructor(e){const t=document.createElement("div");super(t),this._controls=e}}const Dc="https://cdn2.seer-group.com/libs/hdr/aristea_wreck_512.hdr",Lc="https://cdn2.seer-group.com/libs/fonts.type.json",Ec=new _n.Font(Lc);class hs{constructor(e){var t;this._props=e,this.name="",this._defaults={color:""},this.color="",this.name=this._props.name,this.color=this._defaults.color="#"+((t=e.target.color)==null?void 0:t.getHexString())}change(e){var t;this.color=e,(t=this._props.target.color)==null||t.set(e)}reset(){this.change(this._defaults.color)}}var $r=(n=>(n[n.DEFAULT=0]="DEFAULT",n[n.CAN_INSTALL=1]="CAN_INSTALL",n))($r||{});const vr=.15;f.Object3D.DEFAULT_UP.set(0,0,1);let ht,hi=0,fs=0;const Fc=()=>{ht=void 0,hi=0,fs=0},Bc=new f.MeshBasicMaterial({colorWrite:!1});class kc{constructor(e){this.props=e,this.stats=new Ot,this.scene=new f.Scene,this.overlayScene=new f.Scene,this.renderer=new f.WebGLRenderer({antialias:!0,alpha:!0,logarithmicDepthBuffer:!0,powerPreference:"high-performance",preserveDrawingBuffer:!0}),this.css2dRenderer=new we.CSS2DRenderer,this.mousePos=new f.Vector2,this.mouseCoord=new f.Vector2,this.offset=new f.Vector2,this.size=new f.Vector2,this.amr=new Gr({showSizeBox:!0,showController:!0}),this._clock=new f.Clock(!0),this._uiHiddenTime=this._clock.getElapsedTime(),this.camera=new f.PerspectiveCamera(39.6,window.innerWidth/window.innerHeight,.1,1e4),this.d=2,this.orthographicCamera=new f.OrthographicCamera(-this.d*(window.innerWidth/window.innerHeight),this.d*(window.innerWidth/window.innerHeight),this.d,-this.d,.1,1e3),this._axisMoving=!1,this._container=new f.Group,this._raycaster=new f.Raycaster,this._selected=[],this._pointerDownTimeout=0,this._dragging=!1,this.maxSample=1024*2,this.sampleCount=0,this._usePathTracing=!1,this._fpsCache=[],this._fpsCacheMax=20,this._emitter=new xt,this.sound=new Za,this._rafId=null,this._destroyed=!1,this._ground=new f.Mesh(new f.PlaneGeometry(100,100),new f.MeshPhysicalMaterial({color:new f.Color("#eee"),metalness:.4,roughness:.1,clearcoat:1,clearcoatRoughness:.1})),this.light=new f.PointLight(16777215,10,30),this._amrRender=new f.WebGLRenderTarget(1024,1024,{format:f.RGBAFormat,type:f.UnsignedByteType,colorSpace:f.SRGBColorSpace,samples:8}),this._pointCloudMode=!1,this._shadowMode=!1,this.addEventListener=this._emitter.on.bind(this._emitter),this.removeEventListener=this._emitter.on.bind(this._emitter),this._showSlots=!0,this._showSize=!0,this._showControls=!0,this._drag=d=>{this._dragging=!0,this._pointermove(d)},this._dragend=d=>{this._dragging=!1},this._pointermove=d=>{if(this._pointerDownTimeout)return clearTimeout(this._pointerDownTimeout),this._pointerDownTimeout=0;let{top:r,left:l}=this.renderer.domElement.getBoundingClientRect();this.offset.set(l,r),this.mousePos.set(d.clientX-l,d.clientY-r),this.mouseCoord.set((d.clientX-l)/this.size.x*2-1,-((d.clientY-r)/this.size.y)*2+1),this._raycaster.setFromCamera(this.mouseCoord,this.camera)},this._pointerdown=d=>{const r=()=>{let l=[...this._outlinePass.selectedObjects];this._outlinePass.selectedObjects=[],this.amr.slots.forEach(_=>_.selected=!1);const g=this._raycaster.intersectObjects(this.amr.slots,!1)[0];g&&this.amr.slots.forEach(_=>{_.traverse(p=>{p==g.object?l!=null&&l.includes(_)?(l=void 0,_.deviceSelected=!1):(this._outlinePass.selectedObjects=[_],_.deviceSelected=!0):_.deviceSelected=!1})}),this._pointerDownTimeout=0};this._pointerDownTimeout=window.setTimeout(r,200)},this._detectTrackpad=()=>{ht||typeof ht<"u"||(hi===0&&(fs=performance.now()),hi++,performance.now()-fs>66&&(hi>5?ht=!0:ht=!1,ht?this.controls.zoomSpeed=.2:this.controls.zoomSpeed=1,setTimeout(Fc,2e3)))},this.debounceForkHeightChange=el(()=>{var d;(d=this._progressShadow)==null||d.recalculate()},300),this.focusSlots=d=>{if(this.amr.slots.forEach(A=>A.focused=!1),!d.length){this.fit();return}const r=d.flatMap(A=>{if(A.focused=!0,!A.parent)return[];const P=new f.Vector3;return A.parent.getWorldPosition(P),[P]});if(!r.length)return;const l=r.reduce((A,P)=>A.add(P),new f.Vector3).multiplyScalar(1/r.length),h=this.controls.target.clone(),g=this.camera.position.clone().sub(h).normalize();let _=0;for(const A of r){const P=A.clone().sub(l),R=P.dot(g),E=Math.sqrt(Math.max(0,P.lengthSq()-R*R));E>_&&(_=E)}_=_*1.2+.45;const p=this.camera.fov*Math.PI/180,v=2*Math.atan(Math.tan(p/2)*this.camera.aspect),y=_/Math.tan(v/2),x=_/Math.tan(p/2),w=Math.max(y,x),b=new f.Vector3(0,0,l.z),T=l.clone().sub(b).normalize().multiplyScalar(w<1?1:w).add(l),M=this.camera.position.clone(),S=h.clone(),C={t:0};let I=500;const D=M.distanceTo(T)+S.distanceTo(b);D>.001&&(I=Math.min(1e3,Math.max(450,D*45))),this._fitAnimation=new di(C).to({t:1},I).easing(ye.Easing.Quadratic.InOut).onStart(()=>{this.controls.enabled=!1}).onUpdate(()=>{const A=C.t;this.camera.position.lerpVectors(M,T,A),this.controls.target.lerpVectors(S,b,A)}).onComplete(()=>{this.controls.enabled=!0}).start()},this.fit=()=>{new f.Box3().setFromObject(this._container);const r=this.amr.sizeBox.size.getSize(new f.Vector3),l=r.clone().multiplyScalar(.5),h=new f.Vector3(0,0,l.z);let g=l.clone().sub(h);g.lengthSq()<1e-6&&(g=new f.Vector3(1,0,0));const _=g.clone().normalize(),p=r.clone().multiplyScalar(.5),v=[new f.Vector3(p.x,p.y,p.z),new f.Vector3(p.x,p.y,-p.z),new f.Vector3(p.x,-p.y,p.z),new f.Vector3(p.x,-p.y,-p.z),new f.Vector3(-p.x,p.y,p.z),new f.Vector3(-p.x,p.y,-p.z),new f.Vector3(-p.x,-p.y,p.z),new f.Vector3(-p.x,-p.y,-p.z)];let y=0;for(const k of v){const H=k.dot(_),W=Math.sqrt(Math.max(0,k.lengthSq()-H*H));W>y&&(y=W)}y=y*1.05;const x=this.camera.fov*Math.PI/180,w=2*Math.atan(Math.tan(x/2)*this.camera.aspect),b=y/Math.tan(w/2),T=y/Math.tan(x/2),M=Math.max(b,T),S=l.clone();let C=r.z/3;r.z<r.x&&r.z<r.y&&(C=r.x*.8),r.z>r.x&&r.z>r.y&&(C=0),S.z+=C;const I=g.clone().normalize().multiplyScalar(M<1?1:M).add(S),D=Math.max(r.x*2,5);this.light.position.set(D,0,r.z*2);const A=this.camera.position.clone(),P=this.controls.target.clone(),R={t:0};let E=600;const F=A.distanceTo(I)+P.distanceTo(h);F>.001&&(E=Math.min(800,Math.max(650,F*45))),this._fitAnimation=new di(R).to({t:1},E).easing(ye.Easing.Quadratic.InOut).onStart(()=>{this.controls.enabled=!1}).onUpdate(()=>{const k=R.t;this.camera.position.lerpVectors(A,I,k),this.controls.target.lerpVectors(P,h,k)}).onComplete(()=>{this.controls.enabled=!0,!this.shadowMode&&(this._progressShadow.visible=!0,this._progressShadow.isFinished||this._progressShadow.recalculate())}).start(),this.controls.minDistance=Math.max(.2,Math.min(M*.25,M-.1)),this.controls.maxDistance=M*4},this.resize=()=>{var _;const d=this.renderer.domElement.parentElement;if(!d)return;d.style.display="flex",this.renderer.domElement.style.width="100%",this.renderer.domElement.style.height="100%",this.renderer.domElement.style.flexGrow="1";const r=d.clientWidth,l=d.clientHeight;this.size.set(r,l),this.camera.aspect=r/l,this.camera.updateProjectionMatrix(),this._amrRender.setSize(r,l),this._updateCamera(),this.css2dRenderer.setSize(r,l);const h=this.renderer.getPixelRatio();(_=this.pathTracer)==null||_.updateCamera(),this.sampleCount=0,this.renderer.setSize(r,l),this._composer.setSize(r,l),this._composer.passes.forEach(p=>p.setSize(r,l));const g=this._fxaaPass.material.uniforms;g.resolution.value.x=1/(r*h),g.resolution.value.y=1/(l*h),this._bloomPass&&this._bloomPass.setSize(r,l)},this.ticker=()=>{if(!this._destroyed){if(this.stats.begin(),this.renderer.domElement.dispatchEvent(new CustomEvent("ticker")),this._rafId=requestAnimationFrame(this.ticker),this.renderer.autoClear=!1,this.renderer.clear(),this.usePathTracing){this.hideAmrUI(),this.sampleCount<this.maxSample?this.sampleCount++:this.pathTracer.pausePathTracing=!0,this.pathTracer.renderSample();const d=this.renderer.autoClear;this.renderer.autoClear=!1,this.scene.overrideMaterial=Bc,this.renderer.clearDepth(),this.renderer.render(this.scene,this.mainCamera),this.scene.overrideMaterial=null,this.renderer.render(this.overlayScene,this.mainCamera),this.renderer.autoClear=d}else{this._clock.getElapsedTime()-this._uiHiddenTime>.15?this.showAmrUI(!0):this.hideAmrUI(!1,!1);const r=this.stats.fps();this.usePathTracing||(this._fpsCache.length>this._fpsCacheMax&&this._fpsCache.shift(),this._fpsCache.push(r)),this.amr.slots.forEach(l=>{this._dragging?l.getCanInstall()&&l.render(this):l.render(this)}),ye.update(),this.controls.update(),this._progressShadow.update(this.mainCamera),this.css2dRenderer.render(this.scene,this.mainCamera),this.updatePosition(),this.scene.overrideMaterial=null,this.renderer.render(this.scene,this.mainCamera)}this.stats.end()}},this.stats.showPanel(0),this.hideState(),e.fov&&(this.camera.fov=e.fov,this.camera.updateProjectionMatrix()),Fr(yt,this.renderer),this._ground.visible=!1,this.controls=new mn.OrbitControls(this.camera,this.renderer.domElement),this.controls.enablePan=!0,this.controls.rotateSpeed=this.props.isMobile?.6:.5,this.controls.dampingFactor=vr,this.controls.enableDamping=!0,this.controls.maxDistance=10,this.controls.minDistance=1,this.controls.zoomSpeed=this.props.isMobile?.3:zr()?.2:1,this._cameraPositionUI=new Rc(this.controls),this.renderer.setPixelRatio(window.devicePixelRatio||1),this.renderer.autoClear=!0,this.renderer.toneMapping=f.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1.4,this.renderer.outputColorSpace=f.SRGBColorSpace,this.renderer.localClippingEnabled=!0,this.renderer.shadowMap.enabled=!0,this.css2dRenderer.domElement.style.pointerEvents="none",this.css2dRenderer.domElement.style.position="absolute",this.css2dRenderer.domElement.style.top="0px",f.ShaderChunk.tonemapping_pars_fragment=f.ShaderChunk.tonemapping_pars_fragment.replace("vec3 CustomToneMapping( vec3 color ) { return color; }",`
3870
+ float startCompression = 0.8;
3871
+ float desaturation = 0.5;
3872
+ vec3 CustomToneMapping( vec3 color ) {
3873
+ color *= toneMappingExposure;
3874
+
3875
+ float d = 1. - startCompression;
3876
+
3877
+ float peak = max(color.r, max(color.g, color.b));
3878
+ if (peak < startCompression) return color;
3879
+
3880
+ float newPeak = 1. - d * d / (peak + d - startCompression);
3881
+ float invPeak = 1. / peak;
3882
+
3883
+ float extraBrightness = dot(color * (1. - startCompression * invPeak), vec3(1, 1, 1));
3884
+
3885
+ color *= newPeak * invPeak;
3886
+ float g = 1. - 3. / (desaturation * extraBrightness + 3.);
3887
+ return mix(color, vec3(1, 1, 1), g);
3888
+ }`),this.camera.position.set(10,-10,5),this.camera.lookAt(new f.Vector3);const{tiles:t}=$a();this.pathTracer=new pa(this.renderer),this.pathTracer.filterGlossyFactor=.6;let i=window.devicePixelRatio;i<2&&(i=2),this.pathTracer.renderScale=this.props.isMobile?1:i,this.pathTracer.bounces=this.props.isMobile?8:10,this.pathTracer.transmissiveBounces=this.props.isMobile?1:3,this.pathTracer.tiles.set(t,t),this.pathTracer.fadeDuration=0;const s=new Sc(e.workerUrl),a=typeof navigator<"u"?navigator.hardwareConcurrency:4;s.maxWorkerCount=a,this.pathTracer.setBVHWorker(s),this.orthographicCamera.left=-20,this.orthographicCamera.right=20,this.orthographicCamera.top=-20,this.orthographicCamera.bottom=20;let o=this.controls.target.x,c=this.controls.target.y;const u=()=>{this.controls.target.x=o,this.controls.target.y=c};this.controls.addEventListener("change",()=>{var d;this.sampleCount=0,u(),this._uiHiddenTime=this._clock.getElapsedTime(),this.orthographicCamera.position.copy(this.camera.position),this.orthographicCamera.lookAt(this.controls.target),this.usePathTracing&&(this.pathTracer.pausePathTracing=!1,(d=this.pathTracer)==null||d.updateCamera()),this._updateCamera(),!(Math.abs(this.camera.position.x)<.001||Math.abs(this.camera.position.y)<.001)&&(this._axisMoving||(this.mainCamera=this.camera,this.usePathTracing&&this.generateBVH().then()))}),this._mainCamera=this.camera,this._composer=new vn.EffectComposer(this.renderer),this._composer.setPixelRatio(window.devicePixelRatio);const m=new Cs.RenderPass(this.scene,this.camera);this._composer.addPass(m),this._composer.addPass(new gn.OutputPass),this._outlinePass=new Ps.OutlinePass(new f.Vector2(window.innerWidth,window.innerHeight),this.scene,this.camera),this._outlinePass.visibleEdgeColor.set(26367),this._outlinePass.edgeThickness=.5,this._outlinePass.hiddenEdgeColor.set(26367),this._outlinePass.edgeStrength=3,this._outlinePass.edgeGlow=0,this._composer.addPass(this._outlinePass),this._outlinePassError=new Ps.OutlinePass(new f.Vector2(window.innerWidth,window.innerHeight),this.scene,this.camera),this._outlinePassError.visibleEdgeColor.set(16711680),this._outlinePassError.edgeThickness=.5,this._outlinePassError.hiddenEdgeColor.set(16711680),this._outlinePassError.edgeStrength=3,this._outlinePassError.edgeGlow=0,this._composer.addPass(this._outlinePassError),this._bloomPass=new pn.UnrealBloomPass(new f.Vector2(window.innerWidth,window.innerHeight),.1,.1,.2),this._bloomPass.enabled=!1,this._bloomPass.renderToScreen=!1,this._composer.addPass(this._bloomPass),this._composer.renderTarget1.texture.colorSpace=f.SRGBColorSpace,this._composer.renderTarget2.texture.colorSpace=f.SRGBColorSpace,this._fxaaPass=new fn.ShaderPass(dn.FXAAShader),this._composer.addPass(this._fxaaPass),this._progressShadow=new Cc(this.renderer,this.scene,{size:8,lightCount:e.isMobile?6:12,frames:e.isMobile?80:120,lightRadius:8,ambientWeight:.8}),this._progressShadow.lightOrigin.position.set(3,2.5,6),this._progressShadow.visible=!1,this._container.add(this.amr),this.scene.add(this._container),this.ticker(),this._loadEnv(),this._initEvents(),this.scene.add(this._cameraPositionUI),this._ground.rotateX(-Math.PI/2),this.scene.add(this._ground),(typeof e.useAxisBall!="boolean"||e.useAxisBall)&&(this._controlsGizmo=new Mc(this.controls,{size:160,padding:12,offset:e.axisBallOffset||new f.Vector2(10,10),fontSize:17,bubbleSizePrimary:18,bubbleSizeSecondary:14}),this._controlsGizmo.addListener("axis-select-start",()=>{this._axisMoving=!0,this.mainCamera=this.orthographicCamera,this.usePathTracing&&this.generateBVH().then()}),this._controlsGizmo.addListener("axis-select-end",()=>{this._axisMoving=!1})),this.test=new f.Mesh(new f.PlaneGeometry(2,2),new f.MeshBasicMaterial({map:this._amrRender.texture,opacity:.5,transparent:!0,side:f.DoubleSide})),this.test.position.set(0,1,0),this.test.visible=!1,this.scene.add(this.test)}get pointCloudMode(){return this._pointCloudMode}set pointCloudMode(e){this._pointCloudMode=e,this.amr.setPointCloudMode(e),e?setTimeout(()=>{console.log(this.amr.lines.children)},3e3):this._outlinePass.selectedObjects=[],this._bloomPass,e?this.scene.fog=null:this.scene.background=null}get usePathTracing(){return this._usePathTracing}_clearAmrContent(){const e=this.renderer.getRenderTarget();this.renderer.setRenderTarget(this._amrRender),this.renderer.setClearColor(0,0),this.renderer.clear(!0,!0,!0),this.renderer.setRenderTarget(e)}get shadowMode(){return this._shadowMode}set shadowMode(e){e?(this._progressShadow.visible=!1,this.amr.bodyOpacity=.2):(this._progressShadow.visible=!0,this.amr.bodyOpacity=1,this._progressShadow.isFinished||this._progressShadow.recalculate().then()),this._shadowMode=e}set usePathTracing(e){this._clearAmrContent(),e?(this.scene.add(this.light),this.renderer.toneMappingExposure=1.8,this.overlayScene.add(this._progressShadow.shadowCatcherMesh),this.amr&&(this.amr.bodyOpacity=1),this.hideAmrUI(),this.pathTracer.renderToCanvas=!0,this.scene.background=null):(this.light.removeFromParent(),this.renderer.toneMappingExposure=1.4,this.scene.add(this._progressShadow.shadowCatcherMesh),this.pathTracer.renderToCanvas=!1,this.amr.logos.forEach(t=>{var i;(i=t.parent)==null||i.add(t.target)}),this.showAmrUI(),this.amr&&this.amr.opacityCache!==void 0?(this.amr.bodyOpacity=this.amr.opacityCache,this.amr.opacityCache=void 0):this.amr&&(this.amr.bodyOpacity=1),this.pathTracer.reset(),this._ground.visible=!1,this.scene.background=this.scene.environment),this._usePathTracing=e,this.controls.dampingFactor=e?1:vr,this.sampleCount=0}get fpsAverage(){return Or(this._fpsCache)}get mainCamera(){return this._mainCamera}set mainCamera(e){this._mainCamera=e,this._composer.passes.forEach(t=>{t instanceof Cs.RenderPass&&(t.camera=e)}),e instanceof f.OrthographicCamera?this.scene.background=null:this.scene.background=this.scene.environment}showState(){this.stats.dom.style.display="block"}hideState(){this.stats.dom.style.display="none"}hideAmrUI(e=!0,t=!0){this.shadowMode||this.amr.slots.forEach(i=>i.hide()),this.amr.sizeBox.hide(e),this.amr.controllers.forEach(i=>i.hide()),t&&this.amr.goods.forEach(i=>i.hide())}showAmrUI(e=!0){this.showSlots&&this.amr.slots.forEach(t=>t.show()),this.showSize&&this.amr.sizeBox.show(e),this.showControls&&this.amr.controllers.forEach(t=>t.show()),this.amr.goods.forEach(t=>t.show())}get showSlots(){return this._showSlots}set showSlots(e){this._showSlots=e,this.amr.slots.forEach(t=>e?t.show():t.hide())}get showSize(){return this._showSize}set showSize(e){this._showSize=e,e?this.amr.sizeBox.show(!0):this.amr.sizeBox.hide(!0)}get showControls(){return this._showControls}set showControls(e){this._showControls=e,this.amr.controllers.forEach(t=>e?t.show():t.hide())}_updateCamera(){const e=this.mainCamera.position.distanceTo(this.controls.target),t=2*Math.tan(this.camera.fov*.5*Math.PI/180)*e,i=this.size.x/this.size.y;this.orthographicCamera.left=-t*i/2,this.orthographicCamera.right=t*i/2,this.orthographicCamera.top=t/2,this.orthographicCamera.bottom=-t/2,this.orthographicCamera.updateProjectionMatrix()}_loadEnv(){new hn.HDRLoader().load(Dc,t=>{t.mapping=f.EquirectangularReflectionMapping,this._usePathTracing||(this.scene.background=t,this.scene.backgroundBlurriness=1,this.scene.backgroundIntensity=1,this.scene.backgroundRotation=new f.Euler(Math.PI/2,0,Math.PI*.98*.8),this.scene.environment=t,this.overlayScene.environment=t,this.scene.environmentRotation=this.scene.backgroundRotation,this.overlayScene.environmentRotation=this.scene.environmentRotation,this.scene.environmentIntensity=1.4,this.overlayScene.environmentIntensity=this.scene.environmentIntensity),this.pathTracer.updateEnvironment()},()=>{},()=>{})}_initEvents(){window.addEventListener("drag",this._drag),window.addEventListener("dragend",this._dragend),document.addEventListener("wheel",this._detectTrackpad),window.addEventListener("pointermove",this._pointermove),this.renderer.domElement.addEventListener("pointerdown",this._pointerdown)}switchCamera(){this.mainCamera=this.mainCamera===this.camera?this.orthographicCamera:this.camera}toCameraTop(){const e=this.camera.position.distanceTo(this.controls.target);this.camera.position.copy(new f.Vector3(0,e+this.controls.target.y,0))}toCameraRight(){const e=this.camera.position.distanceTo(this.controls.target);this.camera.position.copy(new f.Vector3(0,this.controls.target.y,e))}toCameraFace(){const e=this.camera.position.distanceTo(this.controls.target);this.camera.position.copy(new f.Vector3(e,this.controls.target.y,0))}async generateBVH(){this.pathTracer.pausePathTracing=!1,this.amr.slots.forEach(e=>e.hide()),this.amr&&(this.amr.opacityCache=this.amr.bodyOpacity,this.amr.bodyOpacity=1,this.overlayScene.clear(),this.amr.logos.forEach(e=>{const t=new f.Group;e.target.updateMatrixWorld(!0),t.applyMatrix4(e.target.matrixWorld),t.add(e.target),this.overlayScene.add(t)})),this.usePathTracing=!0,this.pathTracer.setScene(this.scene,this.mainCamera)}async download(e=!1){if(e&&!this.usePathTracing){const t=this._amrRender.width,i=this._amrRender.height,s=new Uint8Array(t*i*4);this.renderer.setRenderTarget(this._amrRender),this.renderer.readRenderTargetPixels(this._amrRender,0,0,t,i,s),this.renderer.setRenderTarget(null);const a=document.createElement("canvas");a.width=t,a.height=i;const o=a.getContext("2d"),c=new ImageData(t,i);for(let u=0;u<i;u++)for(let m=0;m<t;m++){const d=((i-u-1)*t+m)*4,r=(u*t+m)*4;c.data[r]=s[d],c.data[r+1]=s[d+1],c.data[r+2]=s[d+2],c.data[r+3]=s[d+3]}return o.putImageData(c,0,0),a.toDataURL("image/png")}else return new Promise((t,i)=>{this._uiHiddenTime=this._clock.getElapsedTime(),this.hideAmrUI();const s=this.scene.background;this.scene.background=null,setTimeout(()=>{const a=this.renderer.domElement.toDataURL("image/png");return this.scene.background=s,t(a)},this.fpsAverage)})}async captureTriViews(e){var o;const t=(e==null?void 0:e.subject)??this._container;(o=this._progressShadow)==null||o.visible;const i=this.scene.background,s=this.showSize;return new Jr({renderer:this.renderer,scene:this.scene,overlayScene:this.overlayScene,subject:t,onBeforeCapture:()=>{this.scene.background=null,this.hideAmrUI(),this.showSize=!1,this.usePathTracing&&(this.usePathTracing=!1),this._progressShadow.visible=!1},onAfterCapture:()=>{this.scene.background=i,this.showAmrUI(),this.showSize=s,this._progressShadow.visible=!0}}).capture(e)}clearAMR(){Ce(this.overlayScene),this.amr.clean(),this.usePathTracing=!1}async exportAMR(){const e=this._container.clone(!0);return e.traverse(t=>{t.dispose&&(t.dispose(),t.removeFromParent())}),await Ur.parseAsync(e,{onlyVisible:!0,binary:!0})}async addAMR(e,t=""){this.amr.init(this),await this.amr.load(e,t),this._progressShadow.clear(),this.amr.addEventListener("fork-height-change",this.debounceForkHeightChange),this.amr.addEventListener("shape-key-changed",(i,s)=>{this.pathTracer.reset(),this.sampleCount=0,this.pathTracer.setScene(this.scene,this.camera),this.overlayScene.traverse(a=>{if(!Object.keys(a.morphTargetDictionary||{}).includes(i))return;let o=s;a.userData[`origin_${i}`]&&(o-=a.userData[`origin_${i}`]);const c=a.morphTargetDictionary[i];a.morphTargetInfluences&&(a.morphTargetInfluences[c]=o),a instanceof f.Mesh&&a.geometry.translate(0,0,1e-5)}),this._progressShadow.clear(),this._progressShadow.recalculate()})}select(e){typeof e=="string"||(Array.isArray(e)?this._outlinePass.selectedObjects=[...e]:this._outlinePass.selectedObjects=[e])}appendTo(e){e.append(this.renderer.domElement),e.append(this.stats.dom),e.append(this.css2dRenderer.domElement),this.props.isMobile&&(e.classList.add("is-mobile"),e.style.cssText=`
3889
+ -webkit-user-select: none;
3890
+ user-select: none;
3891
+ touch-action: none;
3892
+ -webkit-touch-callout: none;
3893
+ `),this._controlsGizmo&&this._controlsGizmo.appendTo(e),this.stats.dom.style.bottom="0",this.stats.dom.style.top="auto",this.resize(),this._resizeObserver=new ResizeObserver(this.resize.bind(this)),this._resizeObserver.observe(e)}add(e){this._container.add(e)}updatePosition(){}removeFromParent(){var t;const e=this.renderer.domElement.parentElement;e&&((t=this._resizeObserver)==null||t.unobserve(e),e.removeChild(this.renderer.domElement))}clean(){this.amr.clean(),this._progressShadow.clear()}destroy(){var t,i,s;this._destroyed=!0,this._rafId!==null&&(cancelAnimationFrame(this._rafId),this._rafId=null),this._clock.stop(),(t=this._controlsGizmo)==null||t.destroy(),this.amr.destroy(),this.amr.removeFromParent(),this._progressShadow.destroy(),ye.removeAll(),this.stats.dom.remove(),this._emitter.removeAllListeners(),(i=this._fitAnimation)==null||i.stop(),window.removeEventListener("drag",this._drag),document.removeEventListener("wheel",this._detectTrackpad),window.removeEventListener("pointermove",this._pointermove),this.renderer.domElement.removeEventListener("pointerdown",this._pointerdown);const e=this.renderer.domElement.parentElement;e&&((s=this._resizeObserver)==null||s.unobserve(e)),this.controls.dispose(),this.renderer.domElement.remove(),this.renderer.dispose(),this._composer.dispose(),Ce(this.scene),this.scene.clear()}}class Jr{constructor(e){this.deps=e,this.canvas=null,this.pixelBuffer=null,this.orthoCamera=new f.OrthographicCamera(-1,1,1,-1,.1,1e3),this.orthoCamera.position.set(0,0,5),this.perspectiveCamera=new f.PerspectiveCamera(45,1,.1,2e3)}async capture(e){var g,_,p,v,y,x;const t=this.deps.renderer,i=(e==null?void 0:e.subject)??this.deps.subject;if(!i)throw new Error("TriViewCapture: subject is required.");const s=new f.Vector2;t.getSize(s);const a=((g=e==null?void 0:e.size)==null?void 0:g.width)??Math.round(s.x),o=((_=e==null?void 0:e.size)==null?void 0:_.height)??Math.round(s.y),c=(e==null?void 0:e.margin)??.15,u=(e==null?void 0:e.includeOverlay)??!1,m=a/o||1,d=this.resolveViews(e==null?void 0:e.views),r=new f.WebGLRenderTarget(a,o,{format:f.RGBAFormat,type:f.UnsignedByteType});r.texture.colorSpace=f.SRGBColorSpace,r.texture.generateMipmaps=!1,r.depthBuffer=!0;const l=this.storeRendererState(t),h={};try{(v=(p=this.deps).onBeforeCapture)==null||v.call(p);const w=this.computeBounds(i);this.applyRendererState(t,a,o,e==null?void 0:e.backgroundColor);for(const b of d){const T=this.configureCamera(w,b,m,c,a,o);t.setRenderTarget(r),t.clear(!0,!0,!0),t.render(this.deps.scene,T),u&&this.deps.overlayScene&&(t.clearDepth(),t.render(this.deps.overlayScene,T));const M=this.readPixels(t,r,a,o);h[b.key]=M}}finally{r.dispose(),this.restoreRendererState(t,l),(x=(y=this.deps).onAfterCapture)==null||x.call(y)}return h}resolveViews(e){return e&&e.length?e.map(t=>({key:t.key,direction:t.direction.clone(),up:t.up.clone(),plane:t.plane})):[{key:"top",direction:new f.Vector3(0,0,1),up:new f.Vector3(0,1,0),plane:{width:"x",height:"y",depth:"z"}},{key:"front",direction:new f.Vector3(0,-1,0),up:new f.Vector3(0,0,1),plane:{width:"x",height:"z",depth:"y"}},{key:"side",direction:new f.Vector3(1,0,0),up:new f.Vector3(0,0,1),plane:{width:"y",height:"z",depth:"x"}},{key:"perspective",direction:new f.Vector3(1,1,1),up:new f.Vector3(0,0,1),plane:{width:"x",height:"z",depth:"y"},mode:"perspective",fov:39.6}]}computeBounds(e){const t=new f.Box3,i=new f.Box3,s=new f.Vector3,a=new f.Vector3,o=new f.Sphere;return e.updateMatrixWorld(!0),e.traverse(c=>{if(!c.visible)return;const m=c.geometry;if(!m)return;m.boundingBox||m.computeBoundingBox();const d=m.boundingBox;d&&(i.copy(d).applyMatrix4(c.matrixWorld),t.union(i))}),t.isEmpty()?(t.setFromCenterAndSize(s,new f.Vector3(.001,.001,.001)),a.set(.001,.001,.001),o.center.copy(s),o.radius=.001):(t.getCenter(s),t.getSize(a),t.getBoundingSphere(o)),(!Number.isFinite(o.radius)||o.radius<=0)&&(o.radius=Math.max(a.length()*.5,.001)),{box:t,center:s,size:a,sphere:o}}configureCamera(e,t,i,s,a,o){const c=t.direction.clone().normalize();c.lengthSq()===0&&c.set(0,0,1);const u=t.up.clone().normalize();if(Math.abs(u.dot(c))>.999&&(u.set(0,0,1),Math.abs(u.dot(c))>.999&&u.set(0,1,0)),(t.mode??"orthographic")==="perspective"){const w=this.perspectiveCamera,b=t.fov??45,T=f.MathUtils.degToRad(b),M=Math.max(Math.tan(T/2),1e-4),S=Math.max(M*(i||1),1e-4),C=this.getPerspectiveDirection(t,e.size).normalize(),I=new f.Vector3().crossVectors(C,u).normalize();I.lengthSq()<1e-6&&I.set(1,0,0);const D=new f.Vector3().crossVectors(I,C).normalize(),A=Math.max(e.size.x*.5,1e-4),P=Math.max(e.size.y*.5,1e-4),R=Math.max(e.size.z*.5,1e-4),E=[new f.Vector3(-A,-P,-R),new f.Vector3(-A,-P,R),new f.Vector3(-A,P,-R),new f.Vector3(-A,P,R),new f.Vector3(A,-P,-R),new f.Vector3(A,-P,R),new f.Vector3(A,P,-R),new f.Vector3(A,P,R)];let F=0,k=-1/0;for(const Q of E){const X=I.dot(Q),O=D.dot(Q),ve=C.dot(Q);k=Math.max(k,ve);const Ie=ve+Math.abs(X)/S,ue=ve+Math.abs(O)/M;F=Math.max(F,Ie,ue)}F=Math.max(F,k+.1);const H=F*(1+s);let W=1/0;for(const Q of E){const X=C.dot(Q),O=H-X;O>.001&&(W=Math.min(W,O))}return w.fov=b,w.aspect=i||a/Math.max(o,1),w.near=Math.max(.1,Number.isFinite(W)?W*.5:H*.1),w.far=Math.max(w.near+1,H+e.sphere.radius*3),w.position.copy(e.center).add(C.clone().multiplyScalar(H)),w.up.copy(D),w.lookAt(e.center),w.updateProjectionMatrix(),w.updateMatrixWorld(!0),w}const d=this.orthoCamera,r=e.size,l=e.center,h=Math.max(r[t.plane.width]*.5,.01),g=Math.max(r[t.plane.height]*.5,.01),_=Math.max(r[t.plane.depth]*.5,.01);let p=h*(1+s),v=g*(1+s);p/i>v?v=p/i:p=v*i;const y=_*(1+s)+Math.max(p,v),x=l.clone().add(c.multiplyScalar(y));return d.left=-p,d.right=p,d.top=v,d.bottom=-v,d.near=.1,d.far=y*4,d.zoom=1,d.position.copy(x),d.up.copy(u),d.lookAt(l),d.updateProjectionMatrix(),d.updateMatrixWorld(!0),d}getPerspectiveDirection(e,t){const i=e.direction.clone();i.lengthSq()===0&&i.set(1,1,1);const s=new f.Vector3(Math.abs(i.x)||1,Math.abs(i.y)||1,Math.abs(i.z)||1),a=new f.Vector3(Math.sign(i.x||1),Math.sign(i.y||1),Math.sign(i.z||1)),o=.25,c=new f.Vector3(Math.max(o,s.x)*Math.max(t.x,.001),Math.max(o,s.y)*Math.max(t.y,.001),0),u=Math.max((t.x+t.y)*.5,.001),m=Math.max(t.z,.001),d=Math.max(o,s.z),r=m*.5+u*.5;return c.z=d*r,c.multiply(a),c}storeRendererState(e){const t=new f.Vector2;e.getSize(t);const i=new f.Vector4;e.getViewport(i);const s=new f.Vector4;e.getScissor(s);const a=e.getClearColor(new f.Color),o=e.getClearAlpha();return{size:t,pixelRatio:e.getPixelRatio(),viewport:i,scissor:s,scissorTest:e.getScissorTest(),autoClear:e.autoClear,target:e.getRenderTarget(),clearColor:a,clearAlpha:o}}applyRendererState(e,t,i,s){if(e.setPixelRatio(1),e.setSize(t,i,!1),e.setViewport(0,0,t,i),e.setScissor(0,0,t,i),e.setScissorTest(!1),e.autoClear=!0,s!==void 0)if(s===null){const a=e.getClearColor(new f.Color);e.setClearColor(a,0)}else s instanceof f.Color?e.setClearColor(s,1):e.setClearColor(new f.Color(s),1);else{const a=e.getClearColor(new f.Color);e.setClearColor(a,0)}}restoreRendererState(e,t){e.setPixelRatio(t.pixelRatio),e.setSize(t.size.x,t.size.y,!1),e.setViewport(t.viewport.x,t.viewport.y,t.viewport.z,t.viewport.w),e.setScissor(t.scissor.x,t.scissor.y,t.scissor.z,t.scissor.w),e.setScissorTest(t.scissorTest),e.autoClear=t.autoClear,e.setRenderTarget(t.target),e.setClearColor(t.clearColor,t.clearAlpha)}readPixels(e,t,i,s){const a=i*s*4;(!this.pixelBuffer||this.pixelBuffer.length!==a)&&(this.pixelBuffer=new Uint8Array(a)),e.readRenderTargetPixels(t,0,0,i,s,this.pixelBuffer);const o=this.ensureCanvas(i,s),c=o.getContext("2d");if(!c)throw new Error("TriViewCapture: failed to get 2D context.");const u=c.createImageData(i,s),m=u.data,d=this.pixelBuffer;for(let r=0;r<s;r+=1){const h=(s-r-1)*i*4,g=r*i*4;m.set(d.subarray(h,h+i*4),g)}return c.putImageData(u,0,0),o.toDataURL("image/png")}ensureCanvas(e,t){if(typeof document>"u")throw new Error("TriViewCapture: document is not available in this environment.");return this.canvas||(this.canvas=document.createElement("canvas")),(this.canvas.width!==e||this.canvas.height!==t)&&(this.canvas.width=e,this.canvas.height=t),this.canvas}}exports.Amr=Gr;exports.Line=fl;exports.Logo=ts;exports.SGLBLoader=pi;exports.SLOT_EVENTS=Z;exports.Scene3D=kc;exports.Skin=hs;exports.Slot=es;exports.SlotState=$r;exports.TriViewCapture=Jr;exports.arrayBufferToUrl=Ki;exports.calculateArrayAverage=Or;exports.calculateFocalLength=Qa;exports.createSGLBFile=rl;exports.downloadBlob=Ya;exports.dracoExporter=sl;exports.font=Ec;exports.gltfExporter=Ur;exports.gltfLoader=yt;exports.imageBitmapToUrl=$i;exports.isAppleDevice=zr;exports.textureLoader=bs;