@displayxr/inline3d 1.46.0 → 1.47.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/CHANGELOG.md +75 -0
- package/README.md +3 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/depth.d.ts +184 -0
- package/dist/call.js +6 -6
- package/docs/making-3d-look-right.md +49 -0
- package/docs/woven-canvas-rules.md +378 -0
- package/index.d.ts +22 -3
- package/js/inline3d-depth-budget.js +342 -0
- package/js/inline3d-model-entry.js +15 -1
- package/js/inline3d-model-playcanvas.js +27 -2
- package/js/inline3d-model.js +22 -2
- package/js/inline3d-splat-deferred.js +2 -0
- package/js/inline3d-splat-pc-entry.js +2 -1
- package/js/inline3d-splat-playcanvas.js +42 -42
- package/js/inline3d-splat-shared.js +311 -0
- package/js/inline3d-splat.js +31 -3
- package/js/inline3d-three.js +30 -10
- package/js/inline3d-viewer.js +13 -0
- package/js/inline3d.js +35 -0
- package/llms.txt +21 -0
- package/model.d.ts +53 -0
- package/package.json +10 -1
- package/splat.d.ts +33 -0
- package/three.d.ts +7 -2
- package/viewer.d.ts +11 -0
package/js/inline3d-viewer.js
CHANGED
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
mismatchWarning,
|
|
74
74
|
} from './inline3d-buffer-limit.js';
|
|
75
75
|
import { viewerEaseFor, frameTrackingState } from './inline3d-viewer-ease.js';
|
|
76
|
+
import { parseClearColor } from './inline3d-splat-shared.js';
|
|
76
77
|
|
|
77
78
|
const clamp = (v, lo, hi) => (v < lo ? lo : v > hi ? hi : v);
|
|
78
79
|
// NaN/Infinity into a transform silently blanks the tile — three propagates it into the
|
|
@@ -269,6 +270,10 @@ export class SceneViewer {
|
|
|
269
270
|
* @param {number} [opts.feather=0] edge fade in buffer px (needs ./three's EdgeFeather).
|
|
270
271
|
* @param {number[]} [opts.pitchLimit=[-60,60]] degrees; stops the viewer rolling under the
|
|
271
272
|
* subject, which reads as broken rather than as a feature.
|
|
273
|
+
* @param {number[]|string} [opts.clearColor] OPT-IN eye clear, `[r,g,b,a]` in 0..1 or a CSS
|
|
274
|
+
* colour. Unset: the transparent clear (0,0,0,0), exactly as before. An opaque clear
|
|
275
|
+
* avoids stale / black pixels on the weave (web#198); match the page colour behind the
|
|
276
|
+
* canvas.
|
|
272
277
|
*/
|
|
273
278
|
constructor(THREE, canvas, opts = {}) {
|
|
274
279
|
const {
|
|
@@ -307,11 +312,19 @@ export class SceneViewer {
|
|
|
307
312
|
this.logTag = opts.logTag || '[inline3d/viewer]';
|
|
308
313
|
this.pitchLimit = pitchLimit;
|
|
309
314
|
this.idleSpin = idleSpin;
|
|
315
|
+
// Opt-in (null = off, and then nothing below differs from before it existed).
|
|
316
|
+
this.clearColor = parseClearColor(opts.clearColor, this.logTag);
|
|
310
317
|
|
|
311
318
|
// alpha + a zero-alpha clear so the tile can dissolve into the page rather than ending at
|
|
312
319
|
// a hard rectangle. An opaque scene.background would defeat both this and the feather.
|
|
313
320
|
this.renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
|
|
314
321
|
this.renderer.setClearColor(0x000000, 0);
|
|
322
|
+
// clearColor (opt-in) replaces that clear. three reads a hex as sRGB, as a CSS colour is.
|
|
323
|
+
if (this.clearColor) {
|
|
324
|
+
const [r, g, b, a] = this.clearColor;
|
|
325
|
+
const hex = (Math.round(r * 255) << 16) | (Math.round(g * 255) << 8) | Math.round(b * 255);
|
|
326
|
+
this.renderer.setClearColor(hex, a);
|
|
327
|
+
}
|
|
315
328
|
// MUST be 1. layer.getViewport() reports BACKING-STORE px, but three.js multiplies whatever
|
|
316
329
|
// you pass setViewport()/setScissor() by the renderer's pixelRatio — so any other value
|
|
317
330
|
// silently scales every eye viewport (at dpr 2 the left eye covers the whole canvas). It
|
package/js/inline3d.js
CHANGED
|
@@ -36,6 +36,20 @@ import { setSessionViewerEase } from './inline3d-viewer-ease.js';
|
|
|
36
36
|
export { ViewerEase, resolveViewerEaseOption, frameTrackingState, VIEWER_EASE_DEFAULT_MS } from './inline3d-viewer-ease.js';
|
|
37
37
|
export { DISPLAY_METRICS_DEFAULTS, displayMetricsFrom } from './inline3d-display-metrics.js';
|
|
38
38
|
import { displayMetricsFrom } from './inline3d-display-metrics.js';
|
|
39
|
+
// The depth budget: pure measurements (how deep is this scene, in % of the tile width) and the
|
|
40
|
+
// one-time rig warnings. Never a behaviour change — see ./inline3d-depth-budget.js.
|
|
41
|
+
export {
|
|
42
|
+
DEPTH_EYE_SEPARATION_M,
|
|
43
|
+
DEPTH_DEFAULT_VIEWER_M,
|
|
44
|
+
disparityPct,
|
|
45
|
+
cameraRigDisparityPct,
|
|
46
|
+
depthBudgetFromBounds,
|
|
47
|
+
comfortZone,
|
|
48
|
+
comfortDepthFactor,
|
|
49
|
+
cameraRigComfortFactor,
|
|
50
|
+
withheldReasonHint,
|
|
51
|
+
} from './inline3d-depth-budget.js';
|
|
52
|
+
import { warnViewRigOnce, withheldReasonHint } from './inline3d-depth-budget.js';
|
|
39
53
|
|
|
40
54
|
// The eased 2D<->3D transition. A pure state machine (no DOM, no WebXR) ported from the native
|
|
41
55
|
// `dxr::ModeSwitch`, so the browser eases the disparity around a mode switch the same way — and in
|
|
@@ -1272,6 +1286,9 @@ class Inline3D {
|
|
|
1272
1286
|
},
|
|
1273
1287
|
setViewRig: (rig) => {
|
|
1274
1288
|
win.viewRig = rig || null;
|
|
1289
|
+
// One-time console warnings for a rig that looks like a mistake (convergence at infinity,
|
|
1290
|
+
// factors > 1, a FOV in degrees). Read only: the rig goes out exactly as given.
|
|
1291
|
+
if (rig) warnViewRigOnce(win.rigWarned, rig);
|
|
1275
1292
|
return this._pushViewRig(win);
|
|
1276
1293
|
},
|
|
1277
1294
|
/**
|
|
@@ -2367,6 +2384,10 @@ class Inline3D {
|
|
|
2367
2384
|
// and rebuilds layers behind the page's back: a tile that scrolls away and back would
|
|
2368
2385
|
// otherwise silently revert to the default display rig mid-scene.
|
|
2369
2386
|
viewRig: opts.viewRig || null,
|
|
2387
|
+
// Which one-time rig warnings this window has given (setViewRig / opts.viewRig), and
|
|
2388
|
+
// whether its 'withheld' reason has been logged. Diagnostics only.
|
|
2389
|
+
rigWarned: new Set(),
|
|
2390
|
+
warnedWithheld: false,
|
|
2370
2391
|
// The automatic 1-view collapse (the latch itself is manager-wide — the mode is the
|
|
2371
2392
|
// display's, not this window's). `stereoSaved` records the factors in force when the panel
|
|
2372
2393
|
// went flat, for diagnostics; the restore just re-pushes `viewRig`, which the flattening
|
|
@@ -2433,6 +2454,7 @@ class Inline3D {
|
|
|
2433
2454
|
win.fwPromise = new Promise((resolve) => {
|
|
2434
2455
|
win.fwResolve = resolve;
|
|
2435
2456
|
});
|
|
2457
|
+
if (win.viewRig) warnViewRigOnce(win.rigWarned, win.viewRig); // as handle.setViewRig: read only
|
|
2436
2458
|
this._windows.set(canvas, win);
|
|
2437
2459
|
if (this._lazy && this._observer) {
|
|
2438
2460
|
this._observer.observe(win.observeEl);
|
|
@@ -3430,7 +3452,19 @@ class Inline3D {
|
|
|
3430
3452
|
* the browser's report; a confirmed `woven: false` is a capped 'withheld' level, which can still
|
|
3431
3453
|
* recover, so it is NOT a terminal "will not weave" and leaves rewoven() usable.
|
|
3432
3454
|
*/
|
|
3455
|
+
/**
|
|
3456
|
+
* The browser REPORTED this layer withheld long enough to settle a firstWoven / rewoven on it:
|
|
3457
|
+
* say why, once per window (the reason is otherwise only in the settled result). A console line,
|
|
3458
|
+
* nothing else — the window keeps doing exactly what it did.
|
|
3459
|
+
*/
|
|
3460
|
+
_noteWithheld(win, woven, reason, confirmed) {
|
|
3461
|
+
if (woven || !confirmed || win.warnedWithheld || !reason || reason === 'pending' || reason === 'hold-capped') return;
|
|
3462
|
+
win.warnedWithheld = true;
|
|
3463
|
+
console.warn(`[inline3d] the browser withheld this canvas from the weave (${reason}): ${withheldReasonHint(reason)}.`, win.canvas);
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3433
3466
|
_settleFirstWoven(win, woven, reason, confirmed = false) {
|
|
3467
|
+
this._noteWithheld(win, woven, reason, confirmed);
|
|
3434
3468
|
// Every "will not weave" path lands here, so a pending rewoven() is released with it, and a
|
|
3435
3469
|
// later one answers at once (firstWoven may have settled woven:true long before).
|
|
3436
3470
|
if (!woven && !confirmed) {
|
|
@@ -3498,6 +3532,7 @@ class Inline3D {
|
|
|
3498
3532
|
_settleRewoven(win, woven, reason, confirmed = false) {
|
|
3499
3533
|
const rw = win.rw;
|
|
3500
3534
|
if (!rw) return;
|
|
3535
|
+
this._noteWithheld(win, woven, reason, confirmed);
|
|
3501
3536
|
win.rw = null;
|
|
3502
3537
|
rw.resolve(Object.freeze({ woven, confirmed, reason, ms: Math.round(nowMs() - rw.calledAt) }));
|
|
3503
3538
|
}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @displayxr/inline3d — DisplayXR inline-3D web SDK
|
|
2
|
+
|
|
3
|
+
> Glasses-free 3D for web pages on a DisplayXR spatial display: you render one image per eye into a
|
|
4
|
+
> canvas, the DisplayXR Browser weaves them for the panel; an ordinary browser shows the page in 2D.
|
|
5
|
+
|
|
6
|
+
Read first: docs/making-3d-look-right.md — nine depth and comfort rules from real panels
|
|
7
|
+
(keep the viewers' object placement and frame the first view, lay flat arrangements back into
|
|
8
|
+
depth, keep moving things' forward swing small, fixed convergence and no near geometry in worlds,
|
|
9
|
+
low contrast behind the subject, text as HTML near the glass, no coplanar surfaces, no sub-pixel
|
|
10
|
+
detail, a cover that always comes off). The SDK's defaults do the rest.
|
|
11
|
+
|
|
12
|
+
## Samples (they show the API, not a look to copy)
|
|
13
|
+
- samples/model/, samples/splat/, samples/hello-cube/, samples/camera-rig/, samples/display-modes/
|
|
14
|
+
|
|
15
|
+
## Reference
|
|
16
|
+
- docs/authoring-inline-3d.md — every API, both view rigs, comfort maths
|
|
17
|
+
- docs/woven-canvas-rules.md — what the browser does to a woven canvas; CSS, remount and cover rules
|
|
18
|
+
- docs/porting-three-js-apps.md — moving an existing three.js app over
|
|
19
|
+
- docs/authoring-motion-and-effects.md, docs/splat-effects.md — motion, reveals, depth envelopes
|
|
20
|
+
- index.d.ts, three.d.ts, viewer.d.ts, model.d.ts, splat.d.ts — the public API with JSDoc
|
|
21
|
+
- CHANGELOG.md — what changed per release
|
package/model.d.ts
CHANGED
|
@@ -30,6 +30,33 @@ export interface ModelOptions {
|
|
|
30
30
|
margin?: number;
|
|
31
31
|
/** Backstop on total depth, in display heights (default 4.0). Rarely binds. */
|
|
32
32
|
depthLimit?: number;
|
|
33
|
+
/**
|
|
34
|
+
* OPT-IN eye clear: `[r, g, b, a]` in 0..1 (alpha defaults to 1) or a CSS colour string (`#hex`,
|
|
35
|
+
* `rgb()`/`rgba()`, `transparent`, or any colour the browser parses). Unset: the transparent
|
|
36
|
+
* clear, exactly as before. An OPAQUE clear is recommended: where the weave reads an alpha-0
|
|
37
|
+
* pixel it can show stale or black pixels (web#198). Make the page colour behind the canvas
|
|
38
|
+
* match, so the 2D fallback and any feathered edge look the same. Unreadable → one warning,
|
|
39
|
+
* the default clear stays.
|
|
40
|
+
*/
|
|
41
|
+
clearColor?: [number, number, number] | [number, number, number, number] | string;
|
|
42
|
+
/**
|
|
43
|
+
* OPT-IN comfort depth (display rig only). `'auto'` (the Shibata zone of comfort) or
|
|
44
|
+
* `{ zone: 'shibata' | 'percival' | <diopters> }`. The SDK measures the framed subject's depth
|
|
45
|
+
* (tile heights in front of / behind the glass), the canvas's physical height
|
|
46
|
+
* (`displayMetrics()`) and the display's NOMINAL viewer distance (`getDisplayInfo()`, 0.6 m when
|
|
47
|
+
* it reports none — never the live head distance), and multiplies the display rig's `ipdFactor`
|
|
48
|
+
* and `parallaxFactor` (together) by `comfortDepthFactor()` of those, on top of
|
|
49
|
+
* `setStereo`'s values. It ONLY EVER LOWERS DEPTH (the factor is ≤ 1), because the same depth in
|
|
50
|
+
* tile heights carries more vergence load on a small or close device (a tablet at 0.4 m) than on
|
|
51
|
+
* a laptop at 0.6 m: where the subject already fits, nothing changes.
|
|
52
|
+
*
|
|
53
|
+
* Measured when the subject is first framed, when the canvas resizes and when the display
|
|
54
|
+
* reports a change — NOT on zoom or orbit (those are framing choices the developer owns; the box
|
|
55
|
+
* is the framed one at zoom 1), and not per frame. Read the factor in force from `depthFactor`.
|
|
56
|
+
* Ignored, with one console warning, on a camera rig or under `controls: 'page'`. Anything else
|
|
57
|
+
* throws at the call. Unset: nothing is measured or declared — the tile is exactly as before.
|
|
58
|
+
*/
|
|
59
|
+
depth?: 'auto' | { zone?: 'shibata' | 'percival' | number };
|
|
33
60
|
/**
|
|
34
61
|
* Fit the horizontal against the box's DIAGONAL (width and depth) rather than width alone,
|
|
35
62
|
* so a long subject still fits once the turntable turns it (default true).
|
|
@@ -203,6 +230,32 @@ export interface ModelHandle {
|
|
|
203
230
|
/** Resolves once the model has loaded and been framed; rejects if the load failed. */
|
|
204
231
|
readonly ready: Promise<ModelHandle>;
|
|
205
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Live stereo strength — a depth slider, mirroring `SplatHandle.setStereo`. On the display rig
|
|
235
|
+
* (the default) the values are RELATIVE: 1 = what the display shows by construction, below 1 a
|
|
236
|
+
* comfort dial, 0 flat (above 1 exaggerates; sent as given, with a one-time warning). A key given
|
|
237
|
+
* replaces, a key set to `null` returns to 1, `setStereo(null)` clears both. `ipdScale` /
|
|
238
|
+
* `parallaxScale` are accepted too (a model's own values are 1, so they agree). Sticky; applied
|
|
239
|
+
* from the next frame with no cut (pose and framing stay). Re-declares the display rig
|
|
240
|
+
* explicitly (`handle.viewRig`); nothing is declared before the first call. Under
|
|
241
|
+
* `controls: 'page'` (PlayCanvas) the page's camera rig takes them, ABSOLUTE.
|
|
242
|
+
*/
|
|
243
|
+
setStereo(opts: { ipdFactor?: number | null; parallaxFactor?: number | null; ipdScale?: number | null; parallaxScale?: number | null } | null): ModelHandle;
|
|
244
|
+
/** The rig's stereo in force (read back; `setStereo` writes it). Null until the backend has loaded. */
|
|
245
|
+
readonly rig: {
|
|
246
|
+
readonly type: 'display' | 'camera';
|
|
247
|
+
readonly ipdFactor: number;
|
|
248
|
+
readonly parallaxFactor: number;
|
|
249
|
+
readonly stereoDefault: { readonly ipdFactor: number; readonly parallaxFactor: number };
|
|
250
|
+
} | null;
|
|
251
|
+
/**
|
|
252
|
+
* The `depth` option's comfort factor in force, in (0, 1]: what the display rig's ipdFactor and
|
|
253
|
+
* parallaxFactor are multiplied by (under `setStereo`'s values). 1 without the option, before
|
|
254
|
+
* the first measurement, and on a rig it does not apply to.
|
|
255
|
+
*/
|
|
256
|
+
readonly depthFactor: number;
|
|
257
|
+
/** The view-rig descriptor last declared by `setStereo` (or `controls: 'page'`), if any. */
|
|
258
|
+
readonly viewRig?: object;
|
|
206
259
|
/** Throws on `controls: 'page'`. */
|
|
207
260
|
setPose(pose?: OrbitPose): void;
|
|
208
261
|
/** Throws on `controls: 'page'`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
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",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"types": "./cursor-depth.d.ts",
|
|
20
20
|
"import": "./js/inline3d-cursor-depth.js"
|
|
21
21
|
},
|
|
22
|
+
"./depth": {
|
|
23
|
+
"types": "./depth.d.ts",
|
|
24
|
+
"import": "./js/inline3d-depth-budget.js"
|
|
25
|
+
},
|
|
22
26
|
"./viewer": {
|
|
23
27
|
"types": "./viewer.d.ts",
|
|
24
28
|
"import": "./js/inline3d-viewer.js"
|
|
@@ -67,9 +71,13 @@
|
|
|
67
71
|
"./dist/*.js"
|
|
68
72
|
],
|
|
69
73
|
"files": [
|
|
74
|
+
"llms.txt",
|
|
75
|
+
"docs/making-3d-look-right.md",
|
|
76
|
+
"docs/woven-canvas-rules.md",
|
|
70
77
|
"js/inline3d.js",
|
|
71
78
|
"js/inline3d-undock.js",
|
|
72
79
|
"js/inline3d-display-metrics.js",
|
|
80
|
+
"js/inline3d-depth-budget.js",
|
|
73
81
|
"js/inline3d-mode-switch.js",
|
|
74
82
|
"js/inline3d-buffer-limit.js",
|
|
75
83
|
"js/inline3d-viewer-ease.js",
|
|
@@ -111,6 +119,7 @@
|
|
|
111
119
|
"dist/",
|
|
112
120
|
"index.d.ts",
|
|
113
121
|
"three.d.ts",
|
|
122
|
+
"depth.d.ts",
|
|
114
123
|
"cursor-depth.d.ts",
|
|
115
124
|
"viewer.d.ts",
|
|
116
125
|
"splat.d.ts",
|
package/splat.d.ts
CHANGED
|
@@ -409,6 +409,33 @@ export interface SplatOptions {
|
|
|
409
409
|
margin?: number;
|
|
410
410
|
/** Backstop on total depth, in display heights (default 4.0). Rarely binds. */
|
|
411
411
|
depthLimit?: number;
|
|
412
|
+
/**
|
|
413
|
+
* OPT-IN eye clear: `[r, g, b, a]` in 0..1 (alpha defaults to 1) or a CSS colour string (`#hex`,
|
|
414
|
+
* `rgb()`/`rgba()`, `transparent`, or any colour the browser parses). Unset: the transparent
|
|
415
|
+
* clear, exactly as before. An OPAQUE clear is recommended: where the weave reads an alpha-0
|
|
416
|
+
* pixel it can show stale or black pixels (web#198). Make the page colour behind the canvas
|
|
417
|
+
* match, so the 2D fallback and any feathered edge look the same. Unreadable → one warning,
|
|
418
|
+
* the default clear stays.
|
|
419
|
+
*/
|
|
420
|
+
clearColor?: [number, number, number] | [number, number, number, number] | string;
|
|
421
|
+
/**
|
|
422
|
+
* OPT-IN comfort depth (display rig only). `'auto'` (the Shibata zone of comfort) or
|
|
423
|
+
* `{ zone: 'shibata' | 'percival' | <diopters> }`. The SDK measures the framed subject's depth
|
|
424
|
+
* (tile heights in front of / behind the glass), the canvas's physical height
|
|
425
|
+
* (`displayMetrics()`) and the display's NOMINAL viewer distance (`getDisplayInfo()`, 0.6 m when
|
|
426
|
+
* it reports none — never the live head distance), and multiplies the display rig's `ipdFactor`
|
|
427
|
+
* and `parallaxFactor` (together) by `comfortDepthFactor()` of those, on top of
|
|
428
|
+
* `setStereo`'s values (Spark has no setStereo: the factor is the rig's whole ipdFactor / parallaxFactor). It ONLY EVER LOWERS DEPTH (the factor is ≤ 1), because the same depth in
|
|
429
|
+
* tile heights carries more vergence load on a small or close device (a tablet at 0.4 m) than on
|
|
430
|
+
* a laptop at 0.6 m: where the subject already fits, nothing changes.
|
|
431
|
+
*
|
|
432
|
+
* Measured when the subject is first framed, when the canvas resizes and when the display
|
|
433
|
+
* reports a change — NOT on zoom or orbit (those are framing choices the developer owns; the box
|
|
434
|
+
* is the framed one at zoom 1), and not per frame. Read the factor in force from `depthFactor`.
|
|
435
|
+
* Ignored, with one console warning, on a camera rig (an asset with a capture camera, `rig: 'camera'`) or under `controls: 'page'`. Anything else
|
|
436
|
+
* throws at the call. Unset: nothing is measured or declared — the tile is exactly as before.
|
|
437
|
+
*/
|
|
438
|
+
depth?: 'auto' | { zone?: 'shibata' | 'percival' | number };
|
|
412
439
|
/**
|
|
413
440
|
* Fit the horizontal against the box's DIAGONAL (width and depth) rather than width alone,
|
|
414
441
|
* so a long subject still fits once the turntable turns it (default true).
|
|
@@ -1109,6 +1136,12 @@ export interface SplatHandle {
|
|
|
1109
1136
|
*/
|
|
1110
1137
|
warmEntity(entity: unknown, opts?: { timeoutMs?: number }): Promise<number>;
|
|
1111
1138
|
setStereo(opts: SplatStereoOptions | null): SplatHandle;
|
|
1139
|
+
/**
|
|
1140
|
+
* The `depth` option's comfort factor in force, in (0, 1]: what the display rig's ipdFactor and
|
|
1141
|
+
* parallaxFactor are multiplied by (under `setStereo`'s values). 1 without the option, before
|
|
1142
|
+
* the first measurement, and on a rig it does not apply to.
|
|
1143
|
+
*/
|
|
1144
|
+
readonly depthFactor: number;
|
|
1112
1145
|
/** This tile in physical units — the core `TileHandle.displayMetrics()`, on the splat handle. Never rejects. */
|
|
1113
1146
|
displayMetrics(): Promise<DisplayMetrics>;
|
|
1114
1147
|
/**
|
package/three.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// bundles three.js (it is an optional peer dependency).
|
|
4
4
|
|
|
5
5
|
import type { XRViewRigInit } from './index.js';
|
|
6
|
+
export { disparityPct, cameraRigDisparityPct, depthBudgetFromBounds, comfortZone, comfortDepthFactor, cameraRigComfortFactor } from './depth.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A reusable three.js camera driven directly by an XRView's matrices. Construct once with your
|
|
@@ -88,8 +89,12 @@ export interface DisplayRigOptions {
|
|
|
88
89
|
* (so a camera parented under a dolly still reports world space) unless `attach` is set, which
|
|
89
90
|
* emits identity instead.
|
|
90
91
|
*
|
|
91
|
-
* Comfort rule
|
|
92
|
-
*
|
|
92
|
+
* Comfort rule: `ipdFactor × metersToVirtual × convergenceDiopters × N <= 1` (N = the nominal
|
|
93
|
+
* viewer distance the display reports, 0.6 m on a desktop panel). Nothing enforces it: the
|
|
94
|
+
* runtime applies an app-declared camera rig's gain as given (XR_DXR_view_rig §3) and clamps only
|
|
95
|
+
* values outside a field's sanity range. `convergence` 0 / unset (infinity: the whole scene in
|
|
96
|
+
* front of the glass) logs one console warning per page; the descriptor is built as asked.
|
|
97
|
+
* {@link cameraRigDisparityPct} measures the disparity a rig gives.
|
|
93
98
|
*
|
|
94
99
|
* @param THREE your imported three.js module namespace.
|
|
95
100
|
* @param camera a `THREE.PerspectiveCamera` (`.fov` degrees, `.matrixWorld`).
|
package/viewer.d.ts
CHANGED
|
@@ -48,6 +48,15 @@ export interface SceneViewerOptions {
|
|
|
48
48
|
* `createInline3D({ viewerEase })`, else on. `false` restores the snap.
|
|
49
49
|
*/
|
|
50
50
|
viewerEase?: ViewerEaseOption;
|
|
51
|
+
/**
|
|
52
|
+
* OPT-IN eye clear: `[r, g, b, a]` in 0..1 (alpha defaults to 1) or a CSS colour string (`#hex`,
|
|
53
|
+
* `rgb()`/`rgba()`, `transparent`, or any colour the browser parses). Unset: the transparent
|
|
54
|
+
* clear, exactly as before. An OPAQUE clear is recommended: where the weave reads an alpha-0
|
|
55
|
+
* pixel it can show stale or black pixels (web#198). Make the page colour behind the canvas
|
|
56
|
+
* match, so the 2D fallback and any feathered edge look the same. Unreadable → one warning,
|
|
57
|
+
* the default clear stays.
|
|
58
|
+
*/
|
|
59
|
+
clearColor?: [number, number, number] | [number, number, number, number] | string;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
export interface OrbitPose {
|
|
@@ -117,6 +126,8 @@ export declare class SceneViewer {
|
|
|
117
126
|
*/
|
|
118
127
|
readonly effectiveRenderScale: number;
|
|
119
128
|
|
|
129
|
+
/** The `clearColor` option, parsed (`[r,g,b,a]`), or null = the transparent clear. */
|
|
130
|
+
readonly clearColor: number[] | null;
|
|
120
131
|
/** Centre the subject on the zero-disparity plane and scale it to the tile. */
|
|
121
132
|
fitTo(
|
|
122
133
|
center: number[] | { x: number; y: number; z: number },
|