three-live 1.3.1 → 1.4.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/README.md +4 -1
- package/dist/index.d.ts +191 -0
- package/dist/three-author-engine.js +179 -144
- package/dist/three-author.cjs +153 -144
- package/dist/three-author.d.ts +191 -0
- package/dist/three-author.js +153 -144
- package/dist/three-convert.cjs +150 -141
- package/dist/three-convert.d.ts +191 -0
- package/dist/three-convert.js +150 -141
- package/dist/three-live-ai.cjs +41 -0
- package/dist/three-live-ai.d.ts +759 -0
- package/dist/three-live-ai.js +41 -0
- package/dist/three-live-ai.min.js +41 -0
- package/dist/three-live-animation.cjs +6 -6
- package/dist/three-live-animation.d.ts +191 -0
- package/dist/three-live-animation.js +5 -5
- package/dist/three-live-animation.min.js +5 -5
- package/dist/three-live-cad.cjs +2 -2
- package/dist/three-live-cad.d.ts +191 -0
- package/dist/three-live-cad.js +2 -2
- package/dist/three-live-cad.min.js +2 -2
- package/dist/three-live-element.cjs +50 -85
- package/dist/three-live-element.d.ts +191 -0
- package/dist/three-live-element.js +50 -85
- package/dist/three-live-full.cjs +915 -170
- package/dist/three-live-full.js +917 -172
- package/dist/three-live-full.min.js +915 -170
- package/dist/three-live-procedural.cjs +16 -0
- package/dist/three-live-procedural.d.ts +759 -0
- package/dist/three-live-procedural.js +16 -0
- package/dist/three-live-procedural.min.js +16 -0
- package/dist/three-live-sandbox.html +11 -1
- package/dist/three-live-studio.cjs +72 -17
- package/dist/three-live-studio.d.ts +191 -0
- package/dist/three-live-studio.js +72 -17
- package/dist/three-live-studio.min.js +73 -18
- package/dist/three-live-tsl.cjs +103 -0
- package/dist/three-live-tsl.d.ts +759 -0
- package/dist/three-live-tsl.js +103 -0
- package/dist/three-live-tsl.min.js +103 -0
- package/dist/three-live-viewer.cjs +50 -85
- package/dist/three-live-viewer.d.ts +191 -0
- package/dist/three-live-viewer.js +50 -85
- package/dist/three-live-viewer.min.js +50 -85
- package/dist/three-live-webgpu.cjs +585 -0
- package/dist/three-live-webgpu.d.ts +759 -0
- package/dist/three-live-webgpu.js +585 -0
- package/dist/three-live-webgpu.min.js +585 -0
- package/dist/three-live.cjs +155 -146
- package/dist/three-live.js +155 -146
- package/dist/three-live.min.js +155 -146
- package/dist/three-view.cjs +49 -84
- package/dist/three-view.d.ts +191 -0
- package/dist/three-view.js +50 -85
- package/dist/three-xr.cjs +150 -141
- package/dist/three-xr.d.ts +191 -0
- package/dist/three-xr.js +150 -141
- package/package.json +39 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
|
-
*/function Dt(e,t){let i=e?.trim(),r=i?Number(i):NaN;return Number.isFinite(r)?r:t}var jt='SecurityError: Client-modified script compilation (Use Case 1) is disabled by default to satisfy strict CSP and Trusted Types requirements. Use script-src="..." or loadScriptFromSrc(url) for server-generated scripts (Use Case 2), or explicitly opt in via ThreeLiveElement.allowClientScripts = true (or the allow-client-scripts attribute).',$t="Security Error: client-side scripts require allow-client-scripts opt-in.",bt="__THREE_LIVE_REGISTRY__";function Z(){let e=typeof globalThis<"u"?globalThis:{};if(!e[bt]){let t={plugins:[],decoders:new Map};try{Object.defineProperty(e,bt,{value:t,writable:!1,configurable:!1,enumerable:!1})}catch{e[bt]=t}}return e[bt]}var j=Z().plugins;function Wt(e){let t=Z().plugins;t.some(i=>i.name===e.name)||t.push(e),e.onRegister?.()}function qt(){return Z().plugins}var Kt={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4};function Et(e,t,i,r){if(!i||i.bufferView===void 0)return null;let s=e.bufferViews?.[i.bufferView];if(!s)return null;let a=Number(i.count??0);if(!Number.isInteger(a)||a<=0)return null;let o=i.componentType??5126,h=Kt[o];if(!h)throw new RangeError(`glTF accessor has unsupported componentType ${o}`);let l=h*r,n=s.byteStride&&s.byteStride>0?s.byteStride:l,c=(s.byteOffset||0)+(i.byteOffset||0);if(!Number.isInteger(c)||c<0||n<l||c+(a-1)*n+l>t.byteLength)throw new RangeError(`glTF accessor reads past the end of the binary buffer (${t.byteLength} bytes)`);if(o===5126&&n===l&&c%4===0)return new Float32Array(t,c,a*r);let m=new DataView(t),x=i.normalized===!0,f=new Float32Array(a*r);for(let v=0;v<a;v++){let b=c+v*n;for(let T=0;T<r;T++){let M=b+T*h,d;switch(o){case 5126:d=m.getFloat32(M,!0);break;case 5120:d=m.getInt8(M),x&&(d=Math.max(d/127,-1));break;case 5121:d=m.getUint8(M),x&&(d/=255);break;case 5122:d=m.getInt16(M,!0),x&&(d=Math.max(d/32767,-1));break;case 5123:d=m.getUint16(M,!0),x&&(d/=65535);break;default:d=m.getUint32(M,!0),x&&(d/=4294967295)}f[v*r+T]=d}}return f}function Yt(e,t){let i=Number(t.offset?.[0]??0)||0,r=Number(t.offset?.[1]??0)||0,s=Number(t.scale?.[0]??1),a=Number(t.scale?.[1]??1),o=Number(t.rotation??0)||0,h=Math.cos(o),l=Math.sin(o),n=(Number.isFinite(s)?s:1)*h,c=(Number.isFinite(s)?s:1)*l,m=-(Number.isFinite(a)?a:1)*l,x=(Number.isFinite(a)?a:1)*h;for(let f=0;f+1<e.length;f+=2){let v=e[f],b=e[f+1];e[f]=n*v+c*b+i,e[f+1]=m*v+x*b+r}}function wt(e,t,i,r=!0){let s=[],a=null;try{for(let[o,h]of[[35633,t],[35632,i]]){let l=e.createShader(o);if(!l){if(r)throw new Error("Shader allocation failed");return null}if(s.push(l),e.shaderSource(l,h),e.compileShader(l),e.getShaderParameter&&!e.getShaderParameter(l,35713)){if(r)throw new Error(`Shader compile error: ${e.getShaderInfoLog(l)}`);return null}}if(a=e.createProgram(),!a){if(r)throw new Error("Program allocation failed");return null}for(let o of s)e.attachShader(a,o);if(e.linkProgram(a),e.getProgramParameter&&!e.getProgramParameter(a,35714)){let o=r?e.getProgramInfoLog(a):null;if(e.deleteProgram?.(a),a=null,r)throw new Error(`Program link error: ${o}`);return null}return a}finally{for(let o of s)a&&e.detachShader?.(a,o),e.deleteShader?.(o)}}function z(){let e=new Float32Array(16);return e[0]=1,e[5]=1,e[10]=1,e[15]=1,e}function Tt(e,t,i,r,s){let a=1/Math.tan(t/2);e.fill(0),e[0]=a/i,e[5]=a,e[11]=-1;let o=1/(r-s);return e[10]=(s+r)*o,e[14]=2*s*r*o,e}function Pt(e,t,i,r){let[s,a,o]=t,[h,l,n]=r,[c,m,x]=i,f=s-c,v=a-m,b=o-x,T=Math.hypot(f,v,b);T<=1e-5?(f=0,v=0,b=1):(f/=T,v/=T,b/=T);let M=l*b-n*v,d=n*f-h*b,g=h*v-l*f;T=Math.hypot(M,d,g),T<=1e-5?(M=0,d=0,g=0):(M/=T,d/=T,g/=T);let p=v*g-b*d,A=b*M-f*g,w=f*d-v*M;return T=Math.hypot(p,A,w),T<=1e-5?(p=0,A=0,w=0):(p/=T,A/=T,w/=T),e[0]=M,e[1]=p,e[2]=f,e[3]=0,e[4]=d,e[5]=A,e[6]=v,e[7]=0,e[8]=g,e[9]=w,e[10]=b,e[11]=0,e[12]=-(M*s+d*a+g*o),e[13]=-(p*s+A*a+w*o),e[14]=-(f*s+v*a+b*o),e[15]=1,e}function Q(e,t,i){let r=t[0],s=t[1],a=t[2],o=t[3],h=t[4],l=t[5],n=t[6],c=t[7],m=t[8],x=t[9],f=t[10],v=t[11],b=t[12],T=t[13],M=t[14],d=t[15],g=i[0],p=i[1],A=i[2],w=i[3];return e[0]=g*r+p*h+A*m+w*b,e[1]=g*s+p*l+A*x+w*T,e[2]=g*a+p*n+A*f+w*M,e[3]=g*o+p*c+A*v+w*d,g=i[4],p=i[5],A=i[6],w=i[7],e[4]=g*r+p*h+A*m+w*b,e[5]=g*s+p*l+A*x+w*T,e[6]=g*a+p*n+A*f+w*M,e[7]=g*o+p*c+A*v+w*d,g=i[8],p=i[9],A=i[10],w=i[11],e[8]=g*r+p*h+A*m+w*b,e[9]=g*s+p*l+A*x+w*T,e[10]=g*a+p*n+A*f+w*M,e[11]=g*o+p*c+A*v+w*d,g=i[12],p=i[13],A=i[14],w=i[15],e[12]=g*r+p*h+A*m+w*b,e[13]=g*s+p*l+A*x+w*T,e[14]=g*a+p*n+A*f+w*M,e[15]=g*o+p*c+A*v+w*d,e}function Lt(e,t,i,r){let s=t[0],a=t[1],o=t[2],h=t[3],l=s+s,n=a+a,c=o+o,m=s*l,x=s*n,f=s*c,v=a*n,b=a*c,T=o*c,M=h*l,d=h*n,g=h*c,p=r[0],A=r[1],w=r[2];return e[0]=(1-(v+T))*p,e[1]=(x+g)*p,e[2]=(f-d)*p,e[3]=0,e[4]=(x-g)*A,e[5]=(1-(m+T))*A,e[6]=(b+M)*A,e[7]=0,e[8]=(f+d)*w,e[9]=(b-M)*w,e[10]=(1-(m+v))*w,e[11]=0,e[12]=i[0],e[13]=i[1],e[14]=i[2],e[15]=1,e}function ut(e,t,i=0){let r=t[0],s=t[1],a=t[2],o=t[4],h=t[5],l=t[6],n=t[8],c=t[9],m=t[10],x=m*h-l*c,f=-m*o+l*n,v=c*o-h*n,b=r*x+s*f+a*v;return!b||i>0&&(!Number.isFinite(b)||Math.abs(b)<=i)||(b=1/b,e[0]=x*b,e[1]=f*b,e[2]=v*b,e[3]=(-m*s+a*c)*b,e[4]=(m*r-a*n)*b,e[5]=(-c*r+s*n)*b,e[6]=(l*s-a*h)*b,e[7]=(-l*r+a*o)*b,e[8]=(h*r-s*o)*b),e}function Zt(e,t){let i=t[0],r=t[1],s=t[2],a=t[3],o=t[4],h=t[5],l=t[6],n=t[7],c=t[8],m=t[9],x=t[10],f=t[11],v=t[12],b=t[13],T=t[14],M=t[15],d=i*h-r*o,g=i*l-s*o,p=i*n-a*o,A=r*l-s*h,w=r*n-a*h,V=s*n-a*l,_=c*b-m*v,U=c*T-x*v,E=c*M-f*v,y=m*T-x*b,L=m*M-f*b,P=x*M-f*T,u=d*P-g*L+p*y+A*E-w*U+V*_;return u?(u=1/u,e[0]=(h*P-l*L+n*y)*u,e[1]=(s*L-r*P-a*y)*u,e[2]=(b*V-T*w+M*A)*u,e[3]=(x*w-m*V-f*A)*u,e[4]=(l*E-o*P-n*U)*u,e[5]=(i*P-s*E+a*U)*u,e[6]=(T*p-v*V-M*g)*u,e[7]=(c*V-x*p+f*g)*u,e[8]=(o*L-h*E+n*_)*u,e[9]=(r*E-i*L-a*_)*u,e[10]=(v*w-b*p+M*d)*u,e[11]=(m*p-c*w-f*d)*u,e[12]=(h*U-o*y-l*_)*u,e[13]=(i*y-r*U+s*_)*u,e[14]=(b*g-v*A-T*d)*u,e[15]=(c*A-m*g+x*d)*u,e):null}function It(e,t,i,r,s){let a=s[0]*t+s[4]*i+s[8]*r+s[12],o=s[1]*t+s[5]*i+s[9]*r+s[13],h=s[2]*t+s[6]*i+s[10]*r+s[14],l=s[3]*t+s[7]*i+s[11]*r+s[15],n=l!==0?1/l:1;e[0]=a*n,e[1]=o*n,e[2]=h*n}function Qt(e,t,i,r,s,a,o,h,l,n,c,m,x,f,v,b,T=0){let M=n-o,d=c-h,g=m-l,p=x-o,A=f-h,w=v-l,V=s*w-a*A,_=a*p-r*w,U=r*A-s*p,E=M*V+d*_+g*U;if(E>-1e-7&&E<1e-7)return!1;let y=1/E,L=e-o,P=t-h,u=i-l,C=y*(L*V+P*_+u*U);if(C<-T||C>1+T)return!1;let H=P*g-u*d,Y=u*M-L*g,I=L*d-P*M,k=y*(r*H+s*Y+a*I);if(k<-T||C+k>1+T)return!1;let R=y*(p*H+A*Y+w*I);if(R>1e-4&&R<b.distance){b.distance=R,b.point=[e+r*R,t+s*R,i+a*R];let N=d*w-g*A,B=g*p-M*w,F=M*A-d*p,W=Math.hypot(N,B,F)||1;return b.normal=[N/W,B/W,F/W],!0}return!1}function Jt(e,t){let i=Array.isArray(e?.nodes)?e.nodes.length:0,r=[];for(let c=0;c<i;c++)r.push(z());if(i===0)return r;let s=new Set;for(let c of e.nodes)if(Array.isArray(c.children))for(let m of c.children)s.add(m);let a=new Set,o=128,h=(c,m,x=0)=>{if(x>o||c<0||c>=i||a.has(c))return;a.add(c);let f=e.nodes[c];if(!f)return;let v=z();if(t&&t[c])v.set(t[c]);else if(f.matrix&&f.matrix.length===16)v.set(f.matrix);else{let T=f.translation||[0,0,0],M=f.rotation||[0,0,0,1],d=f.scale||[1,1,1];Lt(v,M,T,d)}let b=r[c];if(m?Q(b,m,v):b.set(v),Array.isArray(f.children))for(let T of f.children)typeof T=="number"&&h(T,b,x+1)},l=[],n=e.scenes&&e.scenes[e.scene!==void 0?e.scene:0];if(n&&Array.isArray(n.nodes))l.push(...n.nodes);else for(let c=0;c<i;c++)s.has(c)||l.push(c);for(let c of l)h(c,null);for(let c=0;c<i;c++)!s.has(c)&&!l.includes(c)&&h(c,null);return r}var kt=["neutral","reinhard","none","aces","agx"];function pt(e){let t=String(e??"").trim().toLowerCase();return kt.includes(t)?t:"neutral"}function te(e){return kt.indexOf(pt(e))}function ee(e){return new TextDecoder().decode(e)}var Nt=Z().decoders;function ie(e,t){Nt.set(e.toLowerCase(),t)}function mt(e){return Nt.get(e.toLowerCase())}function Vt(e){let t=ArrayBuffer.isView(e)?e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength):e,i=new DataView(t);if(t.byteLength<12)throw new Error(`Invalid GLB buffer size: ${t.byteLength} bytes`);let r=i.getUint32(0,!0);if(r!==1179937895){let x=i.getUint8(0);throw x===123||x===32||x===10||x===13?new Error("[three-live] Multi-file JSON .gltf is not supported for performance reasons. Please pack your asset into a single binary .glb file."):new Error(`Invalid GLB magic: 0x${r.toString(16)}`)}let s=i.getUint32(4,!0);if(s!==2)throw new Error(`Unsupported GLB version: ${s}`);let a=i.getUint32(8,!0),o=12,h=null,l=null;for(;o+8<=a&&o+8<=t.byteLength;){let x=i.getUint32(o,!0),f=i.getUint32(o+4,!0),v=o+8;if(v+x>t.byteLength)throw new Error(`Truncated GLB chunk: required ${v+x} bytes, buffer has ${t.byteLength}`);if(f===1313821514){let b=new Uint8Array(t,v,x),T=ee(b);h=JSON.parse(T,(M,d)=>M==="__proto__"||M==="constructor"||M==="prototype"?void 0:d)}else f===5130562&&(l=t.slice(v,v+x));o=v+x}if(!h)throw new Error("Missing JSON chunk in GLB");let n=h.extensionsRequired||[];if(n.includes("KHR_draco_mesh_compression")&&!mt("draco"))throw new Error("Model requires KHR_draco_mesh_compression. Register a decoder via ThreeLiveElement.registerDecoder('draco', decoder).");for(let x of["EXT_meshopt_compression","KHR_meshopt_compression"])if(n.includes(x)&&!mt("meshopt"))throw new Error(`Model requires ${x}. Register a decoder via ThreeLiveElement.registerDecoder('meshopt', decoder).`);if(n.includes("KHR_texture_basisu")&&!mt("ktx2"))throw new Error("Model requires KHR_texture_basisu. Register a decoder via ThreeLiveElement.registerDecoder('ktx2', decoder).");let c=l||new ArrayBuffer(0),m={gltf:h,bin:c,animations:[]};for(let x of j)x.onParseGLB?.(m);return m}function re(e){return typeof e=="object"&&e!==null&&"gltf"in e&&typeof e.gltf=="object"&&e.gltf!==null&&"bin"in e&&(e.bin instanceof ArrayBuffer||ArrayBuffer.isView(e.bin))}function xt(e){if(re(e))return e;if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))return Vt(e);throw new TypeError("Invalid 3D model input: expected GLBData ({ gltf, bin }) or binary GLB (ArrayBuffer / ArrayBufferView).")}var Ft=`#version 300 es
|
|
16
|
+
*/function Le(t,e){let i=t?.trim(),r=i?Number(i):NaN;return Number.isFinite(r)?r:e}var $e='SecurityError: Client-modified script compilation (Use Case 1) is disabled by default to satisfy strict CSP and Trusted Types requirements. Use script-src="..." or loadScriptFromSrc(url) for server-generated scripts (Use Case 2), or explicitly opt in via ThreeLiveElement.allowClientScripts = true (or the allow-client-scripts attribute).',Xe="Security Error: client-side scripts require allow-client-scripts opt-in.",ge="__THREE_LIVE_REGISTRY__";function K(){let t=typeof globalThis<"u"?globalThis:{};if(!t[ge]){let e={plugins:[],decoders:new Map};try{Object.defineProperty(t,ge,{value:e,writable:!1,configurable:!1,enumerable:!1})}catch{t[ge]=e}}return t[ge]}var $=K().plugins;function qe(t){let e=K().plugins;e.some(i=>i.name===t.name)||e.push(t),t.onRegister?.()}function Ke(){return K().plugins}var Ye={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4};function Ie(t,e,i,r){if(!i||i.bufferView===void 0)return null;let a=t.bufferViews?.[i.bufferView];if(!a)return null;let s=Number(i.count??0);if(!Number.isInteger(s)||s<=0)return null;let o=i.componentType??5126,n=Ye[o];if(!n)throw new RangeError(`glTF accessor has unsupported componentType ${o}`);let l=n*r,h=a.byteStride&&a.byteStride>0?a.byteStride:l,u=(a.byteOffset||0)+(i.byteOffset||0);if(!Number.isInteger(u)||u<0||h<l||u+(s-1)*h+l>e.byteLength)throw new RangeError(`glTF accessor reads past the end of the binary buffer (${e.byteLength} bytes)`);if(o===5126&&h===l&&u%4===0)return new Float32Array(e,u,s*r);let m=new DataView(e),v=i.normalized===!0,d=new Float32Array(s*r);for(let f=0;f<s;f++){let g=u+f*h;for(let b=0;b<r;b++){let y=g+b*n,p;switch(o){case 5126:p=m.getFloat32(y,!0);break;case 5120:p=m.getInt8(y),v&&(p=Math.max(p/127,-1));break;case 5121:p=m.getUint8(y),v&&(p/=255);break;case 5122:p=m.getInt16(y,!0),v&&(p=Math.max(p/32767,-1));break;case 5123:p=m.getUint16(y,!0),v&&(p/=65535);break;default:p=m.getUint32(y,!0),v&&(p/=4294967295)}d[f*r+b]=p}}return d}function Ze(t,e){let i=Number(e.offset?.[0]??0)||0,r=Number(e.offset?.[1]??0)||0,a=Number(e.scale?.[0]??1),s=Number(e.scale?.[1]??1),o=Number(e.rotation??0)||0,n=Math.cos(o),l=Math.sin(o),h=(Number.isFinite(a)?a:1)*n,u=(Number.isFinite(a)?a:1)*l,m=-(Number.isFinite(s)?s:1)*l,v=(Number.isFinite(s)?s:1)*n;for(let d=0;d+1<t.length;d+=2){let f=t[d],g=t[d+1];t[d]=h*f+u*g+i,t[d+1]=m*f+v*g+r}}function ve(t,e,i,r=!0){let a=[],s=null;try{for(let[o,n]of[[35633,e],[35632,i]]){let l=t.createShader(o);if(!l){if(r)throw new Error("Shader allocation failed");return null}if(a.push(l),t.shaderSource(l,n),t.compileShader(l),t.getShaderParameter&&!t.getShaderParameter(l,35713)){if(r)throw new Error(`Shader compile error: ${t.getShaderInfoLog(l)}`);return null}}if(s=t.createProgram(),!s){if(r)throw new Error("Program allocation failed");return null}for(let o of a)t.attachShader(s,o);if(t.linkProgram(s),t.getProgramParameter&&!t.getProgramParameter(s,35714)){let o=r?t.getProgramInfoLog(s):null;if(t.deleteProgram?.(s),s=null,r)throw new Error(`Program link error: ${o}`);return null}return s}finally{for(let o of a)s&&t.detachShader?.(s,o),t.deleteShader?.(o)}}function X(){let t=new Float32Array(16);return t[0]=1,t[5]=1,t[10]=1,t[15]=1,t}function ke(t,e,i,r,a){let s=1/Math.tan(e/2);t.fill(0),t[0]=s/i,t[5]=s,t[11]=-1;let o=1/(r-a);return t[10]=(a+r)*o,t[14]=2*a*r*o,t}function Ne(t,e,i,r){let[a,s,o]=e,[n,l,h]=r,[u,m,v]=i,d=a-u,f=s-m,g=o-v,b=Math.hypot(d,f,g);b<=1e-5?(d=0,f=0,g=1):(d/=b,f/=b,g/=b);let y=l*g-h*f,p=h*d-n*g,w=n*f-l*d;b=Math.hypot(y,p,w),b<=1e-5?(y=0,p=0,w=0):(y/=b,p/=b,w/=b);let T=f*w-g*p,A=g*y-d*w,x=d*p-f*y;return b=Math.hypot(T,A,x),b<=1e-5?(T=0,A=0,x=0):(T/=b,A/=b,x/=b),t[0]=y,t[1]=T,t[2]=d,t[3]=0,t[4]=p,t[5]=A,t[6]=f,t[7]=0,t[8]=w,t[9]=x,t[10]=g,t[11]=0,t[12]=-(y*a+p*s+w*o),t[13]=-(T*a+A*s+x*o),t[14]=-(d*a+f*s+g*o),t[15]=1,t}function J(t,e,i){let r=e[0],a=e[1],s=e[2],o=e[3],n=e[4],l=e[5],h=e[6],u=e[7],m=e[8],v=e[9],d=e[10],f=e[11],g=e[12],b=e[13],y=e[14],p=e[15],w=i[0],T=i[1],A=i[2],x=i[3];return t[0]=w*r+T*n+A*m+x*g,t[1]=w*a+T*l+A*v+x*b,t[2]=w*s+T*h+A*d+x*y,t[3]=w*o+T*u+A*f+x*p,w=i[4],T=i[5],A=i[6],x=i[7],t[4]=w*r+T*n+A*m+x*g,t[5]=w*a+T*l+A*v+x*b,t[6]=w*s+T*h+A*d+x*y,t[7]=w*o+T*u+A*f+x*p,w=i[8],T=i[9],A=i[10],x=i[11],t[8]=w*r+T*n+A*m+x*g,t[9]=w*a+T*l+A*v+x*b,t[10]=w*s+T*h+A*d+x*y,t[11]=w*o+T*u+A*f+x*p,w=i[12],T=i[13],A=i[14],x=i[15],t[12]=w*r+T*n+A*m+x*g,t[13]=w*a+T*l+A*v+x*b,t[14]=w*s+T*h+A*d+x*y,t[15]=w*o+T*u+A*f+x*p,t}function Ve(t,e,i,r){let a=e[0],s=e[1],o=e[2],n=e[3],l=a+a,h=s+s,u=o+o,m=a*l,v=a*h,d=a*u,f=s*h,g=s*u,b=o*u,y=n*l,p=n*h,w=n*u,T=r[0],A=r[1],x=r[2];return t[0]=(1-(f+b))*T,t[1]=(v+w)*T,t[2]=(d-p)*T,t[3]=0,t[4]=(v-w)*A,t[5]=(1-(m+b))*A,t[6]=(g+y)*A,t[7]=0,t[8]=(d+p)*x,t[9]=(g-y)*x,t[10]=(1-(m+f))*x,t[11]=0,t[12]=i[0],t[13]=i[1],t[14]=i[2],t[15]=1,t}function ue(t,e,i=0){let r=e[0],a=e[1],s=e[2],o=e[4],n=e[5],l=e[6],h=e[8],u=e[9],m=e[10],v=m*n-l*u,d=-m*o+l*h,f=u*o-n*h,g=r*v+a*d+s*f;return!g||i>0&&(!Number.isFinite(g)||Math.abs(g)<=i)||(g=1/g,t[0]=v*g,t[1]=d*g,t[2]=f*g,t[3]=(-m*a+s*u)*g,t[4]=(m*r-s*h)*g,t[5]=(-u*r+a*h)*g,t[6]=(l*a-s*n)*g,t[7]=(-l*r+s*o)*g,t[8]=(n*r-a*o)*g),t}function Qe(t,e){let i=e[0],r=e[1],a=e[2],s=e[3],o=e[4],n=e[5],l=e[6],h=e[7],u=e[8],m=e[9],v=e[10],d=e[11],f=e[12],g=e[13],b=e[14],y=e[15],p=i*n-r*o,w=i*l-a*o,T=i*h-s*o,A=r*l-a*n,x=r*h-s*n,N=a*h-s*l,S=u*g-m*f,E=u*b-v*f,P=u*y-d*f,C=m*b-v*g,V=m*y-d*g,U=v*y-d*b,L=p*U-w*V+T*C+A*P-x*E+N*S;return L?(L=1/L,t[0]=(n*U-l*V+h*C)*L,t[1]=(a*V-r*U-s*C)*L,t[2]=(g*N-b*x+y*A)*L,t[3]=(v*x-m*N-d*A)*L,t[4]=(l*P-o*U-h*E)*L,t[5]=(i*U-a*P+s*E)*L,t[6]=(b*T-f*N-y*w)*L,t[7]=(u*N-v*T+d*w)*L,t[8]=(o*V-n*P+h*S)*L,t[9]=(r*P-i*V-s*S)*L,t[10]=(f*x-g*T+y*p)*L,t[11]=(m*T-u*x-d*p)*L,t[12]=(n*E-o*C-l*S)*L,t[13]=(i*C-r*E+a*S)*L,t[14]=(g*w-f*A-b*p)*L,t[15]=(u*A-m*w+v*p)*L,t):null}function Fe(t,e,i,r,a){let s=a[0]*e+a[4]*i+a[8]*r+a[12],o=a[1]*e+a[5]*i+a[9]*r+a[13],n=a[2]*e+a[6]*i+a[10]*r+a[14],l=a[3]*e+a[7]*i+a[11]*r+a[15],h=l!==0?1/l:1;t[0]=s*h,t[1]=o*h,t[2]=n*h}function Je(t,e,i,r,a,s,o,n,l,h,u,m,v,d,f,g,b=0){let y=h-o,p=u-n,w=m-l,T=v-o,A=d-n,x=f-l,N=a*x-s*A,S=s*T-r*x,E=r*A-a*T,P=y*N+p*S+w*E;if(P>-1e-7&&P<1e-7)return!1;let C=1/P,V=t-o,U=e-n,L=i-l,M=C*(V*N+U*S+L*E);if(M<-b||M>1+b)return!1;let R=U*w-L*p,H=L*y-V*w,c=V*p-U*y,I=C*(r*R+a*H+s*c);if(I<-b||M+I>1+b)return!1;let F=C*(T*R+A*H+x*c);if(F>1e-4&&F<g.distance){g.distance=F,g.point=[t+r*F,e+a*F,i+s*F];let O=p*x-w*A,k=w*T-y*x,D=y*A-p*T,B=Math.hypot(O,k,D)||1;return g.normal=[O/B,k/B,D/B],!0}return!1}function Oe(t,e){let i=Array.isArray(t?.nodes)?t.nodes.length:0,r=[];for(let u=0;u<i;u++)r.push(X());if(i===0)return r;let a=new Set;for(let u of t.nodes)if(Array.isArray(u.children))for(let m of u.children)a.add(m);let s=new Set,o=128,n=(u,m,v=0)=>{if(v>o||u<0||u>=i||s.has(u))return;s.add(u);let d=t.nodes[u];if(!d)return;let f=X();if(e&&e[u])f.set(e[u]);else if(d.matrix&&d.matrix.length===16)f.set(d.matrix);else{let b=d.translation||[0,0,0],y=d.rotation||[0,0,0,1],p=d.scale||[1,1,1];Ve(f,y,b,p)}let g=r[u];if(m?J(g,m,f):g.set(f),Array.isArray(d.children))for(let b of d.children)typeof b=="number"&&n(b,g,v+1)},l=[],h=t.scenes&&t.scenes[t.scene!==void 0?t.scene:0];if(h&&Array.isArray(h.nodes))l.push(...h.nodes);else for(let u=0;u<i;u++)a.has(u)||l.push(u);for(let u of l)n(u,null);for(let u=0;u<i;u++)!a.has(u)&&!l.includes(u)&&n(u,null);return r}var Be=["neutral","reinhard","none","aces","agx"];function me(t){let e=String(t??"").trim().toLowerCase();return Be.includes(e)?e:"neutral"}function et(t){return Be.indexOf(me(t))}function tt(t){return new TextDecoder().decode(t)}var _e=K().decoders;function it(t,e){_e.set(t.toLowerCase(),e)}function xe(t){return _e.get(t.toLowerCase())}function Ue(t){let e=ArrayBuffer.isView(t)?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength):t,i=new DataView(e);if(e.byteLength<12)throw new Error(`Invalid GLB buffer size: ${e.byteLength} bytes`);let r=i.getUint32(0,!0);if(r!==1179937895){let v=i.getUint8(0);throw v===123||v===32||v===10||v===13?new Error("[three-live] Multi-file JSON .gltf is not supported for performance reasons. Please pack your asset into a single binary .glb file."):new Error(`Invalid GLB magic: 0x${r.toString(16)}`)}let a=i.getUint32(4,!0);if(a!==2)throw new Error(`Unsupported GLB version: ${a}`);let s=i.getUint32(8,!0),o=12,n=null,l=null;for(;o+8<=s&&o+8<=e.byteLength;){let v=i.getUint32(o,!0),d=i.getUint32(o+4,!0),f=o+8;if(f+v>e.byteLength)throw new Error(`Truncated GLB chunk: required ${f+v} bytes, buffer has ${e.byteLength}`);if(d===1313821514){let g=new Uint8Array(e,f,v),b=tt(g);n=JSON.parse(b,(y,p)=>y==="__proto__"||y==="constructor"||y==="prototype"?void 0:p)}else d===5130562&&(l=e.slice(f,f+v));o=f+v}if(!n)throw new Error("Missing JSON chunk in GLB");let h=n.extensionsRequired||[];for(let[v,d]of[["KHR_draco_mesh_compression","draco"],["EXT_meshopt_compression","meshopt"],["KHR_meshopt_compression","meshopt"],["KHR_texture_basisu","ktx2"]])if(h.includes(v)&&!xe(d))throw new Error(`Model requires ${v}. Register a decoder via ThreeLiveElement.registerDecoder('${d}', decoder).`);let u=l||new ArrayBuffer(0),m={gltf:n,bin:u,animations:[],animationsParsed:!1};for(let v of $)v.onParseGLB?.(m);return m}function rt(t,e=Oe(t)){let i=t?.extensions?.KHR_lights_punctual?.lights;if(!Array.isArray(i))return[];let r=[],a=new Set,s=(o,n,l,h)=>{let u=o.type,m=u==="directional"||u==="point"||u==="spot"?u:"ambient",v=n?n[8]:-.5,d=n?n[9]:-1,f=n?n[10]:-.8,g=Math.hypot(v,d,f)||1,b=o.extras?.shadow??l,y=o.name||h,p={type:m,color:o.color||[1,1,1],intensity:o.intensity??1};y&&(p.name=y),n&&(p.position=[n[12],n[13],n[14]]),m==="directional"&&n?p.direction=[v/g,d/g,f/g]:(m==="spot"&&(p.direction=n?[-v/g,-d/g,-f/g]:[0,-1,0],p.innerConeAngle=o.spot?.innerConeAngle??0,p.outerConeAngle=o.spot?.outerConeAngle??Math.PI/4),p.range=o.range),b&&(p.shadow=b),r.push(p)};return(t.nodes||[]).forEach((o,n)=>{let l=o?.extensions?.KHR_lights_punctual?.light;typeof l=="number"&&i[l]&&(a.add(l),s(i[l],e[n],o.extras?.shadow,o.name))}),i.forEach((o,n)=>{a.has(n)||s(o)}),r}function st(t){return typeof t=="object"&&t!==null&&"gltf"in t&&typeof t.gltf=="object"&&t.gltf!==null&&"bin"in t&&(t.bin instanceof ArrayBuffer||ArrayBuffer.isView(t.bin))}function be(t){if(st(t))return t;if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))return Ue(t);throw new TypeError("Invalid 3D model input: expected GLBData ({ gltf, bin }) or binary GLB (ArrayBuffer / ArrayBufferView).")}var Se=`#version 300 es
|
|
17
17
|
layout(location=0) in vec3 aPos;
|
|
18
18
|
layout(location=3) in vec3 aOff;
|
|
19
19
|
layout(location=1) in vec3 aNormal;
|
|
@@ -48,7 +48,7 @@ vec2 scaleUV=uUvTransform.zw;
|
|
|
48
48
|
if(scaleUV.x==0.0&&scaleUV.y==0.0)scaleUV=vec2(1.0);
|
|
49
49
|
vUV=aUV*scaleUV+uUvTransform.xy;
|
|
50
50
|
gl_Position=uMVP*vec4(aPosition,1.0);
|
|
51
|
-
}`,
|
|
51
|
+
}`,at=`#version 300 es
|
|
52
52
|
precision highp float;
|
|
53
53
|
in vec3 vNormal,vWorldPos;
|
|
54
54
|
in vec2 vUV;
|
|
@@ -57,117 +57,81 @@ in vec4 vInstTint;
|
|
|
57
57
|
#define uBaseColor (uBaseColor*vInstTint)
|
|
58
58
|
uniform float uMetallic,uRoughness,uEmissive,uEnvIntensity,uExposure;
|
|
59
59
|
uniform vec2 uClearcoat;
|
|
60
|
-
uniform vec3 uCameraPos,uAmbientColor;
|
|
61
|
-
uniform
|
|
62
|
-
uniform
|
|
60
|
+
uniform vec3 uCameraPos,uAmbientColor,uEmissiveFactor;
|
|
61
|
+
uniform mat3 uHemi;
|
|
62
|
+
uniform sampler2D uBaseColorTexture,uMetallicRoughnessTexture,uNormalTexture,uOcclusionTexture,uEnvironmentMap,uEmissiveTexture;
|
|
63
|
+
uniform int uHasTexture,uHasMetallicRoughnessTexture,uHasNormalTexture,uHasOcclusionTexture,uHasEnvironmentMap,uHasEmissiveTexture;
|
|
63
64
|
uniform float uNormalScale,uOcclusionStrength;
|
|
64
|
-
/*XRD_U*/
|
|
65
|
+
/*XRD_U*//*SHD_U*/
|
|
65
66
|
uniform vec2 uViewportSize;
|
|
66
67
|
uniform vec4 uSectionPlane;
|
|
67
68
|
uniform int uToneMapping,uNumDirLights,uNumPointLights,uSectionEnabled;
|
|
68
69
|
uniform vec3 uDirLightDir[2],uDirLightColor[2],uPointLightPos[2],uPointLightColor[2],uPointLightSpotDir[2];
|
|
69
70
|
uniform vec2 uPointLightSpotCone[2];
|
|
70
71
|
out vec4 fragColor;
|
|
71
|
-
|
|
72
72
|
vec2 envBRDF(float r,float n){
|
|
73
|
-
vec4 c0=vec4(-1.0,-0.0275,-0.572,0.022),c1=vec4(1.0,0.0425,1.04,-0.04);
|
|
74
|
-
vec4 rv=r*c0+c1;
|
|
73
|
+
vec4 c0=vec4(-1.0,-0.0275,-0.572,0.022),c1=vec4(1.0,0.0425,1.04,-0.04),rv=r*c0+c1;
|
|
75
74
|
float a=min(rv.x*rv.x,exp2(-9.28*n))*rv.x+rv.y;
|
|
76
75
|
return vec2(-1.04,1.04)*a+rv.zw;
|
|
77
76
|
}
|
|
78
|
-
|
|
79
77
|
vec3 F_SchlickRoughness(vec3 F0,float r,float n){
|
|
80
78
|
return F0+(max(vec3(1.0-r),F0)-F0)*pow(clamp(1.0-n,0.0,1.0),5.0);
|
|
81
79
|
}
|
|
82
|
-
|
|
83
80
|
vec3 getStudioRadiance(vec3 R,float r){
|
|
84
|
-
vec3 kd=normalize(vec3(0.0,1.0,0.35));
|
|
81
|
+
vec3 kd=normalize(vec3(0.0,1.0,0.35)),fd=normalize(vec3(-0.85,0.45,-0.35));
|
|
85
82
|
float ki=pow(max(dot(R,kd),0.0),mix(96.0,1.5,r))*mix(2.4,0.5,r);
|
|
86
|
-
vec3 fd=normalize(vec3(-0.85,0.45,-0.35));
|
|
87
83
|
float fi=pow(max(dot(R,fd),0.0),mix(36.0,1.2,r))*mix(1.3,0.35,r);
|
|
88
84
|
float ri=pow(clamp(1.0-abs(R.y),0.0,1.0),3.5)*mix(0.55,0.22,r);
|
|
89
|
-
|
|
90
|
-
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;
|
|
85
|
+
return mix(vec3(0.06,0.06,0.08),vec3(0.48,0.50,0.55),R.y*0.5+0.5)+vec3(1.0,0.98,0.94)*ki+vec3(0.85,0.92,1.0)*fi+vec3(0.65,0.72,0.85)*ri;
|
|
91
86
|
}
|
|
92
|
-
|
|
93
|
-
vec3
|
|
94
|
-
vec3
|
|
95
|
-
|
|
96
|
-
vec3
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
vec2 duv2=dFdy(uv);
|
|
100
|
-
vec3 dp2perp=cross(dp2,N);
|
|
101
|
-
vec3 dp1perp=cross(N,dp1);
|
|
102
|
-
vec3 T=dp2perp*duv1.x+dp1perp*duv2.x;
|
|
103
|
-
vec3 B=dp2perp*duv1.y+dp1perp*duv2.y;
|
|
104
|
-
float invmax=inversesqrt(max(dot(T,T),dot(B,B)));
|
|
105
|
-
return normalize(mat3(T*invmax,B*invmax,N)*normalize(mapNormal));
|
|
87
|
+
vec3 perturbNormal(vec3 N,vec3 V,vec2 uv,sampler2D m,float s){
|
|
88
|
+
vec3 q=texture(m,uv).xyz*2.0-1.0;q.xy*=s;
|
|
89
|
+
vec3 p1=dFdx(vWorldPos),p2=dFdy(vWorldPos),c2=cross(p2,N),c1=cross(N,p1);
|
|
90
|
+
vec2 u1=dFdx(uv),u2=dFdy(uv);
|
|
91
|
+
vec3 T=c2*u1.x+c1*u2.x,B=c2*u1.y+c1*u2.y;
|
|
92
|
+
float k=inversesqrt(max(dot(T,T),dot(B,B)));
|
|
93
|
+
return normalize(mat3(T*k,B*k,N)*normalize(q));
|
|
106
94
|
}
|
|
107
|
-
|
|
108
95
|
vec2 equirectangularUV(vec3 dir){
|
|
109
96
|
vec3 d=normalize(dir);
|
|
110
|
-
|
|
111
|
-
float v=asin(clamp(d.y,-1.0,1.0))*0.31830988618+0.5;
|
|
112
|
-
return vec2(u,1.0-v);
|
|
97
|
+
return vec2(atan(d.z,d.x)*0.15915494309+0.5,0.5-asin(clamp(d.y,-1.0,1.0))*0.31830988618);
|
|
113
98
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
float
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if(peak<startCompression)return color;
|
|
123
|
-
const float d=1.0-startCompression;
|
|
124
|
-
float newPeak=1.0-d*d/(peak+d-startCompression);
|
|
125
|
-
color*=newPeak/peak;
|
|
126
|
-
float g=1.0-1.0/(desaturation*(peak-newPeak)+1.0);
|
|
127
|
-
return mix(color,newPeak*vec3(1.0),g);
|
|
99
|
+
vec3 neutralToneMapping(vec3 c){
|
|
100
|
+
float x=min(c.r,min(c.g,c.b));
|
|
101
|
+
c-=x<0.08?x-6.25*x*x:0.04;
|
|
102
|
+
float p=max(c.r,max(c.g,c.b));
|
|
103
|
+
if(p<0.76)return c;
|
|
104
|
+
float n=1.0-0.0576/(p-0.52);
|
|
105
|
+
c*=n/p;
|
|
106
|
+
return mix(c,vec3(n),1.0-1.0/(0.15*(p-n)+1.0));
|
|
128
107
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
color*=0.6;
|
|
132
|
-
return clamp((color*(2.51*color+0.03))/(color*(2.43*color+0.59)+0.14),0.0,1.0);
|
|
108
|
+
vec3 acesToneMapping(vec3 c){
|
|
109
|
+
c*=0.6;return clamp((c*(2.51*c+0.03))/(c*(2.43*c+0.59)+0.14),0.0,1.0);
|
|
133
110
|
}
|
|
134
|
-
|
|
135
|
-
vec3
|
|
136
|
-
|
|
137
|
-
vec3
|
|
138
|
-
|
|
139
|
-
0.
|
|
140
|
-
0.
|
|
141
|
-
vec3 ev=clamp((log2(max(inset,vec3(1e-6)))+12.47393)/16.5,0.0,1.0);
|
|
142
|
-
vec3 x2=ev*ev;
|
|
143
|
-
vec3 x4=x2*x2;
|
|
144
|
-
vec3 s=15.5*x4*x2-40.14*x4*ev+31.96*x4-6.868*x2*ev+0.4298*x2+0.1191*ev-0.00232;
|
|
145
|
-
vec3 outset=vec3(
|
|
146
|
-
1.196879*s.r-0.09802088*s.g-0.09902974*s.b,
|
|
147
|
-
-0.05289685*s.r+1.15190313*s.g-0.09896118*s.b,
|
|
148
|
-
-0.05297164*s.r-0.09804345*s.g+1.15107367*s.b);
|
|
149
|
-
return clamp(pow(max(outset,vec3(0.0)),vec3(2.2)),0.0,1.0);
|
|
111
|
+
vec3 agxToneMapping(vec3 c){
|
|
112
|
+
c=max(c,vec3(0.0));
|
|
113
|
+
vec3 i=mat3(0.84247906,0.04232824,0.04237565,0.0784336,0.87846864,0.0784336,0.07922375,0.07916613,0.87914297)*c;
|
|
114
|
+
vec3 e=clamp((log2(max(i,vec3(1e-6)))+12.47393)/16.5,0.0,1.0),x2=e*e,x4=x2*x2;
|
|
115
|
+
vec3 s=15.5*x4*x2-40.14*x4*e+31.96*x4-6.868*x2*e+0.4298*x2+0.1191*e-0.00232;
|
|
116
|
+
vec3 o=mat3(1.196879,-0.05289685,-0.05297164,-0.09802088,1.15190313,-0.09804345,-0.09902974,-0.09896118,1.15107367)*s;
|
|
117
|
+
return clamp(pow(max(o,vec3(0.0)),vec3(2.2)),0.0,1.0);
|
|
150
118
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if(mode==0)return neutralToneMapping(color);
|
|
154
|
-
if(mode==1)return color/(color+vec3(1.0));
|
|
155
|
-
if(mode==3)return acesToneMapping(color);
|
|
156
|
-
if(mode==4)return agxToneMapping(color);
|
|
157
|
-
return color;
|
|
119
|
+
vec3 applyToneMapping(vec3 c,int m){
|
|
120
|
+
return m==0?neutralToneMapping(c):m==1?c/(c+vec3(1.0)):m==3?acesToneMapping(c):m==4?agxToneMapping(c):c;
|
|
158
121
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return base*max(dot(N,L),0.0)*0.75+vec3(pow(NoH,specExp)*specWeight+uClearcoat.x*pow(NoH,mix(64.0,512.0,1.0-uClearcoat.y))*0.35);
|
|
122
|
+
vec3 evalLight(vec3 L,vec3 V,vec3 N,vec3 b,float e,float w){
|
|
123
|
+
float h=max(dot(N,normalize(L+V)),0.0);
|
|
124
|
+
return b*max(dot(N,L),0.0)*0.75+vec3(pow(h,e)*w+uClearcoat.x*pow(h,mix(64.0,512.0,1.0-uClearcoat.y))*0.35);
|
|
163
125
|
}
|
|
164
126
|
|
|
165
127
|
void main(){
|
|
166
128
|
if(uSectionEnabled==1&&dot(vWorldPos,uSectionPlane.xyz)>uSectionPlane.w)discard;
|
|
167
129
|
vec4 base=uBaseColor;
|
|
168
130
|
if(uHasTexture==1)base*=texture(uBaseColorTexture,vUV);
|
|
131
|
+
if(base.a<0.004)discard;
|
|
132
|
+
vec3 em=uHasEmissiveTexture==1?uEmissiveFactor*texture(uEmissiveTexture,vUV).rgb:uEmissiveFactor;
|
|
169
133
|
if(length(vNormal)<1e-4&&uHasTexture==1){
|
|
170
|
-
vec3 unlit=base.rgb+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
134
|
+
vec3 unlit=base.rgb+em+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
171
135
|
fragColor=vec4(unlit,base.a);
|
|
172
136
|
return;
|
|
173
137
|
}
|
|
@@ -199,7 +163,7 @@ float specWeight=mix(0.22*gloss,1.0,metallic);
|
|
|
199
163
|
vec3 directLight=vec3(0.0);
|
|
200
164
|
for(int i=0;i<2;i++){
|
|
201
165
|
if(i>=uNumDirLights)break;
|
|
202
|
-
directLight+=evalLight(normalize(uDirLightDir[i]),V,N,base.rgb,specExp,specWeight)*uDirLightColor[i]
|
|
166
|
+
directLight+=evalLight(normalize(uDirLightDir[i]),V,N,base.rgb,specExp,specWeight)*uDirLightColor[i]/*SHD_D*/;
|
|
203
167
|
}
|
|
204
168
|
for(int i=0;i<2;i++){
|
|
205
169
|
if(i>=uNumPointLights)break;
|
|
@@ -208,7 +172,7 @@ float dist=length(toLight);
|
|
|
208
172
|
vec3 L=toLight/max(dist,0.0001);
|
|
209
173
|
float spotAtt=clamp((dot(-L,uPointLightSpotDir[i])-uPointLightSpotCone[i].y)/max(uPointLightSpotCone[i].x-uPointLightSpotCone[i].y,0.0001),0.0,1.0);
|
|
210
174
|
spotAtt*=spotAtt;
|
|
211
|
-
directLight+=evalLight(L,V,N,base.rgb,specExp,specWeight)*uPointLightColor[i]*spotAtt/(1.0+0.09*dist+0.032*dist*dist)
|
|
175
|
+
directLight+=evalLight(L,V,N,base.rgb,specExp,specWeight)*uPointLightColor[i]*spotAtt/(1.0+0.09*dist+0.032*dist*dist)/*SHD_P*/;
|
|
212
176
|
}
|
|
213
177
|
|
|
214
178
|
vec3 R=reflect(-V,N);
|
|
@@ -228,8 +192,9 @@ envDiffuse=mix(vec3(0.10,0.10,0.12),vec3(0.52,0.54,0.58),N.y*0.5+0.5);
|
|
|
228
192
|
}
|
|
229
193
|
|
|
230
194
|
vec3 kD=(vec3(1.0)-F)*(1.0-metallic);
|
|
195
|
+
directLight+=kD*base.rgb*mix(uHemi[1],uHemi[0],dot(N,uHemi[2])*0.5+0.5)*occ;
|
|
231
196
|
vec3 diffuseIBL=kD*base.rgb*(uAmbientColor+envDiffuse*0.5)*occ;
|
|
232
|
-
vec3 color=directLight+(diffuseIBL+specularIBL)*uEnvIntensity+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
197
|
+
vec3 color=directLight+(diffuseIBL+specularIBL)*uEnvIntensity+em+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
|
|
233
198
|
if(uClearcoat.x>0.0){
|
|
234
199
|
vec3 ccF=F_SchlickRoughness(vec3(0.04),uClearcoat.y,NoV)*uClearcoat.x;
|
|
235
200
|
color=color*(vec3(1.0)-ccF)+getStudioRadiance(R,uClearcoat.y)*ccF*uEnvIntensity;
|
|
@@ -239,11 +204,11 @@ color=applyToneMapping(color,uToneMapping);
|
|
|
239
204
|
float outAlpha=base.a;
|
|
240
205
|
/*XRD_O*/
|
|
241
206
|
fragColor=vec4(color,outAlpha);
|
|
242
|
-
}`,
|
|
207
|
+
}`,ot=`#version 300 es
|
|
243
208
|
layout(location=0) in vec3 aPosition;
|
|
244
209
|
uniform mat4 uMVP;
|
|
245
|
-
void main(){gl_Position=uMVP*vec4(aPosition,1.0);}`,
|
|
210
|
+
void main(){gl_Position=uMVP*vec4(aPosition,1.0);}`,nt=`#version 300 es
|
|
246
211
|
precision highp float;
|
|
247
212
|
uniform vec4 uColorId;
|
|
248
213
|
out vec4 fragColor;
|
|
249
|
-
void main(){fragColor=uColorId;}`;function At(e,t,i){let r={};for(let s of i)r[s]=e.getUniformLocation(t,s);return r}var Ot=["uMVP","uModel","uInstanced","uViewProj","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","uPointLightSpotDir","uPointLightSpotCone","uEnvIntensity","uExposure","uViewportSize","uSectionPlane","uSectionEnabled"];function Bt(){let e=Z().xrDepthShader;return{fs:se.replace("/*XRD_U*/",e?.uniformsGLSL||"").replace("/*XRD_O*/",e?.occlusionGLSL||""),uniforms:e?[...Ot,...e.uniformNames]:Ot}}function ne(e){if(typeof e!="string")return null;let t=e.trim();if(!t||/[\x00-\x1f\x7f]/.test(t))return null;let i=t.toLowerCase();return i.startsWith("data:")?/^data:image\/(png|jpeg|jpg|webp|ktx2|avif)(;|,)/i.test(t)?t:null:i.startsWith("https://")||i.startsWith("blob:")?t:i.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(t)||/(^|[\\/])\.\.([\\/]|$)/.test(t)?null:t}function Rt(e,t,i,r,s,a,o,h){if(r===void 0||!t.accessors?.[r])return null;let l=Et(t,i,t.accessors[r],a);if(!l)return null;h&&(l=l.slice(),Yt(l,h));let n=e.createBuffer();return o.push(n),e.bindBuffer(34962,n),e.bufferData(34962,l,35044),e.enableVertexAttribArray(s),e.vertexAttribPointer(s,a,5126,!1,0,0),l}function Ct(e){let t=Number(e);return Number.isFinite(t)?Math.max(0,t):1}function _t(e,t,i){let r=Bt(),s=Ft,a=r.fs,o=!1;for(let l of j)if(l.onResolveShader){let n=l.onResolveShader(t,i,s,a);n&&(s=n.vs,a=n.fs,o=!0)}let h=o?wt(e,s,a):null;return{program:h,uniforms:h?At(e,h,r.uniforms):null}}function le(e,t,i){let r=t.instanceMatrices;if(!r||r.length<16||typeof e.vertexAttribDivisor!="function"||typeof e.drawElementsInstanced!="function")return!1;let s=r.length>>4,a=t.instanceColors,o=new Float32Array(s*20);for(let l=0;l<s;l++)o.set(r.subarray(l*16,l*16+16),l*20),o[l*20+16]=a?a[l*3]:1,o[l*20+17]=a?a[l*3+1]:1,o[l*20+18]=a?a[l*3+2]:1,o[l*20+19]=1;let h=e.createBuffer();i.push(h),e.bindBuffer(34962,h),e.bufferData(34962,o,35044);for(let l=0;l<5;l++)e.enableVertexAttribArray(8+l),e.vertexAttribPointer(8+l,4,5126,!1,80,l*16),e.vertexAttribDivisor(8+l,1);return!0}function he(e,t){let i=e.materials?.[t?.material];if(!i)return null;let r=[i.pbrMetallicRoughness?.baseColorTexture,i.pbrMetallicRoughness?.metallicRoughnessTexture,i.normalTexture,i.occlusionTexture,i.emissiveTexture];for(let s of r){let a=s?.extensions?.KHR_texture_transform;if(a&&typeof a=="object")return a}return null}var ue=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),Ut=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function yt(e,t){t.indices?e.drawElements(4,t.indexCount,t.indexType,0):e.drawArrays(4,0,t.indexCount)}function Ht(e,t){let i=e?.pbrMetallicRoughness,r=i?.baseColorFactor,s=e?.extensions?.KHR_materials_clearcoat,a=o=>o!==void 0&&t[o.index]?t[o.index]:null;return{baseColor:r?[r[0],r[1],r[2],r[3]??1]:[.8,.8,.8,1],metallic:i?.metallicFactor??.1,roughness:i?.roughnessFactor??.5,clearcoat:s?s.clearcoatFactor??1:0,clearcoatRoughness:Math.max(.04,s?.clearcoatRoughnessFactor??.04),texture:a(i?.baseColorTexture),metallicRoughnessTexture:a(i?.metallicRoughnessTexture),normalTexture:a(e?.normalTexture),normalScale:e?.normalTexture?.scale??1,occlusionTexture:a(e?.occlusionTexture),occlusionStrength:e?.occlusionTexture?.strength??1,isTransmissive:(e?.extensions?.KHR_materials_transmission?.transmissionFactor??0)>0}}function zt(e,t,i){let r=new Set,s=a=>{a&&!r.has(a)&&(r.add(a),e.deleteTexture(a))};for(let a of t)for(let o of a.primitives){if(o.vao&&e.deleteVertexArray(o.vao),o.buffers)for(let l of o.buffers)e.deleteBuffer(l);s(o.texture),s(o.metallicRoughnessTexture),s(o.normalTexture),s(o.occlusionTexture);let h=new Set;o.customProgram&&h.add(o.customProgram);for(let l of o.programCache?.values()??[])l.program&&h.add(l.program);for(let l of h)e.deleteProgram(l)}if(i)for(let a of i)s(a)}function Gt(e,t,i=Ut,r){let s={meshes:[],mesh:null,gpuTextures:[],vao:null,buffers:[]};try{return ce(e,t,i,r,s)}catch(a){let o=s.mesh&&!s.meshes.includes(s.mesh)?[...s.meshes,s.mesh]:s.meshes;zt(e,o,s.gpuTextures),s.vao&&e.deleteVertexArray(s.vao);for(let h of s.buffers)e.deleteBuffer(h);throw a}}function ce(e,t,i,r,s){if(!t||!t.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:a}=t,o=mt("meshopt");o?.decodeBufferViews&&o.decodeBufferViews(a,t);let h=t.bin,l=[];s.meshes=l;let n=[],c=a.extensions?.KHR_materials_variants;c&&Array.isArray(c.variants)&&c.variants.forEach((P,u)=>{n.push(typeof P?.name=="string"&&P.name?P.name:`Variant_${u}`)});let m=Jt(a),x=[];if(Array.isArray(a.nodes))for(let P=0;P<a.nodes.length;P++){let u=a.nodes[P];u.mesh!==void 0&&a.meshes&&a.meshes[u.mesh]&&x.push({node:u,nodeIdx:P,meshIdx:u.mesh})}let f=x.length>0?x:(a.meshes||[]).map((P,u)=>({node:P,nodeIdx:-1,meshIdx:u})),v=[],b=Array.isArray(t.lights)&&t.lights.length>0?t.lights:Array.isArray(a.asset?.extras?.lights)&&a.asset.extras.lights.length>0?a.asset.extras.lights:null;if(b)for(let P of b)v.push({...P,type:P.type||P.light_type||"point",innerConeAngle:P.innerConeAngle??P.inner_cone_angle,outerConeAngle:P.outerConeAngle??P.outer_cone_angle});else if(a.extensions?.KHR_lights_punctual?.lights){let P=a.extensions.KHR_lights_punctual.lights;for(let u of P){let C=u.type==="directional"?"directional":u.type==="point"?"point":u.type==="spot"?"spot":"ambient";v.push({type:C,color:u.color||[1,1,1],intensity:u.intensity!==void 0?u.intensity:1})}}if(v.length===0&&(v.push({type:"ambient",color:[1,1,1],intensity:.35}),v.push({type:"directional",color:[1,1,1],intensity:.85,direction:[.5,1,.8]})),f.length>i.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${i.maxMeshes}). Found: ${f.length}`);let T=[];if(s.gpuTextures=T,a.textures&&a.images){if(a.textures.length>i.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${i.maxTextures}). Found: ${a.textures.length}`);for(let P=0;P<a.textures.length;P++){let u=a.textures[P],C=a.images[u.source];if(C){let H=e.createTexture();e.bindTexture(3553,H),e.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255])),e.texParameteri(3553,10242,10497),e.texParameteri(3553,10243,10497),e.texParameteri(3553,10241,9729),e.texParameteri(3553,10240,9729);let Y=I=>{e.bindTexture(3553,H),e.texImage2D(3553,0,6408,6408,5121,I),e.generateMipmap(3553),r?.()};if(C.bufferView!==void 0){let I=a.bufferViews[C.bufferView],k=I.byteOffset||0,R=new Blob([h.slice(k,k+I.byteLength)],{type:C.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(R).then(Y).catch(()=>{})}else if(C.uri){let I=ne(C.uri);if(I){let k=new Image;k.crossOrigin="anonymous",k.referrerPolicy="no-referrer",k.onload=()=>Y(k),k.src=I}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",C.uri)}T.push(H)}else T.push(null)}}let M=[1/0,1/0,1/0],d=[-1/0,-1/0,-1/0],g=0,p=0;for(let P=0;P<f.length;P++){let u=f[P],C=a.meshes[u.meshIdx],H=u.nodeIdx>=0?m[u.nodeIdx]:z(),Y=new Float32Array(9);ut(Y,H);let I={name:u.node.name||C.name||`Mesh_${u.meshIdx}`,nodeIndex:u.nodeIdx,transform:H,normalMatrix:Y,primitives:[],extras:u.node.extras||C.extras,...u.node?.visible===!1||u.node?.extensions?.KHR_node_visibility?.visible===!1?{visible:!1}:{}};s.mesh=I;let k=u.node?.extensions?.EXT_mesh_gpu_instancing;if(k&&k.attributes&&typeof k.attributes=="object"){let R=k.attributes,N=R.TRANSLATION!==void 0?a.accessors?.[R.TRANSLATION]:null,B=R.ROTATION!==void 0?a.accessors?.[R.ROTATION]:null,F=R.SCALE!==void 0?a.accessors?.[R.SCALE]:null,W=R._COLOR_0!==void 0?a.accessors?.[R._COLOR_0]:null,O=Number(N?.count??B?.count??F?.count??0);if(!Number.isFinite(O)||O<0||O>1e4)throw new Error(`SecurityError: EXT_mesh_gpu_instancing exceeds maximum instance limit (10000). Found: ${O}`);if(O>0){let rt=(D,G)=>{if(!D||D.bufferView===void 0||!a.bufferViews?.[D.bufferView])return null;let K=D.componentType??5126,et=X=>(console.warn(`[three-live] EXT_mesh_gpu_instancing: skipping accessor (${X})`),null);if(K!==5120&&K!==5121&&K!==5122&&K!==5123&&K!==5126)return et(`componentType ${K}`);if(!(Number(D.count)>=O))return et(`count ${D.count} < ${O}`);let S=null;try{S=Et(a,h,{...D,count:O},G)}catch{return et("out of bounds")}return!S||!S.every(Number.isFinite)?et("non-finite value"):S},$=rt(N,3),tt=rt(B,4),st=rt(F,3),ot=W?.type==="VEC4"?4:3,q=rt(W,ot),nt=new Float32Array(O*16),lt=z();for(let D=0;D<O;D++){let G=$?[$[D*3],$[D*3+1],$[D*3+2]]:[0,0,0],K=tt?[tt[D*4],tt[D*4+1],tt[D*4+2],tt[D*4+3]]:[0,0,0,1],et=st?[st[D*3],st[D*3+1],st[D*3+2]]:[1,1,1];Lt(lt,K,G,et),nt.set(lt,D*16)}if(I.instanceMatrices=nt,q){let D=new Float32Array(O*3);for(let G=0;G<O;G++)D[G*3]=q[G*ot],D[G*3+1]=q[G*ot+1],D[G*3+2]=q[G*ot+2];I.instanceColors=D}}}for(let R of C.primitives||[]){if(R.extensions?.KHR_draco_mesh_compression){let S=mt("draco");S&&S.decodePrimitive(a,R,h)}let N=[],B=e.createVertexArray();s.vao=B,s.buffers=N,e.bindVertexArray(B);let F=le(e,I,N),W=a.accessors[R.attributes.POSITION],O=Number(W?.count??0);if(!Number.isFinite(O)||O<0||g+O>i.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${i.maxVertices}).`);if(g+=O,W?.min&&W?.max){let S=X=>{for(let J=0;J<3;J++){let ht=X[12+J],dt=X[12+J];for(let ct=0;ct<3;ct++){let gt=X[ct*4+J]*W.min[ct],vt=X[ct*4+J]*W.max[ct];ht+=gt<vt?gt:vt,dt+=gt>vt?gt:vt}ht<M[J]&&(M[J]=ht),dt>d[J]&&(d[J]=dt)}};if(I.instanceMatrices&&I.instanceMatrices.length>=16){let X=I.instanceMatrices.length>>4,J=z();for(let ht=0;ht<X;ht++){let dt=I.instanceMatrices.subarray(ht*16,ht*16+16);Q(J,H,dt),S(J)}}else S(H)}let rt=Rt(e,a,h,R.attributes.POSITION,0,3,N);Rt(e,a,h,R.attributes.NORMAL,1,3,N),Rt(e,a,h,R.attributes.TEXCOORD_0,2,2,N,he(a,R));let $=0,tt=5123,st=null;if(R.indices!==void 0){let S=a.accessors[R.indices],X=(a.bufferViews[S.bufferView].byteOffset||0)+(S.byteOffset||0);if($=Number(S.count??0),!Number.isFinite($)||$<0||p+$>i.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${i.maxIndices}).`);p+=$,tt=S.componentType===5125?5125:5123;let J=e.createBuffer();N.push(J),e.bindBuffer(34963,J),S.componentType===5125?st=new Uint32Array(h,X,S.count):S.componentType===5121?st=Uint16Array.from(new Uint8Array(h,X,S.count)):st=X%2===0?new Uint16Array(h,X,S.count):new Uint16Array(h.slice(X,X+S.count*2)),e.bufferData(34963,st,35044)}else $=W.count;let ot={};for(let S of j)if(S.onBuildPrimitiveVAO){let X=S.onBuildPrimitiveVAO(e,B,R,a,h);X&&(ot[S.name]=X)}e.bindVertexArray(null);let q=a.materials&&R.material!==void 0?a.materials[R.material]:null,{program:nt,uniforms:lt}=_t(e,R,q),D=Ht(q,T),G=!!(q?.extensions?.KHR_materials_transmission||ot.materials?.isTransmissive),K=R.extensions?.KHR_materials_variants?.mappings,et=Array.isArray(K)?K.filter(S=>S&&typeof S.material=="number"&&Array.isArray(S.variants)).map(S=>({material:S.material|0,variants:S.variants.map(X=>Number(X)|0)})):void 0;I.primitives.push({vao:B,instanced:F,indexCount:$,indexType:tt,...D,positions:rt,indices:st,buffers:N,materialIndex:R.material,defaultMaterialIndex:R.material,variantMappings:et,primitiveDef:R,programCache:new Map([[R.material??-1,{program:nt,uniforms:lt}]]),pluginData:ot,customProgram:nt,customUniforms:lt,isTransmissive:G})}l.push(I)}isFinite(M[0])||(M=[-1,-1,-1]),isFinite(d[0])||(d=[1,1,1]);let A=[(M[0]+d[0])/2,(M[1]+d[1])/2,(M[2]+d[2])/2],w=d[0]-M[0],V=d[1]-M[1],_=d[2]-M[2],U=Math.max(Math.hypot(w,V,_)/2,.5),E=[M[0],M[1],M[2]],y=[d[0],d[1],d[2]],L=t.animations;if(!L){for(let P of j)if(P.onParseGLB?.(t),t.animations){L=t.animations;break}}return L||(L=[]),{meshes:l,bounds:{center:A,radius:U,min:E,max:y},lights:v,animations:L,worldMatrices:m,gpuTextures:T,availableVariants:n}}function ft(e){let t=e.customTarget||e.bounds.center,i=e.currDistance*Math.cos(e.currPhi);return[t[0]+i*Math.sin(e.currTheta),t[1]+e.currDistance*Math.sin(e.currPhi),t[2]+i*Math.cos(e.currTheta)]}var at=class{constructor(e,t,i){this.supportsInstanceOffsets=!0,this.meshes=[],this.backdropMeshes=[],this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]},this.lights=[],this.modelRootMatrix=z(),this.clearColor=[0,0,0,0],this.envIntensity=1,this.exposure=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.gpuTextures=[],this.availableVariants=[],this.activeVariantName=null,this.gltf=null,this.worldMatrices=[],this.initialNodeTransforms=[],this.projMatrix=z(),this.viewMatrix=z(),this.activeViewMatrix=null,this.modelMatrix=z(),this.mvpMatrix=z(),this.normalMatrix=new Float32Array(9),this.initialTheta=.6,this.initialPhi=.35,this.initialDistance=null,this.customDistance=!1,this.distanceMode="auto",this.initialCustomTarget=null,this.customTarget=null,this.fov=Math.PI/4,this.minTheta=-1/0,this.maxTheta=1/0,this.minPhi=-Math.PI*.48,this.maxPhi=Math.PI*.48,this.minDistanceLimit=null,this.maxDistanceLimit=null,this.activePointers=new Map,this.isPanning=!1,this.targetTheta=.6,this.currTheta=.6,this.targetPhi=.35,this.currPhi=.35,this.targetDistance=3,this.currDistance=3,this.autoRotate=!1,this.autoRotateSpeed=Math.PI/6,this.autoRotateDelay=3e3,this.lastInteractionTime=-1/0,this.turntableRotation=0,this.isPointerDown=!1,this.interactive=!0,this.skyboxTexture=null,this.lastPointerX=0,this.lastPointerY=0,this.totalDragDist=0,this.selectedMeshName="",this.pickFbo=null,this.pickTexture=null,this.pickDepth=null,this.pickFboWidth=0,this.pickFboHeight=0,this.animFrameId=null,this.isVisible=!0,this.xrSessionActive=!1,this.lastTime=0,this.lastReportedTheta=-999,this.lastReportedPhi=-999,this.lastReportedZoom=-999,this.boundPointerDown=null,this.boundPointerMove=null,this.boundPointerUp=null,this.boundWheel=null,this.boundKeyDown=null,this.boundContextMenu=null,this.boundSetCamera=null,this.boundResetCamera=null,this.contextLost=!1,this.lastGlbData=null,this.boundContextLost=null,this.boundContextRestored=null,this.stereoSBS=!1,this.renderErrorReported=!1,this.xrDepthState={enabled:!1,texture:null,uvTransform:z(),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 h=e.querySelector("canvas");h||(h=document.createElement("canvas"),h.style.width="100%",h.style.height="100%",h.style.display="block",h.style.touchAction="none",e.prepend(h)),r=h}this.canvas=r,this.opts=s||{},this.opts.clearColor&&(this.clearColor=this.opts.clearColor);let a=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;this.opts.autoRotate!==void 0?this.autoRotate=this.opts.autoRotate&&!a:a&&(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.exposure=Ct(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=pt(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.variantName!==void 0&&(this.activeVariantName=this.opts.variantName||null),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 o=r.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!o)throw new Error("WebGL2 not supported");this.gl=o,this.initGlState(),this.setupEvents(),this.setupContextLossHandling(),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}static registerDecoder(e,t){ie(e,t)}static getDecoder(e){return mt(e)}setupContextLossHandling(){let e=this.canvas;typeof e?.addEventListener=="function"&&(this.boundContextLost=t=>{t.preventDefault?.(),this.contextLost=!0,this.stop()},this.boundContextRestored=()=>this.restoreContext(),e.addEventListener("webglcontextlost",this.boundContextLost),e.addEventListener("webglcontextrestored",this.boundContextRestored))}initGlState(){let e=this.gl,t=Bt();this.renderProg=wt(e,Ft,t.fs),this.pickProg=wt(e,ae,oe),this.uRender=At(e,this.renderProg,t.uniforms),this.uPick=At(e,this.pickProg,["uMVP","uColorId"]),this.setupPickingFbo()}restoreContext(){let e=this.gl;this.contextLost=!1,this.initGlState();for(let t of j)t.onContextRestored?.(e,this);this.meshes=[],this.gpuTextures=[],this.environmentTexture=null,this.lastGlbData&&this.loadGLBData(this.lastGlbData,this.lastLimits),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}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:a,worldMatrices:o,gpuTextures:h,availableVariants:l}=Gt(this.gl,e,t,()=>this.render());if(this.lastGlbData=e,this.lastLimits=t,this.disposeMeshGpuResources(),this.currentClip=null,this.isPlayingAnimation=!1,this.animationTime=0,this.meshes=i,this.bounds=r,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=s,this.animations=a||[],this.worldMatrices=o||[],this.gpuTextures=h||[],this.availableVariants=l||[],this.gltf=e.gltf,this.activeVariantName&&!this.applyVariantMaterial(this.activeVariantName)&&(this.activeVariantName=null),this.initialNodeTransforms=[],Array.isArray(e.gltf?.nodes))for(let m of e.gltf.nodes)this.initialNodeTransforms.push({t:m.translation?[m.translation[0],m.translation[1],m.translation[2]]:[0,0,0],r:m.rotation?[m.rotation[0],m.rotation[1],m.rotation[2],m.rotation[3]]:[0,0,0,1],s:m.scale?[m.scale[0],m.scale[1],m.scale[2]]:[1,1,1]});this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let m of j)m.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 n=e.exposure??e.gltf?.extras?.exposure??e.gltf?.asset?.extras?.exposure;n!==void 0&&(this.exposure=Ct(n));let c=e.environmentIntensity??e.gltf?.extras?.environmentIntensity??e.gltf?.asset?.extras?.environmentIntensity;c!==void 0&&(this.envIntensity=Math.max(0,Number(c)||0)),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(Vt(e))}clearScene(){this.disposeMeshGpuResources(),this.lights=[],this.animations=[],this.currentClip=null,this.isPlayingAnimation=!1,this.animationTime=0,this.lastGlbData=null;for(let e of j)e.onClearScene?.(this);this.worldMatrices=[],this.gltf=null,this.initialNodeTransforms=[],this.turntableRotation=0,this.updateTurntableMatrix(),this.gl&&this.render()}loadModel(e){this.loadGLBData(xt(e))}setBackdropGLB(e,t){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!e){this.update(0),this.render();return}let i=xt(e),{meshes:r}=Gt(this.gl,i,Ut,()=>this.render());if(t)for(let s of r)s.transform[12]+=t[0],s.transform[13]+=t[1],s.transform[14]+=t[2],ut(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),ut(i.normalMatrix,i.transform))}}bindLights(e=this.uRender){let t=this.gl,i=[.28,.28,.28],r=[],s=[],a=[],o=[],h=[],l=[];for(let n of this.lights){let c=n.color||[1,1,1],m=n.intensity!==void 0?n.intensity:1;if(n.type==="ambient")i=[c[0]*m,c[1]*m,c[2]*m];else if(n.type==="directional"&&r.length<6){let x=n.direction||[.5,1,.8];r.push(x[0],x[1],x[2]),s.push(c[0]*m,c[1]*m,c[2]*m)}else if((n.type==="point"||n.type==="spot")&&a.length<6){let x=n.position||[0,0,0];if(a.push(x[0],x[1],x[2]),o.push(c[0]*m,c[1]*m,c[2]*m),n.type==="spot"){let f=n.direction||[0,-1,0],v=Math.max(.01,Math.min(Math.PI/2,n.outerConeAngle??Math.PI/3)),b=Math.max(0,Math.min(v-1e-4,n.innerConeAngle??0));h.push(f[0],f[1],f[2]),l.push(Math.cos(b),Math.cos(v))}else h.push(0,-1,0),l.push(-2,-3)}}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,a.length/3),a.length>0&&(t.uniform3fv(e.uPointLightPos,a),t.uniform3fv(e.uPointLightColor,o),e.uPointLightSpotDir&&t.uniform3fv(e.uPointLightSpotDir,h),e.uPointLightSpotCone&&t.uniform2fv(e.uPointLightSpotCone,l)),t.uniform1f(e.uEnvIntensity,this.envIntensity)}setExposure(e){this.exposure=Ct(e)}getExposure(){return this.exposure}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=pt(e)}getToneMapping(){return this.toneMapping}async setEnvironmentImage(e){for(let t of j)if(t.setEnvironmentImage){await t.setEnvironmentImage(this,e);return}}async setSkyboxImage(e){for(let t of j)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(n=>n.primitives.filter(c=>c.materialIndex===i||e.length===1&&c.materialIndex===void 0)),s=r[0],a=s?[...s.baseColor]:t.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],o=s?s.metallic:t.pbrMetallicRoughness?.metallicFactor??.1,h=s?s.roughness:t.pbrMetallicRoughness?.roughnessFactor??.5,l={baseColorFactor:a,metallicFactor:o,roughnessFactor:h,setBaseColorFactor:n=>{let c=[n[0],n[1],n[2],n[3]??1];l.baseColorFactor=c,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.baseColorFactor=c);for(let m of r)m.baseColor=c;this.render()},setMetallicFactor:n=>{l.metallicFactor=n,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.metallicFactor=n);for(let c of r)c.metallic=n;this.render()},setRoughnessFactor:n=>{l.roughnessFactor=n,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.roughnessFactor=n);for(let c of r)c.roughness=n;this.render()}};return{name:t.name||`Material_${i}`,pbrMetallicRoughness:l}})}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)}getAvailableVariants(){return[...this.availableVariants]}getVariantName(){return this.activeVariantName}selectVariant(e){let t=this.applyVariantMaterial(e);return t&&this.gl&&this.render(),t}applyVariantMaterial(e){let t=e===null||e==="",i=-1;if(t)this.activeVariantName=null;else{if(i=this.availableVariants.indexOf(e),i<0)return!1;this.activeVariantName=e}let r=this.gltf?.materials;if(!Array.isArray(r))return t;for(let s of this.meshes)for(let a of s.primitives){let o=a.defaultMaterialIndex;if(!t&&Array.isArray(a.variantMappings)){for(let l of a.variantMappings)if(Array.isArray(l.variants)&&l.variants.includes(i)){o=l.material;break}}let h=o!==void 0?r[o]:void 0;a.materialIndex=h?o:void 0,Object.assign(a,Ht(h,this.gpuTextures)),this.applyPrimitiveProgram(a,a.materialIndex,h??null)}return!0}applyPrimitiveProgram(e,t,i){if(!this.gl||!e.primitiveDef)return;e.programCache??(e.programCache=new Map);let r=t??-1,s=e.programCache.get(r);s||(s=_t(this.gl,{...e.primitiveDef,material:t},i),e.programCache.set(r,s)),e.customProgram=s.program,e.customUniforms=s.uniforms,e.pluginData&&(e.pluginData.materials=e.isTransmissive?{isTransmissive:!0}:void 0)}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 j)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=z();Q(i,this.projMatrix,this.viewMatrix);let[r,s,a]=e,o=t?t[0]:0,h=t?t[1]:0,l=t?t[2]:0,n=this.modelRootMatrix;n&&(r=n[0]*e[0]+n[4]*e[1]+n[8]*e[2]+n[12],s=n[1]*e[0]+n[5]*e[1]+n[9]*e[2]+n[13],a=n[2]*e[0]+n[6]*e[1]+n[10]*e[2]+n[14],t&&(o=n[0]*t[0]+n[4]*t[1]+n[8]*t[2],h=n[1]*t[0]+n[5]*t[1]+n[9]*t[2],l=n[2]*t[0]+n[6]*t[1]+n[10]*t[2]));let c=i[0]*r+i[4]*s+i[8]*a+i[12],m=i[1]*r+i[5]*s+i[9]*a+i[13],x=i[2]*r+i[6]*s+i[10]*a+i[14],f=i[3]*r+i[7]*s+i[11]*a+i[15];if(f<=1e-4)return{x:0,y:0,z:1,visible:!1};let v=c/f,b=m/f,T=x/f,M=this.canvas.getBoundingClientRect(),d=M.width||this.canvas.clientWidth||this.canvas.width||300,g=M.height||this.canvas.clientHeight||this.canvas.height||150,p=(v*.5+.5)*d,A=(-b*.5+.5)*g,w=v>=-1.1&&v<=1.1&&b>=-1.1&&b<=1.1&&T>=-1&&T<=1;if(w&&t){let[V,_,U]=ft(this),E=[r-V,s-_,a-U];o*E[0]+h*E[1]+l*E[2]>.05&&(w=!1)}return{x:p,y:A,z:T,visible:w}}setSelectedMesh(e){this.selectedMeshName=e||""}getSelectedMesh(){return this.selectedMeshName}setupEvents(){let e=this.canvas,t=()=>typeof performance<"u"?performance.now():Date.now();this.boundContextMenu=i=>{i.preventDefault()},e.addEventListener("contextmenu",this.boundContextMenu),this.boundPointerDown=i=>{this.interactive&&(this.isPointerDown=!0,this.lastInteractionTime=t(),this.lastPointerX=i.clientX,this.lastPointerY=i.clientY,this.totalDragDist=0,this.activePointers.set(i.pointerId,{x:i.clientX,y:i.clientY}),this.isPanning=i.button===2||i.shiftKey||this.activePointers.size===2,e.setPointerCapture(i.pointerId))},e.addEventListener("pointerdown",this.boundPointerDown),this.boundPointerMove=i=>{if(!this.isPointerDown||!this.interactive)return;this.lastInteractionTime=t();let r=this.activePointers.get(i.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},s=i.clientX-r.x,a=i.clientY-r.y;if(this.activePointers.set(i.pointerId,{x:i.clientX,y:i.clientY}),this.lastPointerX=i.clientX,this.lastPointerY=i.clientY,this.totalDragDist+=Math.hypot(s,a),this.isPanning||i.button===2||i.shiftKey||this.activePointers.size===2){let o=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],h=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],l=this.customTarget?[...this.customTarget]:[...this.bounds.center],n=this.currDistance/Math.max(e.clientHeight||300,1)*1.5;l[0]+=(-s*o[0]+a*h[0])*n,l[1]+=(-s*o[1]+a*h[1])*n,l[2]+=(-s*o[2]+a*h[2])*n,this.customTarget=l}else this.targetTheta=this.clampTheta(this.targetTheta-s*.008),this.targetPhi=this.clampPhi(this.targetPhi+a*.008)},e.addEventListener("pointermove",this.boundPointerMove),this.boundPointerUp=i=>{this.lastInteractionTime=t(),this.activePointers.delete(i.pointerId),this.activePointers.size===0?(this.isPointerDown=!1,this.isPanning=!1):this.activePointers.size===1&&(this.isPanning=!1);try{e.releasePointerCapture(i.pointerId)}catch{}if(this.totalDragDist<5&&i.button===0){let r=e.getBoundingClientRect(),s=Math.floor((i.clientX-r.left)*(e.width/Math.max(r.width,1))),a=Math.floor((i.clientY-r.top)*(e.height/Math.max(r.height,1)));this.performMeshPick(s,a,!0)}},e.addEventListener("pointerup",this.boundPointerUp),this.boundWheel=i=>{if(!this.interactive)return;i.preventDefault(),this.lastInteractionTime=t();let r=Math.exp(i.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*r)},e.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=i=>{let r=i.detail||{};r.reset?this.resetCamera():this.setCamera(r.theta,r.phi,r.distance,r.zoom)},this.container.addEventListener("setCamera",this.boundSetCamera),this.boundResetCamera=()=>{this.resetCamera()},this.container.addEventListener("resetCamera",this.boundResetCamera),e.tabIndex!==void 0&&e.tabIndex<0&&(e.tabIndex=0),e.getAttribute?.("role")||e.setAttribute?.("role","region"),e.getAttribute?.("aria-label")||e.setAttribute?.("aria-label","Interactive 3D model viewport"),this.boundKeyDown=i=>{if(this.interactive){switch(i.key){case"ArrowLeft":this.targetTheta=this.clampTheta(this.targetTheta-.1);break;case"ArrowRight":this.targetTheta=this.clampTheta(this.targetTheta+.1);break;case"ArrowUp":this.targetPhi=this.clampPhi(this.targetPhi+.08);break;case"ArrowDown":this.targetPhi=this.clampPhi(this.targetPhi-.08);break;case"+":case"=":this.targetDistance=this.clampDistance(this.targetDistance*.9);break;case"-":case"_":this.targetDistance=this.clampDistance(this.targetDistance*1.1);break;case"Home":this.resetCamera();break;default:return}this.lastInteractionTime=t(),i.preventDefault()}},e.addEventListener("keydown",this.boundKeyDown)}teardownEvents(){let e=(i,r,s)=>{this[s]&&(i.removeEventListener(r,this[s]),this[s]=null)},t=this.canvas;e(t,"webglcontextlost","boundContextLost"),e(t,"webglcontextrestored","boundContextRestored"),e(t,"contextmenu","boundContextMenu"),e(t,"pointerdown","boundPointerDown"),e(t,"pointermove","boundPointerMove"),e(t,"pointerup","boundPointerUp"),e(t,"wheel","boundWheel"),e(t,"keydown","boundKeyDown"),e(this.container,"setCamera","boundSetCamera"),e(this.container,"resetCamera","boundResetCamera")}raycastFromScreenPoint(e,t){let i=this.canvas,r=i.getBoundingClientRect(),s=i.width||300,a=i.height||300,o=r.width>0?Math.floor((e-r.left)*(s/r.width)):Math.floor(e),h=r.height>0?Math.floor((t-r.top)*(a/r.height)):Math.floor(t);return this.performMeshPick(o,h,!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),a=Math.max(1,this.canvas.height||300);e=this.mapStereoPickX(e,s);let o=z();Q(o,this.projMatrix,this.viewMatrix);let h=[],l=Math.max(0,Math.min(s-1,e)),n=Math.max(0,Math.min(a-1,a-1-t));if(this.pickFbo&&r&&!this.xrSessionActive){(this.pickFboWidth!==s||this.pickFboHeight!==a)&&this.resizePickingFbo(s,a),r.bindFramebuffer(36160,this.pickFbo),r.viewport(0,0,s,a),r.enable(2929),r.clearColor(0,0,0,0),r.clear(16640),r.useProgram(this.pickProg);for(let A=0;A<this.meshes.length;A++){let w=this.meshes[A];if(w.visible===!1||w.isPluginMesh)continue;let V=A+1,_=(V&255)/255,U=(V>>8&255)/255,E=(V>>16&255)/255;r.uniform4f(this.uPick.uColorId,_,U,E,1),Q(this.modelMatrix,this.modelRootMatrix,w.transform);let y=w.instanceMatrices;if(y&&y.length>=16){let L=y.length>>4,P=z();for(let u of w.primitives){r.bindVertexArray(u.vao);for(let C=0;C<L;C++)Q(P,this.modelMatrix,y.subarray(C*16,C*16+16)),Q(this.mvpMatrix,o,P),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix),yt(r,u)}}else{Q(this.mvpMatrix,o,this.modelMatrix),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let L of w.primitives)r.bindVertexArray(L.vao),yt(r,L)}}let g=new Uint8Array(4);r.readPixels(l,n,1,1,6408,5121,g),r.bindFramebuffer(36160,null);let p=g[0]+(g[1]<<8)+(g[2]<<16);p>0&&p<=this.meshes.length&&(h=[this.meshes[p-1]])}h.length===0&&(h=this.meshes.filter(g=>g.visible!==!1));let c=null,m=1/0,x=[0,0,0],f=[0,1,0],[v,b,T]=ft(this),M=z();for(let g of h){Q(M,this.modelRootMatrix,g.transform);let p=g.instanceMatrices,A=p&&p.length>=16?p.length>>4:1;for(let w=0;w<A;w++){p&&p.length>=16?Q(this.modelMatrix,M,p.subarray(w*16,w*16+16)):this.modelMatrix.set(M),Q(this.mvpMatrix,o,this.modelMatrix);let V=z();if(!Zt(V,this.mvpMatrix))continue;let _=(l+.5)/s*2-1,U=(n+.5)/a*2-1,E=[0,0,0],y=[0,0,0];It(E,_,U,-1,V),It(y,_,U,1,V);let L=y[0]-E[0],P=y[1]-E[1],u=y[2]-E[2],C=Math.hypot(L,P,u)||1,H=L/C,Y=P/C,I=u/C,k={distance:1/0,point:[0,0,0],normal:[0,1,0]};if((R=>{for(let N of g.primitives){if(!N.positions)continue;let B=N.positions,F=N.indices,W=Math.floor(F?F.length/3:B.length/9);for(let O=0;O<W;O++){let rt=F?F[O*3]:O*3,$=F?F[O*3+1]:O*3+1,tt=F?F[O*3+2]:O*3+2;Qt(E[0],E[1],E[2],H,Y,I,B[rt*3],B[rt*3+1],B[rt*3+2],B[$*3],B[$*3+1],B[$*3+2],B[tt*3],B[tt*3+1],B[tt*3+2],k,R)}}})(1e-4),isFinite(k.distance)){let R=k.point[0],N=k.point[1],B=k.point[2],F=this.modelMatrix,W=F[0]*R+F[4]*N+F[8]*B+F[12],O=F[1]*R+F[5]*N+F[9]*B+F[13],rt=F[2]*R+F[6]*N+F[10]*B+F[14],$=W-v,tt=O-b,st=rt-T,ot=Math.hypot($,tt,st);if(ot<m){ut(this.normalMatrix,this.modelMatrix);let q=this.normalMatrix,nt=k.normal[0],lt=k.normal[1],D=k.normal[2],G=q[0]*nt+q[3]*lt+q[6]*D,K=q[1]*nt+q[4]*lt+q[7]*D,et=q[2]*nt+q[5]*lt+q[8]*D,S=Math.hypot(G,K,et)||1;G/=S,K/=S,et/=S,G*$+K*tt+et*st>0&&(G=-G,K=-K,et=-et),c=g,m=Math.round(ot*1e3)/1e3,x=[Math.round(W*1e3)/1e3,Math.round(O*1e3)/1e3,Math.round(rt*1e3)/1e3],f=[Math.round(G*1e3)/1e3,Math.round(K*1e3)/1e3,Math.round(et*1e3)/1e3]}}}}if(!c)return null;let d={meshIndex:this.meshes.indexOf(c),meshName:c.name,nodeIndex:c.nodeIndex,distance:m,hitPoint:x,normal:f,screenX:e,screenY:t};if(i){for(let g of j)g.onMeshSelect?.(this,d);this.opts.onMeshClick&&this.opts.onMeshClick(d),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:d}))}return d}mapStereoPickX(e,t){if(!this.stereoSBS||this.xrSessionActive||t<2)return e;let i=Math.max(1,Math.floor(t*.5)),r=e>=i,s=r?e-i:e,a=r?Math.max(1,t-i):i,o=(s+.5)/a*2-1;return Math.floor((o*.5+1)*.5*t)}setStereoSBS(e){this.stereoSBS=!!e,this.xrSessionActive||(this.syncCameraMatrices(),this.render())}syncCameraMatrices(){let e=Math.max(1,this.canvas.width||1)/Math.max(1,this.canvas.height||1),t=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10);Tt(this.projMatrix,this.fov,e,.1,t);let i=this.customTarget||this.bounds.center;Pt(this.viewMatrix,ft(this),i,[0,1,0]),Q(this.mvpMatrix,this.projMatrix,this.viewMatrix),ut(this.normalMatrix,this.modelMatrix)}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),this.xrSessionActive||this.syncCameraMatrices()):!this.xrSessionActive&&this.projMatrix[0]===0&&this.syncCameraMatrices()}getGLContext(){return this.gl}setXRSessionActive(e){let t=this.xrSessionActive;if(this.xrSessionActive=e,t&&!e){this.xrDepthState.enabled=!1;for(let i of j)i.onXRSessionEnd?.(this);if(this.lastTime=typeof performance<"u"?performance.now():Date.now(),this.updateTurntableMatrix(),this.isVisible)try{this.resize(),this.syncCameraMatrices(),this.render()}catch(i){this.reportRenderError(i)}}}reportRenderError(e){this.renderErrorReported||(this.renderErrorReported=!0,typeof console<"u"&&console.warn("[three-live] render frame failed:",e))}stepXRUpdate(e){for(let t of j)t.onUpdate?.(this,e)}start(){if(this.animFrameId!==null)return;this.lastTime=typeof performance<"u"?performance.now():Date.now();let e=t=>{if(this.animFrameId===null)return;let i=Math.min(Math.max((t-this.lastTime)/1e3,0),.1);if(this.lastTime=t,this.isVisible&&!this.xrSessionActive)try{this.resize(),this.update(i),this.render()}catch(r){this.reportRenderError(r)}this.animFrameId!==null&&(this.animFrameId=requestAnimationFrame(e))};this.animFrameId=requestAnimationFrame(e)}stop(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null)}setAutoRotate(e){this.autoRotate=e}getAutoRotate(){return this.autoRotate}setAutoRotateSpeed(e){this.autoRotateSpeed=e}getAutoRotateSpeed(){return this.autoRotateSpeed}setAutoRotateDelay(e){this.autoRotateDelay=Math.max(0,Number(e)||0)}getAutoRotateDelay(){return this.autoRotateDelay}resetTurntableRotation(e=0){this.turntableRotation=Number(e)||0,this.updateTurntableMatrix(),this.render()}updateTurntableMatrix(){let e=Math.cos(this.turntableRotation),t=Math.sin(this.turntableRotation),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 a of j)a.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 a of j)a.onCameraChange?.(this,this.container)}this.currTheta+=(this.targetTheta-this.currTheta)*.12,this.currPhi+=(this.targetPhi-this.currPhi)*.12,this.currDistance+=(this.targetDistance-this.currDistance)*.12,this.syncCameraMatrices();let i=Math.round((this.currTheta*180/Math.PI%360+360)%360),r=Math.round(this.currPhi*180/Math.PI),s=Math.round(this.bounds.radius*2.5/this.currDistance*100)/100;if(Math.abs(i-this.lastReportedTheta)>=1||Math.abs(r-this.lastReportedPhi)>=1||Math.abs(s-this.lastReportedZoom)>=.02){this.lastReportedTheta=i,this.lastReportedPhi=r,this.lastReportedZoom=s;let a={theta:i,phi:r,zoom:s,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(a),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:a}))}}renderXRView(e,t,i,r,s=!0,a=0){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(e);let o=e?.transform?.inverse?.matrix||this.viewMatrix,h=e?.projectionMatrix||this.projMatrix,l=e?.transform?.position,n=l?[l.x,l.y,l.z]:[0,1.6,0];t?this.modelRootMatrix.set(t):i&&t&&this.modelRootMatrix.set(t),this.render({viewMatrix:o,projMatrix:h,eyePos:n,viewport:r,eye:e?.eye||"none",clear:a>0?!1:e?.eye!=="right",isAR:s})}render(e){if(this.contextLost)return;if(!e&&this.stereoSBS){let d=Math.max(2,this.canvas.width||2),g=Math.max(1,this.canvas.height||1),p=Math.max(1,Math.floor(d*.5)),A=Math.max(1,d-p),w=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10),V=this.customTarget||this.bounds.center,[_,U,E]=ft(this),y=Math.cos(this.currTheta),L=-Math.sin(this.currTheta),P=.032,u=z(),C=z(),H=[_-y*P,U,E-L*P],Y=[V[0]-y*P*.25,V[1],V[2]-L*P*.25];Tt(u,this.fov,p/g,.1,w),Pt(C,H,Y,[0,1,0]);let I=z(),k=z(),R=[_+y*P,U,E+L*P],N=[V[0]+y*P*.25,V[1],V[2]+L*P*.25];Tt(I,this.fov,A/g,.1,w),Pt(k,R,N,[0,1,0]),this.render({viewMatrix:C,projMatrix:u,eyePos:H,viewport:[0,0,p,g],eye:"left",clear:!0,isAR:!1}),this.render({viewMatrix:k,projMatrix:I,eyePos:R,viewport:[p,0,A,g],eye:"right",clear:!1,isAR:!1}),this.gl.viewport(0,0,d,g);return}let t=this.gl,i=0,r=0,s=this.canvas.width,a=this.canvas.height;e?.viewport?(i=e.viewport[0],r=e.viewport[1],s=e.viewport[2],a=e.viewport[3],t.viewport(i,r,s,a)):t.viewport(0,0,this.canvas.width,this.canvas.height),t.enable(2929),(!e||e.clear!==!1)&&(e?.isAR?t.clearColor(0,0,0,0):t.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),t.clear(16640));let o=z(),h=e?.viewMatrix??this.viewMatrix;this.activeViewMatrix=h,Q(o,e?.projMatrix??this.projMatrix,h);let l=Z().xrDepthShader,n=te(this.toneMapping),[c,m,x]=e?e.eyePos:ft(this);for(let d of j)d.onBeforeDrawScene?.(this,t,o,[c,m,x],n);let f=e?.isAR?0:this.backdropMeshes.length;if(this.meshes.length===0&&f===0)return;let v=e?.eye||"none",b=!1,T=f>0?[...this.backdropMeshes,...this.meshes]:this.meshes,M=d=>{for(let g=0;g<T.length;g++){let p=T[g];if(p.visible===!1)continue;let A=this.selectedMeshName!==""&&p.name===this.selectedMeshName;g<f||p.worldSpace===!0||p.name==="__xr_reticle__"?this.modelMatrix.set(p.transform):Q(this.modelMatrix,this.modelRootMatrix,p.transform),Q(this.mvpMatrix,o,this.modelMatrix),ut(p.normalMatrix,this.modelMatrix);let w=p.extras?.xr?.stereo||p.userData?.xr?.stereo,V=0,_=0,U=1,E=1;w==="sbs"?(U=.5,V=v==="right"?.5:0):w==="ou"&&(E=.5,_=v==="right"?.5:0);for(let y of p.primitives){let L=!!y.isTransmissive;if(!d&&L){b=!0;continue}if(d&&!L)continue;let P=y.customProgram||this.renderProg,u=y.customUniforms||this.uRender;t.useProgram(P),t.vertexAttrib3f(3,0,0,0),u.uInstanced&&t.uniform1i(u.uInstanced,0),t.uniform1i(u.uToneMapping,n),t.uniform1f(u.uEnvIntensity,this.envIntensity),u.uExposure&&t.uniform1f(u.uExposure,this.exposure),t.uniform3f(u.uCameraPos,c,m,x),t.uniform1f(u.uEmissive,A?1:0),t.uniformMatrix4fv(u.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(u.uModel,!1,this.modelMatrix),t.uniformMatrix3fv(u.uNormalMatrix,!1,p.normalMatrix),u.uUvTransform&&t.uniform4f(u.uUvTransform,V,_,U,E),u.uViewportSize&&t.uniform2f(u.uViewportSize,Math.max(1,s),Math.max(1,a)),l?.bind(t,u,this.xrDepthState,h,[i,r,Math.max(1,s),Math.max(1,a)]),this.environmentTexture?(t.activeTexture(33988),t.bindTexture(3553,this.environmentTexture),t.uniform1i(u.uEnvironmentMap,4),t.uniform1i(u.uHasEnvironmentMap,1)):t.uniform1i(u.uHasEnvironmentMap,0),this.bindLights(u),u.uSectionEnabled&&t.uniform1i(u.uSectionEnabled,0);for(let H of j)H.onBeforeDrawPrimitive?.(t,P,y,p,this.worldMatrices||[],this.gltf);t.uniform4fv(u.uBaseColor,y.baseColor),t.uniform1f(u.uMetallic,y.metallic),t.uniform1f(u.uRoughness,y.roughness),u.uClearcoat&&t.uniform2f(u.uClearcoat,y.clearcoat??0,y.clearcoatRoughness??.04),y.texture?(t.activeTexture(33984),t.bindTexture(3553,y.texture),t.uniform1i(u.uBaseColorTexture,0),t.uniform1i(u.uHasTexture,1)):t.uniform1i(u.uHasTexture,0),y.metallicRoughnessTexture?(t.activeTexture(33985),t.bindTexture(3553,y.metallicRoughnessTexture),t.uniform1i(u.uMetallicRoughnessTexture,1),t.uniform1i(u.uHasMetallicRoughnessTexture,1)):t.uniform1i(u.uHasMetallicRoughnessTexture,0),y.normalTexture?(t.activeTexture(33986),t.bindTexture(3553,y.normalTexture),t.uniform1i(u.uNormalTexture,2),t.uniform1i(u.uHasNormalTexture,1),t.uniform1f(u.uNormalScale,y.normalScale)):t.uniform1i(u.uHasNormalTexture,0),y.occlusionTexture?(t.activeTexture(33987),t.bindTexture(3553,y.occlusionTexture),t.uniform1i(u.uOcclusionTexture,3),t.uniform1i(u.uHasOcclusionTexture,1),t.uniform1f(u.uOcclusionStrength,y.occlusionStrength)):t.uniform1i(u.uHasOcclusionTexture,0),t.bindVertexArray(y.vao);let C=p.instanceMatrices;if(y.instanceCount!==void 0)t.drawElementsInstanced(4,y.indexCount,y.indexType,0,y.instanceCount);else if(C&&C.length>=16&&y.instanced&&u.uInstanced&&u.uViewProj){let H=C.length>>4;t.uniform1i(u.uInstanced,1),t.uniformMatrix4fv(u.uViewProj,!1,o),y.indices?t.drawElementsInstanced(4,y.indexCount,y.indexType,0,H):t.drawArraysInstanced(4,0,y.indexCount,H),t.uniform1i(u.uInstanced,0)}else if(C&&C.length>=16){let H=C.length>>4,Y=p.instanceColors,I=z(),k=new Float32Array(9),R=[y.baseColor[0],y.baseColor[1],y.baseColor[2],y.baseColor[3]];for(let N=0;N<H;N++)Q(I,this.modelMatrix,C.subarray(N*16,N*16+16)),Q(this.mvpMatrix,o,I),ut(k,I),t.uniformMatrix4fv(u.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(u.uModel,!1,I),t.uniformMatrix3fv(u.uNormalMatrix,!1,k),Y&&(R[0]=y.baseColor[0]*Y[N*3],R[1]=y.baseColor[1]*Y[N*3+1],R[2]=y.baseColor[2]*Y[N*3+2],R[3]=y.baseColor[3],t.uniform4fv(u.uBaseColor,R)),yt(t,y)}else yt(t,y)}}};if(M(!1),b){for(let d of j)d.onBeforeTransmissivePass?.(t,this);M(!0)}for(let d of j)d.onAfterRender?.(t,this,o,e?.eye??"none",[i,r,s,a],e?.projMatrix??this.projMatrix)}disposeMeshListGpuResources(e,t){zt(this.gl,e,t)}disposeMeshGpuResources(){this.disposeMeshListGpuResources(this.meshes,this.gpuTextures),this.meshes=[],this.gpuTextures=[],this.availableVariants=[]}disposeGpuResources(){let e=this.gl;this.disposeMeshGpuResources(),this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[];for(let t of j)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()}};at.registerPlugin=Wt,at.getRegisteredPlugins=qt;var St=(e,t,i)=>({x:e,y:t,z:i,toString:()=>`${e}m ${t}m ${i}m`}),me=typeof HTMLElement<"u"?HTMLElement:class{};typeof CustomEvent>"u"&&typeof Event<"u"&&(globalThis.CustomEvent=class extends Event{constructor(e,t){super(e,t),this.detail=t?.detail??null}});var Mt=class it extends me{constructor(){super(...arguments),this.viewer=null,this.canvas=null,this.posterEl=null,this.arButton=null,this.currentModel=null,this.activeXRSession=null,this.toastTimer=null,this.currentModelLimits=void 0,this.isModelLoaded=!1,this.scriptHandle=null,this.loadController=null,this.resizeObserver=null,this.mutationObserver=null}static get arProvider(){return Z().arProvider}static set arProvider(t){Z().arProvider=t}static get scriptRunner(){return Z().scriptRunner}static set scriptRunner(t){Z().scriptRunner=t}static get sandboxEngineSrc(){return Z().sandboxEngineSrc??null}static set sandboxEngineSrc(t){Z().sandboxEngineSrc=t}static get sandboxIframeSrc(){return Z().sandboxIframeSrc??null}static set sandboxIframeSrc(t){Z().sandboxIframeSrc=t}static get allowClientScripts(){return!!Z().allowClientScripts}static set allowClientScripts(t){Z().allowClientScripts=t}static registerScriptRunner(t){it.scriptRunner=t}static registerDecoder(t,i){at.registerDecoder(t,i)}static getDecoder(t){return at.getDecoder(t)}static registerAR(t){typeof t=="function"?it.arProvider={activateAR:t}:it.arProvider=t,typeof document<"u"&&document.querySelectorAll("three-live").forEach(i=>{i instanceof it&&i.updateARButtonVisibility()})}static isARSupported(){return!!it.arProvider}getLoadedModel(){return this.currentModel}beginLoad(){let t=this.loadController,i=this.scriptHandle,r=new AbortController;return this.loadController=r,this.scriptHandle=null,t?.abort(),i?.terminate(),r}connectedCallback(){if(typeof document>"u")return;(!this.style.display||this.style.display==="inline")&&(this.style.display="block"),getComputedStyle(this).position==="static"&&(this.style.position="relative"),this.style.overflow="hidden",this.setupDOM(),this.initViewer(),this.setupResizeObserver();let t=this.getAttribute("src"),i=this.getAttribute("script-src");if(t)this.loadModel(t).catch(()=>{});else if(i)this.loadScriptFromSrc(i).catch(()=>{});else{let r=this.querySelector('script[type="text/three"], script[type="text/three-live"]');r&&r.textContent&&this.executeScript(r.textContent).catch(()=>{})}for(let r of at.getRegisteredPlugins())r.onElementConnected?.(this)}disconnectedCallback(){for(let t of at.getRegisteredPlugins())t.onElementDisconnected?.(this);this.beginLoad().abort(),this.mutationObserver?.disconnect(),this.mutationObserver=null,this.resizeObserver?.disconnect(),this.resizeObserver=null,this.activeXRSession?.stop?.().catch?.(()=>{}),this.activeXRSession=null,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=null,this.viewer?.destroy(),this.viewer=null,this.isModelLoaded=!1}attributeChangedCallback(t,i,r){if(i!==r){switch(t){case"src":r&&this.loadModel(r).catch(()=>{});break;case"camera-target":this.applyCameraTarget(r);break;case"min-camera-orbit":case"max-camera-orbit":this.applyOrbitLimits();break;case"field-of-view":this.applyFieldOfView(r);break;case"script-src":r&&this.loadScriptFromSrc(r).catch(()=>{});break;case"sandbox":case"allow-client-scripts":case"ios-src":break;case"poster":this.updatePoster(r);break;case"camera-orbit":this.applyCameraOrbit(r);break;case"selected-mesh":this.viewer&&r!==null&&this.viewer.setSelectedMesh(r);break;case"exposure":if(this.viewer&&r!==null){let s=parseFloat(r);isNaN(s)||this.viewer.setExposure(s)}break;case"shadow-intensity":case"shadow-softness":this.viewer&&this.viewer.setShadow(this.shadowIntensity,this.shadowSoftness);break;case"tone-mapping":this.viewer?.setToneMapping(pt(r));break;case"environment-image":this.viewer&&this.viewer.setEnvironmentImage(r).catch(()=>{});break;case"skybox-image":this.viewer&&this.viewer.setSkyboxImage?.(r)?.catch?.(()=>{});break;case"camera-controls":{let s=this.cameraControls;this.viewer&&this.viewer.setInteractive?.(s),this.canvas&&(this.canvas.style.touchAction=s?"none":"auto");break}case"autoplay":this.viewer&&this.viewer.setAutoplay(r!==null&&r!=="false");break;case"animation-name":this.viewer&&r!==null&&this.viewer.setAnimationName(r);break;case"variant-name":this.viewer&&this.selectVariant(r);break;case"auto-rotate":this.viewer&&this.viewer.setAutoRotate(r!==null&&r!=="false");break;case"auto-rotate-delay":this.viewer&&this.viewer.setAutoRotateDelay(this.autoRotateDelay);break;case"rotation-per-second":this.viewer&&this.viewer.setAutoRotateSpeed(this.parseRotationPerSecond(r));break;case"ar":this.updateARButtonVisibility();break}for(let s of at.getRegisteredPlugins())s.onAttributeChanged?.(this,t,i,r)}}getAttr(t){return this.getAttribute(t)}setAttr(t,i){i!==null?this.setAttribute(t,String(i)):this.removeAttribute(t)}getBoolAttr(t){return this.hasAttribute(t)&&this.getAttr(t)!=="false"}setBoolAttr(t,i){this.setAttr(t,i?"":null)}getFloatAttr(t,i){let r=this.getAttr(t);return r!==null?parseFloat(r):i}get src(){return this.getAttr("src")}set src(t){this.setAttr("src",t)}get cameraControls(){return this.getBoolAttr("camera-controls")}set cameraControls(t){this.setBoolAttr("camera-controls",t)}get cameraOrbit(){return this.getAttr("camera-orbit")}set cameraOrbit(t){this.setAttr("camera-orbit",t)}get cameraTarget(){return this.getAttr("camera-target")}set cameraTarget(t){this.setAttr("camera-target",t)}get minCameraOrbit(){return this.getAttr("min-camera-orbit")}set minCameraOrbit(t){this.setAttr("min-camera-orbit",t)}get maxCameraOrbit(){return this.getAttr("max-camera-orbit")}set maxCameraOrbit(t){this.setAttr("max-camera-orbit",t)}get fieldOfView(){return this.getAttr("field-of-view")}set fieldOfView(t){this.setAttr("field-of-view",t)}get iosSrc(){return this.getAttr("ios-src")}set iosSrc(t){this.setAttr("ios-src",t)}get scriptSrc(){return this.getAttr("script-src")}set scriptSrc(t){this.setAttr("script-src",t)}get sandbox(){return this.getAttr("sandbox")||(Z().sandboxIframeSrc?"iframe":"worker")}set sandbox(t){this.setAttr("sandbox",t)}get allowClientScripts(){return this.getBoolAttr("allow-client-scripts")||it.allowClientScripts}set allowClientScripts(t){this.setBoolAttr("allow-client-scripts",t)}get poster(){return this.getAttr("poster")}set poster(t){this.setAttr("poster",t)}get selectedMesh(){return this.getAttr("selected-mesh")}set selectedMesh(t){this.setAttr("selected-mesh",t)}get exposure(){return this.getFloatAttr("exposure",1)}set exposure(t){this.setAttr("exposure",t)}get autoRotate(){return this.getBoolAttr("auto-rotate")}set autoRotate(t){this.setBoolAttr("auto-rotate",t)}get autoRotateDelay(){return this.getFloatAttr("auto-rotate-delay",3e3)}set autoRotateDelay(t){this.setAttr("auto-rotate-delay",t)}get rotationPerSecond(){return this.getAttr("rotation-per-second")||"30deg"}set rotationPerSecond(t){this.setAttr("rotation-per-second",t)}get turntableRotation(){return this.viewer?this.viewer.turntableRotation:0}get ar(){return this.hasAttribute("ar")}set ar(t){this.setBoolAttr("ar",t)}get arScale(){return this.getAttr("ar-scale")||"auto"}set arScale(t){this.setAttr("ar-scale",t)}get arPlacement(){return this.getAttr("ar-placement")||"floor"}set arPlacement(t){this.setAttr("ar-placement",t)}get canActivateAR(){return it.isARSupported()}get shadowIntensity(){return this.getFloatAttr("shadow-intensity",0)}set shadowIntensity(t){this.setAttr("shadow-intensity",t)}get shadowSoftness(){return this.getFloatAttr("shadow-softness",.5)}set shadowSoftness(t){this.setAttr("shadow-softness",t)}get toneMapping(){return pt(this.getAttr("tone-mapping"))}set toneMapping(t){this.setAttr("tone-mapping",t)}get bloom(){return this.getFloatAttr("bloom",0)}set bloom(t){this.setAttr("bloom",t)}get bloomThreshold(){return Dt(this.getAttr("bloom-threshold"),.62)}set bloomThreshold(t){this.setAttr("bloom-threshold",t)}get bloomRadius(){return Dt(this.getAttr("bloom-radius"),.75)}set bloomRadius(t){this.setAttr("bloom-radius",t)}get outlineSelected(){return this.getBoolAttr("outline-selected")}set outlineSelected(t){this.setBoolAttr("outline-selected",t)}get outlineColor(){return this.getAttr("outline-color")||"#38bdf8"}set outlineColor(t){this.setAttr("outline-color",t)}get environmentImage(){return this.getAttr("environment-image")}set environmentImage(t){this.setAttr("environment-image",t)}get skyboxImage(){return this.getAttr("skybox-image")}set skyboxImage(t){this.setAttr("skybox-image",t)}get autoplay(){return this.getBoolAttr("autoplay")}set autoplay(t){this.setBoolAttr("autoplay",t)}get animationName(){return this.getAttr("animation-name")}set animationName(t){this.setAttr("animation-name",t)}get availableAnimations(){return this.viewer?this.viewer.getAvailableAnimations():[]}get variantName(){return this.viewer?this.viewer.getVariantName():this.getAttr("variant-name")}set variantName(t){this.setAttr("variant-name",t)}get availableVariants(){return this.viewer?this.viewer.getAvailableVariants():[]}fireEvent(t,i){this.dispatchEvent(new CustomEvent(t,{bubbles:!0,composed:!0,detail:i}))}setSlotVisible(t,i){let r=typeof this.querySelector=="function"?this.querySelector(`[slot="${t}"]`):null;r&&(r.hidden=!i,r.style&&(r.style.display=i?"":"none"))}emitError(t,i="script"){this.setSlotVisible("error",!0),this.fireEvent("error",{error:t}),this.fireEvent("three-error",{error:t,message:t?.message||String(t),stage:i})}selectVariant(t){if(!this.viewer)return!1;let i=this.viewer.selectVariant(t);return i&&this.fireEvent("variant-applied",{variantName:this.viewer.getVariantName()}),i}get model(){let t=this.viewer?this.viewer.getModelMaterials():[];return{materials:t,getMaterialByName(i){return t.find(r=>r.name===i)??null}}}play(){this.viewer&&this.viewer.playAnimation(this.animationName||void 0)}pause(){this.viewer&&this.viewer.pauseAnimation()}resetCamera(){this.viewer?.resetCamera()}resetTurntableRotation(t=0){this.viewer?.resetTurntableRotation(t)}setCamera(t,i,r,s){this.viewer&&this.viewer.setCamera(t,i,r,s)}getCameraOrbit(){return this.viewer?this.viewer.getCameraOrbit():{theta:0,phi:0,radius:3,toString(){return"0rad 0rad 3m"}}}getCameraTarget(){return this.viewer?this.viewer.getCameraTarget():St(0,0,0)}getFieldOfView(){return this.viewer?this.viewer.getFieldOfView():45}jumpCameraToGoal(){this.viewer?.jumpCameraToGoal()}toDataURL(t,i){return this.viewer?.render?.(),this.canvas?this.canvas.toDataURL(t,i):""}toBlob(t){return this.viewer?.render?.(),new Promise((i,r)=>{if(!this.canvas||typeof this.canvas.toBlob!="function"){r(new Error("Canvas toBlob is not supported in this environment."));return}this.canvas.toBlob(s=>{s?i(s):r(new Error("Failed to capture canvas blob."))},t?.mimeType,t?.qualityArgument)})}positionAndNormalFromPoint(t,i){let r=this.viewer?.raycastFromScreenPoint(t,i);if(!r)return null;let[s,a,o]=r.hitPoint||r.point,[h,l,n]=r.normal;return{position:St(s,a,o),normal:St(h,l,n)}}loadModel(t){return this.loadModelWithLimits(t)}async loadModelWithLimits(t,i,r=this.beginLoad()){if(r.signal.throwIfAborted(),!this.viewer){this.currentModel=t,this.currentModelLimits=i;return}try{let s;if(typeof t=="string"){let l=await fetch(t,{signal:r.signal});if(!l.ok)throw new Error(`Failed to load "${t}": HTTP ${l.status}`);s=await l.arrayBuffer()}else s=t;r.signal.throwIfAborted();let a=xt(s);this.viewer.loadGLBData(a,i),this.currentModel=a,this.currentModelLimits=i,this.isModelLoaded=!0,this.hidePoster(),this.setSlotVisible("error",!1),this.updateHotspots();let o=this.getAttr("selected-mesh");o&&this.viewer.setSelectedMesh(o);let h=this.getAttr("variant-name");h&&this.selectVariant(h),this.fireEvent("load",{model:a}),this.fireEvent("three-load",{model:a,source:typeof t=="string"?"src":"model"})}catch(s){throw r.signal.aborted||this.emitError(s,"load"),s}}showToast(t,i=4500){if(typeof document>"u")return;let r=this.querySelector(".three-live-toast");r||(r=document.createElement("div"),r.className="three-live-toast",r.style.cssText="position:absolute;bottom:70px;left:50%;transform:translateX(-50%) translateY(10px);z-index:10;padding:10px 16px;background-color:rgba(15,23,42,0.94);color:#f8fafc;border:1px solid rgba(56,189,248,0.45);border-radius:14px;font:500 13px/1.35 system-ui,-apple-system,sans-serif;box-shadow:0 10px 25px rgba(0,0,0,0.45);backdrop-filter:blur(12px);pointer-events:none;opacity:0;transition:opacity .25s ease,transform .25s ease;max-width:88%;text-align:center;white-space:normal;word-break:break-word",this.appendChild(r)),r.textContent=t,this.toastTimer&&clearTimeout(this.toastTimer);let s=()=>{r&&(r.style.opacity="1",r.style.transform="translateX(-50%) translateY(0)")};typeof requestAnimationFrame<"u"?requestAnimationFrame(s):s(),this.toastTimer=setTimeout(()=>{r&&(r.style.opacity="0",r.style.transform="translateX(-50%) translateY(10px)"),this.toastTimer=null},i)}async activateAR(){this.activeXRSession?.isSessionActive?.()&&(await this.activeXRSession.stop().catch(()=>{}),this.activeXRSession=null);let t=(s,a=s.message)=>{throw this.fireEvent("ar-status",{status:"failed",error:s}),this.showToast(a,6e3),s};this.currentModel||t(new Error("No 3D model is loaded in <three-live>.")),it.arProvider||t(new Error("AR module not bundled. Use the default 'three-live' bundle or call ThreeLiveElement.registerAR()."));let i=this.getAttr("ios-src"),r=(this.getAttr("ar-modes")||"").split(/\s+/).filter(Boolean);try{this.fireEvent("ar-status",{status:"session-started"});let s=await it.arProvider.activateAR({model:i||this.currentModel,glbUrl:typeof this.currentModel=="string"?this.currentModel:void 0,view:this.viewer||void 0,element:this,preferredModes:r.length>0?r:void 0,arScale:this.arScale,arPlacement:this.arPlacement,webXROptions:{onExit:()=>{this.activeXRSession=null,this.fireEvent("ar-status",{status:"not-presenting"})},onError:a=>{this.activeXRSession=null,this.fireEvent("ar-status",{status:"failed",error:a}),this.showToast(`AR error: ${a.message}`,6e3)}}});if(s.success){s.session&&(this.activeXRSession=s.session);let a=s.mode==="quick-look"?"Opening Apple AR Quick Look...":s.mode==="scene-viewer"?"Opening Google Scene Viewer...":s.mode==="webxr"?"WebXR AR session started.":"";a&&this.showToast(a)}else{let a=typeof navigator<"u"&&navigator.userAgent||"",o=/Macintosh/i.test(a)&&!(typeof navigator<"u"&&navigator.maxTouchPoints>1),h=/Android|iPhone|iPad|iPod/i.test(a),l=s.error?.message||"AR requires an iOS (Quick Look) or Android (WebXR / Scene Viewer) device.";if(o&&!h&&typeof document<"u"&&this.currentModel&&it.arProvider.createUSDZBlob)try{let n=this.currentModel instanceof Blob&&this.currentModel.type==="model/vnd.usdz+zip"?this.currentModel:it.arProvider.createUSDZBlob(this.currentModel),c=URL.createObjectURL(n),m=document.createElement("a");m.href=c,m.download="three_live_model.usdz",document.body.appendChild(m),m.click(),document.body.removeChild(m),setTimeout(()=>URL.revokeObjectURL(c),3e3),this.showToast("Downloaded USDZ preview for macOS Quick Look.",5e3)}catch{this.showToast(l,6e3)}else this.showToast(l,6e3);s.error&&this.fireEvent("ar-status",{status:"failed",error:s.error})}return s}catch(s){return this.activeXRSession=null,t(s,`AR error: ${s.message||String(s)}`)}}setupDOM(){let t=this.querySelector("canvas");t||(t=document.createElement("canvas"),t.style.cssText=`width:100%;height:100%;display:block;touch-action:${this.cameraControls?"none":"auto"};outline:none`,this.appendChild(t)),this.canvas=t,typeof t.addEventListener=="function"&&!t.__tlCtxBound&&(t.__tlCtxBound=!0,t.addEventListener("webglcontextlost",r=>this.fireEvent("three-context-lost",{originalEvent:r})),t.addEventListener("webglcontextrestored",r=>this.fireEvent("three-context-restored",{originalEvent:r}))),this.setSlotVisible("error",!1),this.isModelLoaded||this.setSlotVisible("poster",!0);let i=this.getAttr("poster");i&&this.updatePoster(i),this.createARButton(),typeof MutationObserver<"u"&&!this.mutationObserver&&(this.mutationObserver=new MutationObserver(()=>{this.updateARButtonVisibility()}),this.mutationObserver.observe(this,{childList:!0}))}initViewer(){if(!this.canvas)return;let t=this.autoRotate,i=this.exposure,r=this.parseOrbitLimit(this.getAttr("min-camera-orbit")),s=this.parseOrbitLimit(this.getAttr("max-camera-orbit")),a=this.parseCameraTarget(this.getAttr("camera-target")),o=this.parseFieldOfView(this.getAttr("field-of-view"));this.viewer=new at(this,this.canvas,{autoRotate:t,autoRotateDelay:this.autoRotateDelay,autoRotateSpeed:this.parseRotationPerSecond(this.getAttr("rotation-per-second")),exposure:i,shadowIntensity:this.shadowIntensity,shadowSoftness:this.shadowSoftness,toneMapping:this.toneMapping,environmentImage:this.environmentImage,autoplay:this.autoplay,animationName:this.animationName||void 0,variantName:this.getAttr("variant-name")||void 0,fieldOfView:o,cameraTarget:a,minCameraOrbit:r,maxCameraOrbit:s,onMeshClick:l=>{this.fireEvent("meshclick",l)},onCameraChange:l=>{this.updateHotspots();for(let n of at.getRegisteredPlugins())n.onCameraChange?.(this.viewer,this);this.fireEvent("camera-change",l)}}),this.viewer.setInteractive(this.cameraControls),this.skyboxImage&&this.viewer.setSkyboxImage(this.skyboxImage).catch(()=>{});let h=this.getAttr("camera-orbit");h&&this.applyCameraOrbit(h),this.currentModel&&this.loadModelWithLimits(this.currentModel,this.currentModelLimits)}setupResizeObserver(){typeof ResizeObserver>"u"||(this.resizeObserver=new ResizeObserver(()=>{this.viewer&&(this.viewer.resize(),this.viewer.render(),this.updateHotspots())}),this.resizeObserver.observe(this))}updatePoster(t){if(!(typeof document>"u")){if(!t){this.posterEl&&(this.posterEl.remove(),this.posterEl=null);return}this.posterEl||(this.posterEl=document.createElement("img"),this.posterEl.alt="3D Scene Preview",this.posterEl.style.cssText="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .35s ease-out;pointer-events:none;z-index:1",this.appendChild(this.posterEl)),this.posterEl.src=t,this.isModelLoaded||(this.posterEl.style.opacity="1")}}hidePoster(){this.setSlotVisible("poster",!1),this.posterEl&&(this.posterEl.style.opacity="0",setTimeout(()=>{this.isModelLoaded&&this.posterEl&&(this.posterEl.remove(),this.posterEl=null)},400))}createARButton(){if(!(typeof document>"u")){if(!this.arButton){let t=document.createElement("button");t.type="button",t.className="three-live-ar-button";for(let[s,a]of[["aria-label","View in Augmented Reality"],["part","default-ar-button"]])t.setAttribute(s,a);let i="http://www.w3.org/2000/svg";if(typeof document.createElementNS=="function"){let s=document.createElementNS(i,"svg");for(let[o,h]of[["width","20"],["height","20"],["viewBox","0 0 24 24"],["fill","none"],["stroke","currentColor"],["stroke-width","2"],["stroke-linecap","round"],["stroke-linejoin","round"]])s.setAttribute(o,h);s.style.marginRight="6px";let a=document.createElementNS(i,"path");a.setAttribute("d","M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16zM3.27 6.96 12 12.01l8.73-5.05M12 22.08V12"),s.appendChild(a),t.appendChild(s)}let r=document.createElement("span");r.textContent="View in AR",t.appendChild(r),t.style.cssText="position:absolute;right:16px;bottom:16px;z-index:2;align-items:center;justify-content:center;padding:8px 16px;background-color:rgba(15,23,42,0.85);color:#fff;border:1px solid rgba(255,255,255,0.15);border-radius:9999px;font:600 13px system-ui,-apple-system,sans-serif;cursor:pointer;backdrop-filter:blur(8px);box-shadow:0 4px 12px rgba(0,0,0,0.25);transition:transform .15s ease,background-color .15s ease;display:none",t.addEventListener("mouseenter",()=>{t.style.backgroundColor="rgba(30, 41, 59, 0.95)",t.style.transform="scale(1.04)"}),t.addEventListener("mouseleave",()=>{t.style.backgroundColor="rgba(15, 23, 42, 0.85)",t.style.transform="scale(1)"}),t.addEventListener("click",s=>{s.stopPropagation(),this.activateAR()}),this.arButton=t,this.appendChild(t)}this.updateARButtonVisibility()}}updateARButtonVisibility(){let t=this.hasAttribute("ar")&&!!it.arProvider,i=typeof this.querySelector=="function"?this.querySelector('[slot="ar-button"]'):null;i?(this.arButton&&(this.arButton.style.display="none"),i.__tlARBound||(i.__tlARBound=!0,i.addEventListener("click",r=>{r.stopPropagation(),this.activateAR()})),i.dataset.tlOrigDisplay===void 0&&(i.dataset.tlOrigDisplay=i.style.display==="none"?"":i.style.display),i.style.display=t?i.dataset.tlOrigDisplay||"":"none"):this.arButton&&(this.arButton.style.display=t?"flex":"none")}applyCameraOrbit(t){if(!(!t||!this.viewer))try{let i=JSON.parse(t);this.viewer.setInitialCamera(i.theta,i.phi,i.distance,i.zoom)}catch{let i=this.parseOrbitLimit(t);(i.theta!==void 0||i.phi!==void 0)&&this.viewer.setInitialCamera(i.theta,i.phi,i.distance)}}parseOrbitLimit(t){if(!t)return{};let[i,r,s]=t.trim().split(/\s+/),a=s&&s!=="auto"?parseFloat(s):NaN;return{theta:i&&i!=="auto"?this.parseFieldOfView(i):void 0,phi:r&&r!=="auto"?this.parseFieldOfView(r):void 0,distance:isNaN(a)?void 0:a}}applyOrbitLimits(){if(!this.viewer)return;let t=this.parseOrbitLimit(this.getAttr("min-camera-orbit")),i=this.parseOrbitLimit(this.getAttr("max-camera-orbit"));this.viewer.setOrbitLimits({minTheta:t.theta,maxTheta:i.theta,minPhi:t.phi,maxPhi:i.phi,minDistance:t.distance,maxDistance:i.distance})}parseCameraTarget(t){if(!t)return;let i=t.trim().split(/\s+/).map(parseFloat);return i.length>=3&&!i.some(isNaN)?[i[0],i[1],i[2]]:void 0}parseFieldOfView(t){if(!t)return;let i=parseFloat(t);return isNaN(i)?void 0:t.endsWith("rad")?i*180/Math.PI:i}parseRotationPerSecond(t){if(!t)return Math.PI/6;let i=t.trim(),r=parseFloat(i);return isNaN(r)?Math.PI/6:i.endsWith("rad")?r:i.endsWith("%")?r/100*Math.PI*2:r*Math.PI/180}applyCameraTarget(t){let i=this.parseCameraTarget(t);this.viewer&&i&&this.viewer.setTarget(i[0],i[1],i[2])}applyFieldOfView(t){let i=this.parseFieldOfView(t);this.viewer&&i!==void 0&&this.viewer.setFieldOfView(i)}updateHotspot(t){let i=this.querySelector(`[slot="${t.name}"]`);i&&(t.position!==void 0&&i.setAttribute("data-position",t.position),t.normal!==void 0&&i.setAttribute("data-normal",t.normal)),this.updateHotspots()}updateHotspots(){for(let t of at.getRegisteredPlugins())if(t.updateHotspotsForElement){t.updateHotspotsForElement(this,this.viewer);return}}runWithScriptRunner(t){let i=it.scriptRunner;if(!i){let a=new Error('Script execution requires "three-live/full" or registerScriptRunner().');return this.showToast(a.message),this.emitError(a,"script"),Promise.reject(a)}let r=this.beginLoad(),s=()=>!r.signal.aborted;return new Promise((a,o)=>{let h=()=>o(r.signal.reason);if(r.signal.addEventListener("abort",h,{once:!0}),!s()){h();return}let l={onModelReady:n=>{this.loadModelWithLimits(n,ue,r).then(()=>a(n),o)},onUpdateTransforms:n=>{s()&&this.viewer?.updateMeshTransforms(n)},onError:n=>{s()&&(this.showToast(n.message),this.emitError(n,"script"),o(n))},onToast:n=>{s()&&this.showToast(n)}};t(i,l).then(n=>{s()?this.scriptHandle=n||null:n?.terminate()},n=>{s()&&l.onError?.(n)})})}loadScriptFromSrc(t){return this.runWithScriptRunner((i,r)=>{if(typeof i.executeUrl!="function"){let s=new Error("Registered ScriptRunner does not support executeUrl() for server-generated scripts.");return r.onError?.(s),Promise.reject(s)}return i.executeUrl(t,this.sandbox,r)})}executeScript(t){if(!it.scriptRunner)return this.runWithScriptRunner(()=>Promise.resolve());if(!this.allowClientScripts){let i=new Error(jt);return this.showToast($t),this.emitError(i,"security"),Promise.reject(i)}return this.runWithScriptRunner((i,r)=>i.execute(t,this.sandbox,r,{allowClientScripts:!0}))}};Mt.observedAttributes=["src","ios-src","script-src","sandbox","allow-client-scripts","poster","camera-controls","camera-orbit","camera-target","min-camera-orbit","max-camera-orbit","field-of-view","selected-mesh","ar","ar-modes","ar-scale","ar-placement","exposure","shadow-intensity","shadow-softness","tone-mapping","bloom","bloom-threshold","bloom-radius","outline","outline-selected","outline-color","environment-image","skybox-image","autoplay","animation-name","variant-name","auto-rotate","auto-rotate-delay","rotation-per-second"],Mt.registerPlugin=at.registerPlugin,Mt.getRegisteredPlugins=at.getRegisteredPlugins;var Xt=Mt;typeof customElements<"u"&&!customElements.get("three-live")&&customElements.define("three-live",Xt);export{Xt as ThreeLiveElement,at as ThreeView,xt as toGLBData};
|
|
214
|
+
void main(){fragColor=uColorId;}`;function ye(t,e,i){let r={};for(let a of i)r[a]=t.getUniformLocation(e,a);return r}var lt="uMVP uModel uInstanced uViewProj uNormalMatrix uUvTransform uBaseColor uMetallic uRoughness uClearcoat uEmissive uCameraPos uBaseColorTexture uHasTexture uMetallicRoughnessTexture uHasMetallicRoughnessTexture uNormalTexture uHasNormalTexture uNormalScale uOcclusionTexture uHasOcclusionTexture uOcclusionStrength uEmissiveFactor uEmissiveTexture uHasEmissiveTexture uToneMapping uEnvironmentMap uHasEnvironmentMap uAmbientColor uHemi uNumDirLights uDirLightDir uDirLightColor uNumPointLights uPointLightPos uPointLightColor uPointLightSpotDir uPointLightSpotCone uEnvIntensity uExposure uViewportSize uSectionPlane uSectionEnabled".split(" ");function Ae(){let t=K(),e=t.xrDepthShader,i=t.shadowMapShader;return{fs:at.replace("/*XRD_U*/",e?.uniformsGLSL||"").replace("/*XRD_O*/",e?.occlusionGLSL||"").replace("/*SHD_U*/",i?.uniformsGLSL||"").replace("/*SHD_D*/",i?.dirGLSL||"").replace("/*SHD_P*/",i?.ptGLSL||""),uniforms:[...lt,...e?.uniformNames||[],...i?.uniformNames||[]]}}function ht(t){if(typeof t!="string")return null;let e=t.trim();if(!e||/[\x00-\x1f\x7f]/.test(e))return null;let i=e.toLowerCase();return i.startsWith("data:")?/^data:image\/(png|jpeg|jpg|webp|ktx2|avif)(;|,)/i.test(e)?e:null:i.startsWith("https://")||i.startsWith("blob:")?e:i.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(e)||/(^|[\\/])\.\.([\\/]|$)/.test(e)?null:e}function Ce(t,e,i,r,a,s,o,n){if(r===void 0||!e.accessors?.[r])return null;let l=Ie(e,i,e.accessors[r],s);if(!l)return null;n&&(l=l.slice(),Ze(l,n));let h=t.createBuffer();return o.push(h),t.bindBuffer(34962,h),t.bufferData(34962,l,35044),t.enableVertexAttribArray(a),t.vertexAttribPointer(a,s,5126,!1,0,0),l}function Re(t){let e=Number(t);return Number.isFinite(e)?Math.max(0,e):1}function He(t,e,i){let r=Ae(),a=Se,s=r.fs,o=!1;for(let l of $)if(l.onResolveShader){let h=l.onResolveShader(e,i,a,s);h&&(a=h.vs,s=h.fs,o=!0)}let n=o?ve(t,a,s):null;return{program:n,uniforms:n?ye(t,n,r.uniforms):null}}function ut(t,e,i){let r=e.instanceMatrices;if(!r||r.length<16||typeof t.vertexAttribDivisor!="function"||typeof t.drawElementsInstanced!="function")return!1;let a=r.length>>4,s=e.instanceColors,o=new Float32Array(a*20);for(let l=0;l<a;l++)o.set(r.subarray(l*16,l*16+16),l*20),o[l*20+16]=s?s[l*3]:1,o[l*20+17]=s?s[l*3+1]:1,o[l*20+18]=s?s[l*3+2]:1,o[l*20+19]=1;let n=t.createBuffer();i.push(n),t.bindBuffer(34962,n),t.bufferData(34962,o,35044);for(let l=0;l<5;l++)t.enableVertexAttribArray(8+l),t.vertexAttribPointer(8+l,4,5126,!1,80,l*16),t.vertexAttribDivisor(8+l,1);return!0}function ct(t,e){let i=t.materials?.[e?.material];if(!i)return null;let r=[i.pbrMetallicRoughness?.baseColorTexture,i.pbrMetallicRoughness?.metallicRoughnessTexture,i.normalTexture,i.occlusionTexture,i.emissiveTexture];for(let a of r){let s=a?.extensions?.KHR_texture_transform;if(s&&typeof s=="object")return s}return null}var mt=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),ze=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function Me(t,e){e.indices?t.drawElements(4,e.indexCount,e.indexType,0):t.drawArrays(4,0,e.indexCount)}function Ge(t,e){let i=t?.pbrMetallicRoughness,r=i?.baseColorFactor,a=t?.emissiveFactor,s=t?.extensions?.KHR_materials_clearcoat,o=n=>n!==void 0&&e[n.index]?e[n.index]:null;return{baseColor:r?[r[0],r[1],r[2],r[3]??1]:[.8,.8,.8,1],metallic:i?.metallicFactor??.1,roughness:i?.roughnessFactor??.5,clearcoat:s?s.clearcoatFactor??1:0,clearcoatRoughness:Math.max(.04,s?.clearcoatRoughnessFactor??.04),texture:o(i?.baseColorTexture),metallicRoughnessTexture:o(i?.metallicRoughnessTexture),normalTexture:o(t?.normalTexture),normalScale:t?.normalTexture?.scale??1,occlusionTexture:o(t?.occlusionTexture),occlusionStrength:t?.occlusionTexture?.strength??1,emissiveTexture:o(t?.emissiveTexture),emissiveFactor:Array.isArray(a)&&a.length>=3?[a[0],a[1],a[2]]:[0,0,0],isTransmissive:(t?.extensions?.KHR_materials_transmission?.transmissionFactor??0)>0}}function je(t,e,i){let r=new Set,a=s=>{s&&!r.has(s)&&(r.add(s),t.deleteTexture(s))};for(let s of e)for(let o of s.primitives){if(o.vao&&t.deleteVertexArray(o.vao),o.buffers)for(let l of o.buffers)t.deleteBuffer(l);for(let l of[o.texture,o.metallicRoughnessTexture,o.normalTexture,o.occlusionTexture,o.emissiveTexture])a(l);let n=new Set;o.customProgram&&n.add(o.customProgram);for(let l of o.programCache?.values()??[])l.program&&n.add(l.program);for(let l of n)t.deleteProgram(l)}if(i)for(let s of i)a(s)}function We(t,e,i=ze,r){let a={meshes:[],mesh:null,gpuTextures:[],vao:null,buffers:[]};try{return dt(t,e,i,r,a)}catch(s){let o=a.mesh&&!a.meshes.includes(a.mesh)?[...a.meshes,a.mesh]:a.meshes;je(t,o,a.gpuTextures),a.vao&&t.deleteVertexArray(a.vao);for(let n of a.buffers)t.deleteBuffer(n);throw s}}function dt(t,e,i,r,a){if(!e||!e.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:s}=e,o=xe("meshopt");o?.decodeBufferViews&&o.decodeBufferViews(s,e);let n=e.bin,l=[];a.meshes=l;let h=[],u=s.extensions?.KHR_materials_variants;u&&Array.isArray(u.variants)&&u.variants.forEach((P,C)=>{h.push(typeof P?.name=="string"&&P.name?P.name:`Variant_${C}`)});let m=Oe(s),v=[];if(Array.isArray(s.nodes))for(let P=0;P<s.nodes.length;P++){let C=s.nodes[P];C.mesh!==void 0&&s.meshes&&s.meshes[C.mesh]&&v.push({node:C,nodeIdx:P,meshIdx:C.mesh})}let d=v.length>0?v:(s.meshes||[]).map((P,C)=>({node:P,nodeIdx:-1,meshIdx:C})),f=[],g=Array.isArray(e.lights)&&e.lights.length>0?e.lights:Array.isArray(s.asset?.extras?.lights)&&s.asset.extras.lights.length>0?s.asset.extras.lights:null;if(g)for(let P of g)f.push({...P,type:P.type||P.light_type||"point",groundColor:P.groundColor??P.ground_color,innerConeAngle:P.innerConeAngle??P.inner_cone_angle,outerConeAngle:P.outerConeAngle??P.outer_cone_angle});else s.extensions?.KHR_lights_punctual?.lights&&f.push(...rt(s,m));if(f.length===0&&(f.push({type:"ambient",color:[1,1,1],intensity:.35}),f.push({type:"directional",color:[1,1,1],intensity:.85,direction:[.5,1,.8]})),d.length>i.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${i.maxMeshes}). Found: ${d.length}`);let b=[];if(a.gpuTextures=b,s.textures&&s.images){if(s.textures.length>i.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${i.maxTextures}). Found: ${s.textures.length}`);for(let P=0;P<s.textures.length;P++){let C=s.textures[P],V=s.images[C.source];if(V){let U=t.createTexture();t.bindTexture(3553,U),t.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255]));for(let[M,R]of[[10242,10497],[10243,10497],[10241,9729],[10240,9729]])t.texParameteri(3553,M,R);let L=M=>{U.__gpuImageSource=M,t.bindTexture(3553,U),t.texImage2D(3553,0,6408,6408,5121,M),t.generateMipmap(3553),r?.()};if(V.bufferView!==void 0){let M=s.bufferViews[V.bufferView],R=M.byteOffset||0,H=new Blob([n.slice(R,R+M.byteLength)],{type:V.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(H).then(L).catch(()=>{})}else if(V.uri){let M=ht(V.uri);if(M){let R=new Image;R.crossOrigin="anonymous",R.referrerPolicy="no-referrer",R.onload=()=>L(R),R.src=M}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",V.uri)}b.push(U)}else b.push(null)}}let y=[1/0,1/0,1/0],p=[-1/0,-1/0,-1/0],w=0,T=0;for(let P=0;P<d.length;P++){let C=d[P],V=s.meshes[C.meshIdx],U=C.nodeIdx>=0?m[C.nodeIdx]:X(),L=new Float32Array(9);ue(L,U);let M=C.node?.extras?.shadow,R={name:C.node.name||V.name||`Mesh_${C.meshIdx}`,nodeIndex:C.nodeIdx,transform:U,normalMatrix:L,primitives:[],extras:C.node.extras||V.extras,...C.node?.visible===!1||C.node?.extensions?.KHR_node_visibility?.visible===!1?{visible:!1}:{},...typeof M?.cast=="boolean"?{castShadow:M.cast}:{},...typeof M?.receive=="boolean"?{receiveShadow:M.receive}:{}};a.mesh=R;let H=C.node?.extensions?.EXT_mesh_gpu_instancing;if(H&&H.attributes&&typeof H.attributes=="object"){let c=H.attributes,I=c.TRANSLATION!==void 0?s.accessors?.[c.TRANSLATION]:null,F=c.ROTATION!==void 0?s.accessors?.[c.ROTATION]:null,O=c.SCALE!==void 0?s.accessors?.[c.SCALE]:null,k=c._COLOR_0!==void 0?s.accessors?.[c._COLOR_0]:null,D=Number(I?.count??F?.count??O?.count??0);if(!Number.isFinite(D)||D<0||D>1e4)throw new Error(`SecurityError: EXT_mesh_gpu_instancing exceeds maximum instance limit (10000). Found: ${D}`);if(D>0){let B=(z,j)=>{if(!z||z.bufferView===void 0||!s.bufferViews?.[z.bufferView])return null;let Z=z.componentType??5126,re=oe=>(console.warn(`[three-live] EXT_mesh_gpu_instancing: skipping accessor (${oe})`),null);if(Z!==5120&&Z!==5121&&Z!==5122&&Z!==5123&&Z!==5126)return re(`componentType ${Z}`);if(!(Number(z.count)>=D))return re(`count ${z.count} < ${D}`);let te=null;try{te=Ie(s,n,{...z,count:D},j)}catch{return re("out of bounds")}return!te||!te.every(Number.isFinite)?re("non-finite value"):te},W=B(I,3),Y=B(F,4),q=B(O,3),ae=k?.type==="VEC4"?4:3,ie=B(k,ae),ne=new Float32Array(D*16),ee=X();for(let z=0;z<D;z++){let j=z*3,Z=z*4;Ve(ee,Y?[Y[Z],Y[Z+1],Y[Z+2],Y[Z+3]]:[0,0,0,1],W?[W[j],W[j+1],W[j+2]]:[0,0,0],q?[q[j],q[j+1],q[j+2]]:[1,1,1]),ne.set(ee,z*16)}if(R.instanceMatrices=ne,ie){let z=new Float32Array(D*3);for(let j=0;j<D;j++)z[j*3]=ie[j*ae],z[j*3+1]=ie[j*ae+1],z[j*3+2]=ie[j*ae+2];R.instanceColors=z}}}for(let c of V.primitives||[]){if(c.extensions?.KHR_draco_mesh_compression){let _=xe("draco");_&&_.decodePrimitive(s,c,n)}let I=[],F=t.createVertexArray();a.vao=F,a.buffers=I,t.bindVertexArray(F);let O=ut(t,R,I),k=s.accessors[c.attributes.POSITION],D=Number(k?.count??0);if(!Number.isFinite(D)||D<0||w+D>i.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${i.maxVertices}).`);if(w+=D,k?.min&&k?.max){let _=G=>{for(let Q=0;Q<3;Q++){let le=G[12+Q],Pe=le;for(let ce=0;ce<3;ce++){let pe=G[ce*4+Q]*k.min[ce],fe=G[ce*4+Q]*k.max[ce];le+=pe<fe?pe:fe,Pe+=pe>fe?pe:fe}le<y[Q]&&(y[Q]=le),Pe>p[Q]&&(p[Q]=Pe)}};if(R.instanceMatrices&&R.instanceMatrices.length>=16){let G=R.instanceMatrices.length>>4,Q=X();for(let le=0;le<G;le++)J(Q,U,R.instanceMatrices.subarray(le*16,le*16+16)),_(Q)}else _(U)}let B=Ce(t,s,n,c.attributes.POSITION,0,3,I),W=Ce(t,s,n,c.attributes.NORMAL,1,3,I),Y=Ce(t,s,n,c.attributes.TEXCOORD_0,2,2,I,ct(s,c)),q=0,ae=5123,ie=null;if(c.indices!==void 0){let _=s.accessors[c.indices],G=(s.bufferViews[_.bufferView].byteOffset||0)+(_.byteOffset||0);if(q=Number(_.count??0),!Number.isFinite(q)||q<0||T+q>i.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${i.maxIndices}).`);T+=q,ae=_.componentType===5125?5125:5123;let Q=t.createBuffer();I.push(Q),t.bindBuffer(34963,Q),_.componentType===5125?ie=new Uint32Array(n,G,_.count):_.componentType===5121?ie=Uint16Array.from(new Uint8Array(n,G,_.count)):ie=G%2===0?new Uint16Array(n,G,_.count):new Uint16Array(n.slice(G,G+_.count*2)),t.bufferData(34963,ie,35044)}else q=k.count;let ne={};for(let _ of $)if(_.onBuildPrimitiveVAO){let G=_.onBuildPrimitiveVAO(t,F,c,s,n);G&&(ne[_.name]=G)}t.bindVertexArray(null);let ee=s.materials&&c.material!==void 0?s.materials[c.material]:null,{program:z,uniforms:j}=He(t,c,ee),Z=Ge(ee,b),re=!!(ee?.extensions?.KHR_materials_transmission||ne.materials?.isTransmissive),te=c.extensions?.KHR_materials_variants?.mappings,oe=Array.isArray(te)?te.filter(_=>_&&typeof _.material=="number"&&Array.isArray(_.variants)).map(_=>({material:_.material|0,variants:_.variants.map(G=>Number(G)|0)})):void 0;R.primitives.push({vao:F,instanced:O,indexCount:q,indexType:ae,...Z,positions:B,normals:W,uvs:Y,indices:ie,buffers:I,materialIndex:c.material,defaultMaterialIndex:c.material,variantMappings:oe,primitiveDef:c,programCache:new Map([[c.material??-1,{program:z,uniforms:j}]]),pluginData:ne,customProgram:z,customUniforms:j,isTransmissive:re})}l.push(R)}isFinite(y[0])||(y=[-1,-1,-1]),isFinite(p[0])||(p=[1,1,1]);let A=[(y[0]+p[0])/2,(y[1]+p[1])/2,(y[2]+p[2])/2],x=Math.max(Math.hypot(p[0]-y[0],p[1]-y[1],p[2]-y[2])/2,.5),N=[...y],S=[...p],E=e.animations;if(e.animationsParsed===!1||!E){for(let P of $)if(P.onParseGLB?.(e),e.animations){E=e.animations;break}}return E||(E=[]),{meshes:l,bounds:{center:A,radius:x,min:N,max:S},lights:f,animations:E,worldMatrices:m,gpuTextures:b,availableVariants:h}}function we(){return typeof performance<"u"?performance.now():Date.now()}function de(t){let e=t.customTarget||t.bounds.center,i=t.currDistance*Math.cos(t.currPhi);return[e[0]+i*Math.sin(t.currTheta),e[1]+t.currDistance*Math.sin(t.currPhi),e[2]+i*Math.cos(t.currTheta)]}var se=class{constructor(t,e,i){this.supportsInstanceOffsets=!0,this.meshes=[],this.backdropMeshes=[],this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]},this.lights=[],this.modelRootMatrix=X(),this.clearColor=[0,0,0,0],this.envIntensity=1,this.exposure=1,this.shadowIntensity=0,this.shadowSoftness=.5,this.toneMapping="neutral",this.environmentTexture=null,this.environmentSource=null,this.animations=[],this.currentClip=null,this.animationTime=0,this.isPlayingAnimation=!1,this.autoplay=!1,this.animationName="",this.gpuTextures=[],this.availableVariants=[],this.activeVariantName=null,this.gltf=null,this.worldMatrices=[],this.initialNodeTransforms=[],this.projMatrix=X(),this.viewMatrix=X(),this.activeViewMatrix=null,this.modelMatrix=X(),this.mvpMatrix=X(),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.selectedMeshNames=new Set,this.pickFbo=null,this.pickTexture=null,this.pickDepth=null,this.pickFboWidth=0,this.pickFboHeight=0,this.animFrameId=null,this.isVisible=!0,this.xrSessionActive=!1,this.lastTime=0,this.lastReportedTheta=-999,this.lastReportedPhi=-999,this.lastReportedZoom=-999,this.boundPointerDown=null,this.boundPointerMove=null,this.boundPointerUp=null,this.boundWheel=null,this.boundKeyDown=null,this.boundContextMenu=null,this.boundSetCamera=null,this.boundResetCamera=null,this.contextLost=!1,this.lastGlbData=null,this.boundContextLost=null,this.boundContextRestored=null,this.stereoSBS=!1,this.renderErrorReported=!1,this.xrDepthState={enabled:!1,texture:null,uvTransform:X(),rawValueToMeters:.001,format:0},this.container=t;let r,a;if(e&&typeof e.getContext=="function"?(r=e,a=i):(a=e,r=a?.canvas),!r){let l=t.querySelector("canvas");l||(l=document.createElement("canvas"),l.style.cssText="width:100%;height:100%;display:block;touch-action:none",t.prepend(l)),r=l}this.canvas=r;let s=this.opts=a||{};s.clearColor&&(this.clearColor=s.clearColor);let o=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;s.autoRotate!==void 0?this.autoRotate=s.autoRotate&&!o:o&&(this.autoRotate=!1),s.autoRotateSpeed!==void 0&&(this.autoRotateSpeed=s.autoRotateSpeed),s.autoRotateDelay!==void 0&&(this.autoRotateDelay=Math.max(0,Number(s.autoRotateDelay)||0)),s.exposure!==void 0&&(this.exposure=Re(s.exposure)),s.camera&&this.setInitialCamera(s.camera.theta,s.camera.phi,s.camera.distance,s.camera.zoom),(s.shadowIntensity!==void 0||s.shadowSoftness!==void 0)&&this.setShadow(s.shadowIntensity??0,s.shadowSoftness),s.shadowMaps!==void 0&&(this.shadowMaps=s.shadowMaps),s.toneMapping!==void 0&&(this.toneMapping=me(s.toneMapping)),s.autoplay!==void 0&&(this.autoplay=s.autoplay),s.animationName!==void 0&&(this.animationName=s.animationName),s.variantName!==void 0&&(this.activeVariantName=s.variantName||null),s.fieldOfView!==void 0&&(this.fov=s.fieldOfView*Math.PI/180),s.distanceMode!==void 0&&(this.distanceMode=s.distanceMode),s.cameraTarget!==void 0&&(this.setTarget(s.cameraTarget[0],s.cameraTarget[1],s.cameraTarget[2]),this.initialCustomTarget=[...s.cameraTarget]),(s.minCameraOrbit||s.maxCameraOrbit)&&this.setOrbitLimits({minTheta:s.minCameraOrbit?.theta,maxTheta:s.maxCameraOrbit?.theta,minPhi:s.minCameraOrbit?.phi,maxPhi:s.maxCameraOrbit?.phi,minDistance:s.minCameraOrbit?.distance,maxDistance:s.maxCameraOrbit?.distance});let n=r.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!n)throw new Error("WebGL2 not supported");this.gl=n,this.initGlState(),this.setupEvents(),this.setupContextLossHandling(),s.environmentImage&&this.setEnvironmentImage(s.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&s.autoStart!==!1&&this.start()}static registerDecoder(t,e){it(t,e)}static getDecoder(t){return xe(t)}setupContextLossHandling(){let t=this.canvas;typeof t?.addEventListener=="function"&&(this.boundContextLost=e=>{e.preventDefault?.(),this.contextLost=!0,this.stop()},this.boundContextRestored=()=>this.restoreContext(),t.addEventListener("webglcontextlost",this.boundContextLost),t.addEventListener("webglcontextrestored",this.boundContextRestored))}initGlState(){let t=this.gl,e=Ae();this.renderProg=ve(t,Se,e.fs),this.pickProg=ve(t,ot,nt),this.uRender=ye(t,this.renderProg,e.uniforms),this.uPick=ye(t,this.pickProg,["uMVP","uColorId"]),this.setupPickingFbo()}recompileRenderProgram(){if(this.contextLost)return;let t=this.gl,e=Ae();this.renderProg&&t.deleteProgram(this.renderProg),this.renderProg=ve(t,Se,e.fs),this.uRender=ye(t,this.renderProg,e.uniforms);for(let i of this.meshes)for(let r of i.primitives)r.customProgram&&(t.deleteProgram(r.customProgram),r.programCache?.clear(),this.applyPrimitiveProgram(r,r.materialIndex,this.gltf?.materials?.[r.materialIndex??-1]??null))}restoreContext(){let t=this.gl;this.contextLost=!1,this.initGlState();for(let e of $)e.onContextRestored?.(t,this);this.meshes=[],this.gpuTextures=[],this.environmentTexture=null,this.lastGlbData&&this.loadGLBData(this.lastGlbData,this.lastLimits),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}setupPickingFbo(){let t=this.gl;typeof t.createFramebuffer=="function"&&(this.pickFbo=t.createFramebuffer(),this.pickTexture=t.createTexture(),this.pickDepth=t.createRenderbuffer(),this.resizePickingFbo(this.canvas.width,this.canvas.height),t.bindFramebuffer(36160,this.pickFbo),t.framebufferTexture2D(36160,36064,3553,this.pickTexture,0),t.framebufferRenderbuffer(36160,36096,36161,this.pickDepth),t.bindFramebuffer(36160,null))}resizePickingFbo(t,e){if(!this.pickFbo)return;let i=this.gl,r=Math.max(1,t),a=Math.max(1,e);this.pickFboWidth=r,this.pickFboHeight=a,i.bindTexture(3553,this.pickTexture),i.texImage2D(3553,0,6408,r,a,0,6408,5121,null),i.texParameteri(3553,10241,9728),i.texParameteri(3553,10240,9728),i.bindRenderbuffer(36161,this.pickDepth),i.renderbufferStorage(36161,33189,r,a)}loadGLBData(t,e){let{meshes:i,bounds:r,lights:a,animations:s,worldMatrices:o,gpuTextures:n,availableVariants:l}=We(this.gl,t,e,()=>this.render());this.lastGlbData=t,this.lastLimits=e,this.disposeMeshGpuResources(),this.currentClip=null,this.isPlayingAnimation=!1,this.animationTime=0,this.meshes=i,this.bounds=r,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=a,this.animations=s||[],this.worldMatrices=o||[],this.gpuTextures=n||[],this.availableVariants=l||[],this.gltf=t.gltf,this.activeVariantName&&!this.applyVariantMaterial(this.activeVariantName)&&(this.activeVariantName=null),this.initialNodeTransforms=(t.gltf?.nodes||[]).map(m=>({t:[m.translation?.[0]??0,m.translation?.[1]??0,m.translation?.[2]??0],r:[m.rotation?.[0]??0,m.rotation?.[1]??0,m.rotation?.[2]??0,m.rotation?.[3]??1],s:[m.scale?.[0]??1,m.scale?.[1]??1,m.scale?.[2]??1]})),this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let m of $)m.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 h=t.exposure??t.gltf?.extras?.exposure??t.gltf?.asset?.extras?.exposure;h!==void 0&&(this.exposure=Re(h));let u=t.environmentIntensity??t.gltf?.extras?.environmentIntensity??t.gltf?.asset?.extras?.environmentIntensity;u!==void 0&&(this.envIntensity=Math.max(0,Number(u)||0)),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(t){this.loadGLBData(Ue(t))}clearScene(){this.disposeMeshGpuResources(),this.lights=[],this.animations=[],this.currentClip=null,this.isPlayingAnimation=!1,this.animationTime=0,this.lastGlbData=null;for(let t of $)t.onClearScene?.(this);this.worldMatrices=[],this.gltf=null,this.initialNodeTransforms=[],this.turntableRotation=0,this.updateTurntableMatrix(),this.gl&&this.render()}loadModel(t){this.loadGLBData(be(t))}setBackdropGLB(t,e){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!t){this.update(0),this.render();return}let i=be(t),{meshes:r}=We(this.gl,i,ze,()=>this.render());if(e)for(let a of r)a.transform[12]+=e[0],a.transform[13]+=e[1],a.transform[14]+=e[2],ue(a.normalMatrix,a.transform);this.backdropMeshes=r,this.update(0),this.render()}setClearColor(t,e,i,r=1){this.clearColor=[t,e,i,r]}updateMeshTransforms(t){for(let e=0;e<this.meshes.length;e++){let i=this.meshes[e],r=t instanceof Map?t.get(i.name)??t.get(e):Array.isArray(t)?t[e]:t&&typeof t=="object"?Object.prototype.hasOwnProperty.call(t,i.name)?t[i.name]:Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0:void 0;r&&r.length===16&&(i.transform.set(r),ue(i.normalMatrix,i.transform))}}bindLights(t=this.uRender){let e=this.gl,i=[.28,.28,.28],r=[0,0,0,0,0,0,0,1,0],a=!1,s=[],o=[],n=[],l=[],h=[],u=[];for(let m of this.lights){let v=m.color||[1,1,1],d=m.intensity!==void 0?m.intensity:1;if(m.type==="ambient")i=[v[0]*d,v[1]*d,v[2]*d];else if(m.type==="hemisphere"){a=!0;let f=m.groundColor||[.2,.2,.2],g=d*.65;for(let p=0;p<3;p++)r[p]+=v[p]*g,r[p+3]+=f[p]*g;let b=m.position||[0,1,0],y=Math.hypot(b[0],b[1],b[2]);y>1e-5&&(r[6]=b[0]/y,r[7]=b[1]/y,r[8]=b[2]/y)}else if(m.type==="directional"&&s.length<6){let f=m.direction||[.5,1,.8];s.push(f[0],f[1],f[2]),o.push(v[0]*d,v[1]*d,v[2]*d)}else if((m.type==="point"||m.type==="spot")&&n.length<6){let f=m.position||[0,0,0];if(n.push(f[0],f[1],f[2]),l.push(v[0]*d,v[1]*d,v[2]*d),m.type==="spot"){let g=m.direction||[0,-1,0],b=Math.max(.01,Math.min(Math.PI/2,m.outerConeAngle??Math.PI/3)),y=Math.max(0,Math.min(b-1e-4,m.innerConeAngle??0));h.push(g[0],g[1],g[2]),u.push(Math.cos(y),Math.cos(b))}else h.push(0,-1,0),u.push(-2,-3)}}s.length===0&&!a&&(s.push(.5,1,.8),o.push(1,1,1)),e.uniform3fv(t.uAmbientColor,i),t.uHemi&&e.uniformMatrix3fv(t.uHemi,!1,r),e.uniform1i(t.uNumDirLights,s.length/3),s.length>0&&(e.uniform3fv(t.uDirLightDir,s),e.uniform3fv(t.uDirLightColor,o)),e.uniform1i(t.uNumPointLights,n.length/3),n.length>0&&(e.uniform3fv(t.uPointLightPos,n),e.uniform3fv(t.uPointLightColor,l),t.uPointLightSpotDir&&e.uniform3fv(t.uPointLightSpotDir,h),t.uPointLightSpotCone&&e.uniform2fv(t.uPointLightSpotCone,u)),e.uniform1f(t.uEnvIntensity,this.envIntensity)}setExposure(t){this.exposure=Re(t)}getExposure(){return this.exposure}setShadow(t,e){this.shadowIntensity=Math.max(0,Math.min(1,Number(t)||0)),e!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(e)||0)))}getShadowIntensity(){return this.shadowIntensity}getShadowSoftness(){return this.shadowSoftness}setToneMapping(t){this.toneMapping=me(t)}getToneMapping(){return this.toneMapping}async setEnvironmentImage(t){this.environmentSource=t&&typeof t=="object"?t:null;for(let e of $)if(e.setEnvironmentImage){await e.setEnvironmentImage(this,t),this.render();return}this.render()}async setSkyboxImage(t){for(let e of $)if(e.setSkyboxImage){await e.setSkyboxImage(this,t);return}}setInteractive(t){this.interactive=t}isInteractive(){return this.interactive}getCameraOrbit(){let t=this.currTheta,e=this.currPhi,i=this.currDistance;return{theta:t,phi:e,radius:i,toString(){return`${t.toFixed(4)}rad ${e.toFixed(4)}rad ${i.toFixed(4)}m`}}}getCameraTarget(){let t=this.customTarget||this.bounds.center;return{x:t[0],y:t[1],z:t[2],toString(){return`${t[0].toFixed(4)}m ${t[1].toFixed(4)}m ${t[2].toFixed(4)}m`}}}jumpCameraToGoal(){this.currTheta=this.targetTheta,this.currPhi=this.targetPhi,this.currDistance=this.targetDistance,this.update(0),this.render()}getModelMaterials(){let t=this.gltf?.materials?.length?this.gltf.materials:[{name:"DefaultMaterial",pbrMetallicRoughness:{}}];return t.map((e,i)=>{let r=this.meshes.flatMap(u=>u.primitives.filter(m=>m.materialIndex===i||t.length===1&&m.materialIndex===void 0)),a=r[0],s=a?[...a.baseColor]:e.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],o=a?a.metallic:e.pbrMetallicRoughness?.metallicFactor??.1,n=a?a.roughness:e.pbrMetallicRoughness?.roughnessFactor??.5,l=(u,m,v)=>{h[u]=v,e.pbrMetallicRoughness&&(e.pbrMetallicRoughness[u]=v);for(let d of r)d[m]=v;this.render()},h={baseColorFactor:s,metallicFactor:o,roughnessFactor:n,setBaseColorFactor:u=>l("baseColorFactor","baseColor",[u[0],u[1],u[2],u[3]??1]),setMetallicFactor:u=>l("metallicFactor","metallic",u),setRoughnessFactor:u=>l("roughnessFactor","roughness",u)};return{name:e.name||`Material_${i}`,pbrMetallicRoughness:h}})}playAnimation(t){if(this.animations.length!==0){if(t){let e=this.animations.find(i=>i.name===t);e&&(this.currentClip=e)}else this.currentClip||(this.currentClip=this.animations[0]);this.isPlayingAnimation=!0}}pauseAnimation(){this.isPlayingAnimation=!1}getAvailableAnimations(){return this.animations.map(t=>t.name)}getAvailableVariants(){return[...this.availableVariants]}getVariantName(){return this.activeVariantName}selectVariant(t){let e=this.applyVariantMaterial(t);return e&&this.gl&&this.render(),e}applyVariantMaterial(t){let e=t===null||t==="",i=-1;if(e)this.activeVariantName=null;else{if(i=this.availableVariants.indexOf(t),i<0)return!1;this.activeVariantName=t}let r=this.gltf?.materials;if(!Array.isArray(r))return e;for(let a of this.meshes)for(let s of a.primitives){let o=s.defaultMaterialIndex;if(!e&&Array.isArray(s.variantMappings)){for(let l of s.variantMappings)if(Array.isArray(l.variants)&&l.variants.includes(i)){o=l.material;break}}let n=o!==void 0?r[o]:void 0;s.materialIndex=n?o:void 0,Object.assign(s,Ge(n,this.gpuTextures)),this.applyPrimitiveProgram(s,s.materialIndex,n??null)}return!0}applyPrimitiveProgram(t,e,i){if(!this.gl||!t.primitiveDef)return;t.programCache??(t.programCache=new Map);let r=e??-1,a=t.programCache.get(r);a||(a=He(this.gl,{...t.primitiveDef,material:e},i),t.programCache.set(r,a)),t.customProgram=a.program,t.customUniforms=a.uniforms,t.pluginData&&(t.pluginData.materials=t.isTransmissive?{isTransmissive:!0}:void 0)}setAutoplay(t){this.autoplay=t,t?this.playAnimation(this.animationName||void 0):this.pauseAnimation()}setAnimationName(t){this.animationName=t,(this.isPlayingAnimation||this.autoplay)&&this.playAnimation(t)}evaluateAnimation(t){for(let e of $)if(e.evaluateAnimation){e.evaluateAnimation(this,t);return}}setTarget(t,e,i){this.customTarget=[t,e,i],this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}getTarget(){return this.customTarget?[...this.customTarget]:null}setFieldOfView(t){let e=Math.max(10,Math.min(90,t));this.fov=e*Math.PI/180}getFieldOfView(){return this.fov*180/Math.PI}setDistanceMode(t){if(this.distanceMode=t,!this.customDistance){let e=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=e,this.targetDistance=e,this.currDistance=e,this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}}getDistanceMode(){return this.distanceMode}setOrbitLimits(t){let e=Math.PI/180,i=Math.PI*.48;t.minTheta!==void 0&&(this.minTheta=t.minTheta*e),t.maxTheta!==void 0&&(this.maxTheta=t.maxTheta*e),t.minPhi!==void 0&&(this.minPhi=Math.max(-i,t.minPhi*e)),t.maxPhi!==void 0&&(this.maxPhi=Math.min(i,t.maxPhi*e)),t.minDistance!==void 0&&(this.minDistanceLimit=t.minDistance),t.maxDistance!==void 0&&(this.maxDistanceLimit=t.maxDistance),this.targetTheta=this.clampTheta(this.targetTheta),this.targetPhi=this.clampPhi(this.targetPhi),this.targetDistance=this.clampDistance(this.targetDistance)}getOrbitLimits(){let t=180/Math.PI;return{minTheta:isFinite(this.minTheta)?this.minTheta*t:void 0,maxTheta:isFinite(this.maxTheta)?this.maxTheta*t:void 0,minPhi:this.minPhi*t,maxPhi:this.maxPhi*t,minDistance:this.minDistanceLimit??void 0,maxDistance:this.maxDistanceLimit??void 0}}clampTheta(t){return Math.max(this.minTheta,Math.min(this.maxTheta,t))}clampPhi(t){return Math.max(this.minPhi,Math.min(this.maxPhi,t))}clampDistance(t){let e=this.bounds?.radius;return Math.max(this.minDistanceLimit??(e?e*.5:.1),Math.min(this.maxDistanceLimit??(e?e*8:100),t))}setCamera(t,e,i,r){t!==void 0&&(this.targetTheta=this.clampTheta(t*Math.PI/180)),e!==void 0&&(this.targetPhi=this.clampPhi(e*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(t,e,i,r){t!==void 0&&(this.initialTheta=this.targetTheta=this.currTheta=this.clampTheta(t*Math.PI/180)),e!==void 0&&(this.initialPhi=this.targetPhi=this.currPhi=this.clampPhi(e*Math.PI/180));let a=i!==void 0&&i>0?i:r!==void 0&&r>0?this.bounds.radius*2.5/r:null;this.customDistance=a!==null,this.initialDistance=this.targetDistance=this.currDistance=this.clampDistance(a??(this.distanceMode==="absolute"?3:this.bounds.radius*2.5)),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.targetDistance=this.clampDistance(this.initialDistance??this.bounds.radius*2.5),this.customTarget=this.initialCustomTarget?[...this.initialCustomTarget]:null,this.turntableRotation=0,this.updateTurntableMatrix()}projectPointToScreen(t,e){let i=X();J(i,this.projMatrix,this.viewMatrix);let r=(S,E,P=1)=>[S[0]*E[0]+S[4]*E[1]+S[8]*E[2]+S[12]*P,S[1]*E[0]+S[5]*E[1]+S[9]*E[2]+S[13]*P,S[2]*E[0]+S[6]*E[1]+S[10]*E[2]+S[14]*P,S[3]*E[0]+S[7]*E[1]+S[11]*E[2]+S[15]*P],a=this.modelRootMatrix,[s,o,n]=a?r(a,t):t,[l,h,u]=e?a?r(a,e,0):e:[0,0,0],[m,v,d,f]=r(i,[s,o,n]);if(f<=1e-4)return{x:0,y:0,z:1,visible:!1};let g=m/f,b=v/f,y=d/f,p=this.canvas.getBoundingClientRect(),w=p.width||this.canvas.clientWidth||this.canvas.width||300,T=p.height||this.canvas.clientHeight||this.canvas.height||150,A=(g*.5+.5)*w,x=(-b*.5+.5)*T,N=g>=-1.1&&g<=1.1&&b>=-1.1&&b<=1.1&&y>=-1&&y<=1;if(N&&e){let[S,E,P]=de(this),C=[s-S,o-E,n-P];l*C[0]+h*C[1]+u*C[2]>.05&&(N=!1)}return{x:A,y:x,z:y,visible:N}}setSelectedMesh(t){this.setSelectedMeshes([t])}setSelectedMeshes(t){this.selectedMeshNames=new Set(t.filter(Boolean))}getSelectedMesh(){return[...this.selectedMeshNames][0]||""}setupEvents(){let t=this.canvas,e=we;this.boundContextMenu=i=>{i.preventDefault()},t.addEventListener("contextmenu",this.boundContextMenu),this.boundPointerDown=i=>{this.interactive&&(this.isPointerDown=!0,this.lastInteractionTime=e(),this.lastPointerX=i.clientX,this.lastPointerY=i.clientY,this.totalDragDist=0,this.activePointers.set(i.pointerId,{x:i.clientX,y:i.clientY}),this.isPanning=i.button===2||i.shiftKey||this.activePointers.size===2,t.setPointerCapture(i.pointerId))},t.addEventListener("pointerdown",this.boundPointerDown),this.boundPointerMove=i=>{if(!this.isPointerDown||!this.interactive)return;this.lastInteractionTime=e();let r=this.activePointers.get(i.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},a=i.clientX-r.x,s=i.clientY-r.y;if(this.activePointers.set(i.pointerId,{x:i.clientX,y:i.clientY}),this.lastPointerX=i.clientX,this.lastPointerY=i.clientY,this.totalDragDist+=Math.hypot(a,s),this.isPanning||i.button===2||i.shiftKey||this.activePointers.size===2){let o=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],n=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],l=this.customTarget?[...this.customTarget]:[...this.bounds.center],h=this.currDistance/Math.max(t.clientHeight||300,1)*1.5;l[0]+=(-a*o[0]+s*n[0])*h,l[1]+=(-a*o[1]+s*n[1])*h,l[2]+=(-a*o[2]+s*n[2])*h,this.customTarget=l}else this.targetTheta=this.clampTheta(this.targetTheta-a*.008),this.targetPhi=this.clampPhi(this.targetPhi+s*.008)},t.addEventListener("pointermove",this.boundPointerMove),this.boundPointerUp=i=>{this.lastInteractionTime=e(),this.activePointers.delete(i.pointerId),this.activePointers.size===0?(this.isPointerDown=!1,this.isPanning=!1):this.activePointers.size===1&&(this.isPanning=!1);try{t.releasePointerCapture(i.pointerId)}catch{}if(this.totalDragDist<5&&i.button===0){let r=t.getBoundingClientRect(),a=Math.floor((i.clientX-r.left)*(t.width/Math.max(r.width,1))),s=Math.floor((i.clientY-r.top)*(t.height/Math.max(r.height,1)));this.performMeshPick(a,s,!0)}},t.addEventListener("pointerup",this.boundPointerUp),this.boundWheel=i=>{if(!this.interactive)return;i.preventDefault(),this.lastInteractionTime=e();let r=Math.exp(i.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*r)},t.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=i=>{let r=i.detail||{};r.reset?this.resetCamera():this.setCamera(r.theta,r.phi,r.distance,r.zoom)},this.container.addEventListener("setCamera",this.boundSetCamera),this.boundResetCamera=()=>{this.resetCamera()},this.container.addEventListener("resetCamera",this.boundResetCamera),t.tabIndex!==void 0&&t.tabIndex<0&&(t.tabIndex=0),t.getAttribute?.("role")||t.setAttribute?.("role","region"),t.getAttribute?.("aria-label")||t.setAttribute?.("aria-label","Interactive 3D model viewport"),this.boundKeyDown=i=>{if(this.interactive){switch(i.key){case"ArrowLeft":this.targetTheta=this.clampTheta(this.targetTheta-.1);break;case"ArrowRight":this.targetTheta=this.clampTheta(this.targetTheta+.1);break;case"ArrowUp":this.targetPhi=this.clampPhi(this.targetPhi+.08);break;case"ArrowDown":this.targetPhi=this.clampPhi(this.targetPhi-.08);break;case"+":case"=":this.targetDistance=this.clampDistance(this.targetDistance*.9);break;case"-":case"_":this.targetDistance=this.clampDistance(this.targetDistance*1.1);break;case"Home":this.resetCamera();break;default:return}this.lastInteractionTime=e(),i.preventDefault()}},t.addEventListener("keydown",this.boundKeyDown)}teardownEvents(){let t=(i,r,a)=>{this[a]&&(i.removeEventListener(r,this[a]),this[a]=null)},e=this.canvas;for(let[i,r]of[["webglcontextlost","boundContextLost"],["webglcontextrestored","boundContextRestored"],["contextmenu","boundContextMenu"],["pointerdown","boundPointerDown"],["pointermove","boundPointerMove"],["pointerup","boundPointerUp"],["wheel","boundWheel"],["keydown","boundKeyDown"]])t(e,i,r);t(this.container,"setCamera","boundSetCamera"),t(this.container,"resetCamera","boundResetCamera")}raycastFromScreenPoint(t,e){let i=this.canvas,r=i.getBoundingClientRect(),a=i.width||300,s=i.height||300,o=r.width>0?Math.floor((t-r.left)*(a/r.width)):Math.floor(t),n=r.height>0?Math.floor((e-r.top)*(s/r.height)):Math.floor(e);return this.performMeshPick(o,n,!1)}performMeshPick(t,e,i=!0){if(this.meshes.length===0)return null;let r=this.gl,a=Math.max(1,this.canvas.width||300),s=Math.max(1,this.canvas.height||300);t=this.mapStereoPickX(t,a);let o=X();J(o,this.projMatrix,this.viewMatrix);let n=[],l=Math.max(0,Math.min(a-1,t)),h=Math.max(0,Math.min(s-1,s-1-e));if(this.pickFbo&&r&&!this.xrSessionActive){(this.pickFboWidth!==a||this.pickFboHeight!==s)&&this.resizePickingFbo(a,s),r.bindFramebuffer(36160,this.pickFbo),r.viewport(0,0,a,s),r.enable(2929),r.clearColor(0,0,0,0),r.clear(16640),r.useProgram(this.pickProg);for(let A=0;A<this.meshes.length;A++){let x=this.meshes[A];if(x.visible===!1||x.isPluginMesh)continue;let N=A+1,S=(N&255)/255,E=(N>>8&255)/255,P=(N>>16&255)/255;r.uniform4f(this.uPick.uColorId,S,E,P,1),J(this.modelMatrix,this.modelRootMatrix,x.transform);let C=x.instanceMatrices;if(C&&C.length>=16){let V=C.length>>4,U=X();for(let L of x.primitives){r.bindVertexArray(L.vao);for(let M=0;M<V;M++)J(U,this.modelMatrix,C.subarray(M*16,M*16+16)),J(this.mvpMatrix,o,U),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix),Me(r,L)}}else{J(this.mvpMatrix,o,this.modelMatrix),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let V of x.primitives)r.bindVertexArray(V.vao),Me(r,V)}}let w=new Uint8Array(4);r.readPixels(l,h,1,1,6408,5121,w),r.bindFramebuffer(36160,null);let T=w[0]+(w[1]<<8)+(w[2]<<16);T>0&&T<=this.meshes.length&&(n=[this.meshes[T-1]])}n.length===0&&(n=this.meshes.filter(w=>w.visible!==!1));let u=null,m=1/0,v=[0,0,0],d=[0,1,0],[f,g,b]=de(this),y=X();for(let w of n){J(y,this.modelRootMatrix,w.transform);let T=w.instanceMatrices,A=T&&T.length>=16?T.length>>4:1;for(let x=0;x<A;x++){T&&T.length>=16?J(this.modelMatrix,y,T.subarray(x*16,x*16+16)):this.modelMatrix.set(y),J(this.mvpMatrix,o,this.modelMatrix);let N=X();if(!Qe(N,this.mvpMatrix))continue;let S=(l+.5)/a*2-1,E=(h+.5)/s*2-1,P=[0,0,0],C=[0,0,0];Fe(P,S,E,-1,N),Fe(C,S,E,1,N);let V=C[0]-P[0],U=C[1]-P[1],L=C[2]-P[2],M=Math.hypot(V,U,L)||1,R=V/M,H=U/M,c=L/M,I={distance:1/0,point:[0,0,0],normal:[0,1,0]};for(let F of w.primitives){if(!F.positions)continue;let O=F.positions,k=F.indices,D=Math.floor(k?k.length/3:O.length/9);for(let B=0;B<D;B++){let W=(k?k[B*3]:B*3)*3,Y=(k?k[B*3+1]:B*3+1)*3,q=(k?k[B*3+2]:B*3+2)*3;Je(P[0],P[1],P[2],R,H,c,O[W],O[W+1],O[W+2],O[Y],O[Y+1],O[Y+2],O[q],O[q+1],O[q+2],I,1e-4)}}if(isFinite(I.distance)){let F=I.point[0],O=I.point[1],k=I.point[2],D=this.modelMatrix,B=D[0]*F+D[4]*O+D[8]*k+D[12],W=D[1]*F+D[5]*O+D[9]*k+D[13],Y=D[2]*F+D[6]*O+D[10]*k+D[14],q=B-f,ae=W-g,ie=Y-b,ne=Math.hypot(q,ae,ie);if(ne<m){ue(this.normalMatrix,this.modelMatrix);let ee=this.normalMatrix,z=I.normal[0],j=I.normal[1],Z=I.normal[2],re=ee[0]*z+ee[3]*j+ee[6]*Z,te=ee[1]*z+ee[4]*j+ee[7]*Z,oe=ee[2]*z+ee[5]*j+ee[8]*Z,_=Math.hypot(re,te,oe)||1;re/=_,te/=_,oe/=_,re*q+te*ae+oe*ie>0&&(re=-re,te=-te,oe=-oe);let G=Q=>Math.round(Q*1e3)/1e3;u=w,m=G(ne),v=[G(B),G(W),G(Y)],d=[G(re),G(te),G(oe)]}}}}if(!u)return null;let p={meshIndex:this.meshes.indexOf(u),meshName:u.name,nodeIndex:u.nodeIndex,distance:m,hitPoint:v,normal:d,screenX:t,screenY:e};if(i){for(let w of $)w.onMeshSelect?.(this,p);this.opts.onMeshClick&&this.opts.onMeshClick(p),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:p}))}return p}mapStereoPickX(t,e){if(!this.stereoSBS||this.xrSessionActive||e<2)return t;let i=Math.max(1,Math.floor(e*.5)),r=t>=i,a=r?t-i:t,s=r?Math.max(1,e-i):i,o=(a+.5)/s*2-1;return Math.floor((o*.5+1)*.5*e)}setStereoSBS(t){this.stereoSBS=!!t,this.xrSessionActive||(this.syncCameraMatrices(),this.render())}syncCameraMatrices(){let t=Math.max(1,this.canvas.width||1)/Math.max(1,this.canvas.height||1),e=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10);ke(this.projMatrix,this.fov,t,.1,e);let i=this.customTarget||this.bounds.center;Ne(this.viewMatrix,de(this),i,[0,1,0]),J(this.mvpMatrix,this.projMatrix,this.viewMatrix),ue(this.normalMatrix,this.modelMatrix)}resize(){let t=Math.min((typeof window<"u"?window.devicePixelRatio:1)||1,2),e=this.canvas.getBoundingClientRect(),i=Math.max(1,Math.floor(e.width*t)),r=Math.max(1,Math.floor(e.height*t));this.canvas.width!==i||this.canvas.height!==r?(this.canvas.width=i,this.canvas.height=r,this.resizePickingFbo(i,r),this.xrSessionActive||this.syncCameraMatrices()):!this.xrSessionActive&&this.projMatrix[0]===0&&this.syncCameraMatrices()}getGLContext(){return this.gl}setXRSessionActive(t){let e=this.xrSessionActive;if(this.xrSessionActive=t,e&&!t){this.xrDepthState.enabled=!1;for(let i of $)i.onXRSessionEnd?.(this);if(this.lastTime=we(),this.updateTurntableMatrix(),this.isVisible)try{this.resize(),this.syncCameraMatrices(),this.render()}catch(i){this.reportRenderError(i)}}}reportRenderError(t){this.renderErrorReported||(this.renderErrorReported=!0,typeof console<"u"&&console.warn("[three-live] render frame failed:",t))}stepXRUpdate(t){for(let e of $)e.onUpdate?.(this,t)}start(){if(this.animFrameId!==null)return;this.lastTime=we();let t=e=>{if(this.animFrameId===null)return;let i=Math.min(Math.max((e-this.lastTime)/1e3,0),.1);if(this.lastTime=e,this.isVisible&&!this.xrSessionActive)try{this.resize(),this.update(i),this.render()}catch(r){this.reportRenderError(r)}this.animFrameId!==null&&(this.animFrameId=requestAnimationFrame(t))};this.animFrameId=requestAnimationFrame(t)}stop(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null)}setAutoRotate(t){this.autoRotate=t}getAutoRotate(){return this.autoRotate}setAutoRotateSpeed(t){this.autoRotateSpeed=t}getAutoRotateSpeed(){return this.autoRotateSpeed}setAutoRotateDelay(t){this.autoRotateDelay=Math.max(0,Number(t)||0)}getAutoRotateDelay(){return this.autoRotateDelay}resetTurntableRotation(t=0){this.turntableRotation=Number(t)||0,this.updateTurntableMatrix(),this.render()}updateTurntableMatrix(){let t=Math.cos(this.turntableRotation),e=Math.sin(this.turntableRotation),[i,,r]=this.bounds.center;this.modelRootMatrix.set([t,0,-e,0,0,1,0,0,e,0,t,0,i-(t*i+e*r),0,r-(-e*i+t*r),1])}setVisible(t){this.isVisible=t}update(t){for(let s of $)s.onUpdate?.(this,t);let e=we();if(!this.isPointerDown&&this.autoRotate&&e-this.lastInteractionTime>=this.autoRotateDelay){this.turntableRotation+=this.autoRotateSpeed*t,this.updateTurntableMatrix();for(let s of $)s.onCameraChange?.(this,this.container)}this.currTheta+=(this.targetTheta-this.currTheta)*.12,this.currPhi+=(this.targetPhi-this.currPhi)*.12,this.currDistance+=(this.targetDistance-this.currDistance)*.12,this.syncCameraMatrices();let i=Math.round((this.currTheta*180/Math.PI%360+360)%360),r=Math.round(this.currPhi*180/Math.PI),a=Math.round(this.bounds.radius*2.5/this.currDistance*100)/100;if(Math.abs(i-this.lastReportedTheta)>=1||Math.abs(r-this.lastReportedPhi)>=1||Math.abs(a-this.lastReportedZoom)>=.02){this.lastReportedTheta=i,this.lastReportedPhi=r,this.lastReportedZoom=a;let s={theta:i,phi:r,zoom:a,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(s),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:s}))}}renderXRView(t,e,i,r,a=!0,s=0){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(t);let o=t?.transform?.inverse?.matrix||this.viewMatrix,n=t?.projectionMatrix||this.projMatrix,l=t?.transform?.position,h=l?[l.x,l.y,l.z]:[0,1.6,0];e&&this.modelRootMatrix.set(e),this.render({viewMatrix:o,projMatrix:n,eyePos:h,viewport:r,eye:t?.eye||"none",clear:s>0?!1:t?.eye!=="right",isAR:a})}render(t){if(this.contextLost)return;if(!t&&this.stereoSBS){let x=Math.max(2,this.canvas.width||2),N=Math.max(1,this.canvas.height||1),S=Math.max(1,Math.floor(x*.5)),E=Math.max(1,x-S),P=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10),C=this.customTarget||this.bounds.center,[V,U,L]=de(this),M=Math.cos(this.currTheta),R=-Math.sin(this.currTheta),H=.032;for(let c of[-1,1]){let I=X(),F=X(),O=c<0?S:E,k=[V+c*M*H,U,L+c*R*H];ke(I,this.fov,O/N,.1,P),Ne(F,k,[C[0]+c*M*H*.25,C[1],C[2]+c*R*H*.25],[0,1,0]),this.render({viewMatrix:F,projMatrix:I,eyePos:k,viewport:[c<0?0:S,0,O,N],eye:c<0?"left":"right",clear:c<0,isAR:!1})}this.gl.viewport(0,0,x,N);return}let e=this.gl,[i,r,a,s]=t?.viewport||[0,0,this.canvas.width,this.canvas.height];if(e.viewport(i,r,a,s),e.enable(2929),!t||t.clear!==!1){let x=t?.isAR?[0,0,0,0]:this.clearColor;e.clearColor(x[0],x[1],x[2],x[3]),e.clear(16640)}let o=X(),n=t?.viewMatrix??this.viewMatrix;this.activeViewMatrix=n;let l=t?.projMatrix??this.projMatrix;J(o,l,n);let h=K(),u=h.xrDepthShader,m=et(this.toneMapping),[v,d,f]=t?t.eyePos:de(this);for(let x of $)x.onBeforeDrawScene?.(this,e,o,[v,d,f],m);let g=t?.isAR?0:this.backdropMeshes.length;if(this.meshes.length===0&&g===0){h.gpuSceneAccelerator?.hideLayer?.(this);return}let b=t?.eye||"none",y=!t||t.clear!==!1;if(!this.xrSessionActive&&h.gpuSceneAccelerator?.renderScene(this,o,l,n,[v,d,f],m,[i,r,a,s],b,y,!!t?.isAR)){y&&!this.skyboxTexture&&(e.clearColor(0,0,0,0),e.clear(16384));for(let x of $)x.name.includes("webgpu")&&x.onAfterRender?.(e,this,o,b,[i,r,a,s],l);return}let p=!1,w=g>0?[...this.backdropMeshes,...this.meshes]:this.meshes,T=(x,N,S,E)=>{N?(e.activeTexture(33984+x),e.bindTexture(3553,N),e.uniform1i(S,x),e.uniform1i(E,1)):e.uniform1i(E,0)},A=x=>{for(let N=0;N<w.length;N++){let S=w[N];if(S.visible===!1)continue;let E=this.selectedMeshNames.has(S.name);if(N<g||S.worldSpace===!0||S.name==="__xr_reticle__")this.modelMatrix.set(S.transform);else{J(this.modelMatrix,this.modelRootMatrix,S.transform);let M=!t&&(S.extras?.xr?.billboard??S.userData?.xr?.billboard);if(M){let R=this.modelMatrix,H=Math.hypot(R[0],R[1],R[2])||1,c=Math.hypot(R[4],R[5],R[6])||1,I=Math.hypot(R[8],R[9],R[10])||1,F=M==="y"||M==="cylindrical"||M==="capsule",O=v-R[12],k=f-R[14],D=Math.hypot(O,k),B=D>1e-5?O/D:0,W=D>1e-5?k/D:1;R.set(F?[W*H,0,-B*H,0,0,c,0,0,B*I,0,W*I]:[n[0]*H,n[4]*H,n[8]*H,0,n[1]*c,n[5]*c,n[9]*c,0,n[2]*I,n[6]*I,n[10]*I])}}J(this.mvpMatrix,o,this.modelMatrix),ue(S.normalMatrix,this.modelMatrix);let P=S.extras?.xr?.stereo||S.userData?.xr?.stereo,C=0,V=0,U=1,L=1;P==="sbs"?(U=.5,C=b==="right"?.5:0):P==="ou"&&(L=.5,V=b==="right"?.5:0);for(let M of S.primitives){let R=!!M.isTransmissive;if(!x&&R){p=!0;continue}if(x&&!R)continue;let H=M.customProgram||this.renderProg,c=M.customUniforms||this.uRender;e.useProgram(H),e.vertexAttrib3f(3,0,0,0),c.uInstanced&&e.uniform1i(c.uInstanced,0),e.uniform1i(c.uToneMapping,m),e.uniform1f(c.uEnvIntensity,this.envIntensity),c.uExposure&&e.uniform1f(c.uExposure,this.exposure),e.uniform3f(c.uCameraPos,v,d,f),e.uniform1f(c.uEmissive,E?1:0),e.uniformMatrix4fv(c.uMVP,!1,this.mvpMatrix),e.uniformMatrix4fv(c.uModel,!1,this.modelMatrix),e.uniformMatrix3fv(c.uNormalMatrix,!1,S.normalMatrix),c.uUvTransform&&e.uniform4f(c.uUvTransform,C,V,U,L),c.uViewportSize&&e.uniform2f(c.uViewportSize,Math.max(1,a),Math.max(1,s)),u?.bind(e,c,this.xrDepthState,n,[i,r,Math.max(1,a),Math.max(1,s)]),h.shadowMapShader?.bind(e,c,this,S),T(4,this.environmentTexture,c.uEnvironmentMap,c.uHasEnvironmentMap),this.bindLights(c),c.uSectionEnabled&&e.uniform1i(c.uSectionEnabled,0);for(let F of $)F.onBeforeDrawPrimitive?.(e,H,M,S,this.worldMatrices||[],this.gltf);e.uniform4fv(c.uBaseColor,M.baseColor),e.uniform1f(c.uMetallic,M.metallic),e.uniform1f(c.uRoughness,M.roughness),c.uClearcoat&&e.uniform2f(c.uClearcoat,M.clearcoat??0,M.clearcoatRoughness??.04),T(0,M.texture,c.uBaseColorTexture,c.uHasTexture),T(1,M.metallicRoughnessTexture,c.uMetallicRoughnessTexture,c.uHasMetallicRoughnessTexture),T(2,M.normalTexture,c.uNormalTexture,c.uHasNormalTexture),M.normalTexture&&e.uniform1f(c.uNormalScale,M.normalScale),T(3,M.occlusionTexture,c.uOcclusionTexture,c.uHasOcclusionTexture),M.occlusionTexture&&e.uniform1f(c.uOcclusionStrength,M.occlusionStrength),e.uniform3fv(c.uEmissiveFactor,M.emissiveFactor),T(8,M.emissiveTexture,c.uEmissiveTexture,c.uHasEmissiveTexture),e.bindVertexArray(M.vao);let I=S.instanceMatrices;if(M.instanceCount!==void 0)e.drawElementsInstanced(4,M.indexCount,M.indexType,0,M.instanceCount);else if(I&&I.length>=16&&M.instanced&&c.uInstanced&&c.uViewProj){let F=I.length>>4;e.uniform1i(c.uInstanced,1),e.uniformMatrix4fv(c.uViewProj,!1,o),M.indices?e.drawElementsInstanced(4,M.indexCount,M.indexType,0,F):e.drawArraysInstanced(4,0,M.indexCount,F),e.uniform1i(c.uInstanced,0)}else if(I&&I.length>=16){let F=I.length>>4,O=S.instanceColors,k=X(),D=new Float32Array(9);for(let B=0;B<F;B++){if(J(k,this.modelMatrix,I.subarray(B*16,B*16+16)),J(this.mvpMatrix,o,k),ue(D,k),e.uniformMatrix4fv(c.uMVP,!1,this.mvpMatrix),e.uniformMatrix4fv(c.uModel,!1,k),e.uniformMatrix3fv(c.uNormalMatrix,!1,D),O){let W=M.baseColor,Y=B*3;e.uniform4fv(c.uBaseColor,[W[0]*O[Y],W[1]*O[Y+1],W[2]*O[Y+2],W[3]])}Me(e,M)}}else Me(e,M)}}};if(A(!1),p){for(let x of $)x.onBeforeTransmissivePass?.(e,this);A(!0)}for(let x of $)x.onAfterRender?.(e,this,o,b,[i,r,a,s],l)}disposeMeshListGpuResources(t,e){je(this.gl,t,e)}disposeMeshGpuResources(){this.disposeMeshListGpuResources(this.meshes,this.gpuTextures),this.meshes=[],this.gpuTextures=[],this.availableVariants=[]}disposeGpuResources(){let t=this.gl;this.disposeMeshGpuResources(),this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[];for(let e of $)e.onDestroy?.(t,this);this.environmentTexture&&(t.deleteTexture(this.environmentTexture),this.environmentTexture=null),this.renderProg&&t.deleteProgram(this.renderProg),this.pickProg&&t.deleteProgram(this.pickProg),this.pickFbo&&t.deleteFramebuffer(this.pickFbo),this.pickTexture&&t.deleteTexture(this.pickTexture),this.pickDepth&&t.deleteRenderbuffer(this.pickDepth),this.pickFbo=null,this.pickTexture=null,this.pickDepth=null}dispose(){this.stop(),this.teardownEvents(),this.disposeGpuResources()}destroy(){this.dispose()}};se.registerPlugin=qe,se.getRegisteredPlugins=Ke;var De=(t,e,i)=>({x:t,y:e,z:i,toString:()=>`${t}m ${e}m ${i}m`}),pt=typeof HTMLElement<"u"?HTMLElement:class{};typeof CustomEvent>"u"&&typeof Event<"u"&&(globalThis.CustomEvent=class extends Event{constructor(t,e){super(t,e),this.detail=e?.detail??null}});var Te=class he extends pt{constructor(){super(...arguments),this.viewer=null,this.canvas=null,this.posterEl=null,this.arButton=null,this.currentModel=null,this.activeXRSession=null,this.toastTimer=null,this.currentModelLimits=void 0,this.isModelLoaded=!1,this.scriptHandle=null,this.loadController=null,this.resizeObserver=null,this.mutationObserver=null}static get sandboxEngineSrc(){return K().sandboxEngineSrc??null}static set sandboxEngineSrc(e){K().sandboxEngineSrc=e}static get sandboxIframeSrc(){return K().sandboxIframeSrc??null}static set sandboxIframeSrc(e){K().sandboxIframeSrc=e}static get allowClientScripts(){return!!K().allowClientScripts}static set allowClientScripts(e){K().allowClientScripts=e}static registerScriptRunner(e){K().scriptRunner=e}static defineModelViewer(e="model-viewer"){if(typeof customElements>"u")return!1;let i=customElements.get(e);return i!=null?i===he||i.prototype instanceof he:(customElements.define(e,class extends he{}),!0)}static registerDecoder(e,i){se.registerDecoder(e,i)}static getDecoder(e){return se.getDecoder(e)}static registerAR(e){K().arProvider=typeof e=="function"?{activateAR:e}:e,typeof document<"u"&&document.querySelectorAll("three-live").forEach(i=>{i instanceof he&&i.updateARButtonVisibility()})}static isARSupported(){return!!K().arProvider}getLoadedModel(){return this.currentModel}beginLoad(){let e=this.loadController,i=this.scriptHandle,r=new AbortController;return this.loadController=r,this.scriptHandle=null,e?.abort(),i?.terminate(),r}connectedCallback(){if(typeof document>"u")return;(!this.style.display||this.style.display==="inline")&&(this.style.display="block"),getComputedStyle(this).position==="static"&&(this.style.position="relative"),this.style.overflow="hidden",this.setupDOM(),this.initViewer(),this.setupResizeObserver();let e=this.getAttribute("src"),i=this.getAttribute("script-src");e?this.loadModel(e).catch(()=>{}):i?this.loadScriptFromSrc(i).catch(()=>{}):this.scheduleInlineScript();for(let r of se.getRegisteredPlugins())r.onElementConnected?.(this)}scheduleInlineScript(){let e=this.loadController,i=()=>{let r=this.querySelector('script[type="text/three"], script[type="text/three-live"]');return this.loadController===e&&r?.textContent?(this.executeScript(r.textContent).catch(()=>{}),!0):!1};queueMicrotask(()=>i()||document.addEventListener("DOMContentLoaded",i))}disconnectedCallback(){for(let e of se.getRegisteredPlugins())e.onElementDisconnected?.(this);this.beginLoad().abort(),this.mutationObserver?.disconnect(),this.mutationObserver=null,this.resizeObserver?.disconnect(),this.resizeObserver=null,this.activeXRSession?.stop?.().catch?.(()=>{}),this.activeXRSession=null,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=null,this.viewer?.destroy(),this.viewer=null,this.isModelLoaded=!1}attributeChangedCallback(e,i,r){if(i===r)return;let a=this.viewer;switch(e){case"src":r&&this.loadModel(r).catch(()=>{});break;case"camera-target":{let s=this.parseCameraTarget(r);a&&s&&a.setTarget(s[0],s[1],s[2]);break}case"min-camera-orbit":case"max-camera-orbit":if(a){let s=this.parseOrbitLimit(this.getAttr("min-camera-orbit")),o=this.parseOrbitLimit(this.getAttr("max-camera-orbit"));a.setOrbitLimits({minTheta:s.theta,maxTheta:o.theta,minPhi:s.phi,maxPhi:o.phi,minDistance:s.distance,maxDistance:o.distance})}break;case"field-of-view":{let s=this.parseFieldOfView(r);a&&s!==void 0&&a.setFieldOfView(s);break}case"script-src":r&&this.loadScriptFromSrc(r).catch(()=>{});break;case"poster":this.updatePoster(r);break;case"camera-orbit":this.applyCameraOrbit(r);break;case"selected-mesh":a?.setSelectedMesh(r??"");break;case"exposure":if(a&&r!==null){let s=parseFloat(r);isNaN(s)||a.setExposure(s)}break;case"shadow-intensity":case"shadow-softness":a?.setShadow(this.shadowIntensity,this.shadowSoftness);break;case"tone-mapping":a?.setToneMapping(me(r));break;case"environment-image":a?.setEnvironmentImage(r).catch(()=>{});break;case"skybox-image":a?.setSkyboxImage?.(r)?.catch?.(()=>{});break;case"camera-controls":{let s=this.cameraControls;a?.setInteractive?.(s),this.canvas&&(this.canvas.style.touchAction=s?"none":"auto");break}case"autoplay":a?.setAutoplay(r!==null&&r!=="false");break;case"animation-name":a&&r!==null&&a.setAnimationName(r);break;case"variant-name":a&&this.selectVariant(r);break;case"auto-rotate":a?.setAutoRotate(r!==null&&r!=="false");break;case"auto-rotate-delay":a?.setAutoRotateDelay(this.autoRotateDelay);break;case"rotation-per-second":a?.setAutoRotateSpeed(this.parseRotationPerSecond(r));break;case"ar":this.updateARButtonVisibility();break;case"renderer":a?.render();break;case"shadow-maps":a&&(a.shadowMaps=r!==null?this.shadowMaps:void 0),a?.render();break}for(let s of se.getRegisteredPlugins())s.onAttributeChanged?.(this,e,i,r)}getAttr(e){return this.getAttribute(e)}setAttr(e,i){i!==null?this.setAttribute(e,String(i)):this.removeAttribute(e)}getBoolAttr(e){return this.hasAttribute(e)&&this.getAttr(e)!=="false"}setBoolAttr(e,i){this.setAttr(e,i?"":null)}getFloatAttr(e,i){let r=this.getAttr(e);return r!==null?parseFloat(r):i}get sandbox(){return this.getAttr("sandbox")||(K().sandboxIframeSrc?"iframe":"worker")}set sandbox(e){this.setAttr("sandbox",e)}get allowClientScripts(){return this.getBoolAttr("allow-client-scripts")||he.allowClientScripts}set allowClientScripts(e){this.setBoolAttr("allow-client-scripts",e)}get turntableRotation(){return this.viewer?this.viewer.turntableRotation:0}get ar(){return this.hasAttribute("ar")}set ar(e){this.setBoolAttr("ar",e)}get canActivateAR(){return he.isARSupported()}get toneMapping(){return me(this.getAttr("tone-mapping"))}set toneMapping(e){this.setAttr("tone-mapping",e)}get bloomThreshold(){return Le(this.getAttr("bloom-threshold"),.62)}set bloomThreshold(e){this.setAttr("bloom-threshold",e)}get bloomRadius(){return Le(this.getAttr("bloom-radius"),.75)}set bloomRadius(e){this.setAttr("bloom-radius",e)}get availableAnimations(){return this.viewer?this.viewer.getAvailableAnimations():[]}get variantName(){return this.viewer?this.viewer.getVariantName():this.getAttr("variant-name")}set variantName(e){this.setAttr("variant-name",e)}get availableVariants(){return this.viewer?this.viewer.getAvailableVariants():[]}get renderer(){let e=this.getAttr("renderer")?.trim().toLowerCase();return e==="webgpu"||e==="webgl2"?e:"auto"}set renderer(e){this.setAttr("renderer",e)}get shadowMaps(){let e=this.getAttr("shadow-maps")?.trim().toLowerCase();return e==="pcf"||e==="off"?e:"auto"}set shadowMaps(e){this.setAttr("shadow-maps",e)}fireEvent(e,i){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:i}))}setSlotVisible(e,i){let r=typeof this.querySelector=="function"?this.querySelector(`[slot="${e}"]`):null;r&&(r.hidden=!i,r.style&&(r.style.display=i?"":"none"))}emitError(e,i="script"){this.setSlotVisible("error",!0),this.fireEvent("error",{error:e}),this.fireEvent("three-error",{error:e,message:e?.message||String(e),stage:i})}selectVariant(e){if(!this.viewer)return!1;let i=this.viewer.selectVariant(e);return i&&this.fireEvent("variant-applied",{variantName:this.viewer.getVariantName()}),i}get model(){let e=this.viewer?this.viewer.getModelMaterials():[];return{materials:e,getMaterialByName(i){return e.find(r=>r.name===i)??null}}}play(){this.viewer?.playAnimation(this.animationName||void 0)}pause(){this.viewer?.pauseAnimation()}resetCamera(){this.viewer?.resetCamera()}resetTurntableRotation(e=0){this.viewer?.resetTurntableRotation(e)}setCamera(e,i,r,a){this.viewer?.setCamera(e,i,r,a)}getCameraOrbit(){return this.viewer?.getCameraOrbit()??{theta:0,phi:0,radius:3,toString:()=>"0rad 0rad 3m"}}getCameraTarget(){return this.viewer?this.viewer.getCameraTarget():De(0,0,0)}getFieldOfView(){return this.viewer?this.viewer.getFieldOfView():45}jumpCameraToGoal(){this.viewer?.jumpCameraToGoal()}toDataURL(e,i){return this.viewer?.render?.(),this.canvas?this.canvas.toDataURL(e,i):""}toBlob(e){return this.viewer?.render?.(),new Promise((i,r)=>{if(!this.canvas||typeof this.canvas.toBlob!="function"){r(new Error("Canvas toBlob is not supported in this environment."));return}this.canvas.toBlob(a=>{a?i(a):r(new Error("Failed to capture canvas blob."))},e?.mimeType,e?.qualityArgument)})}positionAndNormalFromPoint(e,i){let r=this.viewer?.raycastFromScreenPoint(e,i);if(!r)return null;let[a,s,o]=r.hitPoint||r.point,[n,l,h]=r.normal;return{position:De(a,s,o),normal:De(n,l,h)}}loadModel(e){return this.loadModelWithLimits(e)}async loadModelWithLimits(e,i,r=this.beginLoad()){if(r.signal.throwIfAborted(),!this.viewer){this.currentModel=e,this.currentModelLimits=i;return}try{let a;if(typeof e=="string"){let l=await fetch(e,{signal:r.signal});if(!l.ok)throw new Error(`Failed to load "${e}": HTTP ${l.status}`);a=await l.arrayBuffer()}else a=e;r.signal.throwIfAborted();let s=be(a);this.viewer.loadGLBData(s,i),this.currentModel=s,this.currentModelLimits=i,this.isModelLoaded=!0,this.hidePoster(),this.setSlotVisible("error",!1),this.updateHotspots();let o=this.getAttr("selected-mesh");o&&this.viewer.setSelectedMesh(o);let n=this.getAttr("variant-name");n&&this.selectVariant(n),this.fireEvent("load",{model:s}),this.fireEvent("three-load",{model:s,source:typeof e=="string"?"src":"model"})}catch(a){throw r.signal.aborted||this.emitError(a,"load"),a}}showToast(e,i=4500){if(typeof document>"u")return;let r=this.querySelector(".three-live-toast");r||(r=document.createElement("div"),r.className="three-live-toast",r.style.cssText="position:absolute;bottom:70px;left:50%;transform:translateX(-50%) translateY(10px);z-index:10;padding:10px 16px;background:rgba(15,23,42,.94);color:#f8fafc;border:1px solid rgba(56,189,248,.45);border-radius:14px;font:500 13px/1.35 system-ui,-apple-system,sans-serif;box-shadow:0 10px 25px rgba(0,0,0,.45);backdrop-filter:blur(12px);pointer-events:none;opacity:0;transition:opacity .25s,transform .25s;max-width:88%;text-align:center;white-space:normal;word-break:break-word",this.appendChild(r)),r.textContent=e,this.toastTimer&&clearTimeout(this.toastTimer);let a=()=>{r&&(r.style.opacity="1",r.style.transform="translateX(-50%) translateY(0)")};typeof requestAnimationFrame<"u"?requestAnimationFrame(a):a(),this.toastTimer=setTimeout(()=>{r&&(r.style.opacity="0",r.style.transform="translateX(-50%) translateY(10px)"),this.toastTimer=null},i)}async activateAR(){this.activeXRSession?.isSessionActive?.()&&(await this.activeXRSession.stop().catch(()=>{}),this.activeXRSession=null);let e=(s,o=s.message)=>{throw this.fireEvent("ar-status",{status:"failed",error:s}),this.showToast(o,6e3),s};this.currentModel||e(new Error("No 3D model is loaded in <three-live>."));let i=K().arProvider;i||e(new Error("AR module not bundled. Use the default 'three-live' bundle or call ThreeLiveElement.registerAR()."));let r=this.getAttr("ios-src"),a=(this.getAttr("ar-modes")||"").split(/\s+/).filter(Boolean);try{this.fireEvent("ar-status",{status:"session-started"});let s=await i.activateAR({model:r||this.currentModel,glbUrl:typeof this.currentModel=="string"?this.currentModel:void 0,view:this.viewer||void 0,element:this,preferredModes:a.length>0?a:void 0,arScale:this.arScale,arPlacement:this.arPlacement,webXROptions:{onExit:()=>{this.activeXRSession=null,this.fireEvent("ar-status",{status:"not-presenting"})},onError:o=>{this.activeXRSession=null,this.fireEvent("ar-status",{status:"failed",error:o}),this.showToast(`AR error: ${o.message}`,6e3)}}});if(s.success){s.session&&(this.activeXRSession=s.session);let o={"quick-look":"Opening Apple AR Quick Look...","scene-viewer":"Opening Google Scene Viewer...",webxr:"WebXR AR session started."}[s.mode||""]||"";o&&this.showToast(o)}else{let o=s.error?.message||"AR requires an iOS (Quick Look) or Android (WebXR / Scene Viewer) device.";if(this.isDesktopMac()&&typeof document<"u"&&this.currentModel&&i.createUSDZBlob)try{let n=this.currentModel instanceof Blob&&this.currentModel.type==="model/vnd.usdz+zip"?this.currentModel:i.createUSDZBlob(this.currentModel),l=URL.createObjectURL(n),h=document.createElement("a");h.href=l,h.download="three_live_model.usdz",document.body.appendChild(h),h.click(),document.body.removeChild(h),setTimeout(()=>URL.revokeObjectURL(l),3e3),this.showToast("Downloaded USDZ preview for macOS Quick Look.",5e3)}catch{this.showToast(o,6e3)}else this.showToast(o,6e3);s.error&&this.fireEvent("ar-status",{status:"failed",error:s.error})}return s}catch(s){return this.activeXRSession=null,e(s,`AR error: ${s.message||String(s)}`)}}setupDOM(){let e=this.querySelector("canvas");e||(e=document.createElement("canvas"),e.style.cssText=`width:100%;height:100%;display:block;touch-action:${this.cameraControls?"none":"auto"};outline:none`,this.appendChild(e)),this.canvas=e,typeof e.addEventListener=="function"&&!e.__tlCtxBound&&(e.__tlCtxBound=!0,e.addEventListener("webglcontextlost",r=>this.fireEvent("three-context-lost",{originalEvent:r})),e.addEventListener("webglcontextrestored",r=>this.fireEvent("three-context-restored",{originalEvent:r}))),this.setSlotVisible("error",!1),this.isModelLoaded||this.setSlotVisible("poster",!0);let i=this.getAttr("poster");i&&this.updatePoster(i),this.createARButton(),typeof MutationObserver<"u"&&!this.mutationObserver&&(this.mutationObserver=new MutationObserver(()=>{this.updateARButtonVisibility()}),this.mutationObserver.observe(this,{childList:!0}))}initViewer(){if(!this.canvas)return;this.viewer=new se(this,this.canvas,{autoRotate:this.autoRotate,autoRotateDelay:this.autoRotateDelay,autoRotateSpeed:this.parseRotationPerSecond(this.getAttr("rotation-per-second")),exposure:this.exposure,shadowIntensity:this.shadowIntensity,shadowSoftness:this.shadowSoftness,shadowMaps:this.hasAttribute("shadow-maps")?this.shadowMaps:void 0,toneMapping:this.toneMapping,environmentImage:this.environmentImage,autoplay:this.autoplay,animationName:this.animationName||void 0,variantName:this.getAttr("variant-name")||void 0,fieldOfView:this.parseFieldOfView(this.getAttr("field-of-view")),cameraTarget:this.parseCameraTarget(this.getAttr("camera-target")),minCameraOrbit:this.parseOrbitLimit(this.getAttr("min-camera-orbit")),maxCameraOrbit:this.parseOrbitLimit(this.getAttr("max-camera-orbit")),onMeshClick:i=>{this.fireEvent("meshclick",i)},onCameraChange:i=>{this.updateHotspots();for(let r of se.getRegisteredPlugins())r.onCameraChange?.(this.viewer,this);this.fireEvent("camera-change",i)}}),this.viewer.setInteractive(this.cameraControls),this.skyboxImage&&this.viewer.setSkyboxImage(this.skyboxImage).catch(()=>{});let e=this.getAttr("camera-orbit");e&&this.applyCameraOrbit(e),this.currentModel&&this.loadModelWithLimits(this.currentModel,this.currentModelLimits)}setupResizeObserver(){typeof ResizeObserver>"u"||(this.resizeObserver=new ResizeObserver(()=>{this.viewer&&(this.viewer.resize(),this.viewer.render(),this.updateHotspots())}),this.resizeObserver.observe(this))}updatePoster(e){if(!(typeof document>"u")){if(!e){this.posterEl&&(this.posterEl.remove(),this.posterEl=null);return}this.posterEl||(this.posterEl=document.createElement("img"),this.posterEl.alt="3D Scene Preview",this.posterEl.style.cssText="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .35s ease-out;pointer-events:none;z-index:1",this.appendChild(this.posterEl)),this.posterEl.src=e,this.isModelLoaded||(this.posterEl.style.opacity="1")}}hidePoster(){this.setSlotVisible("poster",!1),this.posterEl&&(this.posterEl.style.opacity="0",setTimeout(()=>{this.isModelLoaded&&this.posterEl&&(this.posterEl.remove(),this.posterEl=null)},400))}isDesktopMac(){let e=typeof navigator<"u"&&navigator.userAgent||"";return/Macintosh/i.test(e)&&!(typeof navigator<"u"&&navigator.maxTouchPoints>1)&&!/Android|iPhone|iPad|iPod/i.test(e)}syncARButtonLabel(e){let i=this.isDesktopMac(),r=i?"Quick Look (.usdz)":"View in AR",a=i?"Download .usdz preview for macOS Quick Look (live camera AR requires iOS or Android)":"View in Augmented Reality";typeof e.setAttribute=="function"&&(e.setAttribute("aria-label",a),e.setAttribute("title",a));let s=e._labelSpan||(typeof e.querySelector=="function"?e.querySelector("span"):null);s&&(s.textContent=r)}createARButton(){if(!(typeof document>"u")){if(!this.arButton){let e=document.createElement("button");e.type="button",e.className="three-live-ar-button",e.setAttribute("part","default-ar-button");let i="http://www.w3.org/2000/svg";if(typeof document.createElementNS=="function"){let a=document.createElementNS(i,"svg");for(let[o,n]of Object.entries({width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}))a.setAttribute(o,n);a.style.marginRight="6px";let s=document.createElementNS(i,"path");s.setAttribute("d","M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16zM3.27 6.96 12 12.01l8.73-5.05M12 22.08V12"),a.appendChild(s),e.appendChild(a)}let r=document.createElement("span");e._labelSpan=r,e.appendChild(r),this.syncARButtonLabel(e),e.style.cssText="position:absolute;right:16px;bottom:16px;z-index:2;align-items:center;justify-content:center;padding:8px 16px;background-color:rgba(15,23,42,.85);color:#fff;border:1px solid rgba(255,255,255,.15);border-radius:9999px;font:600 13px system-ui,-apple-system,sans-serif;cursor:pointer;backdrop-filter:blur(8px);box-shadow:0 4px 12px rgba(0,0,0,.25);transition:transform .15s,background-color .15s;display:none";for(let[a,s,o]of[["mouseenter","rgba(30, 41, 59, 0.95)","scale(1.04)"],["mouseleave","rgba(15, 23, 42, 0.85)","scale(1)"]])e.addEventListener(a,()=>{e.style.backgroundColor=s,e.style.transform=o});e.addEventListener("click",a=>{a.stopPropagation(),this.activateAR()}),this.arButton=e,this.appendChild(e)}this.updateARButtonVisibility()}}updateARButtonVisibility(){let e=this.hasAttribute("ar")&&he.isARSupported(),i=typeof this.querySelector=="function"?this.querySelector('[slot="ar-button"]'):null;i?(this.arButton&&(this.arButton.style.display="none"),i.__tlARBound||(i.__tlARBound=!0,i.addEventListener("click",r=>{r.stopPropagation(),this.activateAR()})),i.dataset.tlOrigDisplay===void 0&&(i.dataset.tlOrigDisplay=i.style.display==="none"?"":i.style.display),i.style.display=e?i.dataset.tlOrigDisplay||"":"none"):this.arButton&&(this.syncARButtonLabel(this.arButton),this.arButton.style.display=e?"flex":"none")}applyCameraOrbit(e){if(!(!e||!this.viewer))try{let i=JSON.parse(e);this.viewer.setInitialCamera(i.theta,i.phi,i.distance,i.zoom)}catch{let i=this.parseOrbitLimit(e);(i.theta!==void 0||i.phi!==void 0)&&this.viewer.setInitialCamera(i.theta,i.phi,i.distance)}}parseOrbitLimit(e){if(!e)return{};let[i,r,a]=e.trim().split(/\s+/),s=a&&a!=="auto"?parseFloat(a):NaN;return{theta:i&&i!=="auto"?this.parseFieldOfView(i):void 0,phi:r&&r!=="auto"?this.parseFieldOfView(r):void 0,distance:isNaN(s)?void 0:s}}parseCameraTarget(e){if(!e)return;let i=e.trim().split(/\s+/).map(parseFloat);return i.length>=3&&!i.some(isNaN)?[i[0],i[1],i[2]]:void 0}parseFieldOfView(e){if(!e)return;let i=parseFloat(e);return isNaN(i)?void 0:e.endsWith("rad")?i*180/Math.PI:i}parseRotationPerSecond(e){if(!e)return Math.PI/6;let i=e.trim(),r=parseFloat(i);return isNaN(r)?Math.PI/6:i.endsWith("rad")?r:i.endsWith("%")?r/100*Math.PI*2:r*Math.PI/180}updateHotspot(e){let i=this.querySelector(`[slot="${e.name}"]`);i&&(e.position!==void 0&&i.setAttribute("data-position",e.position),e.normal!==void 0&&i.setAttribute("data-normal",e.normal)),this.updateHotspots()}updateHotspots(){for(let e of se.getRegisteredPlugins())if(e.updateHotspotsForElement){e.updateHotspotsForElement(this,this.viewer);return}}runWithScriptRunner(e){let i=K().scriptRunner;if(!i){let s=new Error('Script execution requires "three-live/full" or registerScriptRunner().');return this.showToast(s.message),this.emitError(s,"script"),Promise.reject(s)}let r=this.beginLoad(),a=()=>!r.signal.aborted;return new Promise((s,o)=>{let n=()=>o(r.signal.reason);if(r.signal.addEventListener("abort",n,{once:!0}),!a()){n();return}let l={onModelReady:h=>{this.loadModelWithLimits(h,mt,r).then(()=>s(h),o)},onUpdateTransforms:h=>{a()&&this.viewer?.updateMeshTransforms(h)},onError:h=>{a()&&(this.showToast(h.message),this.emitError(h,"script"),o(h))},onToast:h=>{a()&&this.showToast(h)}};e(i,l).then(h=>{a()?this.scriptHandle=h||null:h?.terminate()},h=>{a()&&l.onError?.(h)})})}loadScriptFromSrc(e){return this.runWithScriptRunner((i,r)=>{if(typeof i.executeUrl!="function"){let a=new Error("Registered ScriptRunner does not support executeUrl() for server-generated scripts.");return r.onError?.(a),Promise.reject(a)}return i.executeUrl(e,this.sandbox,r)})}executeScript(e){if(!K().scriptRunner)return this.runWithScriptRunner(()=>Promise.resolve());if(!this.allowClientScripts){let i=new Error($e);return this.showToast(Xe),this.emitError(i,"security"),Promise.reject(i)}return this.runWithScriptRunner((i,r)=>i.execute(e,this.sandbox,r,{allowClientScripts:!0}))}};Te.observedAttributes="src ios-src script-src sandbox allow-client-scripts poster camera-controls camera-orbit camera-target min-camera-orbit max-camera-orbit field-of-view selected-mesh ar ar-modes ar-scale ar-placement exposure shadow-intensity shadow-softness tone-mapping bloom bloom-threshold bloom-radius outline outline-selected outline-color environment-image skybox-image autoplay animation-name variant-name auto-rotate auto-rotate-delay rotation-per-second renderer shadow-maps".split(" "),Te.registerPlugin=se.registerPlugin,Te.getRegisteredPlugins=se.getRegisteredPlugins;var Ee=Te;{let t=Ee.prototype,e=(r,a,s)=>Object.defineProperty(t,r,{get:a,set:s,configurable:!0}),i=r=>r.replace(/[A-Z]/g,a=>"-"+a.toLowerCase());for(let r of"src cameraOrbit cameraTarget minCameraOrbit maxCameraOrbit fieldOfView iosSrc scriptSrc poster selectedMesh environmentImage skyboxImage animationName".split(" ")){let a=i(r);e(r,function(){return this.getAttr(a)},function(s){this.setAttr(a,s)})}for(let r of"cameraControls autoRotate outlineSelected autoplay".split(" ")){let a=i(r);e(r,function(){return this.getBoolAttr(a)},function(s){this.setBoolAttr(a,s)})}for(let[r,a]of[["exposure",1],["autoRotateDelay",3e3],["shadowIntensity",0],["shadowSoftness",.5],["bloom",0]]){let s=i(r);e(r,function(){return this.getFloatAttr(s,a)},function(o){this.setAttr(s,o)})}for(let[r,a]of[["rotationPerSecond","30deg"],["arScale","auto"],["arPlacement","floor"],["outlineColor","#38bdf8"]]){let s=i(r);e(r,function(){return this.getAttr(s)||a},function(o){this.setAttr(s,o)})}}typeof customElements<"u"&&!customElements.get("three-live")&&customElements.define("three-live",Ee);export{Ee as ThreeLiveElement,se as ThreeView,be as toGLBData};
|