three-live 0.0.0-stage → 1.1.0
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/LICENSE +202 -0
- package/README.md +58 -2
- package/dist/index.d.ts +224 -0
- package/dist/three-author-engine.js +292 -0
- package/dist/three-author.cjs +292 -0
- package/dist/three-author.d.ts +224 -0
- package/dist/three-author.js +292 -0
- package/dist/three-convert.cjs +286 -0
- package/dist/three-convert.d.ts +224 -0
- package/dist/three-convert.js +286 -0
- package/dist/three-live-animation.cjs +36 -0
- package/dist/three-live-animation.d.ts +224 -0
- package/dist/three-live-animation.js +36 -0
- package/dist/three-live-animation.min.js +36 -0
- package/dist/three-live-element.cjs +217 -0
- package/dist/three-live-element.d.ts +224 -0
- package/dist/three-live-element.js +217 -0
- package/dist/three-live-extras.cjs +42 -0
- package/dist/three-live-extras.d.ts +224 -0
- package/dist/three-live-extras.js +42 -0
- package/dist/three-live-extras.min.js +42 -0
- package/dist/three-live-full.cjs +336 -0
- package/dist/three-live-full.js +336 -0
- package/dist/three-live-full.min.js +336 -0
- package/dist/three-live-sandbox.html +157 -0
- package/dist/three-live-viewer.cjs +217 -0
- package/dist/three-live-viewer.d.ts +224 -0
- package/dist/three-live-viewer.js +217 -0
- package/dist/three-live-viewer.min.js +217 -0
- package/dist/three-live.cjs +294 -0
- package/dist/three-live.js +294 -0
- package/dist/three-live.min.js +294 -0
- package/dist/three-view.cjs +217 -0
- package/dist/three-view.d.ts +224 -0
- package/dist/three-view.js +217 -0
- package/dist/three-xr.cjs +286 -0
- package/dist/three-xr.d.ts +224 -0
- package/dist/three-xr.js +286 -0
- package/package.json +81 -4
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
function we(n,e,t){let i=[],r=new Map,s=[],d=[],y=[],u=new Map,o=f=>{let M=r.get(f);return M===void 0&&(M=i.length,i.push({op:f}),r.set(f,M)),M},a=f=>{let M=u.get(f);return M===void 0&&(M=y.length,y.push({id:f}),u.set(f,M)),M},l=(f,M={})=>s.push({declaration:o(f),...M})-1,g=(f,M,b)=>d.push({id:f,type:M,value:b})-1,T=f=>({node:f,socket:"value"}),m=t?.interactivity??t?.gltfExtensions?.KHR_interactivity;if(m&&typeof m=="object"){let f=Array.isArray(m.graphs)?m.graphs[m.graph??0]:m;if(f&&Array.isArray(f.nodes)){let M=Array.isArray(f.declarations)?f.declarations:[];for(let b of M)b?.op&&o(b.op);Array.isArray(f.variables)&&d.push(...f.variables);for(let b of f.events||[])b?.id&&a(b.id);for(let b of f.nodes){if(!b||typeof b!="object")continue;let I=b.op||(typeof b.declaration=="number"?M[b.declaration]?.op:"");s.push(I?{...b,declaration:o(I)}:{...b})}}}let E=(f,M,b="translation")=>b==="baseColorFactor"||b==="metallicFactor"||b==="roughnessFactor"?`/materials/${Math.max(0,M)}/pbrMetallicRoughness/${b}`:b==="emissiveFactor"||b==="alphaCutoff"?`/materials/${Math.max(0,M)}/${b}`:b==="visible"?`/nodes/${f}/extensions/KHR_node_visibility/visible`:`/nodes/${f}/${b}`,A=new Map;n.forEach((f,M)=>{typeof f?.name=="string"&&!A.has(f.name)&&A.set(f.name,M)});let F=(f,M)=>typeof f.target=="string"&&A.has(f.target)?A.get(f.target):typeof f.targetNode=="number"?f.targetNode:M,P=f=>{let M=n[f];return(typeof M?.mesh=="number"?e[M.mesh]?.primitives?.[0]?.material:0)??0};for(let f=0;f<n.length;f++){let M=n[f],b=M?.extras?.interactivity;if(!b||typeof b!="object")continue;let I=(typeof M.mesh=="number"?e[M.mesh]?.primitives?.[0]?.material:0)??0,c=h=>{let w=Array.isArray(h)?h:[h],L=[];for(let D=0;D<w.length;D++){let p=w[D];if(!p||typeof p!="object")continue;let N=p.action||"interpolate",H=typeof p.duration=="number"?p.duration:.35;if(N==="toggleTransform"){let O=p.property==="rotation"||p.property==="scale"?p.property:"translation",V=O==="rotation"?M.rotation||[0,0,0,1]:O==="scale"?M.scale||[1,1,1]:M.translation||[0,0,0],S=`/nodes/${f}/${O}`,C=g(`__toggle_${f}_${D}`,"bool",!1),R=l("variable/get",{configuration:{variable:C}}),B=l("math/not",{values:{a:T(R)}}),U=l("variable/set",{configuration:{variable:C},values:{value:T(B)}}),k=l("pointer/interpolate",{configuration:{pointer:S},values:{value:{value:Array.isArray(p.to)?p.to:V},duration:{value:H}}}),_=l("pointer/interpolate",{configuration:{pointer:S},values:{value:{value:Array.isArray(p.from)?p.from:V},duration:{value:H}}});s[U].flows={out:{node:l("flow/branch",{values:{condition:T(R)},flows:{true:{node:k},false:{node:_}}})}},L.push(U)}else if(N==="interpolate"){let O=p.to??p.value;if(O===void 0)continue;let V={value:{value:O},duration:{value:H}};p.from!==void 0&&(V.from={value:p.from}),L.push(l("pointer/interpolate",{configuration:{pointer:typeof p.pointer=="string"?p.pointer:E(F(p,f),P(F(p,f)),p.property)},values:V}))}else if(N==="setProperty"){if(p.value===void 0)continue;L.push(l("pointer/set",{configuration:{pointer:typeof p.pointer=="string"?p.pointer:E(F(p,f),P(F(p,f)),p.property)},values:{value:{value:p.value}}}))}else if(N==="toggleVisibility"){let O=F(p,f),V=g(`__vis_${O}_${D}`,"bool",!0),S=l("variable/get",{configuration:{variable:V}}),C=l("math/not",{values:{a:T(S)}}),R=l("variable/set",{configuration:{variable:V},values:{value:T(C)}});s[R].flows={out:{node:l("pointer/set",{configuration:{pointer:`/nodes/${O}/extensions/KHR_node_visibility/visible`},values:{value:T(S)}})}},L.push(R)}else if(N==="cycleMaterialColor"&&Array.isArray(p.colors)&&p.colors.length>0){let O=typeof p.duration=="number"?p.duration:.25,V=`/materials/${Math.max(0,I)}/pbrMetallicRoughness/baseColorFactor`,S=g(`__color_idx_${f}_${D}`,"int",0),C=l("variable/get",{configuration:{variable:S}}),R=l("math/add",{values:{a:T(C),b:{value:1}}}),B=l("math/rem",{values:{a:T(R),b:{value:p.colors.length}}}),U=l("variable/set",{configuration:{variable:S},values:{value:T(B)}}),k={};for(let _=0;_<p.colors.length;_++){let G=p.colors[_],W=Array.isArray(G)&&G.length>=3?[G[0],G[1],G[2],G[3]??1]:[1,1,1,1];k[String(_)]={node:O>0?l("pointer/interpolate",{configuration:{pointer:V},values:{value:{value:W},duration:{value:O}}}):l("pointer/set",{configuration:{pointer:V},values:{value:{value:W}}})}}s[U].flows={out:{node:l("flow/switch",{values:{selection:T(C)},flows:k})}},L.push(U)}else if(N==="playAnimation")L.push(l("animation/start",{configuration:{animation:p.animation??p.clip??0}}));else if(N==="stopAnimation")L.push(l("animation/stop"));else if(N==="sendEvent"){let O={};for(let[V,S]of Object.entries(p.values||{}))O[V]={value:S};L.push(l("event/send",{configuration:{event:a(String(p.event??p.id??"custom"))},values:O}))}}if(!L.length)return null;if(L.length===1)return L[0];let v={};return L.forEach((D,p)=>{v[String(p)]={node:D}}),l("flow/sequence",{flows:v})},x=(h,w,L)=>{let v=c(w);v!==null&&l(h,{...L?{configuration:L}:{},flows:{out:{node:v}}})};if(b.onSelect&&x("pointer/onSelect",b.onSelect,{nodeIndex:f}),b.onHoverIn&&x("pointer/onHoverIn",b.onHoverIn,{nodeIndex:f}),b.onHoverOut&&x("pointer/onHoverOut",b.onHoverOut,{nodeIndex:f}),b.onStart&&x("event/onStart",b.onStart),b.onReceive&&typeof b.onReceive=="object")for(let[h,w]of Object.entries(b.onReceive))x("event/receive",w,{event:a(h)})}return s.length?{graphs:[{declarations:i,nodes:s,variables:d,events:y}],graph:0}:null}var pe="__THREE_LIVE_REGISTRY__";function ue(){let n=typeof globalThis<"u"?globalThis:{};if(!n[pe]){let e={plugins:[],decoders:new Map};try{Object.defineProperty(n,pe,{value:e,writable:!1,configurable:!1,enumerable:!1})}catch{n[pe]=e}}return n[pe]}var K=ue().plugins;function Ee(n){let e=ue().plugins;e.some(t=>t.name===n.name)||e.push(n)}function Pe(){return ue().plugins}function q(){let n=new Float32Array(16);return n[0]=1,n[5]=1,n[10]=1,n[15]=1,n}function Fe(n,e,t,i,r){let s=1/Math.tan(e/2);n.fill(0),n[0]=s/t,n[5]=s,n[11]=-1;let d=1/(i-r);return n[10]=(r+i)*d,n[14]=2*r*i*d,n}function Le(n,e,t,i){let[r,s,d]=e,[y,u,o]=i,[a,l,g]=t,T=r-a,m=s-l,E=d-g,A=Math.hypot(T,m,E);A<=1e-5?(T=0,m=0,E=1):(T/=A,m/=A,E/=A);let F=u*E-o*m,P=o*T-y*E,f=y*m-u*T;A=Math.hypot(F,P,f),A<=1e-5?(F=0,P=0,f=0):(F/=A,P/=A,f/=A);let M=m*f-E*P,b=E*F-T*f,I=T*P-m*F;return A=Math.hypot(M,b,I),A<=1e-5?(M=0,b=0,I=0):(M/=A,b/=A,I/=A),n[0]=F,n[1]=M,n[2]=T,n[3]=0,n[4]=P,n[5]=b,n[6]=m,n[7]=0,n[8]=f,n[9]=I,n[10]=E,n[11]=0,n[12]=-(F*r+P*s+f*d),n[13]=-(M*r+b*s+I*d),n[14]=-(T*r+m*s+E*d),n[15]=1,n}function J(n,e,t){let i=e[0],r=e[1],s=e[2],d=e[3],y=e[4],u=e[5],o=e[6],a=e[7],l=e[8],g=e[9],T=e[10],m=e[11],E=e[12],A=e[13],F=e[14],P=e[15],f=t[0],M=t[1],b=t[2],I=t[3];return n[0]=f*i+M*y+b*l+I*E,n[1]=f*r+M*u+b*g+I*A,n[2]=f*s+M*o+b*T+I*F,n[3]=f*d+M*a+b*m+I*P,f=t[4],M=t[5],b=t[6],I=t[7],n[4]=f*i+M*y+b*l+I*E,n[5]=f*r+M*u+b*g+I*A,n[6]=f*s+M*o+b*T+I*F,n[7]=f*d+M*a+b*m+I*P,f=t[8],M=t[9],b=t[10],I=t[11],n[8]=f*i+M*y+b*l+I*E,n[9]=f*r+M*u+b*g+I*A,n[10]=f*s+M*o+b*T+I*F,n[11]=f*d+M*a+b*m+I*P,f=t[12],M=t[13],b=t[14],I=t[15],n[12]=f*i+M*y+b*l+I*E,n[13]=f*r+M*u+b*g+I*A,n[14]=f*s+M*o+b*T+I*F,n[15]=f*d+M*a+b*m+I*P,n}function Ie(n,e,t,i){let r=e[0],s=e[1],d=e[2],y=e[3],u=r+r,o=s+s,a=d+d,l=r*u,g=r*o,T=r*a,m=s*o,E=s*a,A=d*a,F=y*u,P=y*o,f=y*a,M=i[0],b=i[1],I=i[2];return n[0]=(1-(m+A))*M,n[1]=(g+f)*M,n[2]=(T-P)*M,n[3]=0,n[4]=(g-f)*b,n[5]=(1-(l+A))*b,n[6]=(E+F)*b,n[7]=0,n[8]=(T+P)*I,n[9]=(E-F)*I,n[10]=(1-(l+m))*I,n[11]=0,n[12]=t[0],n[13]=t[1],n[14]=t[2],n[15]=1,n}function ne(n,e){let t=e[0],i=e[1],r=e[2],s=e[4],d=e[5],y=e[6],u=e[8],o=e[9],a=e[10],l=a*d-y*o,g=-a*s+y*u,T=o*s-d*u,m=t*l+i*g+r*T;return m&&(m=1/m,n[0]=l*m,n[1]=(-a*i+r*o)*m,n[2]=(y*i-r*d)*m,n[3]=g*m,n[4]=(a*t-r*u)*m,n[5]=(-y*t+r*s)*m,n[6]=T*m,n[7]=(-o*t+i*u)*m,n[8]=(d*t-i*s)*m),n}function Se(n,e){let t=e[0],i=e[1],r=e[2],s=e[3],d=e[4],y=e[5],u=e[6],o=e[7],a=e[8],l=e[9],g=e[10],T=e[11],m=e[12],E=e[13],A=e[14],F=e[15],P=t*y-i*d,f=t*u-r*d,M=t*o-s*d,b=i*u-r*y,I=i*o-s*y,c=r*o-s*u,x=a*E-l*m,h=a*A-g*m,w=a*F-T*m,L=l*A-g*E,v=l*F-T*E,D=g*F-T*A,p=P*D-f*v+M*L+b*w-I*h+c*x;return p?(p=1/p,n[0]=(y*D-u*v+o*L)*p,n[1]=(r*v-i*D-s*L)*p,n[2]=(E*c-A*I+F*b)*p,n[3]=(g*I-l*c-T*b)*p,n[4]=(u*w-d*D-o*h)*p,n[5]=(t*D-r*w+s*h)*p,n[6]=(A*M-m*c-F*f)*p,n[7]=(a*c-g*M+T*f)*p,n[8]=(d*v-y*w+o*x)*p,n[9]=(i*w-t*v-s*x)*p,n[10]=(m*I-E*M+F*P)*p,n[11]=(l*M-a*I-T*P)*p,n[12]=(y*h-d*L-u*x)*p,n[13]=(t*L-i*h+r*x)*p,n[14]=(E*f-m*b-A*P)*p,n[15]=(a*b-l*f+g*P)*p,n):null}function xe(n,e,t,i,r){let s=r[0]*e+r[4]*t+r[8]*i+r[12],d=r[1]*e+r[5]*t+r[9]*i+r[13],y=r[2]*e+r[6]*t+r[10]*i+r[14],u=r[3]*e+r[7]*t+r[11]*i+r[15],o=u!==0?1/u:1;n[0]=s*o,n[1]=d*o,n[2]=y*o}function Ce(n,e,t,i,r,s,d,y,u,o,a,l,g,T,m,E,A=0){let F=o-d,P=a-y,f=l-u,M=g-d,b=T-y,I=m-u,c=r*I-s*b,x=s*M-i*I,h=i*b-r*M,w=F*c+P*x+f*h;if(w>-1e-7&&w<1e-7)return!1;let L=1/w,v=n-d,D=e-y,p=t-u,N=L*(v*c+D*x+p*h);if(N<-A||N>1+A)return!1;let H=D*f-p*P,O=p*F-v*f,V=v*P-D*F,S=L*(i*H+r*O+s*V);if(S<-A||N+S>1+A)return!1;let C=L*(M*H+b*O+I*V);if(C>1e-4&&C<E.distance){E.distance=C,E.point=[n+i*C,e+r*C,t+s*C];let R=P*I-f*b,B=f*M-F*I,U=F*b-P*M,k=Math.hypot(R,B,U)||1;return E.normal=[R/k,B/k,U/k],!0}return!1}function be(n,e){let t=Array.isArray(n?.nodes)?n.nodes.length:0,i=[];for(let a=0;a<t;a++)i.push(q());if(t===0)return i;let r=new Set;for(let a of n.nodes)if(Array.isArray(a.children))for(let l of a.children)r.add(l);let s=new Set,d=128,y=(a,l,g=0)=>{if(g>d||a<0||a>=t||s.has(a))return;s.add(a);let T=n.nodes[a];if(!T)return;let m=q();if(e&&e[a])m.set(e[a]);else if(T.matrix&&T.matrix.length===16)m.set(T.matrix);else{let A=T.translation||[0,0,0],F=T.rotation||[0,0,0,1],P=T.scale||[1,1,1];Ie(m,F,A,P)}let E=i[a];if(l?J(E,l,m):E.set(m),Array.isArray(T.children))for(let A of T.children)typeof A=="number"&&y(A,E,g+1)},u=[],o=n.scenes&&n.scenes[n.scene!==void 0?n.scene:0];if(o&&Array.isArray(o.nodes))u.push(...o.nodes);else for(let a=0;a<t;a++)r.has(a)||u.push(a);for(let a of u)y(a,null);for(let a=0;a<t;a++)!r.has(a)&&!u.includes(a)&&y(a,null);return i}function Je(n){return new TextDecoder().decode(n)}var Be=ue().decoders;function Qe(n,e){Be.set(n.toLowerCase(),e)}function me(n){return Be.get(n.toLowerCase())}function Ne(n){let e=ArrayBuffer.isView(n)?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):n,t=new DataView(e);if(e.byteLength<12)throw new Error(`Invalid GLB buffer size: ${e.byteLength} bytes`);let i=t.getUint32(0,!0);if(i!==1179937895){let g=t.getUint8(0);throw g===123||g===32||g===10||g===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${i.toString(16)}`)}let r=t.getUint32(4,!0);if(r!==2)throw new Error(`Unsupported GLB version: ${r}`);let s=t.getUint32(8,!0),d=12,y=null,u=null;for(;d+8<=s&&d+8<=e.byteLength;){let g=t.getUint32(d,!0),T=t.getUint32(d+4,!0),m=d+8;if(m+g>e.byteLength)throw new Error(`Truncated GLB chunk: required ${m+g} bytes, buffer has ${e.byteLength}`);if(T===1313821514){let E=new Uint8Array(e,m,g),A=Je(E);y=JSON.parse(A,(F,P)=>F==="__proto__"||F==="constructor"||F==="prototype"?void 0:P)}else T===5130562&&(u=e.slice(m,m+g));d=m+g}if(!y)throw new Error("Missing JSON chunk in GLB");let o=y.extensionsRequired||[];if(o.includes("KHR_draco_mesh_compression")&&!me("draco"))throw new Error("Model requires KHR_draco_mesh_compression. Register a decoder via ThreeLiveElement.registerDecoder('draco', decoder).");if(o.includes("EXT_meshopt_compression")&&!me("meshopt"))throw new Error("Model requires EXT_meshopt_compression. Register a decoder via ThreeLiveElement.registerDecoder('meshopt', decoder).");if(o.includes("KHR_texture_basisu")&&!me("ktx2"))throw new Error("Model requires KHR_texture_basisu. Register a decoder via ThreeLiveElement.registerDecoder('ktx2', decoder).");let a=u||new ArrayBuffer(0),l={gltf:y,bin:a,animations:[]};for(let g of K)g.onParseGLB?.(l);return l}function et(n){return typeof n=="object"&&n!==null&&"gltf"in n&&typeof n.gltf=="object"&&n.gltf!==null&&"bin"in n&&(n.bin instanceof ArrayBuffer||ArrayBuffer.isView(n.bin))}function he(n){if(et(n))return n;if(n instanceof ArrayBuffer||ArrayBuffer.isView(n))return Ne(n);throw new TypeError("Invalid 3D model input: expected GLBData ({ gltf, bin }) or binary GLB (ArrayBuffer / ArrayBufferView).")}var ke=`#version 300 es
|
|
18
|
+
layout(location=0) in vec3 aPosition;
|
|
19
|
+
layout(location=1) in vec3 aNormal;
|
|
20
|
+
layout(location=2) in vec2 aUV;
|
|
21
|
+
uniform mat4 uMVP,uModel;
|
|
22
|
+
uniform mat3 uNormalMatrix;
|
|
23
|
+
uniform vec4 uUvTransform;
|
|
24
|
+
out vec3 vNormal,vWorldPos;
|
|
25
|
+
out vec2 vUV;
|
|
26
|
+
void main(){
|
|
27
|
+
vec3 rawN=uNormalMatrix*aNormal;
|
|
28
|
+
vNormal=length(rawN)>1e-5?normalize(rawN):vec3(0.0);
|
|
29
|
+
vec4 world=uModel*vec4(aPosition,1.0);
|
|
30
|
+
vWorldPos=world.xyz;
|
|
31
|
+
vec2 scaleUV=uUvTransform.zw;
|
|
32
|
+
if(scaleUV.x==0.0&&scaleUV.y==0.0)scaleUV=vec2(1.0);
|
|
33
|
+
vUV=aUV*scaleUV+uUvTransform.xy;
|
|
34
|
+
gl_Position=uMVP*vec4(aPosition,1.0);
|
|
35
|
+
}`,Ve=`#version 300 es
|
|
36
|
+
precision highp float;
|
|
37
|
+
in vec3 vNormal,vWorldPos;
|
|
38
|
+
in vec2 vUV;
|
|
39
|
+
uniform vec4 uBaseColor;
|
|
40
|
+
uniform float uMetallic,uRoughness,uEmissive,uEnvIntensity;
|
|
41
|
+
uniform vec2 uClearcoat;
|
|
42
|
+
uniform vec3 uCameraPos,uAmbientColor;
|
|
43
|
+
uniform sampler2D uBaseColorTexture,uMetallicRoughnessTexture,uNormalTexture,uOcclusionTexture,uEnvironmentMap,uXrDepthTex;
|
|
44
|
+
uniform int uHasTexture,uHasMetallicRoughnessTexture,uHasNormalTexture,uHasOcclusionTexture,uHasEnvironmentMap,uXrDepthEnabled,uXrDepthFormat;
|
|
45
|
+
uniform float uNormalScale,uOcclusionStrength,uXrRawValueToMeters;
|
|
46
|
+
uniform mat4 uXrDepthUVTransform;
|
|
47
|
+
uniform vec2 uViewportSize;
|
|
48
|
+
uniform int uToneMapping,uNumDirLights,uNumPointLights;
|
|
49
|
+
uniform vec3 uDirLightDir[2],uDirLightColor[2],uPointLightPos[2],uPointLightColor[2];
|
|
50
|
+
out vec4 fragColor;
|
|
51
|
+
|
|
52
|
+
vec2 envBRDF(float r,float n){
|
|
53
|
+
vec4 c0=vec4(-1.0,-0.0275,-0.572,0.022),c1=vec4(1.0,0.0425,1.04,-0.04);
|
|
54
|
+
vec4 rv=r*c0+c1;
|
|
55
|
+
float a=min(rv.x*rv.x,exp2(-9.28*n))*rv.x+rv.y;
|
|
56
|
+
return vec2(-1.04,1.04)*a+rv.zw;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
vec3 F_SchlickRoughness(vec3 F0,float r,float n){
|
|
60
|
+
return F0+(max(vec3(1.0-r),F0)-F0)*pow(clamp(1.0-n,0.0,1.0),5.0);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
vec3 getStudioRadiance(vec3 R,float r){
|
|
64
|
+
vec3 kd=normalize(vec3(0.0,1.0,0.35));
|
|
65
|
+
float ki=pow(max(dot(R,kd),0.0),mix(96.0,1.5,r))*mix(2.4,0.5,r);
|
|
66
|
+
vec3 fd=normalize(vec3(-0.85,0.45,-0.35));
|
|
67
|
+
float fi=pow(max(dot(R,fd),0.0),mix(36.0,1.2,r))*mix(1.3,0.35,r);
|
|
68
|
+
float ri=pow(clamp(1.0-abs(R.y),0.0,1.0),3.5)*mix(0.55,0.22,r);
|
|
69
|
+
vec3 ag=mix(vec3(0.06,0.06,0.08),vec3(0.48,0.50,0.55),R.y*0.5+0.5);
|
|
70
|
+
return ag+vec3(1.0,0.98,0.94)*ki+vec3(0.85,0.92,1.0)*fi+vec3(0.65,0.72,0.85)*ri;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
vec3 perturbNormal(vec3 N,vec3 V,vec2 uv,sampler2D normalMap,float scale){
|
|
74
|
+
vec3 mapNormal=texture(normalMap,uv).xyz*2.0-1.0;
|
|
75
|
+
mapNormal.xy*=scale;
|
|
76
|
+
vec3 dp1=dFdx(vWorldPos);
|
|
77
|
+
vec3 dp2=dFdy(vWorldPos);
|
|
78
|
+
vec2 duv1=dFdx(uv);
|
|
79
|
+
vec2 duv2=dFdy(uv);
|
|
80
|
+
vec3 dp2perp=cross(dp2,N);
|
|
81
|
+
vec3 dp1perp=cross(N,dp1);
|
|
82
|
+
vec3 T=dp2perp*duv1.x+dp1perp*duv2.x;
|
|
83
|
+
vec3 B=dp2perp*duv1.y+dp1perp*duv2.y;
|
|
84
|
+
float invmax=inversesqrt(max(dot(T,T),dot(B,B)));
|
|
85
|
+
return normalize(mat3(T*invmax,B*invmax,N)*normalize(mapNormal));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
vec2 equirectangularUV(vec3 dir){
|
|
89
|
+
vec3 d=normalize(dir);
|
|
90
|
+
float u=atan(d.z,d.x)*0.15915494309+0.5;
|
|
91
|
+
float v=asin(clamp(d.y,-1.0,1.0))*0.31830988618+0.5;
|
|
92
|
+
return vec2(u,1.0-v);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
vec3 neutralToneMapping(vec3 color){
|
|
96
|
+
const float startCompression=0.76;
|
|
97
|
+
const float desaturation=0.15;
|
|
98
|
+
float x=min(color.r,min(color.g,color.b));
|
|
99
|
+
float offset=x<0.08?x-6.25*x*x:0.04;
|
|
100
|
+
color-=offset;
|
|
101
|
+
float peak=max(color.r,max(color.g,color.b));
|
|
102
|
+
if(peak<startCompression)return color;
|
|
103
|
+
const float d=1.0-startCompression;
|
|
104
|
+
float newPeak=1.0-d*d/(peak+d-startCompression);
|
|
105
|
+
color*=newPeak/peak;
|
|
106
|
+
float g=1.0-1.0/(desaturation*(peak-newPeak)+1.0);
|
|
107
|
+
return mix(color,newPeak*vec3(1.0),g);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
vec3 applyToneMapping(vec3 color,int mode){
|
|
111
|
+
if(mode==0)return neutralToneMapping(color);
|
|
112
|
+
if(mode==1)return color/(color+vec3(1.0));
|
|
113
|
+
return color;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void main(){
|
|
117
|
+
vec4 base=uBaseColor;
|
|
118
|
+
if(uHasTexture==1)base*=texture(uBaseColorTexture,vUV);
|
|
119
|
+
if(length(vNormal)<1e-4&&uHasTexture==1){
|
|
120
|
+
vec3 unlit=base.rgb+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
121
|
+
fragColor=vec4(unlit,base.a);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
vec3 N=length(vNormal)<1e-4?normalize(cross(dFdx(vWorldPos),dFdy(vWorldPos))):normalize(vNormal);
|
|
125
|
+
if(!gl_FrontFacing)N=-N;
|
|
126
|
+
vec3 V=normalize(uCameraPos-vWorldPos);
|
|
127
|
+
if(uHasNormalTexture==1){
|
|
128
|
+
N=perturbNormal(N,V,vUV,uNormalTexture,uNormalScale);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
float metallic=uMetallic;
|
|
132
|
+
float roughness=uRoughness;
|
|
133
|
+
if(uHasMetallicRoughnessTexture==1){
|
|
134
|
+
vec4 mr=texture(uMetallicRoughnessTexture,vUV);
|
|
135
|
+
roughness*=mr.g;
|
|
136
|
+
metallic*=mr.b;
|
|
137
|
+
}
|
|
138
|
+
roughness=clamp(roughness,0.04,1.0);
|
|
139
|
+
metallic=clamp(metallic,0.0,1.0);
|
|
140
|
+
|
|
141
|
+
float occ=1.0;
|
|
142
|
+
if(uHasOcclusionTexture==1){
|
|
143
|
+
occ=mix(1.0,texture(uOcclusionTexture,vUV).r,uOcclusionStrength);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
float gloss=1.0-roughness;
|
|
147
|
+
float specExp=mix(16.0,256.0,gloss*gloss);
|
|
148
|
+
float specWeight=mix(0.22*gloss,1.0,metallic);
|
|
149
|
+
vec3 directLight=vec3(0.0);
|
|
150
|
+
for(int i=0;i<2;i++){
|
|
151
|
+
if(i>=uNumDirLights)break;
|
|
152
|
+
vec3 L=normalize(uDirLightDir[i]);
|
|
153
|
+
float NdotL=max(dot(N,L),0.0);
|
|
154
|
+
vec3 H=normalize(L+V);
|
|
155
|
+
float NoH=max(dot(N,H),0.0);
|
|
156
|
+
float spec=pow(NoH,specExp)*specWeight+uClearcoat.x*pow(NoH,mix(64.0,512.0,1.0-uClearcoat.y))*0.35;
|
|
157
|
+
directLight+=(base.rgb*NdotL*0.75+vec3(spec))*uDirLightColor[i];
|
|
158
|
+
}
|
|
159
|
+
for(int i=0;i<2;i++){
|
|
160
|
+
if(i>=uNumPointLights)break;
|
|
161
|
+
vec3 toLight=uPointLightPos[i]-vWorldPos;
|
|
162
|
+
float dist=length(toLight);
|
|
163
|
+
vec3 L=toLight/max(dist,0.0001);
|
|
164
|
+
float atten=1.0/(1.0+0.09*dist+0.032*dist*dist);
|
|
165
|
+
float NdotL=max(dot(N,L),0.0);
|
|
166
|
+
vec3 H=normalize(L+V);
|
|
167
|
+
float NoH=max(dot(N,H),0.0);
|
|
168
|
+
float spec=pow(NoH,specExp)*specWeight+uClearcoat.x*pow(NoH,mix(64.0,512.0,1.0-uClearcoat.y))*0.35;
|
|
169
|
+
directLight+=(base.rgb*NdotL*0.75+vec3(spec))*uPointLightColor[i]*atten;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
vec3 R=reflect(-V,N);
|
|
173
|
+
float NoV=clamp(dot(N,V),0.001,1.0);
|
|
174
|
+
vec3 F0=mix(vec3(0.04),base.rgb,metallic);
|
|
175
|
+
vec3 F=F_SchlickRoughness(F0,roughness,NoV);
|
|
176
|
+
vec2 brdf=envBRDF(roughness,NoV);
|
|
177
|
+
|
|
178
|
+
vec3 specularIBL;
|
|
179
|
+
vec3 envDiffuse;
|
|
180
|
+
if(uHasEnvironmentMap==1){
|
|
181
|
+
specularIBL=texture(uEnvironmentMap,equirectangularUV(R)).rgb*(F*brdf.x+brdf.y);
|
|
182
|
+
envDiffuse=texture(uEnvironmentMap,equirectangularUV(N)).rgb;
|
|
183
|
+
}else{
|
|
184
|
+
specularIBL=getStudioRadiance(R,roughness)*(F*brdf.x+brdf.y);
|
|
185
|
+
envDiffuse=mix(vec3(0.10,0.10,0.12),vec3(0.52,0.54,0.58),N.y*0.5+0.5);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
vec3 kD=(vec3(1.0)-F)*(1.0-metallic);
|
|
189
|
+
vec3 diffuseIBL=kD*base.rgb*(uAmbientColor+envDiffuse*0.5)*occ;
|
|
190
|
+
vec3 color=directLight+(diffuseIBL+specularIBL)*uEnvIntensity+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
191
|
+
if(uClearcoat.x>0.0){
|
|
192
|
+
vec3 ccF=F_SchlickRoughness(vec3(0.04),uClearcoat.y,NoV)*uClearcoat.x;
|
|
193
|
+
color=color*(vec3(1.0)-ccF)+getStudioRadiance(R,uClearcoat.y)*ccF*uEnvIntensity;
|
|
194
|
+
}
|
|
195
|
+
color=applyToneMapping(color,uToneMapping);
|
|
196
|
+
float outAlpha=base.a;
|
|
197
|
+
if(uXrDepthEnabled==1){
|
|
198
|
+
vec2 normViewUV=gl_FragCoord.xy/max(uViewportSize,vec2(1.0));
|
|
199
|
+
vec2 depthUV=(uXrDepthUVTransform*vec4(normViewUV,0.0,1.0)).xy;
|
|
200
|
+
vec4 depthSample=texture(uXrDepthTex,depthUV);
|
|
201
|
+
float realDepth=(uXrDepthFormat==1?depthSample.r:(depthSample.r+depthSample.a*256.0))*uXrRawValueToMeters;
|
|
202
|
+
float virtDepth=length(uCameraPos-vWorldPos);
|
|
203
|
+
if(realDepth>0.05&&virtDepth>realDepth){
|
|
204
|
+
float occAlpha=1.0-smoothstep(0.0,0.025,virtDepth-realDepth);
|
|
205
|
+
outAlpha*=occAlpha;
|
|
206
|
+
if(outAlpha<0.01)discard;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
fragColor=vec4(color,outAlpha);
|
|
210
|
+
}`,tt=`#version 300 es
|
|
211
|
+
layout(location=0) in vec3 aPosition;
|
|
212
|
+
uniform mat4 uMVP;
|
|
213
|
+
void main(){gl_Position=uMVP*vec4(aPosition,1.0);}`,nt=`#version 300 es
|
|
214
|
+
precision highp float;
|
|
215
|
+
uniform vec4 uColorId;
|
|
216
|
+
out vec4 fragColor;
|
|
217
|
+
void main(){fragColor=uColorId;}`;function _e(n,e,t){let i=n.createShader(e);if(n.shaderSource(i,t),n.compileShader(i),!n.getShaderParameter(i,35713)){let r=n.getShaderInfoLog(i);throw n.deleteShader(i),new Error(`Shader compile error: ${r}`)}return i}function Me(n,e,t){let i=_e(n,35633,e),r=_e(n,35632,t),s=n.createProgram();if(n.attachShader(s,i),n.attachShader(s,r),n.linkProgram(s),!n.getProgramParameter(s,35714)){let d=n.getProgramInfoLog(s);throw n.deleteProgram(s),new Error(`Program link error: ${d}`)}return s}function Re(n,e,t){let i={};for(let r of t)i[r]=n.getUniformLocation(e,r);return i}var Ge=["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 it(n){if(typeof n!="string")return null;let e=n.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 Te(n,e,t,i,r,s,d){if(i===void 0||!e.accessors?.[i])return null;let y=e.accessors[i],u=e.bufferViews[y.bufferView],o=(u.byteOffset||0)+(y.byteOffset||0),a=u.byteStride&&u.byteStride>s*4?u.byteStride>>2:s,l;if(a===s)l=new Float32Array(t,o,y.count*s);else{l=new Float32Array(y.count*s);let T=new Float32Array(t,u.byteOffset||0,Math.floor(u.byteLength/4)),m=(y.byteOffset||0)>>2;for(let E=0;E<y.count;E++){let A=m+E*a;for(let F=0;F<s;F++)l[E*s+F]=T[A+F]}}let g=n.createBuffer();return d.push(g),n.bindBuffer(34962,g),n.bufferData(34962,l,35044),n.enableVertexAttribArray(r),n.vertexAttribPointer(r,s,5126,!1,0,0),l}var yt=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),Oe=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function Ue(n,e,t=Oe,i){if(!e||!e.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:r,bin:s}=e,d=[],y=be(r),u=[];if(Array.isArray(r.nodes))for(let x=0;x<r.nodes.length;x++){let h=r.nodes[x];h.mesh!==void 0&&r.meshes&&r.meshes[h.mesh]&&u.push({node:h,nodeIdx:x,meshIdx:h.mesh})}let o=u.length>0?u:(r.meshes||[]).map((x,h)=>({node:x,nodeIdx:-1,meshIdx:h})),a=[];if(Array.isArray(e.lights)&&e.lights.length>0)a.push(...e.lights);else if(r.extensions?.KHR_lights_punctual?.lights){let x=r.extensions.KHR_lights_punctual.lights;for(let h of x){let w=h.type==="directional"?"directional":h.type==="point"?"point":"ambient";a.push({type:w,color:h.color||[1,1,1],intensity:h.intensity!==void 0?h.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]})),o.length>t.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${t.maxMeshes}). Found: ${o.length}`);let l=[];if(r.textures&&r.images){if(r.textures.length>t.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${t.maxTextures}). Found: ${r.textures.length}`);for(let x=0;x<r.textures.length;x++){let h=r.textures[x],w=r.images[h.source];if(w){let L=n.createTexture();if(n.bindTexture(3553,L),n.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255])),n.texParameteri(3553,10242,10497),n.texParameteri(3553,10243,10497),n.texParameteri(3553,10241,9729),n.texParameteri(3553,10240,9729),w.bufferView!==void 0){let v=r.bufferViews[w.bufferView],D=s.slice(v.byteOffset||0,(v.byteOffset||0)+v.byteLength),p=new Blob([D],{type:w.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(p).then(N=>{n.bindTexture(3553,L),n.texImage2D(3553,0,6408,6408,5121,N),n.generateMipmap(3553),i?.()}).catch(()=>{})}else if(w.uri){let v=it(w.uri);if(v){let D=new Image;D.crossOrigin="anonymous",D.referrerPolicy="no-referrer",D.onload=()=>{n.bindTexture(3553,L),n.texImage2D(3553,0,6408,6408,5121,D),n.generateMipmap(3553),i?.()},D.src=v}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",w.uri)}l.push(L)}else l.push(null)}}let g=[1/0,1/0,1/0],T=[-1/0,-1/0,-1/0],m=0,E=0;for(let x=0;x<o.length;x++){let h=o[x],w=r.meshes[h.meshIdx],L=h.nodeIdx>=0?y[h.nodeIdx]:q(),v=new Float32Array(9);ne(v,L);let D={name:h.node.name||w.name||`Mesh_${h.meshIdx}`,nodeIndex:h.nodeIdx,transform:L,normalMatrix:v,primitives:[],extras:h.node.extras||w.extras};for(let p of w.primitives||[]){if(p.extensions?.KHR_draco_mesh_compression){let X=me("draco");X&&X.decodePrimitive(r,p,s)}let N=[],H=n.createVertexArray();n.bindVertexArray(H);let O=r.accessors[p.attributes.POSITION],V=Number(O?.count??0);if(!Number.isFinite(V)||V<0||m+V>t.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${t.maxVertices}).`);if(m+=V,O?.min&&O?.max)for(let X=0;X<3;X++){let Q=L[12+X],ce=L[12+X];for(let ie=0;ie<3;ie++){let fe=L[ie*4+X]*O.min[ie],de=L[ie*4+X]*O.max[ie];Q+=fe<de?fe:de,ce+=fe>de?fe:de}Q<g[X]&&(g[X]=Q),ce>T[X]&&(T[X]=ce)}let S=Te(n,r,s,p.attributes.POSITION,0,3,N);Te(n,r,s,p.attributes.NORMAL,1,3,N),Te(n,r,s,p.attributes.TEXCOORD_0,2,2,N);let C=0,R=5123,B=null;if(p.indices!==void 0){let X=r.accessors[p.indices],ce=(r.bufferViews[X.bufferView].byteOffset||0)+(X.byteOffset||0);if(C=Number(X.count??0),!Number.isFinite(C)||C<0||E+C>t.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${t.maxIndices}).`);E+=C,R=X.componentType===5125?5125||5125:5123||5123;let ie=n.createBuffer();N.push(ie),n.bindBuffer(34963,ie),X.componentType===5125?(B=new Uint32Array(s,ce,X.count),n.bufferData(34963,B,35044)):(B=new Uint16Array(s,ce,X.count),n.bufferData(34963,B,35044))}else C=O.count;let U={};for(let X of K)if(X.onBuildPrimitiveVAO){let Q=X.onBuildPrimitiveVAO(n,H,p,r,s);Q&&(U[X.name]=Q)}n.bindVertexArray(null);let k=r.materials&&p.material!==void 0?r.materials[p.material]:null,_=ke,G=Ve,W=!1;for(let X of K)if(X.onResolveShader){let Q=X.onResolveShader(p,k,_,G);Q&&(_=Q.vs,G=Q.fs,W=!0)}let $=W?Me(n,_,G):null,ee=$?Re(n,$,Ge):null,Y=k?.pbrMetallicRoughness,Z=Y?.baseColorFactor||[.8,.8,.8,1],re=Y?.metallicFactor??.1,se=Y?.roughnessFactor??.5,te=k?.extensions?.KHR_materials_clearcoat,j=te?te.clearcoatFactor??1:0,ae=Math.max(.04,te?.clearcoatRoughnessFactor??.04),oe=Y?.baseColorTexture!==void 0&&l[Y.baseColorTexture.index]?l[Y.baseColorTexture.index]:null,le=Y?.metallicRoughnessTexture!==void 0&&l[Y.metallicRoughnessTexture.index]?l[Y.metallicRoughnessTexture.index]:null,Ke=k?.normalTexture!==void 0&&l[k.normalTexture.index]?l[k.normalTexture.index]:null,qe=k?.normalTexture?.scale??1,Ye=k?.occlusionTexture!==void 0&&l[k.occlusionTexture.index]?l[k.occlusionTexture.index]:null,Ze=k?.occlusionTexture?.strength??1,je=!!(k?.extensions?.KHR_materials_transmission||U.materials?.isTransmissive);D.primitives.push({vao:H,indexCount:C,indexType:R,baseColor:Z,metallic:re,roughness:se,clearcoat:j,clearcoatRoughness:ae,positions:S,indices:B,texture:oe,metallicRoughnessTexture:le,normalTexture:Ke,occlusionTexture:Ye,normalScale:qe,occlusionStrength:Ze,buffers:N,materialIndex:p.material,pluginData:U,customProgram:$,customUniforms:ee,isTransmissive:je})}d.push(D)}isFinite(g[0])||(g=[-1,-1,-1]),isFinite(T[0])||(T=[1,1,1]);let A=[(g[0]+T[0])/2,(g[1]+T[1])/2,(g[2]+T[2])/2],F=T[0]-g[0],P=T[1]-g[1],f=T[2]-g[2],M=Math.max(Math.hypot(F,P,f)/2,.5),b=[g[0],g[1],g[2]],I=[T[0],T[1],T[2]],c=e.animations;if(!c){for(let x of K)if(x.onParseGLB?.(e),e.animations){c=e.animations;break}}return c||(c=[]),{meshes:d,bounds:{center:A,radius:M,min:b,max:I},lights:a,animations:c,worldMatrices:y}}var ge=class{constructor(e,t,i){this.meshes=[];this.backdropMeshes=[];this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]};this.lights=[];this.modelRootMatrix=q();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=q();this.viewMatrix=q();this.modelMatrix=q();this.mvpMatrix=q();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:q(),rawValueToMeters:.001,format:0};this.container=e;let r,s;if(t&&typeof t.getContext=="function"?(r=t,s=i):(s=t,r=s?.canvas),!r){let u=e.querySelector("canvas");u||(u=document.createElement("canvas"),u.style.width="100%",u.style.height="100%",u.style.display="block",u.style.touchAction="none",e.prepend(u)),r=u}this.canvas=r,this.opts=s||{},this.opts.clearColor&&(this.clearColor=this.opts.clearColor);let d=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;this.opts.autoRotate!==void 0?this.autoRotate=this.opts.autoRotate&&!d:d&&(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 y=r.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!y)throw new Error("WebGL2 not supported");this.gl=y,this.renderProg=Me(y,ke,Ve),this.pickProg=Me(y,tt,nt),this.uRender=Re(y,this.renderProg,Ge),this.uPick=Re(y,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){Qe(e,t)}static getDecoder(e){return me(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),i=Math.max(1,this.canvas.height);this.pickFboWidth=t,this.pickFboHeight=i,e.bindTexture(3553,this.pickTexture),e.texImage2D(3553,0,6408,t,i,0,6408,5121,null),e.texParameteri(3553,10241,9728),e.texParameteri(3553,10240,9728),e.bindRenderbuffer(36161,this.pickDepth),e.renderbufferStorage(36161,33189,t,i),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 i=this.gl,r=Math.max(1,e),s=Math.max(1,t);this.pickFboWidth=r,this.pickFboHeight=s,i.bindTexture(3553,this.pickTexture),i.texImage2D(3553,0,6408,r,s,0,6408,5121,null),i.bindRenderbuffer(36161,this.pickDepth),i.renderbufferStorage(36161,33189,r,s)}loadGLBData(e,t){let{meshes:i,bounds:r,lights:s,animations:d,worldMatrices:y}=Ue(this.gl,e,t,()=>this.render());if(this.disposeMeshGpuResources(),this.meshes=i,this.bounds=r,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=s,this.animations=d||[],this.worldMatrices=y||[],this.gltf=e.gltf,this.initialNodeTransforms=[],Array.isArray(e.gltf?.nodes))for(let o of e.gltf.nodes)this.initialNodeTransforms.push({t:o.translation?[o.translation[0],o.translation[1],o.translation[2]]:[0,0,0],r:o.rotation?[o.rotation[0],o.rotation[1],o.rotation[2],o.rotation[3]]:[0,0,0,1],s:o.scale?[o.scale[0],o.scale[1],o.scale[2]]:[1,1,1]});this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let o of K)o.onLoadModel?.(this,this.gltf);this.customDistance||(this.initialDistance=this.distanceMode==="absolute"?3:r.radius*2.5,this.targetDistance=this.initialDistance,this.currDistance=this.initialDistance);let u=e.exposure??e.environmentIntensity??e.gltf?.extras?.exposure??e.gltf?.extras?.environmentIntensity??e.gltf?.asset?.extras?.exposure??e.gltf?.asset?.extras?.environmentIntensity;u!==void 0&&(this.envIntensity=Math.max(0,Number(u))),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(Ne(e))}loadModel(e){this.loadGLBData(he(e))}setBackdropGLB(e,t){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!e){this.update(0),this.render();return}let i=he(e),{meshes:r}=Ue(this.gl,i,Oe,()=>this.render());if(t)for(let s of r)s.transform[12]+=t[0],s.transform[13]+=t[1],s.transform[14]+=t[2],ne(s.normalMatrix,s.transform);this.backdropMeshes=r,this.update(0),this.render()}setClearColor(e,t,i,r=1){this.clearColor=[e,t,i,r]}updateMeshTransforms(e){for(let t=0;t<this.meshes.length;t++){let i=this.meshes[t],r;e instanceof Map?r=e.get(i.name)??e.get(t):Array.isArray(e)?r=e[t]:e&&typeof e=="object"&&(Object.prototype.hasOwnProperty.call(e,i.name)?r=e[i.name]:Object.prototype.hasOwnProperty.call(e,t)&&(r=e[t])),r&&r.length===16&&(i.transform.set(r),ne(i.normalMatrix,i.transform))}}bindLights(e=this.uRender){let t=this.gl,i=[.28,.28,.28],r=[],s=[],d=[],y=[];for(let u of this.lights){let o=u.color||[1,1,1],a=u.intensity!==void 0?u.intensity:1;if(u.type==="ambient")i=[o[0]*a,o[1]*a,o[2]*a];else if(u.type==="directional"&&r.length<6){let l=u.direction||[.5,1,.8];r.push(l[0],l[1],l[2]),s.push(o[0]*a,o[1]*a,o[2]*a)}else if(u.type==="point"&&d.length<6){let l=u.position||[0,0,0];d.push(l[0],l[1],l[2]),y.push(o[0]*a,o[1]*a,o[2]*a)}}r.length===0&&(r.push(.5,1,.8),s.push(1,1,1)),t.uniform3fv(e.uAmbientColor,i),t.uniform1i(e.uNumDirLights,r.length/3),r.length>0&&(t.uniform3fv(e.uDirLightDir,r),t.uniform3fv(e.uDirLightColor,s)),t.uniform1i(e.uNumPointLights,d.length/3),d.length>0&&(t.uniform3fv(e.uPointLightPos,d),t.uniform3fv(e.uPointLightColor,y)),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 K)if(t.setEnvironmentImage){await t.setEnvironmentImage(this,e);return}}async setSkyboxImage(e){for(let t of K)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,i=this.currDistance;return{theta:e,phi:t,radius:i,toString(){return`${e.toFixed(4)}rad ${t.toFixed(4)}rad ${i.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,i)=>{let r=this.meshes.flatMap(a=>a.primitives.filter(l=>l.materialIndex===i||e.length===1&&l.materialIndex===void 0)),s=r[0],d=s?[...s.baseColor]:t.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],y=s?s.metallic:t.pbrMetallicRoughness?.metallicFactor??.1,u=s?s.roughness:t.pbrMetallicRoughness?.roughnessFactor??.5,o={baseColorFactor:d,metallicFactor:y,roughnessFactor:u,setBaseColorFactor:a=>{let l=[a[0],a[1],a[2],a[3]??1];o.baseColorFactor=l,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.baseColorFactor=l);for(let g of r)g.baseColor=l;this.render()},setMetallicFactor:a=>{o.metallicFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.metallicFactor=a);for(let l of r)l.metallic=a;this.render()},setRoughnessFactor:a=>{o.roughnessFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.roughnessFactor=a);for(let l of r)l.roughness=a;this.render()}};return{name:t.name||`Material_${i}`,pbrMetallicRoughness:o}})}playAnimation(e){if(this.animations.length!==0){if(e){let t=this.animations.find(i=>i.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 K)if(t.evaluateAnimation){t.evaluateAnimation(this,e);return}}setTarget(e,t,i){this.customTarget=[e,t,i],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,i=this.maxDistanceLimit!==null?this.maxDistanceLimit:this.bounds?this.bounds.radius*8:100;return Math.max(t,Math.min(i,e))}setCamera(e,t,i,r){e!==void 0&&(this.targetTheta=this.clampTheta(e*Math.PI/180)),t!==void 0&&(this.targetPhi=this.clampPhi(t*Math.PI/180)),i!==void 0&&i>0&&(this.targetDistance=this.clampDistance(i)),r!==void 0&&r>0&&(this.targetDistance=this.clampDistance(this.bounds.radius*2.5/r))}setInitialCamera(e,t,i,r){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),i!==void 0&&i>0){let s=this.clampDistance(i);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else if(r!==void 0&&r>0){let s=this.clampDistance(this.bounds.radius*2.5/r);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 i=q();J(i,this.projMatrix,this.viewMatrix);let[r,s,d]=e,y=t?t[0]:0,u=t?t[1]:0,o=t?t[2]:0,a=this.modelRootMatrix;a&&(r=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],d=a[2]*e[0]+a[6]*e[1]+a[10]*e[2]+a[14],t&&(y=a[0]*t[0]+a[4]*t[1]+a[8]*t[2],u=a[1]*t[0]+a[5]*t[1]+a[9]*t[2],o=a[2]*t[0]+a[6]*t[1]+a[10]*t[2]));let l=i[0]*r+i[4]*s+i[8]*d+i[12],g=i[1]*r+i[5]*s+i[9]*d+i[13],T=i[2]*r+i[6]*s+i[10]*d+i[14],m=i[3]*r+i[7]*s+i[11]*d+i[15];if(m<=1e-4)return{x:0,y:0,z:1,visible:!1};let E=l/m,A=g/m,F=T/m,P=this.canvas.getBoundingClientRect(),f=P.width||this.canvas.clientWidth||this.canvas.width||300,M=P.height||this.canvas.clientHeight||this.canvas.height||150,b=(E*.5+.5)*f,I=(-A*.5+.5)*M,c=E>=-1.1&&E<=1.1&&A>=-1.1&&A<=1.1&&F>=-1&&F<=1;if(c&&t){let x=this.customTarget||this.bounds.center,h=x[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),w=x[1]+this.currDistance*Math.sin(this.currPhi),L=x[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),v=[r-h,s-w,d-L];y*v[0]+u*v[1]+o*v[2]>.05&&(c=!1)}return{x:b,y:I,z:F,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 i=this.activePointers.get(t.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},r=t.clientX-i.x,s=t.clientY-i.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(r,s),this.isPanning||t.button===2||t.shiftKey||this.activePointers.size===2){let d=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],y=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],u=this.customTarget?[...this.customTarget]:[...this.bounds.center],o=this.currDistance/Math.max(e.clientHeight||300,1)*1.5;u[0]+=(-r*d[0]+s*y[0])*o,u[1]+=(-r*d[1]+s*y[1])*o,u[2]+=(-r*d[2]+s*y[2])*o,this.customTarget=u}else this.targetTheta=this.clampTheta(this.targetTheta-r*.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 i=e.getBoundingClientRect(),r=Math.floor((t.clientX-i.left)*(e.width/Math.max(i.width,1))),s=Math.floor((t.clientY-i.top)*(e.height/Math.max(i.height,1)));this.performMeshPick(r,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 i=Math.exp(t.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*i)},e.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=t=>{let i=t.detail||{};i.reset?this.resetCamera():this.setCamera(i.theta,i.phi,i.distance,i.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 i=typeof performance<"u"?performance.now():Date.now();switch(t.key){case"ArrowLeft":this.lastInteractionTime=i,this.targetTheta=this.clampTheta(this.targetTheta-.1),t.preventDefault();break;case"ArrowRight":this.lastInteractionTime=i,this.targetTheta=this.clampTheta(this.targetTheta+.1),t.preventDefault();break;case"ArrowUp":this.lastInteractionTime=i,this.targetPhi=this.clampPhi(this.targetPhi+.08),t.preventDefault();break;case"ArrowDown":this.lastInteractionTime=i,this.targetPhi=this.clampPhi(this.targetPhi-.08),t.preventDefault();break;case"+":case"=":{this.lastInteractionTime=i,this.targetDistance=this.clampDistance(this.targetDistance*.9),t.preventDefault();break}case"-":case"_":{this.lastInteractionTime=i,this.targetDistance=this.clampDistance(this.targetDistance*1.1),t.preventDefault();break}case"Home":this.lastInteractionTime=i,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 i=this.canvas,r=i.getBoundingClientRect(),s=i.width||300,d=i.height||300,y=r.width>0?Math.floor((e-r.left)*(s/r.width)):Math.floor(e),u=r.height>0?Math.floor((t-r.top)*(d/r.height)):Math.floor(t);return this.performMeshPick(y,u,!1)}performMeshPick(e,t,i=!0){if(this.meshes.length===0)return null;let r=this.gl,s=Math.max(1,this.canvas.width||300),d=Math.max(1,this.canvas.height||300),y=q();J(y,this.projMatrix,this.viewMatrix);let u=[],o=Math.max(0,Math.min(s-1,e)),a=Math.max(0,Math.min(d-1,d-1-t));if(this.pickFbo&&r){(this.pickFboWidth!==s||this.pickFboHeight!==d)&&this.resizePickingFbo(s,d),r.bindFramebuffer(36160,this.pickFbo),r.viewport(0,0,s,d),r.enable(2929),r.clearColor(0,0,0,0),r.clear(16384|256),r.useProgram(this.pickProg);for(let c=0;c<this.meshes.length;c++){let x=this.meshes[c];if(x.visible===!1||x.isPluginMesh)continue;let h=c+1,w=(h&255)/255,L=(h>>8&255)/255,v=(h>>16&255)/255;r.uniform4f(this.uPick.uColorId,w,L,v,1),J(this.modelMatrix,this.modelRootMatrix,x.transform),J(this.mvpMatrix,y,this.modelMatrix),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let D of x.primitives)r.bindVertexArray(D.vao),r.drawElements(4,D.indexCount,D.indexType,0)}let b=new Uint8Array(4);r.readPixels(o,a,1,1,6408,5121,b),r.bindFramebuffer(36160,null);let I=b[0]+(b[1]<<8)+(b[2]<<16);I>0&&I<=this.meshes.length&&(u=[this.meshes[I-1]])}u.length===0&&(u=this.meshes.filter(b=>b.visible!==!1));let l=null,g=1/0,T=[0,0,0],m=[0,1,0],E=this.customTarget||this.bounds.center,A=E[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),F=E[1]+this.currDistance*Math.sin(this.currPhi),P=E[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let b of u){J(this.modelMatrix,this.modelRootMatrix,b.transform),J(this.mvpMatrix,y,this.modelMatrix);let I=q();if(!Se(I,this.mvpMatrix))continue;let c=(o+.5)/s*2-1,x=(a+.5)/d*2-1,h=[0,0,0],w=[0,0,0];xe(h,c,x,-1,I),xe(w,c,x,1,I);let L=w[0]-h[0],v=w[1]-h[1],D=w[2]-h[2],p=Math.hypot(L,v,D)||1,N=L/p,H=v/p,O=D/p,V={distance:1/0,point:[0,0,0],normal:[0,1,0]};if((C=>{for(let R of b.primitives){if(!R.positions)continue;let B=R.positions,U=R.indices,k=Math.floor(U?U.length/3:B.length/9);for(let _=0;_<k;_++){let G=U?U[_*3]:_*3,W=U?U[_*3+1]:_*3+1,$=U?U[_*3+2]:_*3+2;Ce(h[0],h[1],h[2],N,H,O,B[G*3],B[G*3+1],B[G*3+2],B[W*3],B[W*3+1],B[W*3+2],B[$*3],B[$*3+1],B[$*3+2],V,C)}}})(1e-4),isFinite(V.distance)){let C=V.point[0],R=V.point[1],B=V.point[2],U=this.modelMatrix,k=U[0]*C+U[4]*R+U[8]*B+U[12],_=U[1]*C+U[5]*R+U[9]*B+U[13],G=U[2]*C+U[6]*R+U[10]*B+U[14],W=k-A,$=_-F,ee=G-P,Y=Math.hypot(W,$,ee);if(Y<g){ne(this.normalMatrix,this.modelMatrix);let Z=this.normalMatrix,re=V.normal[0],se=V.normal[1],te=V.normal[2],j=Z[0]*re+Z[3]*se+Z[6]*te,ae=Z[1]*re+Z[4]*se+Z[7]*te,oe=Z[2]*re+Z[5]*se+Z[8]*te,le=Math.hypot(j,ae,oe)||1;j/=le,ae/=le,oe/=le,j*W+ae*$+oe*ee>0&&(j=-j,ae=-ae,oe=-oe),l=b,g=Math.round(Y*1e3)/1e3,T=[Math.round(k*1e3)/1e3,Math.round(_*1e3)/1e3,Math.round(G*1e3)/1e3],m=[Math.round(j*1e3)/1e3,Math.round(ae*1e3)/1e3,Math.round(oe*1e3)/1e3]}}}if(!l)return null;let M={meshIndex:this.meshes.indexOf(l),meshName:l.name,nodeIndex:l.nodeIndex,distance:g,hitPoint:T,normal:m,screenX:e,screenY:t};if(i){for(let b of K)b.onMeshSelect?.(this,M);this.opts.onMeshClick&&this.opts.onMeshClick(M),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:M}))}return M}resize(){let e=Math.min((typeof window<"u"?window.devicePixelRatio:1)||1,2),t=this.canvas.getBoundingClientRect(),i=Math.max(1,Math.floor(t.width*e)),r=Math.max(1,Math.floor(t.height*e));(this.canvas.width!==i||this.canvas.height!==r)&&(this.canvas.width=i,this.canvas.height=r,this.resizePickingFbo(i,r))}start(){if(this.animFrameId!==null)return;this.lastTime=performance.now();let e=t=>{let i=Math.min((t-this.lastTime)/1e3,.1);this.lastTime=t,this.isVisible&&(this.resize(),this.update(i),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),i=this.bounds.center[0],r=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]=i-(e*i+t*r),s[13]=0,s[14]=r-(-t*i+e*r),s[15]=1}setVisible(e){this.isVisible=e}update(e){for(let g of K)g.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 g of K)g.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 i=(this.canvas.width||1)/(this.canvas.height||1),r=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):this.bounds.radius*20;Fe(this.projMatrix,this.fov,i,.1,r);let s=this.customTarget||this.bounds.center,d=s[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),y=s[1]+this.currDistance*Math.sin(this.currPhi),u=s[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);Le(this.viewMatrix,[d,y,u],s,[0,1,0]),J(this.mvpMatrix,this.projMatrix,this.viewMatrix),ne(this.normalMatrix,this.modelMatrix);let o=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(o-this.lastReportedTheta)>=1||Math.abs(a-this.lastReportedPhi)>=1||Math.abs(l-this.lastReportedZoom)>=.02){this.lastReportedTheta=o,this.lastReportedPhi=a,this.lastReportedZoom=l;let g={theta:o,phi:a,zoom:l,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(g),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:g}))}}renderXRView(e,t,i,r){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(e);let s=e?.transform?.inverse?.matrix||this.viewMatrix,d=e?.projectionMatrix||this.projMatrix,y=e?.transform?.position,u=y?[y.x,y.y,y.z]:[0,1.6,0];i&&t&&this.modelRootMatrix.set(t),this.render({viewMatrix:s,projMatrix:d,eyePos:u,viewport:r,eye:e?.eye||"none",clear:e?.eye!=="right"})}render(e){let t=this.gl,i=this.canvas.width,r=this.canvas.height;e?.viewport?(t.viewport(e.viewport[0],e.viewport[1],e.viewport[2],e.viewport[3]),i=e.viewport[2],r=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=q();J(s,e?.projMatrix??this.projMatrix,e?.viewMatrix??this.viewMatrix);let d=this.toneMapping==="reinhard"?1:this.toneMapping==="none"?2:0,y=this.customTarget||this.bounds.center,u=e?e.eyePos[0]:y[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),o=e?e.eyePos[1]:y[1]+this.currDistance*Math.sin(this.currPhi),a=e?e.eyePos[2]:y[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let A of K)A.onBeforeDrawScene?.(this,t,s,[u,o,a],d);if(this.meshes.length===0&&this.backdropMeshes.length===0)return;let l=e?.eye||"none",g=!1,T=this.backdropMeshes.length,m=T>0?[...this.backdropMeshes,...this.meshes]:this.meshes,E=A=>{for(let F=0;F<m.length;F++){let P=m[F];if(P.visible===!1)continue;let f=this.selectedMeshName!==""&&P.name===this.selectedMeshName;F<T?this.modelMatrix.set(P.transform):J(this.modelMatrix,this.modelRootMatrix,P.transform),J(this.mvpMatrix,s,this.modelMatrix),ne(P.normalMatrix,this.modelMatrix);let M=P.extras?.xr?.stereo||P.userData?.xr?.stereo,b=0,I=0,c=1,x=1;M==="sbs"?(c=.5,b=l==="right"?.5:0):M==="ou"&&(x=.5,I=l==="right"?.5:0);for(let h of P.primitives){let w=!!h.isTransmissive;if(!A&&w){g=!0;continue}if(A&&!w)continue;let L=h.customProgram||this.renderProg,v=h.customUniforms||this.uRender;t.useProgram(L),t.uniform1i(v.uToneMapping,d),t.uniform1f(v.uEnvIntensity,this.envIntensity),t.uniform3f(v.uCameraPos,u,o,a),t.uniform1f(v.uEmissive,f?1:0),t.uniformMatrix4fv(v.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(v.uModel,!1,this.modelMatrix),t.uniformMatrix3fv(v.uNormalMatrix,!1,P.normalMatrix),v.uUvTransform&&t.uniform4f(v.uUvTransform,b,I,c,x),v.uViewportSize&&t.uniform2f(v.uViewportSize,Math.max(1,i),Math.max(1,r)),this.xrDepthState.enabled&&this.xrDepthState.texture?(t.activeTexture(33989),t.bindTexture(3553,this.xrDepthState.texture),v.uXrDepthTex&&t.uniform1i(v.uXrDepthTex,5),v.uXrDepthEnabled&&t.uniform1i(v.uXrDepthEnabled,1),v.uXrDepthFormat&&t.uniform1i(v.uXrDepthFormat,this.xrDepthState.format||0),v.uXrRawValueToMeters&&t.uniform1f(v.uXrRawValueToMeters,this.xrDepthState.rawValueToMeters),v.uXrDepthUVTransform&&t.uniformMatrix4fv(v.uXrDepthUVTransform,!1,this.xrDepthState.uvTransform)):v.uXrDepthEnabled&&t.uniform1i(v.uXrDepthEnabled,0),this.environmentTexture?(t.activeTexture(33988),t.bindTexture(3553,this.environmentTexture),t.uniform1i(v.uEnvironmentMap,4),t.uniform1i(v.uHasEnvironmentMap,1)):t.uniform1i(v.uHasEnvironmentMap,0),this.bindLights(v);for(let D of K)D.onBeforeDrawPrimitive?.(t,L,h,P,this.worldMatrices||[],this.gltf);t.uniform4fv(v.uBaseColor,h.baseColor),t.uniform1f(v.uMetallic,h.metallic),t.uniform1f(v.uRoughness,h.roughness),v.uClearcoat&&t.uniform2f(v.uClearcoat,h.clearcoat??0,h.clearcoatRoughness??.04),h.texture?(t.activeTexture(33984),t.bindTexture(3553,h.texture),t.uniform1i(v.uBaseColorTexture,0),t.uniform1i(v.uHasTexture,1)):t.uniform1i(v.uHasTexture,0),h.metallicRoughnessTexture?(t.activeTexture(33985),t.bindTexture(3553,h.metallicRoughnessTexture),t.uniform1i(v.uMetallicRoughnessTexture,1),t.uniform1i(v.uHasMetallicRoughnessTexture,1)):t.uniform1i(v.uHasMetallicRoughnessTexture,0),h.normalTexture?(t.activeTexture(33986),t.bindTexture(3553,h.normalTexture),t.uniform1i(v.uNormalTexture,2),t.uniform1i(v.uHasNormalTexture,1),t.uniform1f(v.uNormalScale,h.normalScale)):t.uniform1i(v.uHasNormalTexture,0),h.occlusionTexture?(t.activeTexture(33987),t.bindTexture(3553,h.occlusionTexture),t.uniform1i(v.uOcclusionTexture,3),t.uniform1i(v.uHasOcclusionTexture,1),t.uniform1f(v.uOcclusionStrength,h.occlusionStrength)):t.uniform1i(v.uHasOcclusionTexture,0),t.bindVertexArray(h.vao),t.drawElements(4,h.indexCount,h.indexType,0)}}};if(E(!1),g){for(let A of K)A.onBeforeTransmissivePass?.(t,this);E(!0)}for(let A of K)A.onAfterRender?.(t,this,s)}disposeMeshListGpuResources(e){let t=this.gl;for(let i of e)for(let r of i.primitives){if(r.vao&&t.deleteVertexArray(r.vao),r.buffers)for(let s of r.buffers)t.deleteBuffer(s);r.texture&&t.deleteTexture(r.texture),r.metallicRoughnessTexture&&t.deleteTexture(r.metallicRoughnessTexture),r.normalTexture&&t.deleteTexture(r.normalTexture),r.occlusionTexture&&t.deleteTexture(r.occlusionTexture),r.customProgram&&t.deleteProgram(r.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 K)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()}};ge.registerPlugin=Ee,ge.getRegisteredPlugins=Pe;function rt(n){return n+3&-4}function st(n){let e={};return n.grab&&(e.interactable={mode:typeof n.grab=="string"?n.grab:"2-hand"},e.movable={scaleInZ:!!n.scale,minScale:typeof n.scale=="object"?n.scale.min??.1:.1,maxScale:typeof n.scale=="object"?n.scale.max??10:10}),n.billboard&&(e.billboard={mode:typeof n.billboard=="string"?n.billboard:"capsule"}),n.follow&&(e.follow={target:typeof n.follow=="object"?n.follow.mode??"head":n.follow}),n.anchor&&(e.anchor={plane:n.anchor}),n.physics&&n.physics!=="none"&&(e.rigidbody={type:n.physics}),e}function at(n,e){n.updateMatrixWorld(!0);let t=[],i=0,r=[],s=[],d=[],y=[],u=new Set,o=[],a=[],l=new Map,g=[];function T(c,x){let h=new Uint8Array(c.buffer,c.byteOffset,c.byteLength),w=rt(h.byteLength),L=new Uint8Array(w);L.set(h),t.push(L);let v=r.length;return r.push({buffer:0,byteOffset:i,byteLength:h.byteLength,target:x}),i+=w,v}function m(c,x,h,w,L,v,D){let p=T(c,h),N=s.length,H={bufferView:p,byteOffset:0,componentType:w,count:L,type:x};return v&&(H.min=v),D&&(H.max=D),s.push(H),N}n.traverse(c=>{(c.isLight||c.color&&c.intensity!==void 0)&&g.push({type:c.type,color:[c.color.r,c.color.g,c.color.b],intensity:c.intensity,position:[c.position.x,c.position.y,c.position.z]})});let E=[];function A(c){let x={name:c.name||""},h=c.position,w=c.quaternion,L=c.scale;if((h.x||h.y||h.z)&&(x.translation=[h.x,h.y,h.z]),(w.x||w.y||w.z||w.w!==1)&&(x.rotation=[w.x,w.y,w.z,w.w]),(L.x!==1||L.y!==1||L.z!==1)&&(x.scale=[L.x,L.y,L.z]),c.userData&&Object.keys(c.userData).length>0&&(x.extras=JSON.parse(JSON.stringify(c.userData,(D,p)=>{if(!(D==="__proto__"||D==="prototype"||D==="constructor"))return typeof p=="function"?void 0:p})),c.userData.xr)){let D=st(c.userData.xr);x.extensions={...x.extensions||{},MOZ_hubs_components:D,ANDROID_xr_scenecore:D},ue().xrTraitSerializer?.gltfNode(x,c.userData.xr),u.add("MOZ_hubs_components").add("ANDROID_xr_scenecore")}if(c.geometry){let D=c.geometry,p=D.attributes.position;if(p&&p.count>0){let N=[1/0,1/0,1/0],H=[-1/0,-1/0,-1/0];for(let C=0;C<p.count;C++){let R=p.getX(C),B=p.getY(C),U=p.getZ(C);R<N[0]&&(N[0]=R),R>H[0]&&(H[0]=R),B<N[1]&&(N[1]=B),B>H[1]&&(H[1]=B),U<N[2]&&(N[2]=U),U>H[2]&&(H[2]=U)}let V={attributes:{POSITION:m(p.array,"VEC3",34962,5126,p.count,N,H)}};if(D.attributes.normal&&(V.attributes.NORMAL=m(D.attributes.normal.array,"VEC3",34962,5126,D.attributes.normal.count)),D.attributes.uv&&(V.attributes.TEXCOORD_0=m(D.attributes.uv.array,"VEC2",34962,5126,D.attributes.uv.count)),D.index){let C=D.index.array instanceof Uint32Array;V.indices=m(D.index.array,"SCALAR",34963,C?5125:5123,D.index.count)}if(c.material){let C=l.get(c.material);if(C===void 0){C=a.length,l.set(c.material,C);let R=c.material,B={name:R.name||"",pbrMetallicRoughness:{baseColorFactor:[R.color.r,R.color.g,R.color.b,R.opacity],metallicFactor:R.metalness,roughnessFactor:R.roughness},doubleSided:R.side===2||R.doubleSided};if(R.emissive&&(R.emissive.r>0||R.emissive.g>0||R.emissive.b>0)){let k=R.emissiveIntensity??1;B.emissiveFactor=[R.emissive.r*k,R.emissive.g*k,R.emissive.b*k]}let U={};R.clearcoat>0&&(U.KHR_materials_clearcoat={clearcoatFactor:R.clearcoat,clearcoatRoughnessFactor:R.clearcoatRoughness||0}),R.sheen>0&&(U.KHR_materials_sheen={sheenColorFactor:R.sheenColor?[R.sheenColor.r,R.sheenColor.g,R.sheenColor.b]:[1,1,1],sheenRoughnessFactor:R.sheenRoughness||0}),R.transmission>0&&(U.KHR_materials_transmission={transmissionFactor:R.transmission}),R.thickness>0&&(U.KHR_materials_volume={thicknessFactor:R.thickness,attenuationDistance:R.attenuationDistance??1/0,attenuationColor:R.attenuationColor?[R.attenuationColor.r,R.attenuationColor.g,R.attenuationColor.b]:[1,1,1]}),R.ior!==void 0&&R.ior!==1.5&&(U.KHR_materials_ior={ior:R.ior}),R.dispersion>0&&(U.KHR_materials_dispersion={dispersion:R.dispersion}),R.iridescence>0&&(U.KHR_materials_iridescence={iridescenceFactor:R.iridescence,iridescenceIor:R.iridescenceIOR??1.3}),Object.keys(U).length>0&&(B.extensions=U),a.push(B)}V.material=C}let S=d.length;d.push({primitives:[V],name:c.name,...x.extras?{extras:x.extras}:{}}),x.mesh=S}}let v=y.length;if(y.push(x),o.push(c),c.children.length>0){x.children=[];for(let D of c.children)x.children.push(A(D))}return v}for(let c of n.children)E.push(A(c));let F=e?.animateCallback||e?.animateFn||(typeof n.userData?.animate=="function"?n.userData.animate:typeof n.__animateFn=="function"?n.__animateFn:typeof globalThis.animate=="function"?globalThis.animate:void 0),P=[];if(typeof F=="function"&&o.length>0){let c=e?.duration??4,x=e?.fps??15,h=Math.max(2,Math.round(c*x)+1),w=new Float32Array(h),L=o.map(S=>({px:S.position.x,py:S.position.y,pz:S.position.z,qx:S.quaternion.x,qy:S.quaternion.y,qz:S.quaternion.z,qw:S.quaternion.w,sx:S.scale.x,sy:S.scale.y,sz:S.scale.z})),v=o.map(()=>new Float32Array(h*3)),D=o.map(()=>new Float32Array(h*4)),p=o.map(()=>new Float32Array(h*3));for(let S=0;S<h;S++){let C=S/(h-1)*c;w[S]=C;try{F(C)}catch{}for(let R=0;R<o.length;R++){let B=o[R];v[R][S*3]=B.position.x,v[R][S*3+1]=B.position.y,v[R][S*3+2]=B.position.z,D[R][S*4]=B.quaternion.x,D[R][S*4+1]=B.quaternion.y,D[R][S*4+2]=B.quaternion.z,D[R][S*4+3]=B.quaternion.w,p[R][S*3]=B.scale.x,p[R][S*3+1]=B.scale.y,p[R][S*3+2]=B.scale.z}}for(let S=0;S<o.length;S++){let C=o[S],R=L[S];C.position.set(R.px,R.py,R.pz),C.quaternion.set(R.qx,R.qy,R.qz,R.qw),C.scale.set(R.sx,R.sy,R.sz)}n.updateMatrixWorld(!0);let N=null,H=()=>(N===null&&(N=m(w,"SCALAR",0,5126,h,[0],[c])),N),O=[],V=[];for(let S=0;S<o.length;S++){let C=L[S],R=!1,B=!1,U=!1;for(let k=0;k<h;k++)(Math.abs(v[S][k*3]-C.px)>1e-4||Math.abs(v[S][k*3+1]-C.py)>1e-4||Math.abs(v[S][k*3+2]-C.pz)>1e-4)&&(R=!0),(Math.abs(D[S][k*4]-C.qx)>1e-4||Math.abs(D[S][k*4+1]-C.qy)>1e-4||Math.abs(D[S][k*4+2]-C.qz)>1e-4||Math.abs(D[S][k*4+3]-C.qw)>1e-4)&&(B=!0),(Math.abs(p[S][k*3]-C.sx)>1e-4||Math.abs(p[S][k*3+1]-C.sy)>1e-4||Math.abs(p[S][k*3+2]-C.sz)>1e-4)&&(U=!0);if(R){let k=m(v[S],"VEC3",0,5126,h),_=O.length;O.push({input:H(),interpolation:"LINEAR",output:k}),V.push({sampler:_,target:{node:S,path:"translation"}})}if(B){let k=m(D[S],"VEC4",0,5126,h),_=O.length;O.push({input:H(),interpolation:"LINEAR",output:k}),V.push({sampler:_,target:{node:S,path:"rotation"}})}if(U){let k=m(p[S],"VEC3",0,5126,h),_=O.length;O.push({input:H(),interpolation:"LINEAR",output:k}),V.push({sampler:_,target:{node:S,path:"scale"}})}}V.length>0&&P.push({name:"ProceduralLoop",samplers:O,channels:V})}let f=we(y,d,n.userData),M={asset:{version:"2.0",generator:"ThreeLiveConvert",extras:{environmentIntensity:n.environmentIntensity}},scenes:[{nodes:E}],scene:0,nodes:y,meshes:d,materials:a,accessors:s,bufferViews:r,buffers:[{byteLength:i}],...P.length>0?{animations:P}:{},...f||u.size>0?{extensionsUsed:[...f?["KHR_interactivity"]:[],...u]}:{},...f?{extensions:{KHR_interactivity:f}}:{}},b=new Uint8Array(i),I=0;for(let c of t)b.set(c,I),I+=c.byteLength;return{gltf:M,bin:b.buffer,lights:g,environmentIntensity:n.environmentIntensity}}function ve(n){return new TextEncoder().encode(n)}function Rt(n,e){let{gltf:t,bin:i}=at(n,e),r=JSON.stringify(t),s=ve(r),d=(4-s.byteLength%4)%4,y=s.byteLength+d,u=20+y+8+i.byteLength,o=new Uint8Array(u),a=new DataView(o.buffer);a.setUint32(0,1179937895,!0),a.setUint32(4,2,!0),a.setUint32(8,u,!0),a.setUint32(12,y,!0),a.setUint32(16,1313821514,!0),o.set(s,20);for(let g=0;g<d;g++)o[20+s.byteLength+g]=32;let l=20+y;return a.setUint32(l,i.byteLength,!0),a.setUint32(l+4,5130562,!0),o.set(new Uint8Array(i),l+8),o}function ot(n,e){n.updateMatrixWorld(!0);let t=[];return n.traverse(i=>{if(i.geometry){let r=i.geometry,s=r.attributes.position;if(!s||s.count===0)return;let d=s.count,y=new Float32Array(d*3),u=i.matrixWorld.elements;for(let c=0;c<d;c++){let x=s.getX(c),h=s.getY(c),w=s.getZ(c);y[c*3]=u[0]*x+u[4]*h+u[8]*w+u[12],y[c*3+1]=u[1]*x+u[5]*h+u[9]*w+u[13],y[c*3+2]=u[2]*x+u[6]*h+u[10]*w+u[14]}let o;if(r.attributes.normal){let c=r.attributes.normal;o=new Float32Array(d*3);let x=new Float32Array(9);ne(x,u);for(let h=0;h<d;h++){let w=c.getX(h),L=c.getY(h),v=c.getZ(h),D=x[0]*w+x[3]*L+x[6]*v,p=x[1]*w+x[4]*L+x[7]*v,N=x[2]*w+x[5]*L+x[8]*v,H=Math.hypot(D,p,N)||1;o[h*3]=D/H,o[h*3+1]=p/H,o[h*3+2]=N/H}}let a;if(r.attributes.uv){let c=r.attributes.uv;a=new Float32Array(d*2);for(let x=0;x<d;x++)a[x*2]=c.getX(x),a[x*2+1]=c.getY(x)}let l;if(r.index)l=r.index.array;else{l=d>65535?new Uint32Array(d):new Uint16Array(d);for(let c=0;c<d;c++)l[c]=c}let g="DefaultMaterial",T=[.8,.8,.8],m=.5,E=.1,A=0,F=0,P=1.5,f=1,M=[0,0,0];if(i.material){let c=i.material;g=c.name||`Material_${t.length}`,c.color&&(T=[c.color.r,c.color.g,c.color.b]),typeof c.roughness=="number"&&(m=c.roughness),typeof c.metalness=="number"&&(E=c.metalness),typeof c.clearcoat=="number"&&(A=c.clearcoat),typeof c.clearcoatRoughness=="number"&&(F=c.clearcoatRoughness),typeof c.ior=="number"&&(P=c.ior);let x=typeof c.opacity=="number"?c.opacity:1,h=typeof c.transmission=="number"?c.transmission:0;if(f=x*(1-h),c.emissive&&(c.emissive.r>0||c.emissive.g>0||c.emissive.b>0)){let w=c.emissiveIntensity??1;M=[c.emissive.r*w,c.emissive.g*w,c.emissive.b*w]}}let b,I=e?.animateCallback||e?.animateFn||(typeof n.userData?.animate=="function"?n.userData.animate:typeof n.__animateFn=="function"?n.__animateFn:typeof globalThis.animate=="function"?globalThis.animate:void 0);if(typeof I=="function"){let c=e?.duration??4,x=e?.fps??4,h=Math.max(2,Math.round(c*x)+1),w=[],L=[],v=[],D=[],p=[i.position.x,i.position.y,i.position.z],N=[i.quaternion.x,i.quaternion.y,i.quaternion.z,i.quaternion.w],H=[i.scale.x,i.scale.y,i.scale.z],O=!1;for(let V=0;V<h;V++){let S=V/(h-1)*c;w.push(S);try{I(S)}catch{}L.push([i.position.x,i.position.y,i.position.z]),v.push([i.quaternion.x,i.quaternion.y,i.quaternion.z,i.quaternion.w]),D.push([i.scale.x,i.scale.y,i.scale.z]),(Math.abs(i.position.x-p[0])>1e-4||Math.abs(i.position.y-p[1])>1e-4||Math.abs(i.position.z-p[2])>1e-4||Math.abs(i.quaternion.x-N[0])>1e-4||Math.abs(i.quaternion.y-N[1])>1e-4||Math.abs(i.quaternion.z-N[2])>1e-4||Math.abs(i.quaternion.w-N[3])>1e-4||Math.abs(i.scale.x-H[0])>1e-4)&&(O=!0)}i.position.set(p[0],p[1],p[2]),i.quaternion.set(N[0],N[1],N[2],N[3]),i.scale.set(H[0],H[1],H[2]),O&&(b={times:w,translations:L,rotations:v,scales:D})}t.push({name:i.name||`Mesh_${t.length}`,positions:y,indices:l,normals:o,uvs:a,materialName:g,color:T,roughness:m,metallic:E,clearcoat:A,clearcoatRoughness:F,ior:P,opacity:f,emissiveColor:M,xrTraits:i.userData?.xr,timeSamples:b})}}),t}function $e(n){let e=[],t=n.gltf,i=n.bin,r=i instanceof ArrayBuffer?i:i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),s=t.accessors||[],d=t.bufferViews||[],y=t.materials||[],u=t.meshes||[],o=t.nodes||[];function a(T){let m=s[T];if(!m)throw new Error(`Accessor ${T} not found`);let E=d[m.bufferView||0],A=(E.byteOffset||0)+(m.byteOffset||0),F=E.byteLength||0,P=r.slice(A,A+F);return{acc:m,buffer:P}}let l=new Map;if(o.length>0){let T=be(t);for(let m=0;m<T.length;m++)l.set(m,T[m])}function g(T,m,E,A){let F=u[T];if(!F)return;let P=new Float32Array(9);ne(P,m);for(let f=0;f<(F.primitives||[]).length;f++){let M=F.primitives[f],b=M.attributes?.POSITION;if(b===void 0)continue;let{acc:I,buffer:c}=a(b),x=new Float32Array(c,0,I.count*3),h=new Float32Array(x.length);for(let _=0;_<I.count;_++){let G=x[_*3],W=x[_*3+1],$=x[_*3+2];h[_*3]=m[0]*G+m[4]*W+m[8]*$+m[12],h[_*3+1]=m[1]*G+m[5]*W+m[9]*$+m[13],h[_*3+2]=m[2]*G+m[6]*W+m[10]*$+m[14]}let w,L=M.attributes?.NORMAL;if(L!==void 0){let{acc:_,buffer:G}=a(L),W=new Float32Array(G,0,_.count*3);w=new Float32Array(W.length);for(let $=0;$<_.count;$++){let ee=W[$*3],Y=W[$*3+1],Z=W[$*3+2],re=P[0]*ee+P[3]*Y+P[6]*Z,se=P[1]*ee+P[4]*Y+P[7]*Z,te=P[2]*ee+P[5]*Y+P[8]*Z,j=Math.hypot(re,se,te)||1;w[$*3]=re/j,w[$*3+1]=se/j,w[$*3+2]=te/j}}let v,D=M.attributes?.TEXCOORD_0;if(D!==void 0){let{acc:_,buffer:G}=a(D);v=new Float32Array(G,0,_.count*2)}let p;if(M.indices!==void 0){let{acc:_,buffer:G}=a(M.indices);_.componentType===5125?p=new Uint32Array(G,0,_.count):p=new Uint16Array(G,0,_.count);let W=I.count;for(let $ of p)if($>=W)throw new Error(`SecurityError: Index buffer value (${$}) out of vertex bounds [0, ${W}).`)}else{let _=I.count;p=_>65535?new Uint32Array(_):new Uint16Array(_);for(let G=0;G<_;G++)p[G]=G}let N="DefaultMaterial",H=[.8,.8,.8],O=.5,V=.1,S=0,C=0,R=1.5,B=1,U=[0,0,0];if(M.material!==void 0&&y[M.material]){let _=y[M.material];N=_.name||`Material_${M.material}`;let G=_.pbrMetallicRoughness||{},W=1;Array.isArray(G.baseColorFactor)&&(H=[G.baseColorFactor[0],G.baseColorFactor[1],G.baseColorFactor[2]],typeof G.baseColorFactor[3]=="number"&&(W=G.baseColorFactor[3])),typeof G.roughnessFactor=="number"&&(O=G.roughnessFactor),typeof G.metallicFactor=="number"&&(V=G.metallicFactor),Array.isArray(_.emissiveFactor)&&_.emissiveFactor.length>=3&&(U=[_.emissiveFactor[0],_.emissiveFactor[1],_.emissiveFactor[2]]);let $=_.extensions||{};$.KHR_materials_clearcoat&&(S=$.KHR_materials_clearcoat.clearcoatFactor??0,C=$.KHR_materials_clearcoat.clearcoatRoughnessFactor??0),$.KHR_materials_ior&&typeof $.KHR_materials_ior.ior=="number"&&(R=$.KHR_materials_ior.ior);let ee=$.KHR_materials_transmission?.transmissionFactor??0;B=W*(1-ee)}let k=(F.primitives||[]).length>1?`${E}_p${f}`:E;e.push({name:k,positions:h,indices:p,normals:w,uvs:v,materialName:N,color:H,roughness:O,metallic:V,clearcoat:S,clearcoatRoughness:C,ior:R,opacity:B,emissiveColor:U,xrTraits:A?.xr||F.extras?.xr})}}if(o.length>0)for(let T=0;T<o.length;T++){let m=o[T];if(m.mesh!==void 0&&m.mesh<u.length){let E=l.get(T)||q(),A=m.name||u[m.mesh].name||`Node_${T}`;g(m.mesh,E,A,m.extras)}}else{let T=q();for(let m=0;m<u.length;m++){let E=u[m].name||`Mesh_${m}`;g(m,T,E,u[m].extras)}}return e}function Ae(n,e){if(!n||typeof n!="string")return e;let t=n.replace(/[^A-Za-z0-9_]/g,"_");return/^[0-9]/.test(t)&&(t="_"+t),t||e}function He(n){return String(n??"").replace(/[\x00-\x1f\x7f]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function z(n){if(!Number.isFinite(n)||Math.abs(n)<1e-7)return"0";let e=Number(n.toFixed(5)).toString();return e.indexOf(".")===-1?`${e}.0`:e}function ze(n){let e=n.length/3,t=new Array(e);for(let i=0;i<e;i++)t[i]=`(${z(n[i*3])}, ${z(n[i*3+1])}, ${z(n[i*3+2])})`;return t.join(", ")}function ut(n,e){let t=new Array(e);for(let i=0;i<e;i++)t[i]=`(${z(n[i*2])}, ${z(1-n[i*2+1])})`;return t.join(", ")}function ct(n){return Array.from(n).join(", ")}function De(n){let e=new Map;for(let u of n){let o=Ae(u.materialName,"DefaultMaterial");e.has(o)||e.set(o,{color:u.color||[.8,.8,.8],roughness:u.roughness??.5,metallic:u.metallic??0,clearcoat:u.clearcoat??0,clearcoatRoughness:u.clearcoatRoughness??0,ior:u.ior??1.5,opacity:u.opacity??1,emissiveColor:u.emissiveColor||[0,0,0]})}let t=0,i=null;for(let u of n){if(u.timeSamples&&u.timeSamples.times.length>0){let o=u.timeSamples.times[u.timeSamples.times.length-1];o>t&&(t=o)}u.xrTraits?.anchor&&!i&&(i=u.xrTraits.anchor==="vertical"||u.xrTraits.anchor==="wall"?"vertical":"horizontal")}let r="";t>0&&(r=`startTimeCode = 0
|
|
218
|
+
endTimeCode = ${z(t)}
|
|
219
|
+
timeCodesPerSecond = 1.0
|
|
220
|
+
`);let s="";i&&(s=`uniform token preliminary:anchoring:type = "plane"
|
|
221
|
+
uniform token preliminary:planeAnchoring:alignment = "${i}"
|
|
222
|
+
`);let d=`#usda 1.0
|
|
223
|
+
(
|
|
224
|
+
defaultPrim = "Root"
|
|
225
|
+
metersPerUnit = 1.0
|
|
226
|
+
upAxis = "Y"
|
|
227
|
+
${r})
|
|
228
|
+
|
|
229
|
+
def Xform "Root" (
|
|
230
|
+
kind = "component"
|
|
231
|
+
)
|
|
232
|
+
{
|
|
233
|
+
${s}def Scope "Materials"
|
|
234
|
+
{
|
|
235
|
+
`;for(let[u,o]of e.entries()){let[a,l,g]=o.color,[T,m,E]=o.emissiveColor,A="";o.clearcoat>0&&(A+=`float inputs:clearcoat = ${z(o.clearcoat)}
|
|
236
|
+
`,A+=`float inputs:clearcoatRoughness = ${z(o.clearcoatRoughness)}
|
|
237
|
+
`),o.ior!==1.5&&(A+=`float inputs:ior = ${z(o.ior)}
|
|
238
|
+
`),o.opacity<1&&(A+=`float inputs:opacity = ${z(o.opacity)}
|
|
239
|
+
`),(T>0||m>0||E>0)&&(A+=`color3f inputs:emissiveColor = (${z(T)}, ${z(m)}, ${z(E)})
|
|
240
|
+
`),d+=`def Material "${u}"
|
|
241
|
+
{
|
|
242
|
+
def Shader "PBRShader"
|
|
243
|
+
{
|
|
244
|
+
uniform token info:id = "UsdPreviewSurface"
|
|
245
|
+
color3f inputs:diffuseColor = (${z(a)}, ${z(l)}, ${z(g)})
|
|
246
|
+
float inputs:metallic = ${z(o.metallic)}
|
|
247
|
+
float inputs:roughness = ${z(o.roughness)}
|
|
248
|
+
${A}token outputs:surface
|
|
249
|
+
}
|
|
250
|
+
token outputs:surface.connect = </Root/Materials/${u}/PBRShader.outputs:surface>
|
|
251
|
+
}
|
|
252
|
+
`}d+=`}
|
|
253
|
+
def Scope "Meshes"
|
|
254
|
+
{
|
|
255
|
+
`;let y=new Set;for(let u=0;u<n.length;u++){let o=n[u],a=o.positions.length/3,l=1/0,g=1/0,T=1/0,m=-1/0,E=-1/0,A=-1/0;for(let c=0;c<a;c++){let x=o.positions[c*3],h=o.positions[c*3+1],w=o.positions[c*3+2];x<l&&(l=x),x>m&&(m=x),h<g&&(g=h),h>E&&(E=h),w<T&&(T=w),w>A&&(A=w)}isFinite(l)||(l=g=T=-1,m=E=A=1);let F=Math.floor(o.indices.length/3),P=Ae(o.materialName,"DefaultMaterial"),f=Ae(o.name,`Mesh_${u}`);y.has(f)&&(f=`${f}_${u}`),y.add(f);let M=F>0?F===1?"3":"3, ".repeat(F-1)+"3":"",b=o.xrTraits,I="";if(b){let c=[];b.physics&&b.physics!=="none"&&c.push('prepend apiSchemas = ["PhysicsBodyAPI", "PhysicsCollisionAPI"]');let x=ue().xrTraitSerializer?.usdLines(b,He)??[];if(!x.length)for(let h of["grab","billboard","follow","anchor","physics"]){let w=h==="follow"&&typeof b.follow=="object"?b.follow.mode??"head":b[h];w!==void 0&&x.push(`string ${h} = "${He(w)}"`)}x.length>0&&c.push(`customData = {
|
|
256
|
+
dictionary xr = {
|
|
257
|
+
${x.join(`
|
|
258
|
+
`)}
|
|
259
|
+
}
|
|
260
|
+
}`),c.length>0&&(I=` (
|
|
261
|
+
${c.join(`
|
|
262
|
+
`)}
|
|
263
|
+
)`)}if(d+=`def Mesh "${f}"${I}
|
|
264
|
+
{
|
|
265
|
+
`,b?.physics&&b.physics!=="none"){let c=b.physics==="static"?"true":"false";d+=`bool physics:rigidBodyEnabled = true
|
|
266
|
+
bool physics:kinematicEnabled = ${c}
|
|
267
|
+
bool physics:collisionEnabled = true
|
|
268
|
+
`}if(o.timeSamples&&o.timeSamples.times.length>0){let c=o.timeSamples,x=c.times.map((L,v)=>{let D=c.translations?.[v]||[0,0,0];return`${z(L)}: (${z(D[0])}, ${z(D[1])}, ${z(D[2])})`}).join(", "),h=c.times.map((L,v)=>{let D=c.rotations?.[v]||[0,0,0,1];return`${z(L)}: (${z(D[3])}, ${z(D[0])}, ${z(D[1])}, ${z(D[2])})`}).join(", "),w=c.times.map((L,v)=>{let D=c.scales?.[v]||[1,1,1];return`${z(L)}: (${z(D[0])}, ${z(D[1])}, ${z(D[2])})`}).join(", ");d+=`double3 xformOp:translate.timeSamples = { ${x} }
|
|
269
|
+
quatf xformOp:orient.timeSamples = { ${h} }
|
|
270
|
+
double3 xformOp:scale.timeSamples = { ${w} }
|
|
271
|
+
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
|
|
272
|
+
`}d+=`float3[] extent = [(${z(l)}, ${z(g)}, ${z(T)}), (${z(m)}, ${z(E)}, ${z(A)})]
|
|
273
|
+
int[] faceVertexCounts = [${M}]
|
|
274
|
+
int[] faceVertexIndices = [${ct(o.indices)}]
|
|
275
|
+
point3f[] points = [${ze(o.positions)}]
|
|
276
|
+
`,o.normals&&o.normals.length===o.positions.length&&(d+=`normal3f[] normals = [${ze(o.normals)}] (
|
|
277
|
+
interpolation = "vertex"
|
|
278
|
+
)
|
|
279
|
+
`),o.uvs&&o.uvs.length===a*2&&(d+=`texCoord2f[] primvars:st = [${ut(o.uvs,a)}] (
|
|
280
|
+
interpolation = "vertex"
|
|
281
|
+
)
|
|
282
|
+
`),d+=`rel material:binding = </Root/Materials/${P}>
|
|
283
|
+
}
|
|
284
|
+
`}return d+=`}
|
|
285
|
+
}
|
|
286
|
+
`,d}function lt(n,e){if(n&&typeof n.traverse=="function"){let r=ot(n,e);return De(r)}let t=he(n),i=$e(t);return De(i)}var ye=null;function mt(n){if(!ye){ye=new Uint32Array(256);for(let t=0;t<256;t++){let i=t;for(let r=0;r<8;r++)i=i&1?3988292384^i>>>1:i>>>1;ye[t]=i}}let e=4294967295;for(let t=0;t<n.length;t++)e=ye[(e^n[t])&255]^e>>>8;return(e^4294967295)>>>0}function Xe(n){let e=[],t=0,i=[];for(let a of n){let l=ve(a.filename),g=mt(a.data),T=a.data.length,m=30+l.length,E=t+m,A=0,F=E%64;F!==0&&(A=64-F);let P=new Uint8Array(m+A),f=new DataView(P.buffer);f.setUint32(0,67324752,!0),f.setUint16(4,20,!0),f.setUint16(6,0,!0),f.setUint16(8,0,!0),f.setUint16(10,0,!0),f.setUint16(12,0,!0),f.setUint32(14,g,!0),f.setUint32(18,T,!0),f.setUint32(22,T,!0),f.setUint16(26,l.length,!0),f.setUint16(28,A,!0),P.set(l,30),A>0&&P.fill(0,30+l.length),e.push({offset:t,size:T,crc:g,filenameBytes:l,entry:a}),i.push(P),i.push(a.data),t+=P.length+a.data.length}let r=t;for(let a of e){let l=new Uint8Array(46+a.filenameBytes.length),g=new DataView(l.buffer);g.setUint32(0,33639248,!0),g.setUint16(4,20,!0),g.setUint16(6,20,!0),g.setUint16(8,0,!0),g.setUint16(10,0,!0),g.setUint16(12,0,!0),g.setUint16(14,0,!0),g.setUint32(16,a.crc,!0),g.setUint32(20,a.size,!0),g.setUint32(24,a.size,!0),g.setUint16(28,a.filenameBytes.length,!0),g.setUint16(30,0,!0),g.setUint16(32,0,!0),g.setUint16(34,0,!0),g.setUint16(36,0,!0),g.setUint32(38,0,!0),g.setUint32(42,a.offset,!0),l.set(a.filenameBytes,46),i.push(l),t+=l.length}let s=t-r,d=new Uint8Array(22),y=new DataView(d.buffer);y.setUint32(0,101010256,!0),y.setUint16(4,0,!0),y.setUint16(6,0,!0),y.setUint16(8,e.length,!0),y.setUint16(10,e.length,!0),y.setUint32(12,s,!0),y.setUint32(16,r,!0),y.setUint16(20,0,!0),i.push(d),t+=22;let u=new Uint8Array(t),o=0;for(let a of i)u.set(a,o),o+=a.length;return u}function ht(n){let e=lt(n),t=ve(e);return Xe([{filename:"model.usda",data:t}])}function We(n){let e=he(n),t=$e(e),i=De(t),r=ve(i);return Xe([{filename:"model.usda",data:r}])}function At(n){return n&&typeof n.toUSDZ=="function"?n.toUSDZ():n&&typeof n.traverse=="function"?ht(n):We(n)}function Dt(n){let e=n&&typeof n.toUSDZ=="function"?n.toUSDZ():We(n);return new Blob([e],{type:"model/vnd.usdz+zip"})}export{Xe as buildUSDZZip,mt as calculateCRC32,we as compileInteractivityGraph,Dt as createUSDZBlob,ve as encodeUtf8,$e as extractMeshesFromGLB,ot as extractMeshesFromScene,lt as generateUSDA,De as generateUSDAFromMeshes,At as generateUSDZ,We as glbToUSDZ,Ae as sanitizeUsdIdentifier,He as sanitizeUsdStringLiteral,at as sceneToCanvas3D,Rt as sceneToGLB,ht as sceneToUSDZ};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
"use strict";var _=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var $=(e,n)=>{for(var r in n)_(e,r,{get:n[r],enumerable:!0})},Y=(e,n,r,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of X(n))!H.call(e,t)&&t!==r&&_(e,t,{get:()=>n[t],enumerable:!(i=J(n,t))||i.enumerable});return e};var q=e=>Y(_({},"__esModule",{value:!0}),e);var Q={};$(Q,{crossFadeTo:()=>W,keyframeAnimationPlugin:()=>D,morphPlugin:()=>B,parseAnimations:()=>I,sampleChannel:()=>F,setMorphTargetWeight:()=>j,skinningPlugin:()=>k});module.exports=q(Q);var M="__THREE_LIVE_REGISTRY__";function G(){let e=typeof globalThis<"u"?globalThis:{};if(!e[M]){let n={plugins:[],decoders:new Map};try{Object.defineProperty(e,M,{value:n,writable:!1,configurable:!1,enumerable:!1})}catch{e[M]=n}}return e[M]}var ee=G().plugins;function S(e){let n=G().plugins;n.some(r=>r.name===e.name)||n.push(e)}function R(){let e=new Float32Array(16);return e[0]=1,e[5]=1,e[10]=1,e[15]=1,e}function K(e,n,r){let i=n[0],t=n[1],c=n[2],f=n[3],u=n[4],s=n[5],b=n[6],o=n[7],a=n[8],m=n[9],l=n[10],p=n[11],A=n[12],h=n[13],x=n[14],d=n[15],y=r[0],g=r[1],T=r[2],P=r[3];return e[0]=y*i+g*u+T*a+P*A,e[1]=y*t+g*s+T*m+P*h,e[2]=y*c+g*b+T*l+P*x,e[3]=y*f+g*o+T*p+P*d,y=r[4],g=r[5],T=r[6],P=r[7],e[4]=y*i+g*u+T*a+P*A,e[5]=y*t+g*s+T*m+P*h,e[6]=y*c+g*b+T*l+P*x,e[7]=y*f+g*o+T*p+P*d,y=r[8],g=r[9],T=r[10],P=r[11],e[8]=y*i+g*u+T*a+P*A,e[9]=y*t+g*s+T*m+P*h,e[10]=y*c+g*b+T*l+P*x,e[11]=y*f+g*o+T*p+P*d,y=r[12],g=r[13],T=r[14],P=r[15],e[12]=y*i+g*u+T*a+P*A,e[13]=y*t+g*s+T*m+P*h,e[14]=y*c+g*b+T*l+P*x,e[15]=y*f+g*o+T*p+P*d,e}function L(e,n,r,i){let t=n[0],c=n[1],f=n[2],u=n[3],s=t+t,b=c+c,o=f+f,a=t*s,m=t*b,l=t*o,p=c*b,A=c*o,h=f*o,x=u*s,d=u*b,y=u*o,g=i[0],T=i[1],P=i[2];return e[0]=(1-(p+h))*g,e[1]=(m+y)*g,e[2]=(l-d)*g,e[3]=0,e[4]=(m-y)*T,e[5]=(1-(a+h))*T,e[6]=(A+x)*T,e[7]=0,e[8]=(l+d)*P,e[9]=(A-x)*P,e[10]=(1-(a+p))*P,e[11]=0,e[12]=r[0],e[13]=r[1],e[14]=r[2],e[15]=1,e}function V(e,n){let r=n[0],i=n[1],t=n[2],c=n[4],f=n[5],u=n[6],s=n[8],b=n[9],o=n[10],a=o*f-u*b,m=-o*c+u*s,l=b*c-f*s,p=r*a+i*m+t*l;return p&&(p=1/p,e[0]=a*p,e[1]=(-o*i+t*b)*p,e[2]=(u*i-t*f)*p,e[3]=m*p,e[4]=(o*r-t*s)*p,e[5]=(-u*r+t*c)*p,e[6]=l*p,e[7]=(-b*r+i*s)*p,e[8]=(f*r-i*c)*p),e}function U(e,n){let r=Array.isArray(e?.nodes)?e.nodes.length:0,i=[];for(let o=0;o<r;o++)i.push(R());if(r===0)return i;let t=new Set;for(let o of e.nodes)if(Array.isArray(o.children))for(let a of o.children)t.add(a);let c=new Set,f=128,u=(o,a,m=0)=>{if(m>f||o<0||o>=r||c.has(o))return;c.add(o);let l=e.nodes[o];if(!l)return;let p=R();if(n&&n[o])p.set(n[o]);else if(l.matrix&&l.matrix.length===16)p.set(l.matrix);else{let h=l.translation||[0,0,0],x=l.rotation||[0,0,0,1],d=l.scale||[1,1,1];L(p,x,h,d)}let A=i[o];if(a?K(A,a,p):A.set(p),Array.isArray(l.children))for(let h of l.children)typeof h=="number"&&u(h,A,m+1)},s=[],b=e.scenes&&e.scenes[e.scene!==void 0?e.scene:0];if(b&&Array.isArray(b.nodes))s.push(...b.nodes);else for(let o=0;o<r;o++)t.has(o)||s.push(o);for(let o of s)u(o,null);for(let o=0;o<r;o++)!t.has(o)&&!s.includes(o)&&u(o,null);return i}function w(e,n,r){return n%4===0?new Float32Array(e,n,r):new Float32Array(e.slice(n,n+r*4))}function z(e,n,r,i){let t=n[0],c=n[1],f=n[2],u=n[3],s=r[0],b=r[1],o=r[2],a=r[3],m=t*s+c*b+f*o+u*a;if(m<0&&(s=-s,b=-b,o=-o,a=-a,m=-m),Math.abs(m)>=1)return e[0]=t,e[1]=c,e[2]=f,e[3]=u,e;let l=Math.acos(m),p=Math.sqrt(1-m*m);if(Math.abs(p)<.001)return e[0]=.5*(t+s),e[1]=.5*(c+b),e[2]=.5*(f+o),e[3]=.5*(u+a),e;let A=Math.sin((1-i)*l)/p,h=Math.sin(i*l)/p;return e[0]=t*A+s*h,e[1]=c*A+b*h,e[2]=f*A+o*h,e[3]=u*A+a*h,e}function N(e,n,r,i){return e[0]=n[0]+i*(r[0]-n[0]),e[1]=n[1]+i*(r[1]-n[1]),e[2]=n[2]+i*(r[2]-n[2]),e}function I(e,n){if(!Array.isArray(e?.animations))return[];let r=[];for(let i=0;i<e.animations.length;i++){let t=e.animations[i],c=t.name||`Animation_${i}`,f=[],u=0;if(Array.isArray(t.channels)&&Array.isArray(t.samplers))for(let s of t.channels){if(!s.target||s.target.node===void 0||!s.target.path)continue;let b=t.samplers[s.sampler];if(!b)continue;let o=e.accessors?.[b.input],a=e.accessors?.[b.output];if(!o||!a)continue;let m=e.bufferViews?.[o.bufferView],l=e.bufferViews?.[a.bufferView];if(!m||!l)continue;let p=(m.byteOffset||0)+(o.byteOffset||0),A=(l.byteOffset||0)+(a.byteOffset||0),h=w(n,p,o.count);h.length>0&&h[h.length-1]>u&&(u=h[h.length-1]);let x=s.target.path==="rotation"?4:s.target.path==="weights"?Math.max(1,Math.round(a.count/Math.max(1,o.count))):3,d=w(n,A,a.count*(s.target.path==="weights"?1:x)),y=b.interpolation==="STEP"?"STEP":"LINEAR";f.push({nodeIndex:s.target.node,path:s.target.path,times:h,values:d,interpolation:y})}f.length>0&&r.push({name:c,duration:u,channels:f})}return r}function F(e,n,r){let{times:i,values:t,path:c,interpolation:f}=e,u=i.length;if(u===0)return;let s=c==="rotation"?4:c==="weights"?Math.max(1,Math.round(t.length/u)):3;if(n<=i[0]){for(let d=0;d<s;d++)r[d]=t[d];return}if(n>=i[u-1]){let d=(u-1)*s;for(let y=0;y<s;y++)r[y]=t[d+y];return}let b=0,o=u-1;for(;b<=o;){let d=b+o>>1;i[d]<=n?b=d+1:o=d-1}let a=Math.max(0,o),m=Math.min(u-1,a+1);if(f==="STEP"||a===m){let d=a*s;for(let y=0;y<s;y++)r[y]=t[d+y];return}let l=i[a],p=i[m],A=(n-l)/Math.max(1e-5,p-l),h=a*s,x=m*s;if(c==="rotation"){let d=[t[h],t[h+1],t[h+2],t[h+3]],y=[t[x],t[x+1],t[x+2],t[x+3]];z(r,d,y,A)}else for(let d=0;d<s;d++)r[d]=t[h+d]+A*(t[x+d]-t[h+d])}var E=new WeakMap;function W(e,n,r=.3){if(!e?.animations)return;let i=e.animations.find(u=>u.name===n);if(!i)return;let t=E.get(e);t||(t=[],e.currentClip&&t.push({clip:e.currentClip,time:e.animationTime||0,weight:1,fadeSpeed:0}),E.set(e,t));let c=r>0?1/r:1e3;for(let u of t)u.clip.name!==n&&(u.fadeSpeed=-c);let f=t.find(u=>u.clip.name===n);f?f.fadeSpeed=c:t.push({clip:i,time:0,weight:r>0?0:1,fadeSpeed:c}),e.currentClip=i,e.isPlayingAnimation=!0}function C(e,n){if(!e.gltf||!Array.isArray(e.gltf.nodes))return;let r=E.get(e);if(!r||r.length===0){if(!e.currentClip)return;r=[{clip:e.currentClip,time:n,weight:1,fadeSpeed:0}]}let i=e.gltf.nodes.length,t=[];for(let a=0;a<i;a++){let m=e.initialNodeTransforms[a];m?t.push({t:[m.t[0],m.t[1],m.t[2]],r:[m.r[0],m.r[1],m.r[2],m.r[3]],s:[m.s[0],m.s[1],m.s[2]]}):t.push({t:[0,0,0],r:[0,0,0,1],s:[1,1,1]})}let c=[0,0,0],f=[0,0,0,1],u=[1,1,1],s=new Float32Array(64);for(let a of r){let m=Math.max(0,Math.min(1,a.weight));if(!(m<=1e-4))for(let l of a.clip.channels){if(l.nodeIndex<0||l.nodeIndex>=i)continue;let p=t[l.nodeIndex];if(l.path==="translation")F(l,a.time,c),N(p.t,p.t,c,m);else if(l.path==="rotation")F(l,a.time,f),z(p.r,p.r,f,m);else if(l.path==="scale")F(l,a.time,u),N(p.s,p.s,u,m);else if(l.path==="weights"&&(F(l,a.time,s),e.meshes)){for(let A of e.meshes)if(A.nodeIndex===l.nodeIndex){for(let h of A.primitives)if(h.pluginData?.morph?.weights){let x=h.pluginData.morph.weights,d=h.pluginData.morph.numTargets||x.length;for(let y=0;y<d;y++)x[y]=x[y]*(1-m)+s[y]*m}}}}}let b=[];for(let a=0;a<i;a++){let m=R(),{t:l,r:p,s:A}=t[a];L(m,p,l,A),b.push(m)}let o=U(e.gltf,b);e.worldMatrices=o;for(let a of e.meshes)a.nodeIndex>=0&&a.nodeIndex<o.length&&(a.transform.set(o[a.nodeIndex]),V(a.normalMatrix,a.transform))}var D={name:"keyframes",evaluateAnimation:C,crossFadeTo:W,onParseGLB(e){!e.animations&&e.gltf?.animations&&(e.animations=I(e.gltf,e.bin))},onUpdate(e,n){if(!e.isPlayingAnimation)return;let r=E.get(e);if(r&&r.length>0){for(let i=r.length-1;i>=0;i--){let t=r[i];if(t.time+=n,t.clip.duration>0&&(t.time%=t.clip.duration),t.fadeSpeed!==0)if(t.weight+=t.fadeSpeed*n,t.weight<=0){r.splice(i,1);continue}else t.weight>=1&&(t.weight=1,t.fadeSpeed=0)}r.length>0&&(e.animationTime=r[r.length-1].time),C(e,e.animationTime)}else e.currentClip&&(e.animationTime+=n,e.currentClip.duration>0&&(e.animationTime%=e.currentClip.duration),C(e,e.animationTime))}};var v=64;function j(e,n,r){if(!(!e?.meshes||n<0||n>=v))for(let i of e.meshes)for(let t of i.primitives){let c=t.pluginData?.morph;c?.weights&&(c.weights[n]=r)}}var B={name:"morph",onResolveShader(e,n,r,i){if(!Array.isArray(e?.targets)||e.targets.length===0)return null;let t=r.replace("uniform mat4 uMVP,uModel;",`uniform mat4 uMVP,uModel;
|
|
18
|
+
uniform sampler2D uMorphDeltasTex;
|
|
19
|
+
uniform float uMorphWeights[${v}];
|
|
20
|
+
uniform int uNumMorphTargets;`);return t=t.replace("vec4 world=uModel*vec4(aPosition,1.0);",`vec3 morphedPos = aPosition;
|
|
21
|
+
for (int m = 0; m < ${v}; m++) {
|
|
22
|
+
if (m >= uNumMorphTargets) break;
|
|
23
|
+
float w = uMorphWeights[m];
|
|
24
|
+
if (abs(w) > 0.0001) {
|
|
25
|
+
morphedPos += texelFetch(uMorphDeltasTex, ivec2(gl_VertexID, m), 0).xyz * w;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
vec4 world=uModel*vec4(morphedPos,1.0);`).replace("gl_Position=uMVP*vec4(aPosition,1.0);","gl_Position=uMVP*vec4(morphedPos,1.0);"),{vs:t,fs:i}},onBuildPrimitiveVAO(e,n,r,i,t){let c=r?.targets;if(!Array.isArray(c)||c.length===0)return null;let f=r.attributes?.POSITION,u=i?.accessors?.[f];if(!u)return null;let s=u.count,b=Math.min(c.length,v),o=new Float32Array(s*b*4);for(let l=0;l<b;l++){let p=c[l].POSITION;if(p===void 0)continue;let A=i.accessors?.[p],h=i.bufferViews?.[A?.bufferView];if(!A||!h)continue;let x=(h.byteOffset||0)+(A.byteOffset||0),d=w(t,x,s*3),y=l*s*4;for(let g=0;g<s;g++)o[y+g*4]=d[g*3],o[y+g*4+1]=d[g*3+1],o[y+g*4+2]=d[g*3+2],o[y+g*4+3]=0}let a=e.createTexture();e.bindTexture(3553,a),e.texImage2D(3553,0,34836,s,b,0,6408,5126,o),e.texParameteri(3553,10242,33071),e.texParameteri(3553,10243,33071),e.texParameteri(3553,10241,9728),e.texParameteri(3553,10240,9728);let m=new Float32Array(v);return{hasMorph:!0,morphTex:a,numTargets:b,vertexCount:s,weights:m}},onBeforeDrawPrimitive(e,n,r,i,t,c){let f=r.pluginData?.morph;if(!f?.hasMorph||!f.morphTex)return;e.activeTexture(33989),e.bindTexture(3553,f.morphTex);let u=e.getUniformLocation(n,"uMorphDeltasTex");u&&e.uniform1i(u,5);let s=e.getUniformLocation(n,"uNumMorphTargets");s&&e.uniform1i(s,f.numTargets);let b=e.getUniformLocation(n,"uMorphWeights[0]");b&&e.uniform1fv(b,f.weights)}};var O=64,k={name:"skinning",onResolveShader(e,n,r,i){if(e?.attributes?.JOINTS_0===void 0||e?.attributes?.WEIGHTS_0===void 0)return null;let t=r.replace("layout(location=2) in vec2 aUV;",`layout(location=2) in vec2 aUV;
|
|
29
|
+
layout(location=4) in uvec4 aJoints;
|
|
30
|
+
layout(location=5) in vec4 aWeights;
|
|
31
|
+
uniform mat4 uJointMatrix[${O}];`),c=t.includes("morphedPos")?"morphedPos":"aPosition";return t=t.replace(`vec4 world=uModel*vec4(${c},1.0);`,`mat4 skinMatrix =
|
|
32
|
+
aWeights.x * uJointMatrix[int(aJoints.x)] +
|
|
33
|
+
aWeights.y * uJointMatrix[int(aJoints.y)] +
|
|
34
|
+
aWeights.z * uJointMatrix[int(aJoints.z)] +
|
|
35
|
+
aWeights.w * uJointMatrix[int(aJoints.w)];
|
|
36
|
+
vec4 world=uModel*(skinMatrix*vec4(${c},1.0));`).replace(`gl_Position=uMVP*vec4(${c},1.0);`,`gl_Position=uMVP*(skinMatrix*vec4(${c},1.0));`),{vs:t,fs:i}},onBuildPrimitiveVAO(e,n,r,i,t){let c=r?.attributes;if(!c||c.JOINTS_0===void 0||c.WEIGHTS_0===void 0)return null;let f=i.accessors[c.JOINTS_0],u=i.accessors[c.WEIGHTS_0];if(!f||!u)return null;let s=i.bufferViews[f.bufferView],b=i.bufferViews[u.bufferView];if(!s||!b)return null;let o=(s.byteOffset||0)+(f.byteOffset||0),a=(b.byteOffset||0)+(u.byteOffset||0),m=e.createBuffer();e.bindBuffer(34962,m);let l=f.componentType===5121?5121:5123,p=l===5121?new Uint8Array(t,o,f.count*4):new Uint16Array(t,o,f.count*4);e.bufferData(34962,p,35044),e.enableVertexAttribArray(4),e.vertexAttribIPointer(4,4,l,0,0);let A=e.createBuffer();e.bindBuffer(34962,A);let h=new Float32Array(t,a,u.count*4);return e.bufferData(34962,h,35044),e.enableVertexAttribArray(5),e.vertexAttribPointer(5,4,5126,!1,0,0),{hasSkin:!0,buffers:[m,A]}},onBeforeDrawPrimitive(e,n,r,i,t,c){if(!r.pluginData?.skinning?.hasSkin)return;let f=c?.nodes?.[i.nodeIndex]?.skin;if(f===void 0||!c.skins||!c.skins[f])return;let s=c.skins[f].joints||[],b=new Float32Array(O*16);for(let a=0;a<s.length&&a<O;a++){let m=s[a],l=t[m]||R();b.subarray(a*16,(a+1)*16).set(l)}let o=e.getUniformLocation(n,"uJointMatrix[0]");o&&e.uniformMatrix4fv(o,!1,b)}};S(B);S(D);S(k);
|