three-live 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -3
- package/dist/three-author-engine.js +45 -40
- package/dist/three-author.cjs +32 -27
- package/dist/three-author.d.ts +3 -3
- package/dist/three-author.js +32 -27
- package/dist/three-convert.cjs +43 -38
- package/dist/three-convert.d.ts +3 -3
- package/dist/three-convert.js +42 -37
- package/dist/three-live-animation.cjs +6 -6
- package/dist/three-live-animation.d.ts +3 -3
- package/dist/three-live-animation.js +5 -5
- package/dist/three-live-animation.min.js +6 -6
- package/dist/three-live-element.cjs +12 -7
- package/dist/three-live-element.d.ts +3 -3
- package/dist/three-live-element.js +12 -7
- package/dist/three-live-extras.cjs +13 -13
- package/dist/three-live-extras.d.ts +3 -3
- package/dist/three-live-extras.js +12 -12
- package/dist/three-live-extras.min.js +13 -13
- package/dist/three-live-full.cjs +69 -64
- package/dist/three-live-full.js +69 -64
- package/dist/three-live-full.min.js +69 -64
- package/dist/three-live-viewer.cjs +12 -7
- package/dist/three-live-viewer.d.ts +3 -3
- package/dist/three-live-viewer.js +12 -7
- package/dist/three-live-viewer.min.js +12 -7
- package/dist/three-live.cjs +49 -44
- package/dist/three-live.js +49 -44
- package/dist/three-live.min.js +49 -44
- package/dist/three-view.cjs +12 -7
- package/dist/three-view.d.ts +3 -3
- package/dist/three-view.js +12 -7
- package/dist/three-xr.cjs +44 -39
- package/dist/three-xr.d.ts +3 -3
- package/dist/three-xr.js +44 -39
- package/package.json +1 -1
package/dist/three-view.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
-
function
|
|
17
|
+
function V(){let i=new Float32Array(16);return i[0]=1,i[5]=1,i[10]=1,i[15]=1,i}function fe(i,e,t,r,n){let s=1/Math.tan(e/2);i.fill(0),i[0]=s/t,i[5]=s,i[11]=-1;let o=1/(r-n);return i[10]=(n+r)*o,i[14]=2*n*r*o,i}function pe(i,e,t,r){let[n,s,o]=e,[h,c,u]=r,[a,l,f]=t,b=n-a,p=s-l,T=o-f,M=Math.hypot(b,p,T);M<=1e-5?(b=0,p=0,T=1):(b/=M,p/=M,T/=M);let D=c*T-u*p,E=u*b-h*T,w=h*p-c*b;M=Math.hypot(D,E,w),M<=1e-5?(D=0,E=0,w=0):(D/=M,E/=M,w/=M);let v=p*w-T*E,d=T*D-b*w,m=b*E-p*D;return M=Math.hypot(v,d,m),M<=1e-5?(v=0,d=0,m=0):(v/=M,d/=M,m/=M),i[0]=D,i[1]=v,i[2]=b,i[3]=0,i[4]=E,i[5]=d,i[6]=p,i[7]=0,i[8]=w,i[9]=m,i[10]=T,i[11]=0,i[12]=-(D*n+E*s+w*o),i[13]=-(v*n+d*s+m*o),i[14]=-(b*n+p*s+T*o),i[15]=1,i}function z(i,e,t){let r=e[0],n=e[1],s=e[2],o=e[3],h=e[4],c=e[5],u=e[6],a=e[7],l=e[8],f=e[9],b=e[10],p=e[11],T=e[12],M=e[13],D=e[14],E=e[15],w=t[0],v=t[1],d=t[2],m=t[3];return i[0]=w*r+v*h+d*l+m*T,i[1]=w*n+v*c+d*f+m*M,i[2]=w*s+v*u+d*b+m*D,i[3]=w*o+v*a+d*p+m*E,w=t[4],v=t[5],d=t[6],m=t[7],i[4]=w*r+v*h+d*l+m*T,i[5]=w*n+v*c+d*f+m*M,i[6]=w*s+v*u+d*b+m*D,i[7]=w*o+v*a+d*p+m*E,w=t[8],v=t[9],d=t[10],m=t[11],i[8]=w*r+v*h+d*l+m*T,i[9]=w*n+v*c+d*f+m*M,i[10]=w*s+v*u+d*b+m*D,i[11]=w*o+v*a+d*p+m*E,w=t[12],v=t[13],d=t[14],m=t[15],i[12]=w*r+v*h+d*l+m*T,i[13]=w*n+v*c+d*f+m*M,i[14]=w*s+v*u+d*b+m*D,i[15]=w*o+v*a+d*p+m*E,i}function Te(i,e,t,r){let n=e[0],s=e[1],o=e[2],h=e[3],c=n+n,u=s+s,a=o+o,l=n*c,f=n*u,b=n*a,p=s*u,T=s*a,M=o*a,D=h*c,E=h*u,w=h*a,v=r[0],d=r[1],m=r[2];return i[0]=(1-(p+M))*v,i[1]=(f+w)*v,i[2]=(b-E)*v,i[3]=0,i[4]=(f-w)*d,i[5]=(1-(l+M))*d,i[6]=(T+D)*d,i[7]=0,i[8]=(b+E)*m,i[9]=(T-D)*m,i[10]=(1-(l+p))*m,i[11]=0,i[12]=t[0],i[13]=t[1],i[14]=t[2],i[15]=1,i}function ne(i,e){let t=e[0],r=e[1],n=e[2],s=e[4],o=e[5],h=e[6],c=e[8],u=e[9],a=e[10],l=a*o-h*u,f=-a*s+h*c,b=u*s-o*c,p=t*l+r*f+n*b;return p&&(p=1/p,i[0]=l*p,i[1]=(-a*r+n*u)*p,i[2]=(h*r-n*o)*p,i[3]=f*p,i[4]=(a*t-n*c)*p,i[5]=(-h*t+n*s)*p,i[6]=b*p,i[7]=(-u*t+r*c)*p,i[8]=(o*t-r*s)*p),i}function Me(i,e){let t=e[0],r=e[1],n=e[2],s=e[3],o=e[4],h=e[5],c=e[6],u=e[7],a=e[8],l=e[9],f=e[10],b=e[11],p=e[12],T=e[13],M=e[14],D=e[15],E=t*h-r*o,w=t*c-n*o,v=t*u-s*o,d=r*c-n*h,m=r*u-s*h,C=n*u-s*c,P=a*T-l*p,g=a*M-f*p,A=a*D-b*p,L=l*M-f*T,F=l*D-b*T,y=f*D-b*M,R=E*y-w*F+v*L+d*A-m*g+C*P;return R?(R=1/R,i[0]=(h*y-c*F+u*L)*R,i[1]=(n*F-r*y-s*L)*R,i[2]=(T*C-M*m+D*d)*R,i[3]=(f*m-l*C-b*d)*R,i[4]=(c*A-o*y-u*g)*R,i[5]=(t*y-n*A+s*g)*R,i[6]=(M*v-p*C-D*w)*R,i[7]=(a*C-f*v+b*w)*R,i[8]=(o*F-h*A+u*P)*R,i[9]=(r*A-t*F-s*P)*R,i[10]=(p*m-T*v+D*E)*R,i[11]=(l*v-a*m-b*E)*R,i[12]=(h*g-o*L-c*P)*R,i[13]=(t*L-r*g+n*P)*R,i[14]=(T*w-p*d-M*E)*R,i[15]=(a*d-l*w+f*E)*R,i):null}function ve(i,e,t,r,n){let s=n[0]*e+n[4]*t+n[8]*r+n[12],o=n[1]*e+n[5]*t+n[9]*r+n[13],h=n[2]*e+n[6]*t+n[10]*r+n[14],c=n[3]*e+n[7]*t+n[11]*r+n[15],u=c!==0?1/c:1;i[0]=s*u,i[1]=o*u,i[2]=h*u}function Re(i,e,t,r,n,s,o,h,c,u,a,l,f,b,p,T,M=0){let D=u-o,E=a-h,w=l-c,v=f-o,d=b-h,m=p-c,C=n*m-s*d,P=s*v-r*m,g=r*d-n*v,A=D*C+E*P+w*g;if(A>-1e-7&&A<1e-7)return!1;let L=1/A,F=i-o,y=e-h,R=t-c,B=L*(F*C+y*P+R*g);if(B<-M||B>1+M)return!1;let x=y*w-R*E,X=R*D-F*w,k=F*E-y*D,te=L*(r*x+n*X+s*k);if(te<-M||B+te>1+M)return!1;let U=L*(v*x+d*X+m*k);if(U>1e-4&&U<T.distance){T.distance=U,T.point=[i+r*U,e+n*U,t+s*U];let H=E*m-w*d,N=w*v-D*m,I=D*d-E*v,_=Math.hypot(H,N,I)||1;return T.normal=[H/_,N/_,I/_],!0}return!1}function De(i,e){let t=Array.isArray(i?.nodes)?i.nodes.length:0,r=[];for(let a=0;a<t;a++)r.push(V());if(t===0)return r;let n=new Set;for(let a of i.nodes)if(Array.isArray(a.children))for(let l of a.children)n.add(l);let s=new Set,o=128,h=(a,l,f=0)=>{if(f>o||a<0||a>=t||s.has(a))return;s.add(a);let b=i.nodes[a];if(!b)return;let p=V();if(e&&e[a])p.set(e[a]);else if(b.matrix&&b.matrix.length===16)p.set(b.matrix);else{let M=b.translation||[0,0,0],D=b.rotation||[0,0,0,1],E=b.scale||[1,1,1];Te(p,D,M,E)}let T=r[a];if(l?z(T,l,p):T.set(p),Array.isArray(b.children))for(let M of b.children)typeof M=="number"&&h(M,T,f+1)},c=[],u=i.scenes&&i.scenes[i.scene!==void 0?i.scene:0];if(u&&Array.isArray(u.nodes))c.push(...u.nodes);else for(let a=0;a<t;a++)n.has(a)||c.push(a);for(let a of c)h(a,null);for(let a=0;a<t;a++)!n.has(a)&&!c.includes(a)&&h(a,null);return r}var be="__THREE_LIVE_REGISTRY__";function ue(){let i=typeof globalThis<"u"?globalThis:{};if(!i[be]){let e={plugins:[],decoders:new Map};try{Object.defineProperty(i,be,{value:e,writable:!1,configurable:!1,enumerable:!1})}catch{i[be]=e}}return i[be]}var G=ue().plugins;function we(i){let e=ue().plugins;e.some(t=>t.name===i.name)||e.push(i)}function Pe(){return ue().plugins}function Xe(i){return new TextDecoder().decode(i)}var Fe=ue().decoders;function He(i,e){Fe.set(i.toLowerCase(),e)}function he(i){return Fe.get(i.toLowerCase())}function Ce(i){let e=ArrayBuffer.isView(i)?i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength):i,t=new DataView(e);if(e.byteLength<12)throw new Error(`Invalid GLB buffer size: ${e.byteLength} bytes`);let r=t.getUint32(0,!0);if(r!==1179937895){let f=t.getUint8(0);throw f===123||f===32||f===10||f===13?new Error("[three-live] Multi-file JSON .gltf is not supported for performance reasons. Please pack your asset into a single binary .glb file."):new Error(`Invalid GLB magic: 0x${r.toString(16)}`)}let n=t.getUint32(4,!0);if(n!==2)throw new Error(`Unsupported GLB version: ${n}`);let s=t.getUint32(8,!0),o=12,h=null,c=null;for(;o+8<=s&&o+8<=e.byteLength;){let f=t.getUint32(o,!0),b=t.getUint32(o+4,!0),p=o+8;if(p+f>e.byteLength)throw new Error(`Truncated GLB chunk: required ${p+f} bytes, buffer has ${e.byteLength}`);if(b===1313821514){let T=new Uint8Array(e,p,f),M=Xe(T);h=JSON.parse(M,(D,E)=>D==="__proto__"||D==="constructor"||D==="prototype"?void 0:E)}else b===5130562&&(c=e.slice(p,p+f));o=p+f}if(!h)throw new Error("Missing JSON chunk in GLB");let u=h.extensionsRequired||[];if(u.includes("KHR_draco_mesh_compression")&&!he("draco"))throw new Error("Model requires KHR_draco_mesh_compression. Register a decoder via ThreeLiveElement.registerDecoder('draco', decoder).");if(u.includes("EXT_meshopt_compression")&&!he("meshopt"))throw new Error("Model requires EXT_meshopt_compression. Register a decoder via ThreeLiveElement.registerDecoder('meshopt', decoder).");if(u.includes("KHR_texture_basisu")&&!he("ktx2"))throw new Error("Model requires KHR_texture_basisu. Register a decoder via ThreeLiveElement.registerDecoder('ktx2', decoder).");let a=c||new ArrayBuffer(0),l={gltf:h,bin:a,animations:[]};for(let f of G)f.onParseGLB?.(l);return l}function Ze(i,e,t){return e%4===0?new Float32Array(i,e,t):new Float32Array(i.slice(e,e+t*4))}function We(i){return typeof i=="object"&&i!==null&&"gltf"in i&&typeof i.gltf=="object"&&i.gltf!==null&&"bin"in i&&(i.bin instanceof ArrayBuffer||ArrayBuffer.isView(i.bin))}function Ee(i){if(We(i))return i;if(i instanceof ArrayBuffer||ArrayBuffer.isView(i))return Ce(i);throw new TypeError("Invalid 3D model input: expected GLBData ({ gltf, bin }) or binary GLB (ArrayBuffer / ArrayBufferView).")}var Ie=`#version 300 es
|
|
18
18
|
layout(location=0) in vec3 aPosition;
|
|
19
19
|
layout(location=1) in vec3 aNormal;
|
|
20
20
|
layout(location=2) in vec2 aUV;
|
|
@@ -45,6 +45,8 @@ uniform int uHasTexture,uHasMetallicRoughnessTexture,uHasNormalTexture,uHasOcclu
|
|
|
45
45
|
uniform float uNormalScale,uOcclusionStrength,uXrRawValueToMeters;
|
|
46
46
|
uniform mat4 uXrDepthUVTransform;
|
|
47
47
|
uniform vec2 uViewportSize;
|
|
48
|
+
uniform vec4 uViewport;
|
|
49
|
+
uniform vec3 uCameraFwd;
|
|
48
50
|
uniform int uToneMapping,uNumDirLights,uNumPointLights;
|
|
49
51
|
uniform vec3 uDirLightDir[2],uDirLightColor[2],uPointLightPos[2],uPointLightColor[2];
|
|
50
52
|
out vec4 fragColor;
|
|
@@ -195,17 +197,20 @@ color=color*(vec3(1.0)-ccF)+getStudioRadiance(R,uClearcoat.y)*ccF*uEnvIntensity;
|
|
|
195
197
|
color=applyToneMapping(color,uToneMapping);
|
|
196
198
|
float outAlpha=base.a;
|
|
197
199
|
if(uXrDepthEnabled==1){
|
|
198
|
-
vec2 normViewUV=gl_FragCoord.
|
|
200
|
+
vec2 normViewUV=vec2((gl_FragCoord.x-uViewport.x)/max(uViewport.z,1.0),1.0-(gl_FragCoord.y-uViewport.y)/max(uViewport.w,1.0));
|
|
199
201
|
vec2 depthUV=(uXrDepthUVTransform*vec4(normViewUV,0.0,1.0)).xy;
|
|
202
|
+
if(depthUV.x>=0.0&&depthUV.x<=1.0&&depthUV.y>=0.0&&depthUV.y<=1.0){
|
|
200
203
|
vec4 depthSample=texture(uXrDepthTex,depthUV);
|
|
201
|
-
float
|
|
202
|
-
float
|
|
203
|
-
|
|
204
|
-
|
|
204
|
+
float rawDepth=uXrDepthFormat==1?depthSample.r:(depthSample.r*255.0+depthSample.a*65280.0);
|
|
205
|
+
float realDepth=rawDepth*uXrRawValueToMeters;
|
|
206
|
+
float virtDepth=dot(uCameraFwd,uCameraFwd)>0.5?dot(vWorldPos-uCameraPos,uCameraFwd):length(uCameraPos-vWorldPos);
|
|
207
|
+
if(rawDepth>0.0&&(uXrDepthFormat==1||rawDepth<65500.0)&&realDepth>0.15&&realDepth<20.0&&virtDepth>realDepth+0.02){
|
|
208
|
+
float occAlpha=1.0-smoothstep(0.0,0.035,virtDepth-realDepth-0.02);
|
|
205
209
|
outAlpha*=occAlpha;
|
|
206
210
|
if(outAlpha<0.01)discard;
|
|
207
211
|
}
|
|
208
212
|
}
|
|
213
|
+
}
|
|
209
214
|
fragColor=vec4(color,outAlpha);
|
|
210
215
|
}`,Oe=`#version 300 es
|
|
211
216
|
layout(location=0) in vec3 aPosition;
|
|
@@ -214,4 +219,4 @@ void main(){gl_Position=uMVP*vec4(aPosition,1.0);}`,ze=`#version 300 es
|
|
|
214
219
|
precision highp float;
|
|
215
220
|
uniform vec4 uColorId;
|
|
216
221
|
out vec4 fragColor;
|
|
217
|
-
void main(){fragColor=uColorId;}`;function Le(i,e,t){let r=i.createShader(e);if(i.shaderSource(r,t),i.compileShader(r),!i.getShaderParameter(r,35713)){let n=i.getShaderInfoLog(r);throw i.deleteShader(r),new Error(`Shader compile error: ${n}`)}return r}function ve(i,e,t){let r=Le(i,35633,e),n=Le(i,35632,t),s=i.createProgram();if(i.attachShader(s,r),i.attachShader(s,n),i.linkProgram(s),!i.getProgramParameter(s,35714)){let c=i.getProgramInfoLog(s);throw i.deleteProgram(s),new Error(`Program link error: ${c}`)}return s}function xe(i,e,t){let r={};for(let n of t)r[n]=i.getUniformLocation(e,n);return r}var Ne=["uMVP","uModel","uNormalMatrix","uUvTransform","uBaseColor","uMetallic","uRoughness","uClearcoat","uEmissive","uCameraPos","uBaseColorTexture","uHasTexture","uMetallicRoughnessTexture","uHasMetallicRoughnessTexture","uNormalTexture","uHasNormalTexture","uNormalScale","uOcclusionTexture","uHasOcclusionTexture","uOcclusionStrength","uToneMapping","uEnvironmentMap","uHasEnvironmentMap","uAmbientColor","uNumDirLights","uDirLightDir","uDirLightColor","uNumPointLights","uPointLightPos","uPointLightColor","uEnvIntensity","uXrDepthTex","uXrDepthEnabled","uXrDepthFormat","uXrRawValueToMeters","uXrDepthUVTransform","uViewportSize"];function Ye(i){if(typeof i!="string")return null;let e=i.trim();if(!e||/[\x00-\x1f\x7f]/.test(e))return null;let t=e.toLowerCase();return t.startsWith("data:")?/^data:image\/(png|jpeg|jpg|webp|ktx2|avif)(;|,)/i.test(e)?e:null:t.startsWith("https://")||t.startsWith("blob:")?e:t.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(e)||/(^|[\\/])\.\.([\\/]|$)/.test(e)?null:e}function be(i,e,t,r,n,s,c){if(r===void 0||!e.accessors?.[r])return null;let h=e.accessors[r],o=e.bufferViews[h.bufferView],u=(o.byteOffset||0)+(h.byteOffset||0),a=o.byteStride&&o.byteStride>s*4?o.byteStride>>2:s,l;if(a===s)l=new Float32Array(t,u,h.count*s);else{l=new Float32Array(h.count*s);let b=new Float32Array(t,o.byteOffset||0,Math.floor(o.byteLength/4)),f=(h.byteOffset||0)>>2;for(let y=0;y<h.count;y++){let x=f+y*a;for(let M=0;M<s;M++)l[y*s+M]=b[x+M]}}let m=i.createBuffer();return c.push(m),i.bindBuffer(34962,m),i.bufferData(34962,l,35044),i.enableVertexAttribArray(n),i.vertexAttribPointer(n,s,5126,!1,0,0),l}var Je=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),Be=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function Ae(i,e,t=Be,r){if(!e||!e.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:n,bin:s}=e,c=[],h=De(n),o=[];if(Array.isArray(n.nodes))for(let E=0;E<n.nodes.length;E++){let p=n.nodes[E];p.mesh!==void 0&&n.meshes&&n.meshes[p.mesh]&&o.push({node:p,nodeIdx:E,meshIdx:p.mesh})}let u=o.length>0?o:(n.meshes||[]).map((E,p)=>({node:E,nodeIdx:-1,meshIdx:p})),a=[];if(Array.isArray(e.lights)&&e.lights.length>0)a.push(...e.lights);else if(n.extensions?.KHR_lights_punctual?.lights){let E=n.extensions.KHR_lights_punctual.lights;for(let p of E){let w=p.type==="directional"?"directional":p.type==="point"?"point":"ambient";a.push({type:w,color:p.color||[1,1,1],intensity:p.intensity!==void 0?p.intensity:1})}}if(a.length===0&&(a.push({type:"ambient",color:[1,1,1],intensity:.35}),a.push({type:"directional",color:[1,1,1],intensity:.85,direction:[.5,1,.8]})),u.length>t.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${t.maxMeshes}). Found: ${u.length}`);let l=[];if(n.textures&&n.images){if(n.textures.length>t.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${t.maxTextures}). Found: ${n.textures.length}`);for(let E=0;E<n.textures.length;E++){let p=n.textures[E],w=n.images[p.source];if(w){let L=i.createTexture();if(i.bindTexture(3553,L),i.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255])),i.texParameteri(3553,10242,10497),i.texParameteri(3553,10243,10497),i.texParameteri(3553,10241,9729),i.texParameteri(3553,10240,9729),w.bufferView!==void 0){let d=n.bufferViews[w.bufferView],A=s.slice(d.byteOffset||0,(d.byteOffset||0)+d.byteLength),P=new Blob([A],{type:w.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(P).then(V=>{i.bindTexture(3553,L),i.texImage2D(3553,0,6408,6408,5121,V),i.generateMipmap(3553),r?.()}).catch(()=>{})}else if(w.uri){let d=Ye(w.uri);if(d){let A=new Image;A.crossOrigin="anonymous",A.referrerPolicy="no-referrer",A.onload=()=>{i.bindTexture(3553,L),i.texImage2D(3553,0,6408,6408,5121,A),i.generateMipmap(3553),r?.()},A.src=d}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",w.uri)}l.push(L)}else l.push(null)}}let m=[1/0,1/0,1/0],b=[-1/0,-1/0,-1/0],f=0,y=0;for(let E=0;E<u.length;E++){let p=u[E],w=n.meshes[p.meshIdx],L=p.nodeIdx>=0?h[p.nodeIdx]:G(),d=new Float32Array(9);ie(d,L);let A={name:p.node.name||w.name||`Mesh_${p.meshIdx}`,nodeIndex:p.nodeIdx,transform:L,normalMatrix:d,primitives:[],extras:p.node.extras||w.extras};for(let P of w.primitives||[]){if(P.extensions?.KHR_draco_mesh_compression){let I=he("draco");I&&I.decodePrimitive(n,P,s)}let V=[],Z=i.createVertexArray();i.bindVertexArray(Z);let O=n.accessors[P.attributes.POSITION],_=Number(O?.count??0);if(!Number.isFinite(_)||_<0||f+_>t.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${t.maxVertices}).`);if(f+=_,O?.min&&O?.max)for(let I=0;I<3;I++){let Y=L[12+I],ne=L[12+I];for(let q=0;q<3;q++){let me=L[q*4+I]*O.min[q],de=L[q*4+I]*O.max[q];Y+=me<de?me:de,ne+=me>de?me:de}Y<m[I]&&(m[I]=Y),ne>b[I]&&(b[I]=ne)}let re=be(i,n,s,P.attributes.POSITION,0,3,V);be(i,n,s,P.attributes.NORMAL,1,3,V),be(i,n,s,P.attributes.TEXCOORD_0,2,2,V);let B=0,H=5123,S=null;if(P.indices!==void 0){let I=n.accessors[P.indices],ne=(n.bufferViews[I.bufferView].byteOffset||0)+(I.byteOffset||0);if(B=Number(I.count??0),!Number.isFinite(B)||B<0||y+B>t.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${t.maxIndices}).`);y+=B,H=I.componentType===5125?5125||5125:5123||5123;let q=i.createBuffer();V.push(q),i.bindBuffer(34963,q),I.componentType===5125?(S=new Uint32Array(s,ne,I.count),i.bufferData(34963,S,35044)):(S=new Uint16Array(s,ne,I.count),i.bufferData(34963,S,35044))}else B=O.count;let C={};for(let I of U)if(I.onBuildPrimitiveVAO){let Y=I.onBuildPrimitiveVAO(i,Z,P,n,s);Y&&(C[I.name]=Y)}i.bindVertexArray(null);let N=n.materials&&P.material!==void 0?n.materials[P.material]:null,k=Ie,j=Se,$=!1;for(let I of U)if(I.onResolveShader){let Y=I.onResolveShader(P,N,k,j);Y&&(k=Y.vs,j=Y.fs,$=!0)}let K=$?ve(i,k,j):null,le=K?xe(i,K,Ne):null,X=N?.pbrMetallicRoughness,z=X?.baseColorFactor||[.8,.8,.8,1],se=X?.metallicFactor??.1,ae=X?.roughnessFactor??.5,te=N?.extensions?.KHR_materials_clearcoat,J=te?te.clearcoatFactor??1:0,Q=Math.max(.04,te?.clearcoatRoughnessFactor??.04),ee=X?.baseColorTexture!==void 0&&l[X.baseColorTexture.index]?l[X.baseColorTexture.index]:null,oe=X?.metallicRoughnessTexture!==void 0&&l[X.metallicRoughnessTexture.index]?l[X.metallicRoughnessTexture.index]:null,Ue=N?.normalTexture!==void 0&&l[N.normalTexture.index]?l[N.normalTexture.index]:null,_e=N?.normalTexture?.scale??1,ke=N?.occlusionTexture!==void 0&&l[N.occlusionTexture.index]?l[N.occlusionTexture.index]:null,Ge=N?.occlusionTexture?.strength??1,Ve=!!(N?.extensions?.KHR_materials_transmission||C.materials?.isTransmissive);A.primitives.push({vao:Z,indexCount:B,indexType:H,baseColor:z,metallic:se,roughness:ae,clearcoat:J,clearcoatRoughness:Q,positions:re,indices:S,texture:ee,metallicRoughnessTexture:oe,normalTexture:Ue,occlusionTexture:ke,normalScale:_e,occlusionStrength:Ge,buffers:V,materialIndex:P.material,pluginData:C,customProgram:K,customUniforms:le,isTransmissive:Ve})}c.push(A)}isFinite(m[0])||(m=[-1,-1,-1]),isFinite(b[0])||(b=[1,1,1]);let x=[(m[0]+b[0])/2,(m[1]+b[1])/2,(m[2]+b[2])/2],M=b[0]-m[0],R=b[1]-m[1],D=b[2]-m[2],T=Math.max(Math.hypot(M,R,D)/2,.5),v=[m[0],m[1],m[2]],g=[b[0],b[1],b[2]],F=e.animations;if(!F){for(let E of U)if(E.onParseGLB?.(e),e.animations){F=e.animations;break}}return F||(F=[]),{meshes:c,bounds:{center:x,radius:T,min:v,max:g},lights:a,animations:F,worldMatrices:h}}var ce=class{constructor(e,t,r){this.meshes=[];this.backdropMeshes=[];this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]};this.lights=[];this.modelRootMatrix=G();this.clearColor=[0,0,0,0];this.envIntensity=1;this.shadowIntensity=0;this.shadowSoftness=.5;this.toneMapping="neutral";this.environmentTexture=null;this.animations=[];this.currentClip=null;this.animationTime=0;this.isPlayingAnimation=!1;this.autoplay=!1;this.animationName="";this.gltf=null;this.worldMatrices=[];this.initialNodeTransforms=[];this.projMatrix=G();this.viewMatrix=G();this.modelMatrix=G();this.mvpMatrix=G();this.normalMatrix=new Float32Array(9);this.initialTheta=.6;this.initialPhi=.35;this.initialDistance=null;this.customDistance=!1;this.distanceMode="auto";this.initialCustomTarget=null;this.customTarget=null;this.fov=Math.PI/4;this.minTheta=-1/0;this.maxTheta=1/0;this.minPhi=-Math.PI*.48;this.maxPhi=Math.PI*.48;this.minDistanceLimit=null;this.maxDistanceLimit=null;this.activePointers=new Map;this.isPanning=!1;this.targetTheta=.6;this.currTheta=.6;this.targetPhi=.35;this.currPhi=.35;this.targetDistance=3;this.currDistance=3;this.autoRotate=!1;this.autoRotateSpeed=Math.PI/6;this.autoRotateDelay=3e3;this.lastInteractionTime=-1/0;this.turntableRotation=0;this.isPointerDown=!1;this.interactive=!0;this.skyboxTexture=null;this.lastPointerX=0;this.lastPointerY=0;this.totalDragDist=0;this.selectedMeshName="";this.pickFbo=null;this.pickTexture=null;this.pickDepth=null;this.pickFboWidth=0;this.pickFboHeight=0;this.animFrameId=null;this.isVisible=!0;this.lastTime=0;this.lastReportedTheta=-999;this.lastReportedPhi=-999;this.lastReportedZoom=-999;this.boundPointerDown=null;this.boundPointerMove=null;this.boundPointerUp=null;this.boundWheel=null;this.boundKeyDown=null;this.boundContextMenu=null;this.boundSetCamera=null;this.boundResetCamera=null;this.xrDepthState={enabled:!1,texture:null,uvTransform:G(),rawValueToMeters:.001,format:0};this.container=e;let n,s;if(t&&typeof t.getContext=="function"?(n=t,s=r):(s=t,n=s?.canvas),!n){let o=e.querySelector("canvas");o||(o=document.createElement("canvas"),o.style.width="100%",o.style.height="100%",o.style.display="block",o.style.touchAction="none",e.prepend(o)),n=o}this.canvas=n,this.opts=s||{},this.opts.clearColor&&(this.clearColor=this.opts.clearColor);let c=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;this.opts.autoRotate!==void 0?this.autoRotate=this.opts.autoRotate&&!c:c&&(this.autoRotate=!1),this.opts.autoRotateSpeed!==void 0&&(this.autoRotateSpeed=this.opts.autoRotateSpeed),this.opts.autoRotateDelay!==void 0&&(this.autoRotateDelay=Math.max(0,Number(this.opts.autoRotateDelay)||0)),this.opts.exposure!==void 0&&(this.envIntensity=Math.max(0,Number(this.opts.exposure))),this.opts.camera&&this.setInitialCamera(this.opts.camera.theta,this.opts.camera.phi,this.opts.camera.distance,this.opts.camera.zoom),this.opts.shadowIntensity!==void 0&&(this.shadowIntensity=Math.max(0,Math.min(1,Number(this.opts.shadowIntensity)||0))),this.opts.shadowSoftness!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(this.opts.shadowSoftness)||0))),this.opts.toneMapping!==void 0&&(this.toneMapping=this.opts.toneMapping),this.opts.autoplay!==void 0&&(this.autoplay=this.opts.autoplay),this.opts.animationName!==void 0&&(this.animationName=this.opts.animationName),this.opts.fieldOfView!==void 0&&(this.fov=this.opts.fieldOfView*Math.PI/180),this.opts.distanceMode!==void 0&&(this.distanceMode=this.opts.distanceMode),this.opts.cameraTarget!==void 0&&(this.setTarget(this.opts.cameraTarget[0],this.opts.cameraTarget[1],this.opts.cameraTarget[2]),this.initialCustomTarget=[...this.opts.cameraTarget]),(this.opts.minCameraOrbit||this.opts.maxCameraOrbit)&&this.setOrbitLimits({minTheta:this.opts.minCameraOrbit?.theta,maxTheta:this.opts.maxCameraOrbit?.theta,minPhi:this.opts.minCameraOrbit?.phi,maxPhi:this.opts.maxCameraOrbit?.phi,minDistance:this.opts.minCameraOrbit?.distance,maxDistance:this.opts.maxCameraOrbit?.distance});let h=n.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!h)throw new Error("WebGL2 not supported");this.gl=h,this.renderProg=ve(h,Ie,Se),this.pickProg=ve(h,Oe,ze),this.uRender=xe(h,this.renderProg,Ne),this.uPick=xe(h,this.pickProg,["uMVP","uColorId"]),this.setupPickingFbo(),this.setupEvents(),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}static registerDecoder(e,t){Xe(e,t)}static getDecoder(e){return he(e)}setupPickingFbo(){let e=this.gl;if(typeof e.createFramebuffer!="function")return;this.pickFbo=e.createFramebuffer(),this.pickTexture=e.createTexture(),this.pickDepth=e.createRenderbuffer();let t=Math.max(1,this.canvas.width),r=Math.max(1,this.canvas.height);this.pickFboWidth=t,this.pickFboHeight=r,e.bindTexture(3553,this.pickTexture),e.texImage2D(3553,0,6408,t,r,0,6408,5121,null),e.texParameteri(3553,10241,9728),e.texParameteri(3553,10240,9728),e.bindRenderbuffer(36161,this.pickDepth),e.renderbufferStorage(36161,33189,t,r),e.bindFramebuffer(36160,this.pickFbo),e.framebufferTexture2D(36160,36064,3553,this.pickTexture,0),e.framebufferRenderbuffer(36160,36096,36161,this.pickDepth),e.bindFramebuffer(36160,null)}resizePickingFbo(e,t){if(!this.pickFbo)return;let r=this.gl,n=Math.max(1,e),s=Math.max(1,t);this.pickFboWidth=n,this.pickFboHeight=s,r.bindTexture(3553,this.pickTexture),r.texImage2D(3553,0,6408,n,s,0,6408,5121,null),r.bindRenderbuffer(36161,this.pickDepth),r.renderbufferStorage(36161,33189,n,s)}loadGLBData(e,t){let{meshes:r,bounds:n,lights:s,animations:c,worldMatrices:h}=Ae(this.gl,e,t,()=>this.render());if(this.disposeMeshGpuResources(),this.meshes=r,this.bounds=n,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=s,this.animations=c||[],this.worldMatrices=h||[],this.gltf=e.gltf,this.initialNodeTransforms=[],Array.isArray(e.gltf?.nodes))for(let u of e.gltf.nodes)this.initialNodeTransforms.push({t:u.translation?[u.translation[0],u.translation[1],u.translation[2]]:[0,0,0],r:u.rotation?[u.rotation[0],u.rotation[1],u.rotation[2],u.rotation[3]]:[0,0,0,1],s:u.scale?[u.scale[0],u.scale[1],u.scale[2]]:[1,1,1]});this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let u of U)u.onLoadModel?.(this,this.gltf);this.customDistance||(this.initialDistance=this.distanceMode==="absolute"?3:n.radius*2.5,this.targetDistance=this.initialDistance,this.currDistance=this.initialDistance);let o=e.exposure??e.environmentIntensity??e.gltf?.extras?.exposure??e.gltf?.extras?.environmentIntensity??e.gltf?.asset?.extras?.exposure??e.gltf?.asset?.extras?.environmentIntensity;o!==void 0&&(this.envIntensity=Math.max(0,Number(o))),this.container&&typeof this.container.hasAttribute=="function"&&this.container.hasAttribute("poster")&&this.container.removeAttribute("poster"),this.resize(),this.update(0),this.render(),this.animFrameId===null&&typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}loadGLB(e){this.loadGLBData(Ce(e))}loadModel(e){this.loadGLBData(we(e))}setBackdropGLB(e,t){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!e){this.update(0),this.render();return}let r=we(e),{meshes:n}=Ae(this.gl,r,Be,()=>this.render());if(t)for(let s of n)s.transform[12]+=t[0],s.transform[13]+=t[1],s.transform[14]+=t[2],ie(s.normalMatrix,s.transform);this.backdropMeshes=n,this.update(0),this.render()}setClearColor(e,t,r,n=1){this.clearColor=[e,t,r,n]}updateMeshTransforms(e){for(let t=0;t<this.meshes.length;t++){let r=this.meshes[t],n;e instanceof Map?n=e.get(r.name)??e.get(t):Array.isArray(e)?n=e[t]:e&&typeof e=="object"&&(Object.prototype.hasOwnProperty.call(e,r.name)?n=e[r.name]:Object.prototype.hasOwnProperty.call(e,t)&&(n=e[t])),n&&n.length===16&&(r.transform.set(n),ie(r.normalMatrix,r.transform))}}bindLights(e=this.uRender){let t=this.gl,r=[.28,.28,.28],n=[],s=[],c=[],h=[];for(let o of this.lights){let u=o.color||[1,1,1],a=o.intensity!==void 0?o.intensity:1;if(o.type==="ambient")r=[u[0]*a,u[1]*a,u[2]*a];else if(o.type==="directional"&&n.length<6){let l=o.direction||[.5,1,.8];n.push(l[0],l[1],l[2]),s.push(u[0]*a,u[1]*a,u[2]*a)}else if(o.type==="point"&&c.length<6){let l=o.position||[0,0,0];c.push(l[0],l[1],l[2]),h.push(u[0]*a,u[1]*a,u[2]*a)}}n.length===0&&(n.push(.5,1,.8),s.push(1,1,1)),t.uniform3fv(e.uAmbientColor,r),t.uniform1i(e.uNumDirLights,n.length/3),n.length>0&&(t.uniform3fv(e.uDirLightDir,n),t.uniform3fv(e.uDirLightColor,s)),t.uniform1i(e.uNumPointLights,c.length/3),c.length>0&&(t.uniform3fv(e.uPointLightPos,c),t.uniform3fv(e.uPointLightColor,h)),t.uniform1f(e.uEnvIntensity,this.envIntensity)}setExposure(e){this.envIntensity=Math.max(0,Number(e))}getExposure(){return this.envIntensity}setShadow(e,t){this.shadowIntensity=Math.max(0,Math.min(1,Number(e)||0)),t!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(t)||0)))}getShadowIntensity(){return this.shadowIntensity}getShadowSoftness(){return this.shadowSoftness}setToneMapping(e){this.toneMapping=e}getToneMapping(){return this.toneMapping}async setEnvironmentImage(e){for(let t of U)if(t.setEnvironmentImage){await t.setEnvironmentImage(this,e);return}}async setSkyboxImage(e){for(let t of U)if(t.setSkyboxImage){await t.setSkyboxImage(this,e);return}}setInteractive(e){this.interactive=e}isInteractive(){return this.interactive}getCameraOrbit(){let e=this.currTheta,t=this.currPhi,r=this.currDistance;return{theta:e,phi:t,radius:r,toString(){return`${e.toFixed(4)}rad ${t.toFixed(4)}rad ${r.toFixed(4)}m`}}}getCameraTarget(){let e=this.customTarget||this.bounds.center;return{x:e[0],y:e[1],z:e[2],toString(){return`${e[0].toFixed(4)}m ${e[1].toFixed(4)}m ${e[2].toFixed(4)}m`}}}jumpCameraToGoal(){this.currTheta=this.targetTheta,this.currPhi=this.targetPhi,this.currDistance=this.targetDistance,this.update(0),this.render()}getModelMaterials(){let e=this.gltf?.materials?.length?this.gltf.materials:[{name:"DefaultMaterial",pbrMetallicRoughness:{}}];return e.map((t,r)=>{let n=this.meshes.flatMap(a=>a.primitives.filter(l=>l.materialIndex===r||e.length===1&&l.materialIndex===void 0)),s=n[0],c=s?[...s.baseColor]:t.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],h=s?s.metallic:t.pbrMetallicRoughness?.metallicFactor??.1,o=s?s.roughness:t.pbrMetallicRoughness?.roughnessFactor??.5,u={baseColorFactor:c,metallicFactor:h,roughnessFactor:o,setBaseColorFactor:a=>{let l=[a[0],a[1],a[2],a[3]??1];u.baseColorFactor=l,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.baseColorFactor=l);for(let m of n)m.baseColor=l;this.render()},setMetallicFactor:a=>{u.metallicFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.metallicFactor=a);for(let l of n)l.metallic=a;this.render()},setRoughnessFactor:a=>{u.roughnessFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.roughnessFactor=a);for(let l of n)l.roughness=a;this.render()}};return{name:t.name||`Material_${r}`,pbrMetallicRoughness:u}})}playAnimation(e){if(this.animations.length!==0){if(e){let t=this.animations.find(r=>r.name===e);t&&(this.currentClip=t)}else this.currentClip||(this.currentClip=this.animations[0]);this.isPlayingAnimation=!0}}pauseAnimation(){this.isPlayingAnimation=!1}getAvailableAnimations(){return this.animations.map(e=>e.name)}setAutoplay(e){this.autoplay=e,e?this.playAnimation(this.animationName||void 0):this.pauseAnimation()}setAnimationName(e){this.animationName=e,(this.isPlayingAnimation||this.autoplay)&&this.playAnimation(e)}evaluateAnimation(e){for(let t of U)if(t.evaluateAnimation){t.evaluateAnimation(this,e);return}}setTarget(e,t,r){this.customTarget=[e,t,r],this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}getTarget(){return this.customTarget?[...this.customTarget]:null}setFieldOfView(e){let t=Math.max(10,Math.min(90,e));this.fov=t*Math.PI/180}getFieldOfView(){return this.fov*180/Math.PI}setDistanceMode(e){if(this.distanceMode=e,!this.customDistance){let t=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=t,this.targetDistance=t,this.currDistance=t,this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}}getDistanceMode(){return this.distanceMode}setOrbitLimits(e){e.minTheta!==void 0&&(this.minTheta=e.minTheta*Math.PI/180),e.maxTheta!==void 0&&(this.maxTheta=e.maxTheta*Math.PI/180),e.minPhi!==void 0&&(this.minPhi=Math.max(-Math.PI*.48,e.minPhi*Math.PI/180)),e.maxPhi!==void 0&&(this.maxPhi=Math.min(Math.PI*.48,e.maxPhi*Math.PI/180)),e.minDistance!==void 0&&(this.minDistanceLimit=e.minDistance),e.maxDistance!==void 0&&(this.maxDistanceLimit=e.maxDistance),this.targetTheta=this.clampTheta(this.targetTheta),this.targetPhi=this.clampPhi(this.targetPhi),this.targetDistance=this.clampDistance(this.targetDistance)}getOrbitLimits(){return{minTheta:isFinite(this.minTheta)?this.minTheta*180/Math.PI:void 0,maxTheta:isFinite(this.maxTheta)?this.maxTheta*180/Math.PI:void 0,minPhi:this.minPhi*180/Math.PI,maxPhi:this.maxPhi*180/Math.PI,minDistance:this.minDistanceLimit!==null?this.minDistanceLimit:void 0,maxDistance:this.maxDistanceLimit!==null?this.maxDistanceLimit:void 0}}clampTheta(e){return Math.max(this.minTheta,Math.min(this.maxTheta,e))}clampPhi(e){return Math.max(this.minPhi,Math.min(this.maxPhi,e))}clampDistance(e){let t=this.minDistanceLimit!==null?this.minDistanceLimit:this.bounds?this.bounds.radius*.5:.1,r=this.maxDistanceLimit!==null?this.maxDistanceLimit:this.bounds?this.bounds.radius*8:100;return Math.max(t,Math.min(r,e))}setCamera(e,t,r,n){e!==void 0&&(this.targetTheta=this.clampTheta(e*Math.PI/180)),t!==void 0&&(this.targetPhi=this.clampPhi(t*Math.PI/180)),r!==void 0&&r>0&&(this.targetDistance=this.clampDistance(r)),n!==void 0&&n>0&&(this.targetDistance=this.clampDistance(this.bounds.radius*2.5/n))}setInitialCamera(e,t,r,n){if(e!==void 0&&(this.initialTheta=this.clampTheta(e*Math.PI/180),this.targetTheta=this.initialTheta,this.currTheta=this.initialTheta),t!==void 0&&(this.initialPhi=this.clampPhi(t*Math.PI/180),this.targetPhi=this.initialPhi,this.currPhi=this.initialPhi),r!==void 0&&r>0){let s=this.clampDistance(r);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else if(n!==void 0&&n>0){let s=this.clampDistance(this.bounds.radius*2.5/n);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else{this.customDistance=!1;let s=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=s,this.targetDistance=s,this.currDistance=s}this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}resetCamera(){this.targetTheta=this.clampTheta(this.initialTheta),this.targetPhi=this.clampPhi(this.initialPhi),this.initialDistance!==null?this.targetDistance=this.clampDistance(this.initialDistance):this.targetDistance=this.clampDistance(this.bounds.radius*2.5),this.initialCustomTarget?this.customTarget=[...this.initialCustomTarget]:this.customTarget=null,this.turntableRotation=0,this.updateTurntableMatrix()}projectPointToScreen(e,t){let r=G();W(r,this.projMatrix,this.viewMatrix);let[n,s,c]=e,h=t?t[0]:0,o=t?t[1]:0,u=t?t[2]:0,a=this.modelRootMatrix;a&&(n=a[0]*e[0]+a[4]*e[1]+a[8]*e[2]+a[12],s=a[1]*e[0]+a[5]*e[1]+a[9]*e[2]+a[13],c=a[2]*e[0]+a[6]*e[1]+a[10]*e[2]+a[14],t&&(h=a[0]*t[0]+a[4]*t[1]+a[8]*t[2],o=a[1]*t[0]+a[5]*t[1]+a[9]*t[2],u=a[2]*t[0]+a[6]*t[1]+a[10]*t[2]));let l=r[0]*n+r[4]*s+r[8]*c+r[12],m=r[1]*n+r[5]*s+r[9]*c+r[13],b=r[2]*n+r[6]*s+r[10]*c+r[14],f=r[3]*n+r[7]*s+r[11]*c+r[15];if(f<=1e-4)return{x:0,y:0,z:1,visible:!1};let y=l/f,x=m/f,M=b/f,R=this.canvas.getBoundingClientRect(),D=R.width||this.canvas.clientWidth||this.canvas.width||300,T=R.height||this.canvas.clientHeight||this.canvas.height||150,v=(y*.5+.5)*D,g=(-x*.5+.5)*T,F=y>=-1.1&&y<=1.1&&x>=-1.1&&x<=1.1&&M>=-1&&M<=1;if(F&&t){let E=this.customTarget||this.bounds.center,p=E[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),w=E[1]+this.currDistance*Math.sin(this.currPhi),L=E[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),d=[n-p,s-w,c-L];h*d[0]+o*d[1]+u*d[2]>.05&&(F=!1)}return{x:v,y:g,z:M,visible:F}}setSelectedMesh(e){this.selectedMeshName=e||""}setupEvents(){let e=this.canvas;this.boundContextMenu=t=>{t.preventDefault()},e.addEventListener("contextmenu",this.boundContextMenu),this.boundPointerDown=t=>{this.interactive&&(this.isPointerDown=!0,this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist=0,this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.isPanning=t.button===2||t.shiftKey||this.activePointers.size===2,e.setPointerCapture(t.pointerId))},e.addEventListener("pointerdown",this.boundPointerDown),this.boundPointerMove=t=>{if(!this.isPointerDown||!this.interactive)return;this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let r=this.activePointers.get(t.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},n=t.clientX-r.x,s=t.clientY-r.y;if(this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist+=Math.hypot(n,s),this.isPanning||t.button===2||t.shiftKey||this.activePointers.size===2){let c=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],h=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],o=this.customTarget?[...this.customTarget]:[...this.bounds.center],u=this.currDistance/Math.max(e.clientHeight||300,1)*1.5;o[0]+=(-n*c[0]+s*h[0])*u,o[1]+=(-n*c[1]+s*h[1])*u,o[2]+=(-n*c[2]+s*h[2])*u,this.customTarget=o}else this.targetTheta=this.clampTheta(this.targetTheta-n*.008),this.targetPhi=this.clampPhi(this.targetPhi+s*.008)},e.addEventListener("pointermove",this.boundPointerMove),this.boundPointerUp=t=>{this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.activePointers.delete(t.pointerId),this.activePointers.size===0?(this.isPointerDown=!1,this.isPanning=!1):this.activePointers.size===1&&(this.isPanning=!1);try{e.releasePointerCapture(t.pointerId)}catch{}if(this.totalDragDist<5&&t.button===0){let r=e.getBoundingClientRect(),n=Math.floor((t.clientX-r.left)*(e.width/Math.max(r.width,1))),s=Math.floor((t.clientY-r.top)*(e.height/Math.max(r.height,1)));this.performMeshPick(n,s,!0)}},e.addEventListener("pointerup",this.boundPointerUp),this.boundWheel=t=>{if(!this.interactive)return;t.preventDefault(),this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let r=Math.exp(t.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*r)},e.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=t=>{let r=t.detail||{};r.reset?this.resetCamera():this.setCamera(r.theta,r.phi,r.distance,r.zoom)},this.container.addEventListener("setCamera",this.boundSetCamera),this.boundResetCamera=()=>{this.resetCamera()},this.container.addEventListener("resetCamera",this.boundResetCamera),e.tabIndex!==void 0&&e.tabIndex<0&&(e.tabIndex=0),e.getAttribute?.("role")||e.setAttribute?.("role","region"),e.getAttribute?.("aria-label")||e.setAttribute?.("aria-label","Interactive 3D model viewport"),this.boundKeyDown=t=>{if(!this.interactive)return;let r=typeof performance<"u"?performance.now():Date.now();switch(t.key){case"ArrowLeft":this.lastInteractionTime=r,this.targetTheta=this.clampTheta(this.targetTheta-.1),t.preventDefault();break;case"ArrowRight":this.lastInteractionTime=r,this.targetTheta=this.clampTheta(this.targetTheta+.1),t.preventDefault();break;case"ArrowUp":this.lastInteractionTime=r,this.targetPhi=this.clampPhi(this.targetPhi+.08),t.preventDefault();break;case"ArrowDown":this.lastInteractionTime=r,this.targetPhi=this.clampPhi(this.targetPhi-.08),t.preventDefault();break;case"+":case"=":{this.lastInteractionTime=r,this.targetDistance=this.clampDistance(this.targetDistance*.9),t.preventDefault();break}case"-":case"_":{this.lastInteractionTime=r,this.targetDistance=this.clampDistance(this.targetDistance*1.1),t.preventDefault();break}case"Home":this.lastInteractionTime=r,this.resetCamera(),t.preventDefault();break}},e.addEventListener("keydown",this.boundKeyDown)}teardownEvents(){let e=this.canvas;this.boundContextMenu&&(e.removeEventListener("contextmenu",this.boundContextMenu),this.boundContextMenu=null),this.boundPointerDown&&(e.removeEventListener("pointerdown",this.boundPointerDown),this.boundPointerDown=null),this.boundPointerMove&&(e.removeEventListener("pointermove",this.boundPointerMove),this.boundPointerMove=null),this.boundPointerUp&&(e.removeEventListener("pointerup",this.boundPointerUp),this.boundPointerUp=null),this.boundWheel&&(e.removeEventListener("wheel",this.boundWheel),this.boundWheel=null),this.boundKeyDown&&(e.removeEventListener("keydown",this.boundKeyDown),this.boundKeyDown=null),this.boundSetCamera&&(this.container.removeEventListener("setCamera",this.boundSetCamera),this.boundSetCamera=null),this.boundResetCamera&&(this.container.removeEventListener("resetCamera",this.boundResetCamera),this.boundResetCamera=null)}raycastFromScreenPoint(e,t){let r=this.canvas,n=r.getBoundingClientRect(),s=r.width||300,c=r.height||300,h=n.width>0?Math.floor((e-n.left)*(s/n.width)):Math.floor(e),o=n.height>0?Math.floor((t-n.top)*(c/n.height)):Math.floor(t);return this.performMeshPick(h,o,!1)}performMeshPick(e,t,r=!0){if(this.meshes.length===0)return null;let n=this.gl,s=Math.max(1,this.canvas.width||300),c=Math.max(1,this.canvas.height||300),h=G();W(h,this.projMatrix,this.viewMatrix);let o=[],u=Math.max(0,Math.min(s-1,e)),a=Math.max(0,Math.min(c-1,c-1-t));if(this.pickFbo&&n){(this.pickFboWidth!==s||this.pickFboHeight!==c)&&this.resizePickingFbo(s,c),n.bindFramebuffer(36160,this.pickFbo),n.viewport(0,0,s,c),n.enable(2929),n.clearColor(0,0,0,0),n.clear(16384|256),n.useProgram(this.pickProg);for(let F=0;F<this.meshes.length;F++){let E=this.meshes[F];if(E.visible===!1||E.isPluginMesh)continue;let p=F+1,w=(p&255)/255,L=(p>>8&255)/255,d=(p>>16&255)/255;n.uniform4f(this.uPick.uColorId,w,L,d,1),W(this.modelMatrix,this.modelRootMatrix,E.transform),W(this.mvpMatrix,h,this.modelMatrix),n.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let A of E.primitives)n.bindVertexArray(A.vao),n.drawElements(4,A.indexCount,A.indexType,0)}let v=new Uint8Array(4);n.readPixels(u,a,1,1,6408,5121,v),n.bindFramebuffer(36160,null);let g=v[0]+(v[1]<<8)+(v[2]<<16);g>0&&g<=this.meshes.length&&(o=[this.meshes[g-1]])}o.length===0&&(o=this.meshes.filter(v=>v.visible!==!1));let l=null,m=1/0,b=[0,0,0],f=[0,1,0],y=this.customTarget||this.bounds.center,x=y[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),M=y[1]+this.currDistance*Math.sin(this.currPhi),R=y[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let v of o){W(this.modelMatrix,this.modelRootMatrix,v.transform),W(this.mvpMatrix,h,this.modelMatrix);let g=G();if(!Me(g,this.mvpMatrix))continue;let F=(u+.5)/s*2-1,E=(a+.5)/c*2-1,p=[0,0,0],w=[0,0,0];pe(p,F,E,-1,g),pe(w,F,E,1,g);let L=w[0]-p[0],d=w[1]-p[1],A=w[2]-p[2],P=Math.hypot(L,d,A)||1,V=L/P,Z=d/P,O=A/P,_={distance:1/0,point:[0,0,0],normal:[0,1,0]};if((B=>{for(let H of v.primitives){if(!H.positions)continue;let S=H.positions,C=H.indices,N=Math.floor(C?C.length/3:S.length/9);for(let k=0;k<N;k++){let j=C?C[k*3]:k*3,$=C?C[k*3+1]:k*3+1,K=C?C[k*3+2]:k*3+2;Re(p[0],p[1],p[2],V,Z,O,S[j*3],S[j*3+1],S[j*3+2],S[$*3],S[$*3+1],S[$*3+2],S[K*3],S[K*3+1],S[K*3+2],_,B)}}})(1e-4),isFinite(_.distance)){let B=_.point[0],H=_.point[1],S=_.point[2],C=this.modelMatrix,N=C[0]*B+C[4]*H+C[8]*S+C[12],k=C[1]*B+C[5]*H+C[9]*S+C[13],j=C[2]*B+C[6]*H+C[10]*S+C[14],$=N-x,K=k-M,le=j-R,X=Math.hypot($,K,le);if(X<m){ie(this.normalMatrix,this.modelMatrix);let z=this.normalMatrix,se=_.normal[0],ae=_.normal[1],te=_.normal[2],J=z[0]*se+z[3]*ae+z[6]*te,Q=z[1]*se+z[4]*ae+z[7]*te,ee=z[2]*se+z[5]*ae+z[8]*te,oe=Math.hypot(J,Q,ee)||1;J/=oe,Q/=oe,ee/=oe,J*$+Q*K+ee*le>0&&(J=-J,Q=-Q,ee=-ee),l=v,m=Math.round(X*1e3)/1e3,b=[Math.round(N*1e3)/1e3,Math.round(k*1e3)/1e3,Math.round(j*1e3)/1e3],f=[Math.round(J*1e3)/1e3,Math.round(Q*1e3)/1e3,Math.round(ee*1e3)/1e3]}}}if(!l)return null;let T={meshIndex:this.meshes.indexOf(l),meshName:l.name,nodeIndex:l.nodeIndex,distance:m,hitPoint:b,normal:f,screenX:e,screenY:t};if(r){for(let v of U)v.onMeshSelect?.(this,T);this.opts.onMeshClick&&this.opts.onMeshClick(T),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:T}))}return T}resize(){let e=Math.min((typeof window<"u"?window.devicePixelRatio:1)||1,2),t=this.canvas.getBoundingClientRect(),r=Math.max(1,Math.floor(t.width*e)),n=Math.max(1,Math.floor(t.height*e));(this.canvas.width!==r||this.canvas.height!==n)&&(this.canvas.width=r,this.canvas.height=n,this.resizePickingFbo(r,n))}start(){if(this.animFrameId!==null)return;this.lastTime=performance.now();let e=t=>{let r=Math.min((t-this.lastTime)/1e3,.1);this.lastTime=t,this.isVisible&&(this.resize(),this.update(r),this.render()),this.animFrameId=requestAnimationFrame(e)};this.animFrameId=requestAnimationFrame(e)}stop(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null)}setAutoRotate(e){this.autoRotate=e}getAutoRotate(){return this.autoRotate}setAutoRotateSpeed(e){this.autoRotateSpeed=e}getAutoRotateSpeed(){return this.autoRotateSpeed}setAutoRotateDelay(e){this.autoRotateDelay=Math.max(0,Number(e)||0)}getAutoRotateDelay(){return this.autoRotateDelay}resetTurntableRotation(e=0){this.turntableRotation=Number(e)||0,this.updateTurntableMatrix(),this.render()}updateTurntableMatrix(){let e=Math.cos(this.turntableRotation),t=Math.sin(this.turntableRotation),r=this.bounds.center[0],n=this.bounds.center[2],s=this.modelRootMatrix;s[0]=e,s[1]=0,s[2]=-t,s[3]=0,s[4]=0,s[5]=1,s[6]=0,s[7]=0,s[8]=t,s[9]=0,s[10]=e,s[11]=0,s[12]=r-(e*r+t*n),s[13]=0,s[14]=n-(-t*r+e*n),s[15]=1}setVisible(e){this.isVisible=e}update(e){for(let m of U)m.onUpdate?.(this,e);let t=typeof performance<"u"?performance.now():Date.now();if(!this.isPointerDown&&this.autoRotate&&t-this.lastInteractionTime>=this.autoRotateDelay){this.turntableRotation+=this.autoRotateSpeed*e,this.updateTurntableMatrix();for(let m of U)m.onCameraChange?.(this,this.container)}this.currTheta+=(this.targetTheta-this.currTheta)*.12,this.currPhi+=(this.targetPhi-this.currPhi)*.12,this.currDistance+=(this.targetDistance-this.currDistance)*.12;let r=(this.canvas.width||1)/(this.canvas.height||1),n=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):this.bounds.radius*20;ge(this.projMatrix,this.fov,r,.1,n);let s=this.customTarget||this.bounds.center,c=s[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),h=s[1]+this.currDistance*Math.sin(this.currPhi),o=s[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);ye(this.viewMatrix,[c,h,o],s,[0,1,0]),W(this.mvpMatrix,this.projMatrix,this.viewMatrix),ie(this.normalMatrix,this.modelMatrix);let u=Math.round((this.currTheta*180/Math.PI%360+360)%360),a=Math.round(this.currPhi*180/Math.PI),l=Math.round(this.bounds.radius*2.5/this.currDistance*100)/100;if(Math.abs(u-this.lastReportedTheta)>=1||Math.abs(a-this.lastReportedPhi)>=1||Math.abs(l-this.lastReportedZoom)>=.02){this.lastReportedTheta=u,this.lastReportedPhi=a,this.lastReportedZoom=l;let m={theta:u,phi:a,zoom:l,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(m),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:m}))}}renderXRView(e,t,r,n){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(e);let s=e?.transform?.inverse?.matrix||this.viewMatrix,c=e?.projectionMatrix||this.projMatrix,h=e?.transform?.position,o=h?[h.x,h.y,h.z]:[0,1.6,0];r&&t&&this.modelRootMatrix.set(t),this.render({viewMatrix:s,projMatrix:c,eyePos:o,viewport:n,eye:e?.eye||"none",clear:e?.eye!=="right"})}render(e){let t=this.gl,r=this.canvas.width,n=this.canvas.height;e?.viewport?(t.viewport(e.viewport[0],e.viewport[1],e.viewport[2],e.viewport[3]),r=e.viewport[2],n=e.viewport[3]):t.viewport(0,0,this.canvas.width,this.canvas.height),t.enable(2929),(!e||e.clear!==!1)&&(t.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),t.clear(16384|256));let s=G();W(s,e?.projMatrix??this.projMatrix,e?.viewMatrix??this.viewMatrix);let c=this.toneMapping==="reinhard"?1:this.toneMapping==="none"?2:0,h=this.customTarget||this.bounds.center,o=e?e.eyePos[0]:h[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),u=e?e.eyePos[1]:h[1]+this.currDistance*Math.sin(this.currPhi),a=e?e.eyePos[2]:h[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let x of U)x.onBeforeDrawScene?.(this,t,s,[o,u,a],c);if(this.meshes.length===0&&this.backdropMeshes.length===0)return;let l=e?.eye||"none",m=!1,b=this.backdropMeshes.length,f=b>0?[...this.backdropMeshes,...this.meshes]:this.meshes,y=x=>{for(let M=0;M<f.length;M++){let R=f[M];if(R.visible===!1)continue;let D=this.selectedMeshName!==""&&R.name===this.selectedMeshName;M<b?this.modelMatrix.set(R.transform):W(this.modelMatrix,this.modelRootMatrix,R.transform),W(this.mvpMatrix,s,this.modelMatrix),ie(R.normalMatrix,this.modelMatrix);let T=R.extras?.xr?.stereo||R.userData?.xr?.stereo,v=0,g=0,F=1,E=1;T==="sbs"?(F=.5,v=l==="right"?.5:0):T==="ou"&&(E=.5,g=l==="right"?.5:0);for(let p of R.primitives){let w=!!p.isTransmissive;if(!x&&w){m=!0;continue}if(x&&!w)continue;let L=p.customProgram||this.renderProg,d=p.customUniforms||this.uRender;t.useProgram(L),t.uniform1i(d.uToneMapping,c),t.uniform1f(d.uEnvIntensity,this.envIntensity),t.uniform3f(d.uCameraPos,o,u,a),t.uniform1f(d.uEmissive,D?1:0),t.uniformMatrix4fv(d.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(d.uModel,!1,this.modelMatrix),t.uniformMatrix3fv(d.uNormalMatrix,!1,R.normalMatrix),d.uUvTransform&&t.uniform4f(d.uUvTransform,v,g,F,E),d.uViewportSize&&t.uniform2f(d.uViewportSize,Math.max(1,r),Math.max(1,n)),this.xrDepthState.enabled&&this.xrDepthState.texture?(t.activeTexture(33989),t.bindTexture(3553,this.xrDepthState.texture),d.uXrDepthTex&&t.uniform1i(d.uXrDepthTex,5),d.uXrDepthEnabled&&t.uniform1i(d.uXrDepthEnabled,1),d.uXrDepthFormat&&t.uniform1i(d.uXrDepthFormat,this.xrDepthState.format||0),d.uXrRawValueToMeters&&t.uniform1f(d.uXrRawValueToMeters,this.xrDepthState.rawValueToMeters),d.uXrDepthUVTransform&&t.uniformMatrix4fv(d.uXrDepthUVTransform,!1,this.xrDepthState.uvTransform)):d.uXrDepthEnabled&&t.uniform1i(d.uXrDepthEnabled,0),this.environmentTexture?(t.activeTexture(33988),t.bindTexture(3553,this.environmentTexture),t.uniform1i(d.uEnvironmentMap,4),t.uniform1i(d.uHasEnvironmentMap,1)):t.uniform1i(d.uHasEnvironmentMap,0),this.bindLights(d);for(let A of U)A.onBeforeDrawPrimitive?.(t,L,p,R,this.worldMatrices||[],this.gltf);t.uniform4fv(d.uBaseColor,p.baseColor),t.uniform1f(d.uMetallic,p.metallic),t.uniform1f(d.uRoughness,p.roughness),d.uClearcoat&&t.uniform2f(d.uClearcoat,p.clearcoat??0,p.clearcoatRoughness??.04),p.texture?(t.activeTexture(33984),t.bindTexture(3553,p.texture),t.uniform1i(d.uBaseColorTexture,0),t.uniform1i(d.uHasTexture,1)):t.uniform1i(d.uHasTexture,0),p.metallicRoughnessTexture?(t.activeTexture(33985),t.bindTexture(3553,p.metallicRoughnessTexture),t.uniform1i(d.uMetallicRoughnessTexture,1),t.uniform1i(d.uHasMetallicRoughnessTexture,1)):t.uniform1i(d.uHasMetallicRoughnessTexture,0),p.normalTexture?(t.activeTexture(33986),t.bindTexture(3553,p.normalTexture),t.uniform1i(d.uNormalTexture,2),t.uniform1i(d.uHasNormalTexture,1),t.uniform1f(d.uNormalScale,p.normalScale)):t.uniform1i(d.uHasNormalTexture,0),p.occlusionTexture?(t.activeTexture(33987),t.bindTexture(3553,p.occlusionTexture),t.uniform1i(d.uOcclusionTexture,3),t.uniform1i(d.uHasOcclusionTexture,1),t.uniform1f(d.uOcclusionStrength,p.occlusionStrength)):t.uniform1i(d.uHasOcclusionTexture,0),t.bindVertexArray(p.vao),t.drawElements(4,p.indexCount,p.indexType,0)}}};if(y(!1),m){for(let x of U)x.onBeforeTransmissivePass?.(t,this);y(!0)}for(let x of U)x.onAfterRender?.(t,this,s)}disposeMeshListGpuResources(e){let t=this.gl;for(let r of e)for(let n of r.primitives){if(n.vao&&t.deleteVertexArray(n.vao),n.buffers)for(let s of n.buffers)t.deleteBuffer(s);n.texture&&t.deleteTexture(n.texture),n.metallicRoughnessTexture&&t.deleteTexture(n.metallicRoughnessTexture),n.normalTexture&&t.deleteTexture(n.normalTexture),n.occlusionTexture&&t.deleteTexture(n.occlusionTexture),n.customProgram&&t.deleteProgram(n.customProgram)}}disposeMeshGpuResources(){this.disposeMeshListGpuResources(this.meshes),this.meshes=[]}disposeGpuResources(){let e=this.gl;this.disposeMeshGpuResources(),this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[];for(let t of U)t.onDestroy?.(e,this);this.environmentTexture&&(e.deleteTexture(this.environmentTexture),this.environmentTexture=null),this.renderProg&&e.deleteProgram(this.renderProg),this.pickProg&&e.deleteProgram(this.pickProg),this.pickFbo&&e.deleteFramebuffer(this.pickFbo),this.pickTexture&&e.deleteTexture(this.pickTexture),this.pickDepth&&e.deleteRenderbuffer(this.pickDepth),this.pickFbo=null,this.pickTexture=null,this.pickDepth=null}dispose(){this.stop(),this.teardownEvents(),this.disposeGpuResources()}destroy(){this.dispose()}};ce.registerPlugin=Pe,ce.getRegisteredPlugins=Ee;var Qe=ce;export{ce as MicroViewer,Je as SANDBOX_HOST_SCENE_LIMITS,ce as ThreeView,He as decodeUtf8,Qe as default,he as getDecoder,Ee as getRegisteredPlugins,We as isGLBData,ie as mat3NormalFromMat4,G as mat4Create,Te as mat4FromRotationTranslationScale,Me as mat4Invert,ye as mat4LookAt,W as mat4Multiply,ge as mat4Perspective,Ce as parseGLB,Re as rayIntersectsTriangle,Ze as readFloat32Array,Xe as registerDecoder,Pe as registerPlugin,De as resolveNodeWorldMatrices,Ye as sanitizeTextureUri,we as toGLBData,pe as unprojectPoint};
|
|
222
|
+
void main(){fragColor=uColorId;}`;function Ae(i,e,t){let r=i.createShader(e);if(i.shaderSource(r,t),i.compileShader(r),!i.getShaderParameter(r,35713)){let n=i.getShaderInfoLog(r);throw i.deleteShader(r),new Error(`Shader compile error: ${n}`)}return r}function ge(i,e,t){let r=Ae(i,35633,e),n=Ae(i,35632,t),s=i.createProgram();if(i.attachShader(s,r),i.attachShader(s,n),i.linkProgram(s),!i.getProgramParameter(s,35714)){let o=i.getProgramInfoLog(s);throw i.deleteProgram(s),new Error(`Program link error: ${o}`)}return s}function ye(i,e,t){let r={};for(let n of t)r[n]=i.getUniformLocation(e,n);return r}var Ne=["uMVP","uModel","uNormalMatrix","uUvTransform","uBaseColor","uMetallic","uRoughness","uClearcoat","uEmissive","uCameraPos","uBaseColorTexture","uHasTexture","uMetallicRoughnessTexture","uHasMetallicRoughnessTexture","uNormalTexture","uHasNormalTexture","uNormalScale","uOcclusionTexture","uHasOcclusionTexture","uOcclusionStrength","uToneMapping","uEnvironmentMap","uHasEnvironmentMap","uAmbientColor","uNumDirLights","uDirLightDir","uDirLightColor","uNumPointLights","uPointLightPos","uPointLightColor","uEnvIntensity","uXrDepthTex","uXrDepthEnabled","uXrDepthFormat","uXrRawValueToMeters","uXrDepthUVTransform","uViewportSize","uViewport","uCameraFwd"];function Ye(i){if(typeof i!="string")return null;let e=i.trim();if(!e||/[\x00-\x1f\x7f]/.test(e))return null;let t=e.toLowerCase();return t.startsWith("data:")?/^data:image\/(png|jpeg|jpg|webp|ktx2|avif)(;|,)/i.test(e)?e:null:t.startsWith("https://")||t.startsWith("blob:")?e:t.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(e)||/(^|[\\/])\.\.([\\/]|$)/.test(e)?null:e}function xe(i,e,t,r,n,s,o){if(r===void 0||!e.accessors?.[r])return null;let h=e.accessors[r],c=e.bufferViews[h.bufferView],u=(c.byteOffset||0)+(h.byteOffset||0),a=c.byteStride&&c.byteStride>s*4?c.byteStride>>2:s,l;if(a===s)l=new Float32Array(t,u,h.count*s);else{l=new Float32Array(h.count*s);let b=new Float32Array(t,c.byteOffset||0,Math.floor(c.byteLength/4)),p=(h.byteOffset||0)>>2;for(let T=0;T<h.count;T++){let M=p+T*a;for(let D=0;D<s;D++)l[T*s+D]=b[M+D]}}let f=i.createBuffer();return o.push(f),i.bindBuffer(34962,f),i.bufferData(34962,l,35044),i.enableVertexAttribArray(n),i.vertexAttribPointer(n,s,5126,!1,0,0),l}var Je=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),Be=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function Le(i,e,t=Be,r){if(!e||!e.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:n,bin:s}=e,o=[],h=De(n),c=[];if(Array.isArray(n.nodes))for(let P=0;P<n.nodes.length;P++){let g=n.nodes[P];g.mesh!==void 0&&n.meshes&&n.meshes[g.mesh]&&c.push({node:g,nodeIdx:P,meshIdx:g.mesh})}let u=c.length>0?c:(n.meshes||[]).map((P,g)=>({node:P,nodeIdx:-1,meshIdx:g})),a=[];if(Array.isArray(e.lights)&&e.lights.length>0)a.push(...e.lights);else if(n.extensions?.KHR_lights_punctual?.lights){let P=n.extensions.KHR_lights_punctual.lights;for(let g of P){let A=g.type==="directional"?"directional":g.type==="point"?"point":"ambient";a.push({type:A,color:g.color||[1,1,1],intensity:g.intensity!==void 0?g.intensity:1})}}if(a.length===0&&(a.push({type:"ambient",color:[1,1,1],intensity:.35}),a.push({type:"directional",color:[1,1,1],intensity:.85,direction:[.5,1,.8]})),u.length>t.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${t.maxMeshes}). Found: ${u.length}`);let l=[];if(n.textures&&n.images){if(n.textures.length>t.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${t.maxTextures}). Found: ${n.textures.length}`);for(let P=0;P<n.textures.length;P++){let g=n.textures[P],A=n.images[g.source];if(A){let L=i.createTexture();if(i.bindTexture(3553,L),i.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255])),i.texParameteri(3553,10242,10497),i.texParameteri(3553,10243,10497),i.texParameteri(3553,10241,9729),i.texParameteri(3553,10240,9729),A.bufferView!==void 0){let F=n.bufferViews[A.bufferView],y=s.slice(F.byteOffset||0,(F.byteOffset||0)+F.byteLength),R=new Blob([y],{type:A.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(R).then(B=>{i.bindTexture(3553,L),i.texImage2D(3553,0,6408,6408,5121,B),i.generateMipmap(3553),r?.()}).catch(()=>{})}else if(A.uri){let F=Ye(A.uri);if(F){let y=new Image;y.crossOrigin="anonymous",y.referrerPolicy="no-referrer",y.onload=()=>{i.bindTexture(3553,L),i.texImage2D(3553,0,6408,6408,5121,y),i.generateMipmap(3553),r?.()},y.src=F}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",A.uri)}l.push(L)}else l.push(null)}}let f=[1/0,1/0,1/0],b=[-1/0,-1/0,-1/0],p=0,T=0;for(let P=0;P<u.length;P++){let g=u[P],A=n.meshes[g.meshIdx],L=g.nodeIdx>=0?h[g.nodeIdx]:V(),F=new Float32Array(9);ne(F,L);let y={name:g.node.name||A.name||`Mesh_${g.meshIdx}`,nodeIndex:g.nodeIdx,transform:L,normalMatrix:F,primitives:[],extras:g.node.extras||A.extras};for(let R of A.primitives||[]){if(R.extensions?.KHR_draco_mesh_compression){let S=he("draco");S&&S.decodePrimitive(n,R,s)}let B=[],x=i.createVertexArray();i.bindVertexArray(x);let X=n.accessors[R.attributes.POSITION],k=Number(X?.count??0);if(!Number.isFinite(k)||k<0||p+k>t.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${t.maxVertices}).`);if(p+=k,X?.min&&X?.max)for(let S=0;S<3;S++){let j=L[12+S],re=L[12+S];for(let Z=0;Z<3;Z++){let me=L[Z*4+S]*X.min[Z],de=L[Z*4+S]*X.max[Z];j+=me<de?me:de,re+=me>de?me:de}j<f[S]&&(f[S]=j),re>b[S]&&(b[S]=re)}let te=xe(i,n,s,R.attributes.POSITION,0,3,B);xe(i,n,s,R.attributes.NORMAL,1,3,B),xe(i,n,s,R.attributes.TEXCOORD_0,2,2,B);let U=0,H=5123,N=null;if(R.indices!==void 0){let S=n.accessors[R.indices],re=(n.bufferViews[S.bufferView].byteOffset||0)+(S.byteOffset||0);if(U=Number(S.count??0),!Number.isFinite(U)||U<0||T+U>t.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${t.maxIndices}).`);T+=U,H=S.componentType===5125?5125||5125:5123||5123;let Z=i.createBuffer();B.push(Z),i.bindBuffer(34963,Z),S.componentType===5125?(N=new Uint32Array(s,re,S.count),i.bufferData(34963,N,35044)):(N=new Uint16Array(s,re,S.count),i.bufferData(34963,N,35044))}else U=X.count;let I={};for(let S of G)if(S.onBuildPrimitiveVAO){let j=S.onBuildPrimitiveVAO(i,x,R,n,s);j&&(I[S.name]=j)}i.bindVertexArray(null);let _=n.materials&&R.material!==void 0?n.materials[R.material]:null,W=Ie,K=Se,q=!1;for(let S of G)if(S.onResolveShader){let j=S.onResolveShader(R,_,W,K);j&&(W=j.vs,K=j.fs,q=!0)}let $=q?ge(i,W,K):null,le=$?ye(i,$,Ne):null,O=_?.pbrMetallicRoughness,Y=O?.baseColorFactor||[.8,.8,.8,1],se=O?.metallicFactor??.1,ae=O?.roughnessFactor??.5,ie=_?.extensions?.KHR_materials_clearcoat,J=ie?ie.clearcoatFactor??1:0,Q=Math.max(.04,ie?.clearcoatRoughnessFactor??.04),ee=O?.baseColorTexture!==void 0&&l[O.baseColorTexture.index]?l[O.baseColorTexture.index]:null,oe=O?.metallicRoughnessTexture!==void 0&&l[O.metallicRoughnessTexture.index]?l[O.metallicRoughnessTexture.index]:null,Ue=_?.normalTexture!==void 0&&l[_.normalTexture.index]?l[_.normalTexture.index]:null,_e=_?.normalTexture?.scale??1,ke=_?.occlusionTexture!==void 0&&l[_.occlusionTexture.index]?l[_.occlusionTexture.index]:null,Ge=_?.occlusionTexture?.strength??1,Ve=!!(_?.extensions?.KHR_materials_transmission||I.materials?.isTransmissive);y.primitives.push({vao:x,indexCount:U,indexType:H,baseColor:Y,metallic:se,roughness:ae,clearcoat:J,clearcoatRoughness:Q,positions:te,indices:N,texture:ee,metallicRoughnessTexture:oe,normalTexture:Ue,occlusionTexture:ke,normalScale:_e,occlusionStrength:Ge,buffers:B,materialIndex:R.material,pluginData:I,customProgram:$,customUniforms:le,isTransmissive:Ve})}o.push(y)}isFinite(f[0])||(f=[-1,-1,-1]),isFinite(b[0])||(b=[1,1,1]);let M=[(f[0]+b[0])/2,(f[1]+b[1])/2,(f[2]+b[2])/2],D=b[0]-f[0],E=b[1]-f[1],w=b[2]-f[2],v=Math.max(Math.hypot(D,E,w)/2,.5),d=[f[0],f[1],f[2]],m=[b[0],b[1],b[2]],C=e.animations;if(!C){for(let P of G)if(P.onParseGLB?.(e),e.animations){C=e.animations;break}}return C||(C=[]),{meshes:o,bounds:{center:M,radius:v,min:d,max:m},lights:a,animations:C,worldMatrices:h}}var ce=class{constructor(e,t,r){this.meshes=[];this.backdropMeshes=[];this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]};this.lights=[];this.modelRootMatrix=V();this.clearColor=[0,0,0,0];this.envIntensity=1;this.shadowIntensity=0;this.shadowSoftness=.5;this.toneMapping="neutral";this.environmentTexture=null;this.animations=[];this.currentClip=null;this.animationTime=0;this.isPlayingAnimation=!1;this.autoplay=!1;this.animationName="";this.gltf=null;this.worldMatrices=[];this.initialNodeTransforms=[];this.projMatrix=V();this.viewMatrix=V();this.modelMatrix=V();this.mvpMatrix=V();this.normalMatrix=new Float32Array(9);this.initialTheta=.6;this.initialPhi=.35;this.initialDistance=null;this.customDistance=!1;this.distanceMode="auto";this.initialCustomTarget=null;this.customTarget=null;this.fov=Math.PI/4;this.minTheta=-1/0;this.maxTheta=1/0;this.minPhi=-Math.PI*.48;this.maxPhi=Math.PI*.48;this.minDistanceLimit=null;this.maxDistanceLimit=null;this.activePointers=new Map;this.isPanning=!1;this.targetTheta=.6;this.currTheta=.6;this.targetPhi=.35;this.currPhi=.35;this.targetDistance=3;this.currDistance=3;this.autoRotate=!1;this.autoRotateSpeed=Math.PI/6;this.autoRotateDelay=3e3;this.lastInteractionTime=-1/0;this.turntableRotation=0;this.isPointerDown=!1;this.interactive=!0;this.skyboxTexture=null;this.lastPointerX=0;this.lastPointerY=0;this.totalDragDist=0;this.selectedMeshName="";this.pickFbo=null;this.pickTexture=null;this.pickDepth=null;this.pickFboWidth=0;this.pickFboHeight=0;this.animFrameId=null;this.isVisible=!0;this.xrSessionActive=!1;this.lastTime=0;this.lastReportedTheta=-999;this.lastReportedPhi=-999;this.lastReportedZoom=-999;this.boundPointerDown=null;this.boundPointerMove=null;this.boundPointerUp=null;this.boundWheel=null;this.boundKeyDown=null;this.boundContextMenu=null;this.boundSetCamera=null;this.boundResetCamera=null;this.stereoSBS=!1;this.renderErrorReported=!1;this.xrDepthState={enabled:!1,texture:null,uvTransform:V(),rawValueToMeters:.001,format:0};this.container=e;let n,s;if(t&&typeof t.getContext=="function"?(n=t,s=r):(s=t,n=s?.canvas),!n){let c=e.querySelector("canvas");c||(c=document.createElement("canvas"),c.style.width="100%",c.style.height="100%",c.style.display="block",c.style.touchAction="none",e.prepend(c)),n=c}this.canvas=n,this.opts=s||{},this.opts.clearColor&&(this.clearColor=this.opts.clearColor);let o=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;this.opts.autoRotate!==void 0?this.autoRotate=this.opts.autoRotate&&!o:o&&(this.autoRotate=!1),this.opts.autoRotateSpeed!==void 0&&(this.autoRotateSpeed=this.opts.autoRotateSpeed),this.opts.autoRotateDelay!==void 0&&(this.autoRotateDelay=Math.max(0,Number(this.opts.autoRotateDelay)||0)),this.opts.exposure!==void 0&&(this.envIntensity=Math.max(0,Number(this.opts.exposure))),this.opts.camera&&this.setInitialCamera(this.opts.camera.theta,this.opts.camera.phi,this.opts.camera.distance,this.opts.camera.zoom),this.opts.shadowIntensity!==void 0&&(this.shadowIntensity=Math.max(0,Math.min(1,Number(this.opts.shadowIntensity)||0))),this.opts.shadowSoftness!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(this.opts.shadowSoftness)||0))),this.opts.toneMapping!==void 0&&(this.toneMapping=this.opts.toneMapping),this.opts.autoplay!==void 0&&(this.autoplay=this.opts.autoplay),this.opts.animationName!==void 0&&(this.animationName=this.opts.animationName),this.opts.fieldOfView!==void 0&&(this.fov=this.opts.fieldOfView*Math.PI/180),this.opts.distanceMode!==void 0&&(this.distanceMode=this.opts.distanceMode),this.opts.cameraTarget!==void 0&&(this.setTarget(this.opts.cameraTarget[0],this.opts.cameraTarget[1],this.opts.cameraTarget[2]),this.initialCustomTarget=[...this.opts.cameraTarget]),(this.opts.minCameraOrbit||this.opts.maxCameraOrbit)&&this.setOrbitLimits({minTheta:this.opts.minCameraOrbit?.theta,maxTheta:this.opts.maxCameraOrbit?.theta,minPhi:this.opts.minCameraOrbit?.phi,maxPhi:this.opts.maxCameraOrbit?.phi,minDistance:this.opts.minCameraOrbit?.distance,maxDistance:this.opts.maxCameraOrbit?.distance});let h=n.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!h)throw new Error("WebGL2 not supported");this.gl=h,this.renderProg=ge(h,Ie,Se),this.pickProg=ge(h,Oe,ze),this.uRender=ye(h,this.renderProg,Ne),this.uPick=ye(h,this.pickProg,["uMVP","uColorId"]),this.setupPickingFbo(),this.setupEvents(),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}static registerDecoder(e,t){He(e,t)}static getDecoder(e){return he(e)}setupPickingFbo(){let e=this.gl;if(typeof e.createFramebuffer!="function")return;this.pickFbo=e.createFramebuffer(),this.pickTexture=e.createTexture(),this.pickDepth=e.createRenderbuffer();let t=Math.max(1,this.canvas.width),r=Math.max(1,this.canvas.height);this.pickFboWidth=t,this.pickFboHeight=r,e.bindTexture(3553,this.pickTexture),e.texImage2D(3553,0,6408,t,r,0,6408,5121,null),e.texParameteri(3553,10241,9728),e.texParameteri(3553,10240,9728),e.bindRenderbuffer(36161,this.pickDepth),e.renderbufferStorage(36161,33189,t,r),e.bindFramebuffer(36160,this.pickFbo),e.framebufferTexture2D(36160,36064,3553,this.pickTexture,0),e.framebufferRenderbuffer(36160,36096,36161,this.pickDepth),e.bindFramebuffer(36160,null)}resizePickingFbo(e,t){if(!this.pickFbo)return;let r=this.gl,n=Math.max(1,e),s=Math.max(1,t);this.pickFboWidth=n,this.pickFboHeight=s,r.bindTexture(3553,this.pickTexture),r.texImage2D(3553,0,6408,n,s,0,6408,5121,null),r.bindRenderbuffer(36161,this.pickDepth),r.renderbufferStorage(36161,33189,n,s)}loadGLBData(e,t){let{meshes:r,bounds:n,lights:s,animations:o,worldMatrices:h}=Le(this.gl,e,t,()=>this.render());if(this.disposeMeshGpuResources(),this.meshes=r,this.bounds=n,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=s,this.animations=o||[],this.worldMatrices=h||[],this.gltf=e.gltf,this.initialNodeTransforms=[],Array.isArray(e.gltf?.nodes))for(let u of e.gltf.nodes)this.initialNodeTransforms.push({t:u.translation?[u.translation[0],u.translation[1],u.translation[2]]:[0,0,0],r:u.rotation?[u.rotation[0],u.rotation[1],u.rotation[2],u.rotation[3]]:[0,0,0,1],s:u.scale?[u.scale[0],u.scale[1],u.scale[2]]:[1,1,1]});this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let u of G)u.onLoadModel?.(this,this.gltf);this.customDistance||(this.initialDistance=this.distanceMode==="absolute"?3:n.radius*2.5,this.targetDistance=this.initialDistance,this.currDistance=this.initialDistance);let c=e.exposure??e.environmentIntensity??e.gltf?.extras?.exposure??e.gltf?.extras?.environmentIntensity??e.gltf?.asset?.extras?.exposure??e.gltf?.asset?.extras?.environmentIntensity;c!==void 0&&(this.envIntensity=Math.max(0,Number(c))),this.container&&typeof this.container.hasAttribute=="function"&&this.container.hasAttribute("poster")&&this.container.removeAttribute("poster"),this.resize(),this.update(0),this.render(),this.animFrameId===null&&typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}loadGLB(e){this.loadGLBData(Ce(e))}clearScene(){this.disposeMeshGpuResources(),this.lights=[],this.animations=[],this.currentClip=null,this.isPlayingAnimation=!1,this.worldMatrices=[],this.gltf=null,this.initialNodeTransforms=[],this.turntableRotation=0,this.updateTurntableMatrix(),this.gl&&this.render()}loadModel(e){this.loadGLBData(Ee(e))}setBackdropGLB(e,t){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!e){this.update(0),this.render();return}let r=Ee(e),{meshes:n}=Le(this.gl,r,Be,()=>this.render());if(t)for(let s of n)s.transform[12]+=t[0],s.transform[13]+=t[1],s.transform[14]+=t[2],ne(s.normalMatrix,s.transform);this.backdropMeshes=n,this.update(0),this.render()}setClearColor(e,t,r,n=1){this.clearColor=[e,t,r,n]}updateMeshTransforms(e){for(let t=0;t<this.meshes.length;t++){let r=this.meshes[t],n;e instanceof Map?n=e.get(r.name)??e.get(t):Array.isArray(e)?n=e[t]:e&&typeof e=="object"&&(Object.prototype.hasOwnProperty.call(e,r.name)?n=e[r.name]:Object.prototype.hasOwnProperty.call(e,t)&&(n=e[t])),n&&n.length===16&&(r.transform.set(n),ne(r.normalMatrix,r.transform))}}bindLights(e=this.uRender){let t=this.gl,r=[.28,.28,.28],n=[],s=[],o=[],h=[];for(let c of this.lights){let u=c.color||[1,1,1],a=c.intensity!==void 0?c.intensity:1;if(c.type==="ambient")r=[u[0]*a,u[1]*a,u[2]*a];else if(c.type==="directional"&&n.length<6){let l=c.direction||[.5,1,.8];n.push(l[0],l[1],l[2]),s.push(u[0]*a,u[1]*a,u[2]*a)}else if(c.type==="point"&&o.length<6){let l=c.position||[0,0,0];o.push(l[0],l[1],l[2]),h.push(u[0]*a,u[1]*a,u[2]*a)}}n.length===0&&(n.push(.5,1,.8),s.push(1,1,1)),t.uniform3fv(e.uAmbientColor,r),t.uniform1i(e.uNumDirLights,n.length/3),n.length>0&&(t.uniform3fv(e.uDirLightDir,n),t.uniform3fv(e.uDirLightColor,s)),t.uniform1i(e.uNumPointLights,o.length/3),o.length>0&&(t.uniform3fv(e.uPointLightPos,o),t.uniform3fv(e.uPointLightColor,h)),t.uniform1f(e.uEnvIntensity,this.envIntensity)}setExposure(e){this.envIntensity=Math.max(0,Number(e))}getExposure(){return this.envIntensity}setShadow(e,t){this.shadowIntensity=Math.max(0,Math.min(1,Number(e)||0)),t!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(t)||0)))}getShadowIntensity(){return this.shadowIntensity}getShadowSoftness(){return this.shadowSoftness}setToneMapping(e){this.toneMapping=e}getToneMapping(){return this.toneMapping}async setEnvironmentImage(e){for(let t of G)if(t.setEnvironmentImage){await t.setEnvironmentImage(this,e);return}}async setSkyboxImage(e){for(let t of G)if(t.setSkyboxImage){await t.setSkyboxImage(this,e);return}}setInteractive(e){this.interactive=e}isInteractive(){return this.interactive}getCameraOrbit(){let e=this.currTheta,t=this.currPhi,r=this.currDistance;return{theta:e,phi:t,radius:r,toString(){return`${e.toFixed(4)}rad ${t.toFixed(4)}rad ${r.toFixed(4)}m`}}}getCameraTarget(){let e=this.customTarget||this.bounds.center;return{x:e[0],y:e[1],z:e[2],toString(){return`${e[0].toFixed(4)}m ${e[1].toFixed(4)}m ${e[2].toFixed(4)}m`}}}jumpCameraToGoal(){this.currTheta=this.targetTheta,this.currPhi=this.targetPhi,this.currDistance=this.targetDistance,this.update(0),this.render()}getModelMaterials(){let e=this.gltf?.materials?.length?this.gltf.materials:[{name:"DefaultMaterial",pbrMetallicRoughness:{}}];return e.map((t,r)=>{let n=this.meshes.flatMap(a=>a.primitives.filter(l=>l.materialIndex===r||e.length===1&&l.materialIndex===void 0)),s=n[0],o=s?[...s.baseColor]:t.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],h=s?s.metallic:t.pbrMetallicRoughness?.metallicFactor??.1,c=s?s.roughness:t.pbrMetallicRoughness?.roughnessFactor??.5,u={baseColorFactor:o,metallicFactor:h,roughnessFactor:c,setBaseColorFactor:a=>{let l=[a[0],a[1],a[2],a[3]??1];u.baseColorFactor=l,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.baseColorFactor=l);for(let f of n)f.baseColor=l;this.render()},setMetallicFactor:a=>{u.metallicFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.metallicFactor=a);for(let l of n)l.metallic=a;this.render()},setRoughnessFactor:a=>{u.roughnessFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.roughnessFactor=a);for(let l of n)l.roughness=a;this.render()}};return{name:t.name||`Material_${r}`,pbrMetallicRoughness:u}})}playAnimation(e){if(this.animations.length!==0){if(e){let t=this.animations.find(r=>r.name===e);t&&(this.currentClip=t)}else this.currentClip||(this.currentClip=this.animations[0]);this.isPlayingAnimation=!0}}pauseAnimation(){this.isPlayingAnimation=!1}getAvailableAnimations(){return this.animations.map(e=>e.name)}setAutoplay(e){this.autoplay=e,e?this.playAnimation(this.animationName||void 0):this.pauseAnimation()}setAnimationName(e){this.animationName=e,(this.isPlayingAnimation||this.autoplay)&&this.playAnimation(e)}evaluateAnimation(e){for(let t of G)if(t.evaluateAnimation){t.evaluateAnimation(this,e);return}}setTarget(e,t,r){this.customTarget=[e,t,r],this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}getTarget(){return this.customTarget?[...this.customTarget]:null}setFieldOfView(e){let t=Math.max(10,Math.min(90,e));this.fov=t*Math.PI/180}getFieldOfView(){return this.fov*180/Math.PI}setDistanceMode(e){if(this.distanceMode=e,!this.customDistance){let t=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=t,this.targetDistance=t,this.currDistance=t,this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}}getDistanceMode(){return this.distanceMode}setOrbitLimits(e){e.minTheta!==void 0&&(this.minTheta=e.minTheta*Math.PI/180),e.maxTheta!==void 0&&(this.maxTheta=e.maxTheta*Math.PI/180),e.minPhi!==void 0&&(this.minPhi=Math.max(-Math.PI*.48,e.minPhi*Math.PI/180)),e.maxPhi!==void 0&&(this.maxPhi=Math.min(Math.PI*.48,e.maxPhi*Math.PI/180)),e.minDistance!==void 0&&(this.minDistanceLimit=e.minDistance),e.maxDistance!==void 0&&(this.maxDistanceLimit=e.maxDistance),this.targetTheta=this.clampTheta(this.targetTheta),this.targetPhi=this.clampPhi(this.targetPhi),this.targetDistance=this.clampDistance(this.targetDistance)}getOrbitLimits(){return{minTheta:isFinite(this.minTheta)?this.minTheta*180/Math.PI:void 0,maxTheta:isFinite(this.maxTheta)?this.maxTheta*180/Math.PI:void 0,minPhi:this.minPhi*180/Math.PI,maxPhi:this.maxPhi*180/Math.PI,minDistance:this.minDistanceLimit!==null?this.minDistanceLimit:void 0,maxDistance:this.maxDistanceLimit!==null?this.maxDistanceLimit:void 0}}clampTheta(e){return Math.max(this.minTheta,Math.min(this.maxTheta,e))}clampPhi(e){return Math.max(this.minPhi,Math.min(this.maxPhi,e))}clampDistance(e){let t=this.minDistanceLimit!==null?this.minDistanceLimit:this.bounds?this.bounds.radius*.5:.1,r=this.maxDistanceLimit!==null?this.maxDistanceLimit:this.bounds?this.bounds.radius*8:100;return Math.max(t,Math.min(r,e))}setCamera(e,t,r,n){e!==void 0&&(this.targetTheta=this.clampTheta(e*Math.PI/180)),t!==void 0&&(this.targetPhi=this.clampPhi(t*Math.PI/180)),r!==void 0&&r>0&&(this.targetDistance=this.clampDistance(r)),n!==void 0&&n>0&&(this.targetDistance=this.clampDistance(this.bounds.radius*2.5/n))}setInitialCamera(e,t,r,n){if(e!==void 0&&(this.initialTheta=this.clampTheta(e*Math.PI/180),this.targetTheta=this.initialTheta,this.currTheta=this.initialTheta),t!==void 0&&(this.initialPhi=this.clampPhi(t*Math.PI/180),this.targetPhi=this.initialPhi,this.currPhi=this.initialPhi),r!==void 0&&r>0){let s=this.clampDistance(r);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else if(n!==void 0&&n>0){let s=this.clampDistance(this.bounds.radius*2.5/n);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else{this.customDistance=!1;let s=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=s,this.targetDistance=s,this.currDistance=s}this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}resetCamera(){this.targetTheta=this.clampTheta(this.initialTheta),this.targetPhi=this.clampPhi(this.initialPhi),this.initialDistance!==null?this.targetDistance=this.clampDistance(this.initialDistance):this.targetDistance=this.clampDistance(this.bounds.radius*2.5),this.initialCustomTarget?this.customTarget=[...this.initialCustomTarget]:this.customTarget=null,this.turntableRotation=0,this.updateTurntableMatrix()}projectPointToScreen(e,t){let r=V();z(r,this.projMatrix,this.viewMatrix);let[n,s,o]=e,h=t?t[0]:0,c=t?t[1]:0,u=t?t[2]:0,a=this.modelRootMatrix;a&&(n=a[0]*e[0]+a[4]*e[1]+a[8]*e[2]+a[12],s=a[1]*e[0]+a[5]*e[1]+a[9]*e[2]+a[13],o=a[2]*e[0]+a[6]*e[1]+a[10]*e[2]+a[14],t&&(h=a[0]*t[0]+a[4]*t[1]+a[8]*t[2],c=a[1]*t[0]+a[5]*t[1]+a[9]*t[2],u=a[2]*t[0]+a[6]*t[1]+a[10]*t[2]));let l=r[0]*n+r[4]*s+r[8]*o+r[12],f=r[1]*n+r[5]*s+r[9]*o+r[13],b=r[2]*n+r[6]*s+r[10]*o+r[14],p=r[3]*n+r[7]*s+r[11]*o+r[15];if(p<=1e-4)return{x:0,y:0,z:1,visible:!1};let T=l/p,M=f/p,D=b/p,E=this.canvas.getBoundingClientRect(),w=E.width||this.canvas.clientWidth||this.canvas.width||300,v=E.height||this.canvas.clientHeight||this.canvas.height||150,d=(T*.5+.5)*w,m=(-M*.5+.5)*v,C=T>=-1.1&&T<=1.1&&M>=-1.1&&M<=1.1&&D>=-1&&D<=1;if(C&&t){let P=this.customTarget||this.bounds.center,g=P[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),A=P[1]+this.currDistance*Math.sin(this.currPhi),L=P[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),F=[n-g,s-A,o-L];h*F[0]+c*F[1]+u*F[2]>.05&&(C=!1)}return{x:d,y:m,z:D,visible:C}}setSelectedMesh(e){this.selectedMeshName=e||""}setupEvents(){let e=this.canvas;this.boundContextMenu=t=>{t.preventDefault()},e.addEventListener("contextmenu",this.boundContextMenu),this.boundPointerDown=t=>{this.interactive&&(this.isPointerDown=!0,this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist=0,this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.isPanning=t.button===2||t.shiftKey||this.activePointers.size===2,e.setPointerCapture(t.pointerId))},e.addEventListener("pointerdown",this.boundPointerDown),this.boundPointerMove=t=>{if(!this.isPointerDown||!this.interactive)return;this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let r=this.activePointers.get(t.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},n=t.clientX-r.x,s=t.clientY-r.y;if(this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist+=Math.hypot(n,s),this.isPanning||t.button===2||t.shiftKey||this.activePointers.size===2){let o=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],h=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],c=this.customTarget?[...this.customTarget]:[...this.bounds.center],u=this.currDistance/Math.max(e.clientHeight||300,1)*1.5;c[0]+=(-n*o[0]+s*h[0])*u,c[1]+=(-n*o[1]+s*h[1])*u,c[2]+=(-n*o[2]+s*h[2])*u,this.customTarget=c}else this.targetTheta=this.clampTheta(this.targetTheta-n*.008),this.targetPhi=this.clampPhi(this.targetPhi+s*.008)},e.addEventListener("pointermove",this.boundPointerMove),this.boundPointerUp=t=>{this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.activePointers.delete(t.pointerId),this.activePointers.size===0?(this.isPointerDown=!1,this.isPanning=!1):this.activePointers.size===1&&(this.isPanning=!1);try{e.releasePointerCapture(t.pointerId)}catch{}if(this.totalDragDist<5&&t.button===0){let r=e.getBoundingClientRect(),n=Math.floor((t.clientX-r.left)*(e.width/Math.max(r.width,1))),s=Math.floor((t.clientY-r.top)*(e.height/Math.max(r.height,1)));this.performMeshPick(n,s,!0)}},e.addEventListener("pointerup",this.boundPointerUp),this.boundWheel=t=>{if(!this.interactive)return;t.preventDefault(),this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let r=Math.exp(t.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*r)},e.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=t=>{let r=t.detail||{};r.reset?this.resetCamera():this.setCamera(r.theta,r.phi,r.distance,r.zoom)},this.container.addEventListener("setCamera",this.boundSetCamera),this.boundResetCamera=()=>{this.resetCamera()},this.container.addEventListener("resetCamera",this.boundResetCamera),e.tabIndex!==void 0&&e.tabIndex<0&&(e.tabIndex=0),e.getAttribute?.("role")||e.setAttribute?.("role","region"),e.getAttribute?.("aria-label")||e.setAttribute?.("aria-label","Interactive 3D model viewport"),this.boundKeyDown=t=>{if(!this.interactive)return;let r=typeof performance<"u"?performance.now():Date.now();switch(t.key){case"ArrowLeft":this.lastInteractionTime=r,this.targetTheta=this.clampTheta(this.targetTheta-.1),t.preventDefault();break;case"ArrowRight":this.lastInteractionTime=r,this.targetTheta=this.clampTheta(this.targetTheta+.1),t.preventDefault();break;case"ArrowUp":this.lastInteractionTime=r,this.targetPhi=this.clampPhi(this.targetPhi+.08),t.preventDefault();break;case"ArrowDown":this.lastInteractionTime=r,this.targetPhi=this.clampPhi(this.targetPhi-.08),t.preventDefault();break;case"+":case"=":{this.lastInteractionTime=r,this.targetDistance=this.clampDistance(this.targetDistance*.9),t.preventDefault();break}case"-":case"_":{this.lastInteractionTime=r,this.targetDistance=this.clampDistance(this.targetDistance*1.1),t.preventDefault();break}case"Home":this.lastInteractionTime=r,this.resetCamera(),t.preventDefault();break}},e.addEventListener("keydown",this.boundKeyDown)}teardownEvents(){let e=this.canvas;this.boundContextMenu&&(e.removeEventListener("contextmenu",this.boundContextMenu),this.boundContextMenu=null),this.boundPointerDown&&(e.removeEventListener("pointerdown",this.boundPointerDown),this.boundPointerDown=null),this.boundPointerMove&&(e.removeEventListener("pointermove",this.boundPointerMove),this.boundPointerMove=null),this.boundPointerUp&&(e.removeEventListener("pointerup",this.boundPointerUp),this.boundPointerUp=null),this.boundWheel&&(e.removeEventListener("wheel",this.boundWheel),this.boundWheel=null),this.boundKeyDown&&(e.removeEventListener("keydown",this.boundKeyDown),this.boundKeyDown=null),this.boundSetCamera&&(this.container.removeEventListener("setCamera",this.boundSetCamera),this.boundSetCamera=null),this.boundResetCamera&&(this.container.removeEventListener("resetCamera",this.boundResetCamera),this.boundResetCamera=null)}raycastFromScreenPoint(e,t){let r=this.canvas,n=r.getBoundingClientRect(),s=r.width||300,o=r.height||300,h=n.width>0?Math.floor((e-n.left)*(s/n.width)):Math.floor(e),c=n.height>0?Math.floor((t-n.top)*(o/n.height)):Math.floor(t);return this.performMeshPick(h,c,!1)}performMeshPick(e,t,r=!0){if(this.meshes.length===0)return null;let n=this.gl,s=Math.max(1,this.canvas.width||300),o=Math.max(1,this.canvas.height||300);e=this.mapStereoPickX(e,s);let h=V();z(h,this.projMatrix,this.viewMatrix);let c=[],u=Math.max(0,Math.min(s-1,e)),a=Math.max(0,Math.min(o-1,o-1-t));if(this.pickFbo&&n&&!this.xrSessionActive){(this.pickFboWidth!==s||this.pickFboHeight!==o)&&this.resizePickingFbo(s,o),n.bindFramebuffer(36160,this.pickFbo),n.viewport(0,0,s,o),n.enable(2929),n.clearColor(0,0,0,0),n.clear(16384|256),n.useProgram(this.pickProg);for(let C=0;C<this.meshes.length;C++){let P=this.meshes[C];if(P.visible===!1||P.isPluginMesh)continue;let g=C+1,A=(g&255)/255,L=(g>>8&255)/255,F=(g>>16&255)/255;n.uniform4f(this.uPick.uColorId,A,L,F,1),z(this.modelMatrix,this.modelRootMatrix,P.transform),z(this.mvpMatrix,h,this.modelMatrix),n.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let y of P.primitives)n.bindVertexArray(y.vao),n.drawElements(4,y.indexCount,y.indexType,0)}let d=new Uint8Array(4);n.readPixels(u,a,1,1,6408,5121,d),n.bindFramebuffer(36160,null);let m=d[0]+(d[1]<<8)+(d[2]<<16);m>0&&m<=this.meshes.length&&(c=[this.meshes[m-1]])}c.length===0&&(c=this.meshes.filter(d=>d.visible!==!1));let l=null,f=1/0,b=[0,0,0],p=[0,1,0],T=this.customTarget||this.bounds.center,M=T[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),D=T[1]+this.currDistance*Math.sin(this.currPhi),E=T[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let d of c){z(this.modelMatrix,this.modelRootMatrix,d.transform),z(this.mvpMatrix,h,this.modelMatrix);let m=V();if(!Me(m,this.mvpMatrix))continue;let C=(u+.5)/s*2-1,P=(a+.5)/o*2-1,g=[0,0,0],A=[0,0,0];ve(g,C,P,-1,m),ve(A,C,P,1,m);let L=A[0]-g[0],F=A[1]-g[1],y=A[2]-g[2],R=Math.hypot(L,F,y)||1,B=L/R,x=F/R,X=y/R,k={distance:1/0,point:[0,0,0],normal:[0,1,0]};if((U=>{for(let H of d.primitives){if(!H.positions)continue;let N=H.positions,I=H.indices,_=Math.floor(I?I.length/3:N.length/9);for(let W=0;W<_;W++){let K=I?I[W*3]:W*3,q=I?I[W*3+1]:W*3+1,$=I?I[W*3+2]:W*3+2;Re(g[0],g[1],g[2],B,x,X,N[K*3],N[K*3+1],N[K*3+2],N[q*3],N[q*3+1],N[q*3+2],N[$*3],N[$*3+1],N[$*3+2],k,U)}}})(1e-4),isFinite(k.distance)){let U=k.point[0],H=k.point[1],N=k.point[2],I=this.modelMatrix,_=I[0]*U+I[4]*H+I[8]*N+I[12],W=I[1]*U+I[5]*H+I[9]*N+I[13],K=I[2]*U+I[6]*H+I[10]*N+I[14],q=_-M,$=W-D,le=K-E,O=Math.hypot(q,$,le);if(O<f){ne(this.normalMatrix,this.modelMatrix);let Y=this.normalMatrix,se=k.normal[0],ae=k.normal[1],ie=k.normal[2],J=Y[0]*se+Y[3]*ae+Y[6]*ie,Q=Y[1]*se+Y[4]*ae+Y[7]*ie,ee=Y[2]*se+Y[5]*ae+Y[8]*ie,oe=Math.hypot(J,Q,ee)||1;J/=oe,Q/=oe,ee/=oe,J*q+Q*$+ee*le>0&&(J=-J,Q=-Q,ee=-ee),l=d,f=Math.round(O*1e3)/1e3,b=[Math.round(_*1e3)/1e3,Math.round(W*1e3)/1e3,Math.round(K*1e3)/1e3],p=[Math.round(J*1e3)/1e3,Math.round(Q*1e3)/1e3,Math.round(ee*1e3)/1e3]}}}if(!l)return null;let v={meshIndex:this.meshes.indexOf(l),meshName:l.name,nodeIndex:l.nodeIndex,distance:f,hitPoint:b,normal:p,screenX:e,screenY:t};if(r){for(let d of G)d.onMeshSelect?.(this,v);this.opts.onMeshClick&&this.opts.onMeshClick(v),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:v}))}return v}mapStereoPickX(e,t){if(!this.stereoSBS||this.xrSessionActive||t<2)return e;let r=Math.max(1,Math.floor(t*.5)),n=e>=r,s=n?e-r:e,o=n?Math.max(1,t-r):r,h=(s+.5)/o*2-1;return Math.floor((h*.5+1)*.5*t)}setStereoSBS(e){this.stereoSBS=!!e,this.xrSessionActive||(this.syncCameraMatrices(),this.render())}syncCameraMatrices(){let e=Math.max(1,this.canvas.width||1)/Math.max(1,this.canvas.height||1),t=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10);fe(this.projMatrix,this.fov,e,.1,t);let r=this.customTarget||this.bounds.center,n=r[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),s=r[1]+this.currDistance*Math.sin(this.currPhi),o=r[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);pe(this.viewMatrix,[n,s,o],r,[0,1,0]),z(this.mvpMatrix,this.projMatrix,this.viewMatrix),ne(this.normalMatrix,this.modelMatrix)}resize(){let e=Math.min((typeof window<"u"?window.devicePixelRatio:1)||1,2),t=this.canvas.getBoundingClientRect(),r=Math.max(1,Math.floor(t.width*e)),n=Math.max(1,Math.floor(t.height*e));this.canvas.width!==r||this.canvas.height!==n?(this.canvas.width=r,this.canvas.height=n,this.resizePickingFbo(r,n),this.xrSessionActive||this.syncCameraMatrices()):!this.xrSessionActive&&this.projMatrix[0]===0&&this.syncCameraMatrices()}getGLContext(){return this.gl}setXRSessionActive(e){let t=this.xrSessionActive;if(this.xrSessionActive=e,t&&!e){this.xrDepthState.enabled=!1;for(let r of G)r.onXRSessionEnd?.(this);if(this.lastTime=typeof performance<"u"?performance.now():Date.now(),this.updateTurntableMatrix(),this.isVisible)try{this.resize(),this.syncCameraMatrices(),this.render()}catch(r){this.reportRenderError(r)}}}reportRenderError(e){this.renderErrorReported||(this.renderErrorReported=!0,typeof console<"u"&&console.warn("[three-live] render frame failed:",e))}stepXRUpdate(e){for(let t of G)t.onUpdate?.(this,e)}start(){if(this.animFrameId!==null)return;this.lastTime=typeof performance<"u"?performance.now():Date.now();let e=t=>{if(this.animFrameId===null)return;let r=Math.min(Math.max((t-this.lastTime)/1e3,0),.1);if(this.lastTime=t,this.isVisible&&!this.xrSessionActive)try{this.resize(),this.update(r),this.render()}catch(n){this.reportRenderError(n)}this.animFrameId!==null&&(this.animFrameId=requestAnimationFrame(e))};this.animFrameId=requestAnimationFrame(e)}stop(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null)}setAutoRotate(e){this.autoRotate=e}getAutoRotate(){return this.autoRotate}setAutoRotateSpeed(e){this.autoRotateSpeed=e}getAutoRotateSpeed(){return this.autoRotateSpeed}setAutoRotateDelay(e){this.autoRotateDelay=Math.max(0,Number(e)||0)}getAutoRotateDelay(){return this.autoRotateDelay}resetTurntableRotation(e=0){this.turntableRotation=Number(e)||0,this.updateTurntableMatrix(),this.render()}updateTurntableMatrix(){let e=Math.cos(this.turntableRotation),t=Math.sin(this.turntableRotation),r=this.bounds.center[0],n=this.bounds.center[2],s=this.modelRootMatrix;s[0]=e,s[1]=0,s[2]=-t,s[3]=0,s[4]=0,s[5]=1,s[6]=0,s[7]=0,s[8]=t,s[9]=0,s[10]=e,s[11]=0,s[12]=r-(e*r+t*n),s[13]=0,s[14]=n-(-t*r+e*n),s[15]=1}setVisible(e){this.isVisible=e}update(e){for(let o of G)o.onUpdate?.(this,e);let t=typeof performance<"u"?performance.now():Date.now();if(!this.isPointerDown&&this.autoRotate&&t-this.lastInteractionTime>=this.autoRotateDelay){this.turntableRotation+=this.autoRotateSpeed*e,this.updateTurntableMatrix();for(let o of G)o.onCameraChange?.(this,this.container)}this.currTheta+=(this.targetTheta-this.currTheta)*.12,this.currPhi+=(this.targetPhi-this.currPhi)*.12,this.currDistance+=(this.targetDistance-this.currDistance)*.12,this.syncCameraMatrices();let r=Math.round((this.currTheta*180/Math.PI%360+360)%360),n=Math.round(this.currPhi*180/Math.PI),s=Math.round(this.bounds.radius*2.5/this.currDistance*100)/100;if(Math.abs(r-this.lastReportedTheta)>=1||Math.abs(n-this.lastReportedPhi)>=1||Math.abs(s-this.lastReportedZoom)>=.02){this.lastReportedTheta=r,this.lastReportedPhi=n,this.lastReportedZoom=s;let o={theta:r,phi:n,zoom:s,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(o),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:o}))}}renderXRView(e,t,r,n,s=!0,o=0){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(e);let h=e?.transform?.inverse?.matrix||this.viewMatrix,c=e?.projectionMatrix||this.projMatrix,u=e?.transform?.position,a=u?[u.x,u.y,u.z]:[0,1.6,0];t?this.modelRootMatrix.set(t):r&&t&&this.modelRootMatrix.set(t),this.render({viewMatrix:h,projMatrix:c,eyePos:a,viewport:n,eye:e?.eye||"none",clear:o>0?!1:e?.eye!=="right",isAR:s})}render(e){if(!e&&this.stereoSBS){let v=Math.max(2,this.canvas.width||2),d=Math.max(1,this.canvas.height||1),m=Math.max(1,Math.floor(v*.5)),C=Math.max(1,v-m),P=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10),g=this.customTarget||this.bounds.center,A=g[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),L=g[1]+this.currDistance*Math.sin(this.currPhi),F=g[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),y=Math.cos(this.currTheta),R=-Math.sin(this.currTheta),B=.032,x=V(),X=V(),k=[A-y*B,L,F-R*B],te=[g[0]-y*B*.25,g[1],g[2]-R*B*.25];fe(x,this.fov,m/d,.1,P),pe(X,k,te,[0,1,0]);let U=V(),H=V(),N=[A+y*B,L,F+R*B],I=[g[0]+y*B*.25,g[1],g[2]+R*B*.25];fe(U,this.fov,C/d,.1,P),pe(H,N,I,[0,1,0]),this.render({viewMatrix:X,projMatrix:x,eyePos:k,viewport:[0,0,m,d],eye:"left",clear:!0,isAR:!1}),this.render({viewMatrix:H,projMatrix:U,eyePos:N,viewport:[m,0,C,d],eye:"right",clear:!1,isAR:!1}),this.gl.viewport(0,0,v,d);return}let t=this.gl,r=0,n=0,s=this.canvas.width,o=this.canvas.height;e?.viewport?(r=e.viewport[0],n=e.viewport[1],s=e.viewport[2],o=e.viewport[3],t.viewport(r,n,s,o)):t.viewport(0,0,this.canvas.width,this.canvas.height),t.enable(2929),(!e||e.clear!==!1)&&(e?.isAR?t.clearColor(0,0,0,0):t.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),t.clear(16384|256));let h=V(),c=e?.viewMatrix??this.viewMatrix;z(h,e?.projMatrix??this.projMatrix,c);let u=[-c[2],-c[6],-c[10]],a=this.toneMapping==="reinhard"?1:this.toneMapping==="none"?2:0,l=this.customTarget||this.bounds.center,f=e?e.eyePos[0]:l[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),b=e?e.eyePos[1]:l[1]+this.currDistance*Math.sin(this.currPhi),p=e?e.eyePos[2]:l[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let v of G)v.onBeforeDrawScene?.(this,t,h,[f,b,p],a);let T=e?.isAR?0:this.backdropMeshes.length;if(this.meshes.length===0&&T===0)return;let M=e?.eye||"none",D=!1,E=T>0?[...this.backdropMeshes,...this.meshes]:this.meshes,w=v=>{for(let d=0;d<E.length;d++){let m=E[d];if(m.visible===!1)continue;let C=this.selectedMeshName!==""&&m.name===this.selectedMeshName;d<T||m.worldSpace===!0||m.name==="__xr_reticle__"?this.modelMatrix.set(m.transform):z(this.modelMatrix,this.modelRootMatrix,m.transform),z(this.mvpMatrix,h,this.modelMatrix),ne(m.normalMatrix,this.modelMatrix);let P=m.extras?.xr?.stereo||m.userData?.xr?.stereo,g=0,A=0,L=1,F=1;P==="sbs"?(L=.5,g=M==="right"?.5:0):P==="ou"&&(F=.5,A=M==="right"?.5:0);for(let y of m.primitives){let R=!!y.isTransmissive;if(!v&&R){D=!0;continue}if(v&&!R)continue;let B=y.customProgram||this.renderProg,x=y.customUniforms||this.uRender;t.useProgram(B),t.uniform1i(x.uToneMapping,a),t.uniform1f(x.uEnvIntensity,this.envIntensity),t.uniform3f(x.uCameraPos,f,b,p),x.uCameraFwd&&t.uniform3f(x.uCameraFwd,u[0],u[1],u[2]),t.uniform1f(x.uEmissive,C?1:0),t.uniformMatrix4fv(x.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(x.uModel,!1,this.modelMatrix),t.uniformMatrix3fv(x.uNormalMatrix,!1,m.normalMatrix),x.uUvTransform&&t.uniform4f(x.uUvTransform,g,A,L,F),x.uViewportSize&&t.uniform2f(x.uViewportSize,Math.max(1,s),Math.max(1,o)),x.uViewport&&t.uniform4f(x.uViewport,r,n,Math.max(1,s),Math.max(1,o)),this.xrDepthState.enabled&&this.xrDepthState.texture?(t.activeTexture(33989),t.bindTexture(3553,this.xrDepthState.texture),x.uXrDepthTex&&t.uniform1i(x.uXrDepthTex,5),x.uXrDepthEnabled&&t.uniform1i(x.uXrDepthEnabled,1),x.uXrDepthFormat&&t.uniform1i(x.uXrDepthFormat,this.xrDepthState.format||0),x.uXrRawValueToMeters&&t.uniform1f(x.uXrRawValueToMeters,this.xrDepthState.rawValueToMeters),x.uXrDepthUVTransform&&t.uniformMatrix4fv(x.uXrDepthUVTransform,!1,this.xrDepthState.uvTransform)):x.uXrDepthEnabled&&t.uniform1i(x.uXrDepthEnabled,0),this.environmentTexture?(t.activeTexture(33988),t.bindTexture(3553,this.environmentTexture),t.uniform1i(x.uEnvironmentMap,4),t.uniform1i(x.uHasEnvironmentMap,1)):t.uniform1i(x.uHasEnvironmentMap,0),this.bindLights(x);for(let X of G)X.onBeforeDrawPrimitive?.(t,B,y,m,this.worldMatrices||[],this.gltf);t.uniform4fv(x.uBaseColor,y.baseColor),t.uniform1f(x.uMetallic,y.metallic),t.uniform1f(x.uRoughness,y.roughness),x.uClearcoat&&t.uniform2f(x.uClearcoat,y.clearcoat??0,y.clearcoatRoughness??.04),y.texture?(t.activeTexture(33984),t.bindTexture(3553,y.texture),t.uniform1i(x.uBaseColorTexture,0),t.uniform1i(x.uHasTexture,1)):t.uniform1i(x.uHasTexture,0),y.metallicRoughnessTexture?(t.activeTexture(33985),t.bindTexture(3553,y.metallicRoughnessTexture),t.uniform1i(x.uMetallicRoughnessTexture,1),t.uniform1i(x.uHasMetallicRoughnessTexture,1)):t.uniform1i(x.uHasMetallicRoughnessTexture,0),y.normalTexture?(t.activeTexture(33986),t.bindTexture(3553,y.normalTexture),t.uniform1i(x.uNormalTexture,2),t.uniform1i(x.uHasNormalTexture,1),t.uniform1f(x.uNormalScale,y.normalScale)):t.uniform1i(x.uHasNormalTexture,0),y.occlusionTexture?(t.activeTexture(33987),t.bindTexture(3553,y.occlusionTexture),t.uniform1i(x.uOcclusionTexture,3),t.uniform1i(x.uHasOcclusionTexture,1),t.uniform1f(x.uOcclusionStrength,y.occlusionStrength)):t.uniform1i(x.uHasOcclusionTexture,0),t.bindVertexArray(y.vao),t.drawElements(4,y.indexCount,y.indexType,0)}}};if(w(!1),D){for(let v of G)v.onBeforeTransmissivePass?.(t,this);w(!0)}for(let v of G)v.onAfterRender?.(t,this,h)}disposeMeshListGpuResources(e){let t=this.gl;for(let r of e)for(let n of r.primitives){if(n.vao&&t.deleteVertexArray(n.vao),n.buffers)for(let s of n.buffers)t.deleteBuffer(s);n.texture&&t.deleteTexture(n.texture),n.metallicRoughnessTexture&&t.deleteTexture(n.metallicRoughnessTexture),n.normalTexture&&t.deleteTexture(n.normalTexture),n.occlusionTexture&&t.deleteTexture(n.occlusionTexture),n.customProgram&&t.deleteProgram(n.customProgram)}}disposeMeshGpuResources(){this.disposeMeshListGpuResources(this.meshes),this.meshes=[]}disposeGpuResources(){let e=this.gl;this.disposeMeshGpuResources(),this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[];for(let t of G)t.onDestroy?.(e,this);this.environmentTexture&&(e.deleteTexture(this.environmentTexture),this.environmentTexture=null),this.renderProg&&e.deleteProgram(this.renderProg),this.pickProg&&e.deleteProgram(this.pickProg),this.pickFbo&&e.deleteFramebuffer(this.pickFbo),this.pickTexture&&e.deleteTexture(this.pickTexture),this.pickDepth&&e.deleteRenderbuffer(this.pickDepth),this.pickFbo=null,this.pickTexture=null,this.pickDepth=null}dispose(){this.stop(),this.teardownEvents(),this.disposeGpuResources()}destroy(){this.dispose()}};ce.registerPlugin=we,ce.getRegisteredPlugins=Pe;var Qe=ce;export{ce as MicroViewer,Je as SANDBOX_HOST_SCENE_LIMITS,ce as ThreeView,Xe as decodeUtf8,Qe as default,he as getDecoder,Pe as getRegisteredPlugins,We as isGLBData,ne as mat3NormalFromMat4,V as mat4Create,Te as mat4FromRotationTranslationScale,Me as mat4Invert,pe as mat4LookAt,z as mat4Multiply,fe as mat4Perspective,Ce as parseGLB,Re as rayIntersectsTriangle,Ze as readFloat32Array,He as registerDecoder,we as registerPlugin,De as resolveNodeWorldMatrices,Ye as sanitizeTextureUri,Ee as toGLBData,ve as unprojectPoint};
|