@displayxr/inline3d 1.47.0 → 1.47.2
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/CHANGELOG.md +29 -0
- package/dist/call.js +1 -1
- package/docs/making-3d-look-right.md +13 -5
- package/docs/woven-canvas-rules.md +1 -1
- package/js/inline3d-splat-playcanvas.js +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
|
|
|
5
5
|
`./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
|
|
6
6
|
which tier they touch, because that is what tells you whether an upgrade can move your pixels.
|
|
7
7
|
|
|
8
|
+
## 1.47.2 — 2026-10-30
|
|
9
|
+
|
|
10
|
+
### Docs only — two more panel findings in the shipped guide
|
|
11
|
+
|
|
12
|
+
No code change. `docs/making-3d-look-right.md` and `docs/woven-canvas-rules.md` (both in the
|
|
13
|
+
package):
|
|
14
|
+
|
|
15
|
+
- **Rule 9:** a `firstWoven` of `woven: false` is not "no 3D here". Drop the cover and keep drawing
|
|
16
|
+
both eyes, since the layer can still join, and go flat only on `onLayerLost` or with no session.
|
|
17
|
+
Never draw one full-width flat picture into a canvas the browser is still weaving: each eye
|
|
18
|
+
would see a different half of it. To show a flat picture on purpose, remove the scene, or call
|
|
19
|
+
`setStereoEnabled(false)` and keep drawing every view.
|
|
20
|
+
- **Rule 5:** in front of the glass, contrast matters more than the depth number. Keep bright
|
|
21
|
+
subjects off near-black backgrounds, above all the ones that come closest; dark grey is the
|
|
22
|
+
minimum, not the target.
|
|
23
|
+
|
|
24
|
+
## 1.47.1 — 2026-10-29
|
|
25
|
+
|
|
26
|
+
### Fixed — a splat on a camera rig briefly declared convergence at infinity (`./splat`, PlayCanvas)
|
|
27
|
+
|
|
28
|
+
Touches the preview tier (`./splat` on PlayCanvas) only.
|
|
29
|
+
|
|
30
|
+
- When a camera-rig splat's focus sat at or behind its camera — in practice the first push, before
|
|
31
|
+
the first focus has landed — the adapter declared `convergence: 0` (infinity), which asks for
|
|
32
|
+
the whole scene in front of the glass, for one push. It now keeps the rig as declared until the
|
|
33
|
+
focus is in front of the camera. Seen on a panel as one such rig in the first 0.3–2 s of each
|
|
34
|
+
page of an app built on 1.47.0 (and silently in earlier versions); 1.47.0's one-time
|
|
35
|
+
convergence-0 warning is what surfaced it, and it no longer fires from the SDK's own rigs.
|
|
36
|
+
|
|
8
37
|
## 1.47.0 — 2026-10-29
|
|
9
38
|
|
|
10
39
|
The look-right release: a short guide for people and coding agents (`docs/making-3d-look-right.md`,
|
package/dist/call.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @displayxr/inline3d 1.47.
|
|
1
|
+
/* @displayxr/inline3d 1.47.2 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
|
|
2
2
|
var Ds=Object.defineProperty;var le=(r,e)=>()=>(r&&(e=r(r=0)),e);var Ps=(r,e)=>{for(var t in e)Ds(r,t,{get:e[t],enumerable:!0})};function vr(r,e,t=1){let i=Je,n=!!r&&r.displayWidthMeters>0&&r.displayHeightMeters>0&&r.displayPixelWidth>0&&r.displayPixelHeight>0,s=n?[r.displayWidthMeters,r.displayHeightMeters]:[...i.displaySizeM],o=n?[r.displayPixelWidth,r.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=n?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),d=r?.nominalViewerPosition?.z,f=Number.isFinite(d)&&d>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:f?d:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:n?"display":"default",viewer:f?"display":"default",eyeSeparation:"default"}}}var Je,Bt=le(()=>{"use strict";Je=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063})});function ut(r,e,t,i,n,s,o,a,l,c,d){if(s<0||s+a>t||o<0)return-1;let f=0,h=0,u=0,p=a*l;for(let _=0;_<l;_++){let b=(n+_)*e+i,S=(o+_)*e+t+s;for(let x=0;x<a;x++){let O=r[S+x];f+=O,h+=O*O,u+=r[b+x]*O}}let m=f/p,g=h/p-m*m;return g<1?-1:(u/p-c*m)/(d*Math.sqrt(g))}function Oo(r,e,t,i,n,s){let o=0,a=0;for(let d=0;d<s;d++){let f=(i+d)*e+t;for(let h=0;h<n;h++){let u=r[f+h];o+=u,a+=u*u}}let l=n*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function _e(r,e,t,i,n,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:d}={}){let f=e/2,{mean:h,std:u}=Oo(r,e,i,n,s,o);if(u<6)return null;let p=-2,m=0,g=0,_=new Map,b=(k,v,w,y,M)=>{for(let I=y;I<=M;I++){let T=n+I;if(!(T<0||T+o>t))for(let N=k;N<=v;N+=w){let $=ut(r,e,f,i,n,i-N,T,s,o,h,u);$>(_.get(N)??-2)&&_.set(N,$),$>p&&(p=$,m=N,g=I)}}},S=l-a>8;if(b(a,l,S?2:1,-c,c),S&&p>-1){let k=m,v=g;b(Math.max(a,k-2),Math.min(l,k+2),1,Math.max(-c,v-1),Math.min(c,v+1))}if(p<-1)return null;let x=-2,O=k=>{let v=-2;for(let w=-c;w<=c;w++){let y=n+w;if(!(y<0||y+o>t))for(let M=k-1;M<=k+1;M++)v=Math.max(v,ut(r,e,f,i,n,i-M,y,s,o,h,u))}return v};for(let[k,v]of _){if(Math.abs(k-m)<3||v<=x)continue;let y=v>=(_.get(k-2)??-2)&&v>=(_.get(k+2)??-2)&&v>0?O(k):v;y>x&&(x=y)}if(l-a>12&&x>-2&&p-x<(d??.08))return null;let E=ut(r,e,f,i,n,i-(m-1),n+g,s,o,h,u),C=ut(r,e,f,i,n,i-(m+1),n+g,s,o,h,u),P=0,D=E-2*p+C;return E>-1&&C>-1&&D<0&&(P=Math.max(-.5,Math.min(.5,.5*(E-C)/D))),{d:m+P,dy:g,c:p}}function Do(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.step||s,a=i.dMax??Math.round(n*.3),l=i.dMin??-Math.round(n*.05),c=Math.round(n*(i.roiX0??.15)),d=Math.round(n*(i.roiX1??.85))-s,f=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,u=[];for(let p=f;p<=h;p+=o)for(let m=c;m<=d;m+=o){let g=_e(r,e,t,m,p,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});g&&g.c>=(i.minNcc??.8)&&u.push({x:m,y:p,...g})}return u}function Po(r,{tol:e=2,relTol:t=.1,minFrac:i=.12,minBlocks:n=3}={}){if(!r.length)return null;let s=Math.max(n,Math.ceil(r.length*i)),o=r.map(a=>a.d).sort((a,l)=>l-a);for(let a of o){let l=Math.max(e,t*Math.abs(a)),c=r.filter(d=>Math.abs(d.d-a)<=l);if(c.length>=s){let d=c.map(f=>f.d).sort((f,h)=>f-h);return{d:d[d.length>>1],members:c}}}return null}function Ao(r,e){let t=Math.min(...r.map(l=>l.y)),n=r.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...n),o=Math.max(...n)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function Si(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.dMax??Math.round(n*.3),a=i.dMin??-Math.round(n*.05),l=i.focus||null,c="focus",d=0,f=null;if(!l){let S=Do(r,e,t,{...i,block:s,dMax:o,dMin:a});d=S.length;let x=Po(S,i);if(!x)return null;l=Ao(x.members,s),f=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),u=Math.round(s*(i.refineH??1.5)),p=Math.round(Math.max(0,Math.min(n-h,l.x-h/2))),m=Math.round(Math.max(0,Math.min(t-u,l.y-u/2))),g=f===null?a:Math.max(a,Math.floor(f)-4),_=f===null?o:Math.min(o,Math.ceil(f)+4),b=_e(r,e,t,p,m,h,u,{dMin:g,dMax:_,dyMax:i.dyMax??2});return b&&b.c>=(i.minNcc??.8)?{d:b.d,x:l.x,y:l.y,c:b.c,method:c,blocks:d}:f!==null?{d:f,x:l.x,y:l.y,c:0,method:c,blocks:d}:null}function dt(r,e){let t=new Uint8Array(e);for(let i=0,n=0;i<e;i++,n+=4)t[i]=r[n]*77+r[n+1]*150+r[n+2]*29>>8;return t}function ft({n:r=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>r&&e.shift();let n=[...e].sort((s,o)=>s-o);return t.value=n[n.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function rn(r,e,t,i,n,s){let o=new Float32Array(n*s);for(let a=0;a<s;a++)for(let l=0;l<n;l++)o[a*n+l]=r[(i+a)*e+t+l];return o}function Lo(r,e,t,i,n,s,o,a,l,c){let d=e/2,f=n*s,h=0,u=0;for(let b=0;b<f;b++)h+=i[b],u+=i[b]*i[b];h/=f;let p=Math.sqrt(Math.max(1e-6,u/f-h*h)),m=-2,g=o,_=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let S=Math.max(0,o-l);S<=Math.min(d-n,o+l);S++){let x=0,O=0,E=0;for(let k=0;k<s;k++){let v=(b+k)*e+S;for(let w=0;w<n;w++){let y=r[v+w];x+=y,O+=y*y,E+=y*i[k*n+w]}}let C=x/f,P=O/f-C*C;if(P<1)continue;let D=(E/f-C*h)/(Math.sqrt(P)*p);D>m&&(m=D,g=S,_=b)}return{x:g,y:_,c:m}}function Ue({fullEveryMs:r=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:n=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,d,f,h,u={}){let p=d/2,m=u.block||Math.max(8,Math.round(p/20)),g=Math.round(m*3),_=Math.round(m*1.5),b=null;if(o&&o.w===g&&o.h===_){let C=Lo(c,d,f,o.tpl,g,_,o.x,o.y,t,i);if(C.c>=n){let P=_e(c,d,f,C.x,C.y,g,_,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});P&&P.c>=.8&&(b={m:P,f:C})}}let S=({m:C,f:P})=>(o={...o,x:P.x,y:P.y,d:C.d,tpl:rn(c,d,P.x,P.y,g,_)},{d:C.d,x:P.x+g/2,y:P.y+_/2,c:C.c,method:"track",blocks:0});if(b&&h-o.at<r)return S(b);let x=Si(c,d,f,u);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let C=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!C?{d:x.d}:null,!C)return o.at=h,S(b)}else a=null;if(!x)return o=null,null;let O=Math.round(Math.max(0,Math.min(p-g,x.x-g/2))),E=Math.round(Math.max(0,Math.min(f-_,x.y-_/2)));return o={x:O,y:E,d:x.d,tpl:rn(c,d,O,E,g,_),w:g,h:_,at:h},x},reset(){o=null,a=null}}}function nn(r,e,t,i,n,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(n/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let u=0;u<l;u++)for(let p=0;p<a;p++){let m=0;for(let g=0;g<o;g++){let _=e+(u*o+g)*t+p*o;for(let b=0;b<o;b++)m+=r[_+b]}c[u*a+p]=m/h|0}return{img:c,w:a,h:l}}let d=o>>2,f=3*o>>2;for(let h=0;h<l;h++){let u=e+(h*o+d)*t,p=e+(h*o+f)*t;for(let m=0;m<a;m++){let g=m*o+d,_=m*o+f;c[h*a+m]=r[u+g]+r[u+_]+r[p+g]+r[p+_]>>2}}return{img:c,w:a,h:l}}var Mi=le(()=>{"use strict"});function vt(r,e="@displayxr/inline3d"){if(r==null||r===!0)return{...ve};r===!1&&(r="off");let t=()=>new Error(`${e}: cursor.soften ${JSON.stringify(r)} \u2014 expected ${mt.map(s=>`'${s}'`).join(" | ")} or { ${gt.join(", ")} }.`);if(typeof r=="string"){if(!mt.includes(r))throw t();return{...ve,...sn(r)}}if(typeof r!="object"||Array.isArray(r))throw t();let i=Object.keys(r).filter(s=>!gt.includes(s));if(i.length)throw new Error(`${e}: cursor.soften \u2014 unknown option(s) ${i.join(", ")}; expected ${gt.join(", ")}.`);if(r.mode!==void 0&&!mt.includes(r.mode))throw t();let n={...ve,...sn(r.mode??"both")};for(let s of Object.keys(_t)){if(r[s]===void 0)continue;let[o,a,l]=_t[s];if(!Io(s,r[s]))throw new Error(`${e}: cursor.soften.${s} must be a number in ${l?"(":"["}${o}, ${a}].`);n[s]=r[s]}return n}function an(r,e="@displayxr/inline3d"){if(r==null||r===!1)return null;if(r==="depth"||r===!0)return{};if(typeof r!="object")throw new Error(`${e}: cursor ${JSON.stringify(r)} \u2014 expected 'depth' or { ${pt.join(", ")} }.`);let t=Object.keys(r).filter(i=>!pt.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${pt.join(", ")}.`);if(r.anchor!==void 0&&!Ei.includes(r.anchor))throw new Error(`${e}: cursor.anchor "${r.anchor}" \u2014 expected ${Ei.join(", ")}.`);if(r.pointerScope!==void 0&&r.pointerScope!=="canvas"&&r.pointerScope!=="window")throw new Error(`${e}: cursor.pointerScope "${r.pointerScope}" \u2014 expected 'canvas' or 'window'.`);if(r.debug!==void 0&&typeof r.debug!="boolean"&&r.debug!=="both")throw new Error(`${e}: cursor.debug ${JSON.stringify(r.debug)} \u2014 expected true, false or 'both'.`);for(let i of["height","margin"])if(r[i]!==void 0&&!(typeof r[i]=="number"&&r[i]>0&&Number.isFinite(r[i])))throw new Error(`${e}: cursor.${i} must be a positive number.`);if(r.soften!==void 0&&vt(r.soften,e),r.shape!==void 0&&!ye.includes(r.shape))throw new Error(`${e}: cursor.shape ${JSON.stringify(r.shape)} \u2014 expected ${ye.map(i=>`'${i}'`).join(" | ")}.`);if(r.shapeFor!==void 0&&r.shapeFor!==null&&typeof r.shapeFor!="function")throw new Error(`${e}: cursor.shapeFor must be a function (hit) => shape.`);return{...r}}function yt(r,e="@displayxr/inline3d"){let t=an(r,e);if(!t)return null;let i=Object.keys(t).filter(n=>!on.includes(n));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${on.join(", ")}.`);return t}var Ei,pt,we,ye,mt,ve,_t,gt,Io,sn,on,be=le(()=>{"use strict";Ei=Object.freeze(["hybrid","screen","world"]),pt=Object.freeze(["height","margin","anchor","pointerScope","debug","soften","shape","shapeFor"]),we=Object.freeze(["arrow","pointer","grab","grabbing","move","text","vertical-text","crosshair","not-allowed","help","wait","progress","copy","alias","context-menu","cell","ns-resize","ew-resize","nesw-resize","nwse-resize","col-resize","row-resize","zoom-in","zoom-out"]),ye=Object.freeze(["auto","none",...we]),mt=Object.freeze(["both","off","alpha","blur"]),ve=Object.freeze({blur:!0,alpha:!0,blurK:.1,blurMaxPx:8,blurMaxFrac:.06,alphaMin:.5,fullD:.03}),_t=Object.freeze({blurK:[0,1e3,!1],blurMaxPx:[0,8,!1],blurMaxFrac:[0,.5,!1],alphaMin:[0,1,!1],fullD:[0,1e3,!0]}),gt=Object.freeze(["mode",...Object.keys(_t)]),Io=(r,e)=>{let[t,i,n]=_t[r];return typeof e=="number"&&Number.isFinite(e)&&e>=t&&e<=i&&!(n&&e<=t)},sn=r=>({blur:r==="both"||r==="blur",alpha:r==="both"||r==="alpha"});on=Object.freeze(["height","pointerScope","soften","shape","shapeFor"])});function Pi(r){return typeof r=="string"&&kn[r.trim().toLowerCase()]||"arrow"}function Uo(r){let e=[],t=0,i="",n="";for(let s=0;s<r.length;s++){let o=r[s];if(i){if(o==="\\"&&s+1<r.length){n+=o+r[++s];continue}o===i&&(i="")}else if(o==='"'||o==="'")i=o;else if(o==="(")t++;else if(o===")")t=Math.max(0,t-1);else if(o===","&&t===0){e.push(n.trim()),n="";continue}n+=o}return n.trim()&&e.push(n.trim()),e}function Ai(r){if(typeof r!="string")return{images:[],keyword:"auto"};let e=St.get(r);if(e)return e;let t=[],i="auto";for(let n of Uo(r)){let s=/^url\(\s*(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)'|([^)\s]*))\s*\)\s*(.*)$/is.exec(n);if(s){let o=(s[1]??s[2]??s[3]??"").replace(/\\(.)/g,"$1"),a=(s[4]||"").trim().split(/\s+/).filter(Boolean).map(Number),l=a.length===2&&a.every(Number.isFinite)?[a[0],a[1]]:null;o&&t.push({url:o,hotspot:l});continue}/^(-webkit-)?image-set\(/i.test(n)||(i=n.trim().toLowerCase())}return e=Object.freeze({images:Object.freeze(t),keyword:i}),St.size>64&&St.clear(),St.set(r,e),e}function Tn(r){return Pi(Ai(r).keyword)}function On(r,e=0){if(!r||r.byteLength<22)return null;let t=new DataView(r);if(t.getUint16(0,!0)!==0||t.getUint16(2,!0)!==2)return null;let i=t.getUint16(4,!0),n=-1;for(let o=0;o<i&&6+16*o+16<=r.byteLength;o++){let a=t.getUint8(6+16*o)||256;if((n<0||a===e)&&(n=o),a===e)break}if(n<0)return null;let s=6+16*n;return[t.getUint16(s+4,!0),t.getUint16(s+6,!0)]}function Dn(r,e=Li){let t=Ai(r);for(let i of t.images){let n=e.get(i.url);if(n.state==="failed")continue;if(n.state!=="ready")break;let s=Math.min(1,Cn/Math.max(n.width,n.height)),o=i.hotspot||n.curHotspot||[0,0],a=n.width*s,l=n.height*s,c=[Math.min(a,Math.max(0,o[0]*s)),Math.min(l,Math.max(0,o[1]*s))];return{kind:"image",key:i.url,entry:n,width:a,height:l,hotspot:c}}return Me(Pi(t.keyword))}function Me(r){if(r==="none")return{kind:"none"};let e=we.includes(r)?r:"arrow";return{kind:"shape",name:e,key:`shape:${e}`}}function R(r,e,t,i,[n=0,s=0,o=0,a=0]=[]){let l=[],c=(d,f)=>{let h=l[l.length-1];(!h||Math.abs(h[0]-d)>1e-9||Math.abs(h[1]-f)>1e-9)&&l.push([d,f])};return c(r+n,e),c(t-s,e),c(t,e+s),c(t,i-o),c(t-o,i),c(r+a,i),c(r,i-a),c(r,e+n),l.length>1&&Math.abs(l[0][0]-l[l.length-1][0])<1e-9&&Math.abs(l[0][1]-l[l.length-1][1])<1e-9&&l.pop(),l}function Et(r,e,t,i,n,s=n/3.5){let o=t-r,a=i-e,l=Math.hypot(o,a),c=o/l,d=a/l,f=-d*(n/2),h=c*(n/2),u=t-c*s,p=i-d*s,m=1-2*s/n;return Ee([[r+f,e+h],[u+f,p+h],[t+f*m,i+h*m],[t-f*m,i-h*m],[u-f,p-h],[r-f,e-h]])}function xn(r,e,t,i,n){let s=t-r,o=i-e,a=Math.hypot(s,o),l=-o/a*(n/2),c=s/a*(n/2);return Ee([[r+l,e+c],[t+l,i+c],[t-l,i-c],[r-l,e-c]])}function Pn(r,e,t,i=20){return Ee(Array.from({length:i},(n,s)=>[r+t*Math.cos(2*Math.PI*s/i),e+t*Math.sin(2*Math.PI*s/i)]))}function Bo(r,e,t,i,n=24){let s=[],o=(a,l)=>[r+a*Math.cos(l),e+a*Math.sin(l)];for(let a=0;a<n;a++){let l=[0,1,2,3].map(c=>2*Math.PI*(a+c)/n);s.push(Ee([...l.map(c=>o(i,c)),...l.reverse().map(c=>o(t,c))]))}return s}function qo(){return{pointer:{hot:[6.8,0],parts:[R(5,0,8.6,14,[1.2,1.2,0,0]),R(7.6,5.4,10.9,14,[1.1,1.1,0,0]),R(9.9,6.4,13.2,14,[1.1,1.1,0,0]),R(12.2,7.6,15.2,14,[.9,.9,0,0]),R(4.2,10.8,15.2,19,[0,0,3,2.2]),Et(7.4,15,1,9,3.6)]},grab:{hot:[8.6,12.5],parts:[R(3,2.6,6.6,12.4,[1.2,1.2,0,0]),R(5.6,.6,9.2,12.4,[1.2,1.2,0,0]),R(8.2,1.4,11.8,12.4,[1.2,1.2,0,0]),R(10.8,3.6,14.2,12.4,[1.1,1.1,0,0]),R(3,9.4,14.2,18,[0,0,2.6,2.6]),Et(6.2,14.4,.4,7,3.6)]},grabbing:{hot:[8.6,13],parts:[R(3,5.6,6.6,12.4,[1.2,1.2,0,0]),R(5.6,5,9.2,12.4,[1.2,1.2,0,0]),R(8.2,5.2,11.8,12.4,[1.2,1.2,0,0]),R(10.8,6,14.2,12.4,[1.1,1.1,0,0]),R(3,9.4,14.2,18,[0,0,2.6,2.6]),Et(6,14.2,1.2,9,3.6)]},move:{hot:[9.5,9.5],parts:[R(3,7.8,16,11.2),R(7.8,3,11.2,16),V([9.5,0],[14,4.6],[5,4.6]),V([9.5,19],[5,14.4],[14,14.4]),V([0,9.5],[4.6,5],[4.6,14]),V([19,9.5],[14.4,14],[14.4,5])]},text:{hot:[9.5,9.5],parts:[R(8,.5,11,18.5),R(4.5,0,14.5,3),R(4.5,16,14.5,19)]},"vertical-text":{hot:[9.5,9.5],parts:Be([R(8,.5,11,18.5),R(4.5,0,14.5,3),R(4.5,16,14.5,19)],90,9.5,9.5)},crosshair:{hot:[9.5,9.5],parts:[R(0,8,19,11),R(8,0,11,19)]},cell:{hot:[9.5,9.5],parts:[R(1.5,6.3,17.5,12.7),R(6.3,1.5,12.7,17.5)]},"not-allowed":{hot:[9.5,9.5],parts:[...Bo(9.5,9.5,5.4,8.8),xn(4.6,4.6,14.4,14.4,3.4)]},help:{hot:[0,0],parts:[...se(Xe(),.8),Pn(13.6,12.4,5.4)],detail:[R(11.6,9,15.4,10.2),R(14.4,9,15.6,12.6),R(12.9,11.6,15.6,12.8),R(12.9,11.6,14.1,13.8),R(12.9,14.8,14.1,16)]},wait:{hot:[9.5,9.5],parts:Xo()},progress:{hot:[0,0],parts:[...se(Xe(),.8),R(10.6,9,18.8,11.6),R(10.6,16.4,18.8,19),V([11.4,10.2],[18,10.2],[14.7,14.4]),V([14.7,13.6],[18,17.8],[11.4,17.8])]},copy:{hot:[0,0],parts:[...se(Xe(),.8),R(9.6,9.8,18.8,19,[1.2,1.2,1.2,1.2])],detail:[R(13.6,11.8,14.8,17),R(11.6,13.8,16.8,15)]},alias:{hot:[0,0],parts:[...se(Xe(),.8),R(9.6,9.8,18.8,19,[1.2,1.2,1.2,1.2])],detail:[xn(11.8,16.8,15.6,13,1.3),V([16.8,11.8],[16.8,15.4],[13.2,11.8])]},"context-menu":{hot:[0,0],parts:[...se(Xe(),.8),R(9.2,8.6,18.8,19)],detail:[R(11,10.8,17,11.8),R(11,13.3,17,14.3),R(11,15.8,17,16.8)]},"ns-resize":{hot:[9.5,9.5],parts:Mt()},"ew-resize":{hot:[9.5,9.5],parts:Be(Mt(),90,9.5,9.5)},"nesw-resize":{hot:[9.5,9.5],parts:se(Be(Mt(),45,9.5,9.5),1.2,-1.9,-1.9)},"nwse-resize":{hot:[9.5,9.5],parts:se(Be(Mt(),-45,9.5,9.5),1.2,-1.9,-1.9)},"col-resize":{hot:[9.5,9.5],parts:Sn()},"row-resize":{hot:[9.5,9.5],parts:Be(Sn(),90,9.5,9.5)},"zoom-in":{hot:[7.5,7.5],parts:Mn(),detail:[R(4.4,6.9,10.6,8.1),R(6.9,4.4,8.1,10.6)]},"zoom-out":{hot:[7.5,7.5],parts:Mn(),detail:[R(4.4,6.9,10.6,8.1)]}}}function Ii(r){let e=we.includes(r)?r:"arrow",t=En.get(e);if(t)return t;let i=c=>Object.freeze(c.map(d=>Object.freeze(d.map(f=>Object.freeze(f))))),n,s,o;if(e==="arrow")n=[ee],s=[Nn],o=[];else{let c=(Go||=qo())[e],d=f=>f.map(h=>h.map(([u,p])=>[(u-c.hot[0])/19,(p-c.hot[1])/19]));n=i(d(c.parts)),s=i(n.map(f=>Tt(1/19,f))),o=i(d(c.detail||[]))}let a=n.flat().map(c=>c[0]),l=n.flat().map(c=>c[1]);return t=Object.freeze({name:e,parts:Object.freeze(n),fill:Object.freeze(s),detail:Object.freeze(o),box:Object.freeze([Math.min(...a),Math.min(...l),Math.max(...a),Math.max(...l)])}),En.set(e,t),t}function Re(r,e=1/19){let t=Ii(r);return Math.abs(e-1/19)<1e-12?{outline:t.parts,fill:t.fill,detail:t.detail}:{outline:t.parts,fill:t.parts.map(i=>Tt(e,i)),detail:t.detail}}function An(r,e,t=0){let i=Ii(r).box,n=(e>0&&Number.isFinite(e)?e:0)+(t>0&&Number.isFinite(t)?t:0);return[i[0]-n,i[1]-n,i[2]+n,i[3]+n]}function Ln(r,e,t,i,n,s=Wi,o=Hi,a=Re(r)){let l=0,c=0,d=0,f=0,h=0,u=i>0?Ge:Ge.slice(0,1),p=a.detail&&a.detail.length?a.detail:null;for(let[m,g,_]of u){let b=e+m*i,S=t+g*i,x=Di(Oi(a.outline,b,S),n),O=x>0?Di(Oi(a.fill,b,S),n):0;p&&O>0&&(O*=1-Di(Oi(p,b,S),n)),l+=_*(o[0]*x+(s[0]-o[0])*O),c+=_*(o[1]*x+(s[1]-o[1])*O),d+=_*(o[2]*x+(s[2]-o[2])*O),f+=_*x,h+=_}return f/=h,f>1e-5?[l/h/f,c/h/f,d/h/f,f]:[0,0,0,0]}function Fi(r,e,t,i,n,s,o=Wi,a=Hi,l=Re(r)){let c=i>0&&Number.isFinite(i)?i:1,d=1/c,[f,h,u,p]=An(r,n,d),m=Math.floor(e+f*c),g=Math.floor(t+h*c),_=Math.max(1,Math.ceil(e+u*c)-m),b=Math.max(1,Math.ceil(t+p*c)-g),S=new Uint8ClampedArray(_*b*4),x=s>=0&&s<=1?s:1;for(let O=0;O<b;O++){let E=(g+O+.5-t)/c;for(let C=0;C<_;C++){let P=Ln(r,(m+C+.5-e)/c,E,n,d,o,a,l);if(!(P[3]>0))continue;let D=(O*_+C)*4;S[D]=Math.round(P[0]*255),S[D+1]=Math.round(P[1]*255),S[D+2]=Math.round(P[2]*255),S[D+3]=Math.round(P[3]*x*255)}}return{x0:m,y0:g,width:_,height:b,data:S}}function Ni(r,e,t,i,n,s=Re(e),o="#fff",a="#000"){for(let[l,c]of[[s.outline,a],[s.fill,o],[s.detail||[],a]]){r.fillStyle=c;for(let d of l)r.beginPath(),d.forEach(([f,h],u)=>(u?r.lineTo:r.moveTo).call(r,t+f*n,i+h*n)),r.closePath(),r.fill()}}function ji(r,e,t,i,n){let s=i>0&&Number.isFinite(i)?Math.ceil(i)+1:0,o=e+2*s,a=t+2*s,l=new Uint8ClampedArray(o*a*4),c=n>=0&&n<=1?n:1,d=s?Ge:Ge.slice(0,1);for(let f=0;f<a;f++)for(let h=0;h<o;h++){let u=0,p=0,m=0,g=0,_=0;for(let[S,x,O]of d){_+=O;let E=Math.round(h-s+S*i),C=Math.round(f-s+x*i);if(E<0||C<0||E>=e||C>=t)continue;let P=(C*e+E)*4,D=r[P+3]/255*O;u+=r[P]*D,p+=r[P+1]*D,m+=r[P+2]*D,g+=D}if(!(g>1e-5))continue;let b=(f*o+h)*4;l[b]=u/g,l[b+1]=p/g,l[b+2]=m/g,l[b+3]=g/_*c*255}return{pad:s,width:o,height:a,data:l}}function kt(r=globalThis.document){if(!r||!r.createElement)return!1;let e="inline3d-cursor-style";if(r.getElementById&&r.getElementById(e))return!0;let t=r.createElement("style");return t.id=e,t.textContent=Rn,(r.head||r.documentElement)?.appendChild(t),!0}function Fn(r,e){let t=globalThis.getComputedStyle;if(!r||typeof t!="function")return null;let i=[];for(let n of e)n&&n.hasAttribute&&n.hasAttribute(B)&&(i.push([n,n.getAttribute(B)]),n.removeAttribute(B));try{let n=t(r).cursor;return typeof n=="string"?n:null}catch{return null}finally{for(let[n,s]of i)n.setAttribute(B,s??"")}}var B,Rn,Cn,kn,$o,St,Vo,Rt,Li,Ee,V,Be,se,Xe,Mt,Sn,Xo,Mn,Go,En,Oi,Di,In,Ct,qe,zi=le(()=>{"use strict";$i();be();B="data-inline3d-cursor-hidden",Rn=`[${B}],[${B}] *{cursor:none!important}`,Cn=128,kn=Object.freeze({auto:"arrow",default:"arrow",none:"none",pointer:"pointer",grab:"grab","-webkit-grab":"grab",grabbing:"grabbing","-webkit-grabbing":"grabbing",move:"move","all-scroll":"move",text:"text","vertical-text":"vertical-text",crosshair:"crosshair","not-allowed":"not-allowed","no-drop":"not-allowed",help:"help",wait:"wait",progress:"progress",copy:"copy",alias:"alias","context-menu":"context-menu",cell:"cell","n-resize":"ns-resize","s-resize":"ns-resize","ns-resize":"ns-resize","e-resize":"ew-resize","w-resize":"ew-resize","ew-resize":"ew-resize","ne-resize":"nesw-resize","sw-resize":"nesw-resize","nesw-resize":"nesw-resize","nw-resize":"nwse-resize","se-resize":"nwse-resize","nwse-resize":"nwse-resize","col-resize":"col-resize","row-resize":"row-resize","zoom-in":"zoom-in","-webkit-zoom-in":"zoom-in","zoom-out":"zoom-out","-webkit-zoom-out":"zoom-out"}),$o=Object.freeze(Object.keys(kn));St=new Map;Vo=r=>/\.cur(?:[?#]|$)/i.test(r)||/^data:image\/(?:x-win-bitmap|x-icon|vnd\.microsoft\.icon)/i.test(r),Rt=class{constructor({ImageCtor:e=globalThis.Image,fetchFn:t=globalThis.fetch}={}){this._Image=e,this._fetch=t,this._m=new Map}get(e){let t=this._m.get(e);if(t)return t;if(t={url:e,state:"loading",image:null,width:0,height:0,curHotspot:null},this._m.set(e,t),typeof this._Image!="function")return t.state="failed",t;let i=new this._Image;i.crossOrigin="anonymous";let n=1,s=()=>{--n>0||t.state==="failed"||(t.state="ready")};return i.onload=()=>{let o=i.naturalWidth||i.width,a=i.naturalHeight||i.height;if(!(o>0&&a>0))return void(t.state="failed");t.image=i,t.width=o,t.height=a,s()},i.onerror=()=>{t.state="failed"},Vo(e)&&typeof this._fetch=="function"&&(n++,Promise.resolve().then(()=>this._fetch(e,e.startsWith("data:")?void 0:{mode:"cors"})).then(o=>o&&o.ok!==!1?o.arrayBuffer():null).then(o=>{t.curHotspot=o?On(o,t.width):null}).catch(()=>{}).finally(s)),i.src=e,t}},Li=new Rt;Ee=r=>{let e=0;for(let t=0;t<r.length;t++){let[i,n]=r[t],[s,o]=r[(t+1)%r.length];e+=i*o-s*n}return e>0?r:r.reverse()};V=(r,e,t)=>Ee([r,e,t]),Be=(r,e,t,i)=>{let n=e*Math.PI/180,s=Math.cos(n),o=Math.sin(n);return r.map(a=>Ee(a.map(([l,c])=>[t+(l-t)*s-(c-i)*o,i+(l-t)*o+(c-i)*s])))},se=(r,e,t=0,i=0)=>r.map(n=>n.map(([s,o])=>[s*e+t,o*e+i])),Xe=()=>[ee.map(([r,e])=>[r*19,e*19])],Mt=()=>[R(8,3,11,16),V([9.5,0],[14.2,5],[4.8,5]),V([9.5,19],[4.8,14],[14.2,14])],Sn=()=>[R(8,1,11,18),R(3.4,8,7.4,11),V([0,9.5],[4.4,5],[4.4,14]),R(11.6,8,15.6,11),V([19,9.5],[14.6,14],[14.6,5])],Xo=()=>[R(3,0,16,3),R(3,16,16,19),V([4.2,.5],[14.8,.5],[9.5,10]),V([9.5,9],[14.8,18.5],[4.2,18.5])],Mn=()=>[Pn(7.5,7.5,7),Et(11.6,11.6,18.4,18.4,3.8,1)];Go=null,En=new Map;Oi=(r,e,t)=>{let i=1/0;for(let n of r)i=Math.min(i,jn(n,e,t));return i},Di=(r,e)=>e>0?Math.min(1,Math.max(0,.5-r/e)):r<0?1:0;In=100;Ct=class{constructor(e,{throttleMs:t=In}={}){this.pointer=e,this.throttleMs=t,this.css=null,this.reads=0,this._el=null,this._stale=!0,this._urgent=!0,this._lastRead=-1/0;let i=n=>s=>{let o=typeof s.composedPath=="function"?s.composedPath():null,a=o&&o.length?o[0]:s.target;a&&a.nodeType===1&&(this._el=a),this._stale=!0,n&&(this._urgent=!0)};this._onMove=i(!1),this._onPress=i(!0),this._target=e.scope==="window"?globalThis:e.canvas,this._target&&this._target.addEventListener&&(this._target.addEventListener("pointermove",this._onMove),this._target.addEventListener("pointerdown",this._onPress),this._target.addEventListener("pointerup",this._onPress),this._target.addEventListener("pointercancel",this._onPress))}value(e=globalThis.performance?globalThis.performance.now():Date.now()){return this._stale&&(this._urgent||this.css===null||e-this._lastRead>=this.throttleMs)&&this.read(e),this.css??"auto"}shape(e){return Tn(this.value(e))}read(e=globalThis.performance?globalThis.performance.now():Date.now()){let t=globalThis.document,i=this.pointer.canvas,n=this._el;n&&n.isConnected===!1&&(n=null);let s=Fn(n||i,[i,t&&t.documentElement]);return this.reads++,this._lastRead=e,this._stale=!1,this._urgent=!1,s!==null&&(this.css=s),this.css??"auto"}dispose(){this._target&&this._target.removeEventListener&&(this._target.removeEventListener("pointermove",this._onMove),this._target.removeEventListener("pointerdown",this._onPress),this._target.removeEventListener("pointerup",this._onPress),this._target.removeEventListener("pointercancel",this._onPress))}},qe=class{constructor(e,{shape:t="auto",shapeFor:i=null,images:n=Li}={}){if(!ye.includes(t))throw new Error(`@displayxr/inline3d: cursor.shape "${t}" \u2014 expected ${ye.join(", ")}.`);this.option=t,this.shapeFor=typeof i=="function"?i:null,this.images=n,this.reader=t==="auto"?new Ct(e):null,this.sprite=Me(t==="auto"?"arrow":t)}get current(){return this.sprite.kind==="shape"?this.sprite.name:this.sprite.kind}pick(e,t){let i=this.reader?this.reader.value(t):null,n=i===null?null:Dn(i,this.images),s=n?n.kind==="shape"?n.name:n.kind:null,o;if(this.shapeFor)try{o=this.shapeFor({...e,css:s,cssValue:i})}catch(l){this._warned||(this._warned=!0,console.warn("[inline3d] cursor.shapeFor threw; using the page cursor.",l))}let a=l=>l==="none"||we.includes(l);return a(o)?this.sprite=Me(o):a(this.option)?this.sprite=Me(this.option):this.sprite=n||Me("arrow"),this.sprite}dispose(){this.reader?.dispose()}}});function $n(r){return r>0&&Number.isFinite(r)?Math.min(.5,Bi/r):Yo}function Un(r,e){return r<=Ko?!(e>0&&Number.isFinite(e))||-r*e>=Jo:!1}function Xi(r,e,t){if(!e||!Number.isFinite(t)||!(t<0))return 0;let i=Math.min(0,Number.isFinite(r.maxDisparity)?r.maxDisparity:0);return Math.min(i,Math.max(r.minDisparity,t-r.margin))}function Vn(r,e,t,i){if(!r.primed||i<r.last||i-r.last>e.stale)return r.primed=!0,r.disparity=t,r.last=i,t;if(i===r.last)return r.disparity;let n=i-r.last,s=t<r.disparity?e.riseTau:e.sinkTau,o=s>0?1-Math.exp(-n/s):1;return r.disparity+=o*(t-r.disparity),r.last=i,r.disparity}function zn(r){let e=r&&r.pointerType;return!e||e==="mouse"?!0:e==="pen"?!(r.buttons>0):!1}function Zo(r){return!!r&&"onpointerrawupdate"in r&&globalThis.isSecureContext!==!1}function Qo(r){let e=globalThis.document;if(!e||!e.documentElement)return;r&&kt(e),Ui=Math.max(0,Ui+(r?1:-1));let t=e.documentElement;Ui>0?t.setAttribute?.(B,""):t.removeAttribute?.(B)}function Wn(r){return!!r&&typeof r.setCursorDepth=="function"&&typeof r.getCursorDepthSupport=="function"}function ra(r,e,t,i){let n=.75*t,s=[[r,e]];for(let o=0;o<8;o++){let a=o*Math.PI/4;s.push([r+n*Math.cos(a)/i,e+n*Math.sin(a)])}return s}function Bn(r,e,t,i){return[[r,e],...ra(r+.3*t/i,e+.5*t,t,i)]}function Tt(r,e=ee){let t=0;for(let s=0;s<e.length;s++){let[o,a]=e[s],[l,c]=e[(s+1)%e.length];t+=o*c-l*a}let i=t>0?1:-1,n=e.map((s,o)=>{let a=e[(o+1)%e.length],l=a[0]-s[0],c=a[1]-s[1],d=Math.hypot(l,c)||1;return[-c/d*i,l/d*i]});return e.map((s,o)=>{let a=n[(o+e.length-1)%e.length],l=n[o],c=r/(1+a[0]*l[0]+a[1]*l[1]);return[s[0]+(a[0]+l[0])*c,s[1]+(a[1]+l[1])*c]})}function Xn(r,e,t,i=ve){let n={blurPx:0,alpha:1},s=i;if(!s)return n;if(s.blur&&Number.isFinite(e)&&s.blurK>0&&s.blurMaxPx>0){let o=s.blurMaxPx;if(s.blurMaxFrac>0&&Number.isFinite(t)&&t>0){let l=s.blurMaxFrac*t;o=l<o?l:o}let a=s.blurK*Math.abs(e);n.blurPx=a<o?a:o}if(s.alpha&&Number.isFinite(r)&&s.fullD>0){let o=Math.abs(r)/s.fullD;o=o<1?o:1;let a=o*o*(3-2*o),l=s.alphaMin<0?0:s.alphaMin>1?1:s.alphaMin;n.alpha=1-(1-l)*a}return n}function jn(r,e,t){let i=(e-r[0][0])**2+(t-r[0][1])**2,n=1;for(let s=0,o=r.length-1;s<r.length;o=s,s++){let a=r[s],l=r[o],c=l[0]-a[0],d=l[1]-a[1],f=e-a[0],h=t-a[1],u=Math.min(1,Math.max(0,(f*c+h*d)/(c*c+d*d))),p=f-c*u,m=h-d*u;i=Math.min(i,p*p+m*m);let g=t>=a[1],_=t<l[1],b=c*h>d*f;(g&&_&&b||!g&&!_&&!b)&&(n=-n)}return n*Math.sqrt(i)}var Yo,Bi,Ko,Jo,Pt,Ot,Ui,ea,ta,ia,Vi,Dt,Hn,ee,Tl,Nn,Wi,Hi,Ge,Ol,Dl,Pl,$i=le(()=>{"use strict";be();be();zi();zi();Yo=.03,Bi=19;Ko=-.005,Jo=.5;Pt=Object.freeze({margin:.015,minDisparity:-.6,maxDisparity:0,riseTau:.03,sinkTau:.25,stale:.5});Ot=class{constructor(e,{scope:t="canvas",keepCss:i=!1}={}){if(t!=="canvas"&&t!=="window")throw new Error(`@displayxr/inline3d: cursor pointerScope "${t}" \u2014 expected 'canvas' or 'window'.`);this.canvas=e,this.scope=t,this.keepCss=!!i,this._uv=null,this.sampleTime=0,this.samples=0,this._hidden=!1,this._cx=0,this._cy=0,this._pending=!1,this._onMove=n=>this._sample(n),this._onLeave=()=>{this.uv=null},this._onDown=n=>{zn(n)||(this.uv=null)},this._target=t==="window"?globalThis:e,this.source=Zo(this._target)?"pointerrawupdate":"pointermove",this._target.addEventListener("pointermove",this._onMove),this.source==="pointerrawupdate"&&this._target.addEventListener("pointerrawupdate",this._onMove),this._target.addEventListener("pointerdown",this._onDown),t==="window"?(this._onOut=n=>{n.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}get uv(){if(this._pending){this._pending=!1;let e=this.canvas.getBoundingClientRect();if(!(e.width>0&&e.height>0))this._uv=null;else{let t=(this._cx-e.left)/e.width,i=(this._cy-e.top)/e.height;this._uv=t>=0&&t<=1&&i>=0&&i<=1?[t,i]:null}}return this._uv}set uv(e){this._pending=!1,this._uv=e}_sample(e){if(!zn(e)){this.uv=null;return}let t=typeof e.getCoalescedEvents=="function"?e.getCoalescedEvents():null,i=t&&t.length?t[t.length-1]:e,n=i.timeStamp>0?i.timeStamp:e.timeStamp>0?e.timeStamp:globalThis.performance?globalThis.performance.now():Date.now();n<this.sampleTime||(this.samples++,this.sampleTime=n,this._cx=i.clientX,this._cy=i.clientY,this._pending=!0)}set(e,t){this.uv=e==null?null:[e,t]}aspect(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.width/e.height:1}cssHeight(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.height:0}panelPx(){return this.cssHeight()*(globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1)}panelSize(){let e=this.canvas.getBoundingClientRect(),t=globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1;return e.width>0&&e.height>0?[e.width*t,e.height*t]:[0,0]}hideCss(e){this.keepCss&&(e=!1),e!==this._hidden&&(this.scope==="window"?Qo(e):this.canvas.setAttribute&&(e?(kt(),this.canvas.setAttribute(B,"")):this.canvas.removeAttribute(B)),this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.source==="pointerrawupdate"&&this._target.removeEventListener("pointerrawupdate",this._onMove),this._target.removeEventListener("pointerdown",this._onDown),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}};Ui=0;ea=2e3,ta=6,ia=1e4;Vi=new WeakMap,Dt=class{constructor(){this.target=null,this._sent=!1,this.last=null}get support(){let e=this.target;if(!Wn(e))return"none";let t=Vi.get(e);return t?t.state:"pending"}get drawing(){return this.support==="runtime"}bind(e){let t=e||null;if(t!==this.target&&(this.withdraw(),this.target=t),!Wn(t))return!1;let i=Vi.get(t);if(i||Vi.set(t,i={state:"pending",probes:0,inFlight:!1,at:0}),i.state==="runtime"||i.inFlight)return i.state==="runtime";let n=globalThis.performance?globalThis.performance.now():Date.now(),s=i.probes<ta?ea:ia;if(i.probes===0||n-i.at>=s){i.probes++,i.at=n,i.inFlight=!0;let o;try{o=Promise.resolve(t.getCursorDepthSupport())}catch(a){o=Promise.reject(a)}o.then(a=>{i.inFlight=!1,i.state=a==="runtime"?"runtime":"none"},()=>{i.inFlight=!1,i.state="none"})}return i.state==="runtime"}report(e,t,i){if(!this.drawing)return!1;let n={u:Hn(e),v:Hn(t)};i!=null&&Number.isFinite(i)&&(n.disparityPx=i);try{this.target.setCursorDepth(n)}catch{return!1}return this._sent=!0,this.last={u:n.u,v:n.v,disparityPx:n.disparityPx??null},!0}withdraw(){if(this.last=null,!!this._sent){this._sent=!1;try{this.target?.setCursorDepth()}catch{}}}dispose(){this.withdraw(),this.target=null}},Hn=r=>r>0?r<1?r:1:0;ee=Object.freeze([[0,0],[0,16],[4.2,12.4],[6.9,18.6],[9.5,17.5],[6.8,11.5],[11.7,11.5]].map(([r,e])=>Object.freeze([r/19,e/19]))),Tl=Object.freeze([[0,1,2],[0,2,5],[0,5,6],[2,3,4],[2,4,5]]);Nn=Object.freeze(Tt(1/19).map(r=>Object.freeze(r))),Wi=Object.freeze([1,1,1,1]),Hi=Object.freeze([.02,.02,.03,1]);Ge=Object.freeze([Object.freeze([0,0,1]),...[[.5,0],[-.5,0],[0,.5],[0,-.5]].map(([r,e])=>Object.freeze([r,e,.7066])),...Array.from({length:8},(r,e)=>{let t=.3927+.7854*e;return Object.freeze([Math.cos(t),Math.sin(t),.2494])})]),Ol=Object.freeze([Math.max(...ee.map(r=>r[0])),Math.max(...ee.map(r=>r[1]))]);Dl=Object.freeze({declarations:`#ifdef PICK_PASS
|
|
3
3
|
#include "pickPS"
|
|
4
4
|
#endif
|
|
@@ -25,8 +25,11 @@ on real panels; everything else about how your scene looks is your call.
|
|
|
25
25
|
5. **Low contrast between the subject and what is behind it.** The display's crosstalk correction
|
|
26
26
|
works only within the range of the image, so a bright edge on black ghosts first. A light or
|
|
27
27
|
mid-tone, low-contrast background works best: a real texture or a soft gradient, not generated
|
|
28
|
-
noise. A dark grey is the minimum
|
|
29
|
-
|
|
28
|
+
noise. A dark grey is the minimum (a bright orange beak still ghosts against it), and pure
|
|
29
|
+
black is the worst case; keep the subject's darkest faces above the background. In front of
|
|
30
|
+
the glass, contrast matters more than the depth number: the same pop-out read fine on a
|
|
31
|
+
mid-tone globe and ghosted on a dark one. Keep bright subjects off near-black backgrounds,
|
|
32
|
+
above all the ones that come closest. Soften high-contrast detail far from the glass in the colours and
|
|
30
33
|
materials, not with fog, since camera-distance fog follows the viewer's head.
|
|
31
34
|
6. **Text: flat HTML near the glass, at a readable size.** Text drawn in the 3D scene, especially
|
|
32
35
|
white on dark, ghosts. Put titles, labels and values in HTML, or keep in-scene labels close to
|
|
@@ -39,9 +42,14 @@ on real panels; everything else about how your scene looks is your call.
|
|
|
39
42
|
8. **No detail finer than a few pixels.** Thin lines, single-pixel stars and fine repeating
|
|
40
43
|
patterns alias and shimmer as the head moves. Draw them thicker, softer or as sprites, and size
|
|
41
44
|
textures to their surfaces instead of stretching them.
|
|
42
|
-
9. **A cover over the canvas must always come off
|
|
43
|
-
also remove the cover after a few seconds and if your setup
|
|
44
|
-
leaves the page with its UI and no scene.
|
|
45
|
+
9. **A cover over the canvas must always come off, and only a lost layer means flat.** If you
|
|
46
|
+
hide the canvas until `firstWoven`, also remove the cover after a few seconds and if your setup
|
|
47
|
+
throws; otherwise a missed signal leaves the page with its UI and no scene. A `firstWoven` of
|
|
48
|
+
`woven: false` is not "no 3D here": drop the cover and keep drawing both eyes (the layer can
|
|
49
|
+
still join). Go flat only on `onLayerLost` or with no session. And never draw one full-width
|
|
50
|
+
flat picture into a canvas the browser is still weaving: it splits it, so each eye sees a
|
|
51
|
+
different half of the room. To show a flat picture on purpose, remove the scene first, or call
|
|
52
|
+
`setStereoEnabled(false)` and keep drawing every view you are given.
|
|
45
53
|
|
|
46
54
|
The mechanics (one view per eye, CSS that breaks the weave, the 2D/3D switch) are in
|
|
47
55
|
[woven-canvas-rules.md](woven-canvas-rules.md) and [authoring-inline-3d.md](authoring-inline-3d.md),
|
|
@@ -121,7 +121,7 @@ poster.remove(); // cut, never fade
|
|
|
121
121
|
|---|---|---|
|
|
122
122
|
| `woven: true`, `reason: 'woven'`, `confirmed: true` | the browser reported the layer woven (`XRDisplayLayer.wovenState`), after a real stereo frame | drop the cover |
|
|
123
123
|
| `woven: true`, `reason: 'hold-elapsed'` | a browser without that report: the window has drawn a real stereo frame on a layer that has existed for `firstWovenHoldMs` (default **1200**, the browser's measured worst case) | drop the cover |
|
|
124
|
-
| `woven: false`, `confirmed: true`, `reason` a withheld token (or `'pending'`) | the browser kept reporting the layer withheld for the whole safety cap (four holds, at least 4.8 s). The canvas is not taken flat | drop the cover
|
|
124
|
+
| `woven: false`, `confirmed: true`, `reason` a withheld token (or `'pending'`) | the browser kept reporting the layer withheld for the whole safety cap (four holds, at least 4.8 s). The canvas is not taken flat, and the layer can still join | drop the cover and **keep drawing both eyes**, then read the token in §3: it names the page fix. Do not switch to a flat full-width picture: the browser is still weaving the canvas and would give each eye a different half of it |
|
|
125
125
|
| `woven: false`, `reason: 'layer-failed'` / `'session-ended'` / `'removed'` | this window will not weave. An image or video canvas has already been painted flat, and a scene's `onLayerLost` has already run | drop the cover onto the 2D fallback |
|
|
126
126
|
| `woven: false`, `reason: 'unsupported'` (`addSplat` / `addModel` only) | no inline-3D session: the viewer is on its mono path | same |
|
|
127
127
|
|
|
@@ -3983,6 +3983,10 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
|
|
|
3983
3983
|
// three looks down −z; convergence is the focus's distance along that axis (the PLANE).
|
|
3984
3984
|
const fwd = [-pose[8], -pose[9], -pose[10]];
|
|
3985
3985
|
const d = (f.x - pose[12]) * fwd[0] + (f.y - pose[13]) * fwd[1] + (f.z - pose[14]) * fwd[2];
|
|
3986
|
+
// A focus at or behind the camera has no zero-disparity plane in front of it: a transient
|
|
3987
|
+
// before the first focus lands, or a focus moved behind the camera. Keep the rig as declared;
|
|
3988
|
+
// convergence at infinity would put the whole scene in front of the glass.
|
|
3989
|
+
if (!(d > 0)) return;
|
|
3986
3990
|
if (!force && Math.abs(d - lastConvergence) < 1e-3) return;
|
|
3987
3991
|
lastConvergence = d;
|
|
3988
3992
|
out.rig.convergence = d;
|
|
@@ -3996,7 +4000,7 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
|
|
|
3996
4000
|
fov: viewer.mono.fov,
|
|
3997
4001
|
},
|
|
3998
4002
|
{
|
|
3999
|
-
convergence: d
|
|
4003
|
+
convergence: d,
|
|
4000
4004
|
ipdFactor: out.rig.ipdFactor,
|
|
4001
4005
|
parallaxFactor: out.rig.parallaxFactor,
|
|
4002
4006
|
out: camRigObj,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.47.
|
|
3
|
+
"version": "1.47.2",
|
|
4
4
|
"description": "Turn any HTML <canvas> into a 3D window on a spatial display, inside an ordinary web page, for the DisplayXR Browser. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|