@displayxr/inline3d 1.31.0 → 1.33.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 +72 -0
- package/call.d.ts +6 -1
- package/dist/call.js +4 -4
- package/index.d.ts +36 -0
- package/js/call/signaling.js +14 -6
- package/js/inline3d-display-metrics.js +51 -0
- package/js/inline3d-splat-deferred.js +12 -0
- package/js/inline3d-splat-effects.js +92 -2
- package/js/inline3d-splat-playcanvas.js +270 -3
- package/js/inline3d-splat.js +14 -0
- package/js/inline3d.js +21 -0
- package/package.json +2 -1
- package/splat.d.ts +69 -1
package/js/inline3d.js
CHANGED
|
@@ -34,6 +34,8 @@ export { undock, undockAvailable, undockUrl, tileScreenRect };
|
|
|
34
34
|
import { setSessionViewerEase } from './inline3d-viewer-ease.js';
|
|
35
35
|
// The tracking-acquisition ease, for pages that render their own addScene from the views.
|
|
36
36
|
export { ViewerEase, resolveViewerEaseOption, frameTrackingState, VIEWER_EASE_DEFAULT_MS } from './inline3d-viewer-ease.js';
|
|
37
|
+
export { DISPLAY_METRICS_DEFAULTS, displayMetricsFrom } from './inline3d-display-metrics.js';
|
|
38
|
+
import { displayMetricsFrom } from './inline3d-display-metrics.js';
|
|
37
39
|
|
|
38
40
|
// The eased 2D<->3D transition. A pure state machine (no DOM, no WebXR) ported from the native
|
|
39
41
|
// `dxr::ModeSwitch`, so the browser eases the disparity around a mode switch the same way — and in
|
|
@@ -133,6 +135,7 @@ const hasViewRig = () => {
|
|
|
133
135
|
// required — a browser with a partial set is a browser mid-implementation, and treating it as
|
|
134
136
|
// supported would hand a page a `requestRenderingMode is not a function` at the worst moment.
|
|
135
137
|
const DISPLAY_MODE_METHODS = ['getDisplayInfo', 'getRenderingModes', 'requestRenderingMode'];
|
|
138
|
+
|
|
136
139
|
// The two display events, fired on the XRSession rather than the layer — so a page hears about a
|
|
137
140
|
// mode or hardware-state change even while its tile's layer is closed (lazy mode), and one
|
|
138
141
|
// subscription covers every window in the document.
|
|
@@ -1088,6 +1091,24 @@ class Inline3D {
|
|
|
1088
1091
|
* @returns {Promise<object|null>}
|
|
1089
1092
|
*/
|
|
1090
1093
|
getDisplayInfo: () => this._layerCall(win, 'getDisplayInfo', 'getDisplayInfo()'),
|
|
1094
|
+
/**
|
|
1095
|
+
* This window in PHYSICAL units: the canvas's size in metres, metres per CSS px, the panel,
|
|
1096
|
+
* the nominal viewer distance and the eye separation — from getDisplayInfo(), with every
|
|
1097
|
+
* value that could not be measured filled from a stated default (see `source`). Never
|
|
1098
|
+
* rejects: no display API, no live layer, no glasses-free display all resolve the defaults.
|
|
1099
|
+
* The canvas size is re-read at each call (call it again after a resize).
|
|
1100
|
+
*
|
|
1101
|
+
* @returns {Promise<object>}
|
|
1102
|
+
*/
|
|
1103
|
+
displayMetrics: async () => {
|
|
1104
|
+
let info = null;
|
|
1105
|
+
try {
|
|
1106
|
+
info = await this._layerCall(win, 'getDisplayInfo', 'getDisplayInfo()');
|
|
1107
|
+
} catch {
|
|
1108
|
+
/* no display API / no live layer: the defaults */
|
|
1109
|
+
}
|
|
1110
|
+
return displayMetricsFrom(info, canvas.getBoundingClientRect(), globalThis.devicePixelRatio || 1);
|
|
1111
|
+
},
|
|
1091
1112
|
/**
|
|
1092
1113
|
* Every rendering mode the runtime can put this display in, as reported by the runtime:
|
|
1093
1114
|
* `{modeIndex, modeName, viewCount, viewScaleX, viewScaleY, tileColumns, tileRows,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.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",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"files": [
|
|
66
66
|
"js/inline3d.js",
|
|
67
67
|
"js/inline3d-undock.js",
|
|
68
|
+
"js/inline3d-display-metrics.js",
|
|
68
69
|
"js/inline3d-mode-switch.js",
|
|
69
70
|
"js/inline3d-buffer-limit.js",
|
|
70
71
|
"js/inline3d-viewer-ease.js",
|
package/splat.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// EXPERIMENTAL — not covered by the 1.x semver promise. See docs/sdk-stability.md.
|
|
3
3
|
|
|
4
4
|
import type { SceneViewer, SubjectBounds, OrbitPose } from './viewer.js';
|
|
5
|
-
import type { FirstWovenResult, ViewerEaseOption } from './index.js';
|
|
5
|
+
import type { FirstWovenResult, ViewerEaseOption, DisplayMetrics } from './index.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* The knobs behind `SplatOptions.perf`. Every one is a Spark 2.1.0 setting except `alphaRadius`,
|
|
@@ -174,8 +174,11 @@ export interface ResolvedRig {
|
|
|
174
174
|
focusDistances: { subject_m: number | null; near_m: number | null; far_m: number | null } | null;
|
|
175
175
|
/** Focus distance along the rest camera's view axis — the zero-disparity PLANE. */
|
|
176
176
|
convergence: number;
|
|
177
|
+
/** In force — `setStereo`'s values when set, else `stereoDefault`'s. */
|
|
177
178
|
ipdFactor: number;
|
|
178
179
|
parallaxFactor: number;
|
|
180
|
+
/** The asset's own scalars (block `dxr`, else addSplat's options, else 1) — what `setStereo(null)` restores. PlayCanvas backend. */
|
|
181
|
+
stereoDefault?: { ipdFactor: number; parallaxFactor: number };
|
|
179
182
|
}
|
|
180
183
|
|
|
181
184
|
/**
|
|
@@ -731,6 +734,41 @@ export interface SplatSetRigDisplayOptions {
|
|
|
731
734
|
frame?: { center: number[] | { x: number; y: number; z: number }; extent: number[] | { x: number; y: number; z: number } };
|
|
732
735
|
}
|
|
733
736
|
|
|
737
|
+
/** A rectangle in canvas fractions: origin top-left, y DOWN (a DOM rect / canvas size). */
|
|
738
|
+
export interface SplatCanvasRect {
|
|
739
|
+
x: number;
|
|
740
|
+
y: number;
|
|
741
|
+
w: number;
|
|
742
|
+
h: number;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/** `handle.setDepthEnvelope`'s options. Metres are on the panel. */
|
|
746
|
+
export interface SplatDepthEnvelopeOptions {
|
|
747
|
+
/** The out-of-glass cap well inside the frame. Default 0.02. */
|
|
748
|
+
maxFrontM?: number;
|
|
749
|
+
/** The cap AT a stage edge / rect edge. Default 0.001 (clamped to `maxFrontM`). */
|
|
750
|
+
edgeM?: number;
|
|
751
|
+
/** Ramp width from `edgeM` to `maxFrontM`. Default 0.016. */
|
|
752
|
+
bandM?: number;
|
|
753
|
+
/** The window content may come out in. Default (or `null`): the whole canvas. */
|
|
754
|
+
stage?: SplatCanvasRect | null;
|
|
755
|
+
/** 2D elements over the canvas to keep flat around; `weight` 0..1 (default 1) fades one in/out. The 8 heaviest are kept. */
|
|
756
|
+
rects?: Array<SplatCanvasRect & { weight?: number }> | null;
|
|
757
|
+
/** Viewer distance override; default `nominalViewerPosition.z`, else 0.65. */
|
|
758
|
+
viewerM?: number | null;
|
|
759
|
+
/** Canvas physical size override, [w, h]; default the CSS box × the panel's metres per CSS px. */
|
|
760
|
+
canvasSizeM?: [number, number] | null;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/** `handle.setStereo`'s options. Each a finite number >= 0; `null` = back to the asset's own. */
|
|
764
|
+
export interface SplatStereoOptions {
|
|
765
|
+
ipdFactor?: number | null;
|
|
766
|
+
parallaxFactor?: number | null;
|
|
767
|
+
/** RELATIVE to the asset's own (`rig.stereoDefault`): re-applied to each asset `setSource` brings in. Exclusive with `ipdFactor`; the last one given wins. */
|
|
768
|
+
ipdScale?: number | null;
|
|
769
|
+
parallaxScale?: number | null;
|
|
770
|
+
}
|
|
771
|
+
|
|
734
772
|
/** `setSource`'s options. */
|
|
735
773
|
export interface SplatSourceOptions {
|
|
736
774
|
/** > 0 = a crossfade of this length (the 1.10 option; same as `transition: 'crossfade'`). */
|
|
@@ -1017,6 +1055,36 @@ export interface SplatHandle {
|
|
|
1017
1055
|
*/
|
|
1018
1056
|
setRig(type: 'display', opts?: SplatSetRigDisplayOptions): Promise<SplatHandle>;
|
|
1019
1057
|
setRig(type: 'camera' | 'auto'): Promise<SplatHandle>;
|
|
1058
|
+
/**
|
|
1059
|
+
* PlayCanvas backend only — throws on Spark. Live stereo strength: re-declares the rig in force
|
|
1060
|
+
* with these scalars on the next frame, with NO cut (pose, focus and framing stay) — a depth
|
|
1061
|
+
* slider. A key given replaces; a key set to `null` returns to the asset's own value (the SOG
|
|
1062
|
+
* camera block's `dxr`, else addSplat's options, else 1); `setStereo(null)` clears both. Sticky
|
|
1063
|
+
* across `setSource` and `setRig`. On a camera rig the values are ABSOLUTE, exactly like
|
|
1064
|
+
* addSplat's `ipdFactor`/`parallaxFactor`; on a display rig they replace the declared display
|
|
1065
|
+
* rig's factors. `controls:'page'` applies them from the next tick. A stereo video holds its own
|
|
1066
|
+
* display rig; a value set meanwhile applies when the video exits. `handle.rig.ipdFactor` /
|
|
1067
|
+
* `parallaxFactor` read what is in force. The 2D↔3D mode-switch ramp still multiplies on top.
|
|
1068
|
+
*/
|
|
1069
|
+
setStereo(opts: SplatStereoOptions | null): SplatHandle;
|
|
1070
|
+
/** This tile in physical units — the core `TileHandle.displayMetrics()`, on the splat handle. Never rejects. */
|
|
1071
|
+
displayMetrics(): Promise<DisplayMetrics>;
|
|
1072
|
+
/**
|
|
1073
|
+
* PlayCanvas backend only — throws on Spark. THE FRAME ENVELOPE: content may come OUT of the
|
|
1074
|
+
* glass only well inside the frame. At each screen spot the out-of-glass cap is
|
|
1075
|
+
* `edgeM + (maxFrontM − edgeM) · smoothstep(0, bandM, distance)`, where `distance` (metres on the
|
|
1076
|
+
* panel) is to the nearest `stage` edge or to any `rects` entry (weighted). A gaussian beyond the
|
|
1077
|
+
* cap slides back along its own ray from the declared camera rig (centre and scale together), so
|
|
1078
|
+
* the 2D picture is unchanged, the sort stays valid and both eyes agree; behind the glass is never
|
|
1079
|
+
* touched. Tile-wide and LIVE: every asset — an incoming one from its first frame, both sides of
|
|
1080
|
+
* a crossfade — is judged through the rig declared now (its convergence, lens, `ipdFactor` ×
|
|
1081
|
+
* `metersToVirtual`, so `setStereo` is accounted for). Camera rigs only (incl. `controls:'page'`);
|
|
1082
|
+
* inert on a display rig and while a stereo video holds the rig. Physical size comes from
|
|
1083
|
+
* `getDisplayInfo()` (see `displayMetrics()`), overridable with `canvasSizeM` / `viewerM`.
|
|
1084
|
+
* A key given replaces; `null` turns it off. Cheap to call per layout change: uniforms only.
|
|
1085
|
+
* docs/splat-effects.md §Depth envelope.
|
|
1086
|
+
*/
|
|
1087
|
+
setDepthEnvelope(opts: SplatDepthEnvelopeOptions | null): SplatHandle;
|
|
1020
1088
|
/**
|
|
1021
1089
|
* PlayCanvas backend only — throws on Spark, and with `controls:'page'`. Play a stereo video ON
|
|
1022
1090
|
* this handle: no new canvas, layer or session (docs/playcanvas-adapter.md §setVideo). The splat
|