@displayxr/inline3d 1.38.0 → 1.39.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 +137 -0
- package/dist/call.js +4 -4
- package/index.d.ts +155 -18
- package/js/inline3d-model-entry.js +7 -0
- package/js/inline3d-model-playcanvas.js +5 -0
- package/js/inline3d-model.js +12 -0
- package/js/inline3d-splat-pc-entry.js +7 -1
- package/js/inline3d-splat-playcanvas.js +105 -4
- package/js/inline3d-splat-shared.js +17 -0
- package/js/inline3d-splat.js +12 -0
- package/js/inline3d-viewer.js +35 -5
- package/js/inline3d.js +667 -17
- package/model.d.ts +8 -1
- package/package.json +1 -1
- package/splat.d.ts +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,143 @@ 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.39.0 — 2026-10-09
|
|
9
|
+
|
|
10
|
+
Core (`.`) changes are **additive**, with every existing default unchanged: `firstWoven` and
|
|
11
|
+
`rewoven()` settle on the browser's `wovenState` report where it exists (the hold path elsewhere,
|
|
12
|
+
byte for byte), the optional `onResize` on `addScene`, a warning on a double attach (the call
|
|
13
|
+
proceeds as before), and the display reads (`getDisplayInfo()` / `getRenderingModes()` /
|
|
14
|
+
`requestRenderingMode()`) waiting for a layer's first frame instead of answering `null` / `[]`
|
|
15
|
+
early. One **preview-tier default** changes: `rectCover` is `'auto'` on `./splat` and `./model`
|
|
16
|
+
(`'off'` in the core). New types only (`WovenState`, `WovenWithheldReason`, `RectCoverOption`);
|
|
17
|
+
nothing removed.
|
|
18
|
+
|
|
19
|
+
### Core: `firstWoven` / `rewoven()` settle on the browser's join report (`.`, additive)
|
|
20
|
+
|
|
21
|
+
- **`XRDisplayLayer.wovenState`** (`'pending' | 'woven' | 'withheld'`, plus `withheldReason`) is
|
|
22
|
+
the browser's per-frame report of whether a layer's rect went into the weave (DisplayXR Browser
|
|
23
|
+
draft PR #258, Windows, feature-flagged). Detected with `'wovenState' in
|
|
24
|
+
XRDisplayLayer.prototype`. Where it is absent (mac, Linux, Android, Windows builds without it)
|
|
25
|
+
nothing changes: the hold, `confirmed: false`, byte for byte.
|
|
26
|
+
- Where it is present:
|
|
27
|
+
- **`firstWoven`** settles `{ woven: true, confirmed: true, reason: 'woven' }` on the first
|
|
28
|
+
`'woven'` read once a stereo frame is drawn, with no hold.
|
|
29
|
+
- **`rewoven()`** settles on a `'woven'` read that follows a `'withheld'`/`'pending'` read seen
|
|
30
|
+
after the call, or three session frames after the last box change seen after the call, or,
|
|
31
|
+
when no box change is seen after the call, three session frames after the call. The report
|
|
32
|
+
is a live per-frame level trailing the join by 1–3 frames, so a read three frames on reflects
|
|
33
|
+
the rect as it was at the call; a `'woven'` from the old rect, or one read on the frame of the
|
|
34
|
+
call, never settles it. A stereo frame since the call is still required, and the cap stays.
|
|
35
|
+
- The no-change case is the common one: a page that moves the canvas, then calls
|
|
36
|
+
`rewoven()`. It used to wait a full hold of steady `'woven'` reads (a kiosk panel run:
|
|
37
|
+
46/46 calls confirmed, median 1206 ms, the same as the timer path). It now settles about
|
|
38
|
+
three frames after the call (~50 ms). The timer path (no `wovenState`) is unchanged.
|
|
39
|
+
- **The cap stays, as a safety.** A layer that never leaves `'withheld'` (a CSS effect on an
|
|
40
|
+
ancestor) settles `{ woven: false, confirmed: true, reason: <withheldReason> }` (or
|
|
41
|
+
`'pending'`) four holds after the call, never sooner than 4.8 s. That is a level, not a loss:
|
|
42
|
+
the canvas is not taken flat and `rewoven()` keeps working.
|
|
43
|
+
- **New read-only `handle.wovenState` / `handle.withheldReason`** on the `TileHandle`, read live
|
|
44
|
+
(`null` where the browser does not report it, `'pending'` while the window has no layer). Types:
|
|
45
|
+
`WovenState`, `WovenWithheldReason`; `FirstWovenResult.reason` gains `'woven'`, `'pending'` and
|
|
46
|
+
the withheld tokens.
|
|
47
|
+
- "Woven" means submitted to the weave. A GPU-stage failure after submit is not reflected.
|
|
48
|
+
|
|
49
|
+
### Cover across a rect change, owned by the SDK (`rectCover`; core primitive, subpath default)
|
|
50
|
+
|
|
51
|
+
- **New `rectCover` option on every `add*()`**: `'auto' | 'off' | { color?, snapshot? }`. Once a
|
|
52
|
+
window has woven, a change of its canvas's CSS size, dpr or page position raises a cover on the
|
|
53
|
+
frame the change is seen, and cuts it when `rewoven()` settles. A further change while it is up
|
|
54
|
+
restarts the wait. `remove()` and session end take it out of the DOM.
|
|
55
|
+
- **What the cover is:** a 2D canvas placed as the canvas's next sibling, never a second woven
|
|
56
|
+
canvas. It has `pointer-events: none` and `data-inline3d-cover`, and it is filled with `color`
|
|
57
|
+
(default `#000`).
|
|
58
|
+
- **The snapshot:** with `snapshot` (the default), the cover also shows the last frame: the left
|
|
59
|
+
eye, cover-fit to the new box. It is taken once per change, with one `drawImage` into a canvas
|
|
60
|
+
the size of the CSS box. Never `toDataURL`, never per frame.
|
|
61
|
+
- **Not before the first join:** cover a fresh canvas yourself until `firstWoven` (rule 5).
|
|
62
|
+
- **Defaults.** `'off'` on the core `addScene` / `addImage` / `addVideo` (frozen tier, unchanged).
|
|
63
|
+
**`'auto'` on `./splat` and `./model`, all engines.** That is a default change in the preview
|
|
64
|
+
tier: a page that already runs its own cover passes `rectCover: 'off'`.
|
|
65
|
+
- **`rewoven()` now also restarts on a pure move** (core, timing only). The box it watches gained
|
|
66
|
+
the canvas's page position (viewport rect plus document scroll, whole CSS px). A canvas moved
|
|
67
|
+
to another place at the same size goes through the same identity gap. Scrolling the document is
|
|
68
|
+
not a move. A scroll inside a nested scroller does read as one.
|
|
69
|
+
- From a kiosk demo that keeps one woven canvas and moves it between screens: a black box at the
|
|
70
|
+
new rect for 0.4–1.2 s, covered by hand on timers until now.
|
|
71
|
+
|
|
72
|
+
### Resize and draw in the same task (`./splat`, `./model`; core `onResize`, additive)
|
|
73
|
+
|
|
74
|
+
- **The PlayCanvas viewer** (`./splat` `engine: 'playcanvas'`, `./model`'s default engine) now
|
|
75
|
+
resizes its backing store and replays the last frame inside the ResizeObserver callback, which
|
|
76
|
+
runs before the paint. Before, it waited for the next animation frame, and for one paint the
|
|
77
|
+
old store was shown stretched onto the new box.
|
|
78
|
+
- **The replay keeps its proportions.** The cached frustum's x row is scaled by the aspect
|
|
79
|
+
change, until the runtime's next views carry the true one.
|
|
80
|
+
- **Guards.** A callback that arrives while the viewer is drawing, or re-entrantly while it is
|
|
81
|
+
resizing, takes the old one-frame debounce instead.
|
|
82
|
+
- **Not covered:** `./splat` on Spark and `./model` `engine: 'three'` (`SceneViewer`) keep the
|
|
83
|
+
one-frame debounce for now.
|
|
84
|
+
- **Core `addScene(…, { onResize(box) })`**, optional. It is called in the same ResizeObserver
|
|
85
|
+
callback with `{ width, height, dpr }`, so a page-drawn window can resize and draw before the
|
|
86
|
+
paint too. It runs only on a real change, and a throw is caught. Without it, nothing changes:
|
|
87
|
+
no observer is attached to a scene canvas.
|
|
88
|
+
|
|
89
|
+
### Display reads wait for the layer's first frame (core `.`, additive, no new API)
|
|
90
|
+
|
|
91
|
+
- **`getDisplayInfo()` / `getRenderingModes()` / `requestRenderingMode()`**, on a tile handle or
|
|
92
|
+
the wall, called before the window's layer has delivered its first frame now **wait for it** and
|
|
93
|
+
ask the layer then. Before, a page calling them right after `add*()` got `null` / `[]` (and a
|
|
94
|
+
request answered "not forwarded"): the browser only answers once the layer has a weave session,
|
|
95
|
+
and `null` is documented as "no glasses-free display". Found by the samples panel test (#151),
|
|
96
|
+
which worked around it page-side with `await handle.firstWoven`; that is no longer needed.
|
|
97
|
+
- **Released by** the first `'woven'` read where the browser reports `wovenState`, or the
|
|
98
|
+
layer's first stereo frame elsewhere. No first-woven hold. A `'withheld'` read does not
|
|
99
|
+
release: the layer reads it right after creation, before the weave session can answer
|
|
100
|
+
(measured on a Chromium 156 panel build: released on it, `getDisplayInfo()` answered `null`
|
|
101
|
+
at 1.55 s while the layer only read `'woven'` at ~3.9 s).
|
|
102
|
+
- **A `null` / `[]` answer before the cap is not returned.** The read is asked again on each
|
|
103
|
+
later release signal (the next `'woven'` read, or the next session frame once a stereo frame
|
|
104
|
+
has been drawn) and resolves with the first non-empty answer, on both paths.
|
|
105
|
+
`requestRenderingMode()` is forwarded once on the release, not retried.
|
|
106
|
+
- **Capped** at the first-woven cap: four holds from the layer's construction, never under
|
|
107
|
+
4.8 s. Only past it is the layer's `null` / `[]` returned, as a real absence.
|
|
108
|
+
- **Unchanged:** once a read on the layer has answered for real, later calls go straight
|
|
109
|
+
through; no session, no live layer, a failed layer, or a window removed / session ended
|
|
110
|
+
mid-wait settles at once, as before.
|
|
111
|
+
|
|
112
|
+
### Double-attach warning (core, and the `./splat` / `./model` entries)
|
|
113
|
+
|
|
114
|
+
- `addScene` / `addImage` / `addVideo` / `addSplat` / `addModel` on a canvas that is still
|
|
115
|
+
registered on the same wall (not yet `remove()`d) now **warns**, once per canvas. The warning
|
|
116
|
+
names the method and the live registration, and says the call is rebuilding the layer (a fresh
|
|
117
|
+
0.4–1.2 s identity gap) or putting a second renderer on the context.
|
|
118
|
+
- **It is a warning only, so no page changes behavior.** The call proceeds exactly as before: the
|
|
119
|
+
core closes and rebuilds the layer, the subpaths attach a new renderer, and the call returns its
|
|
120
|
+
own new handle. A page that re-adds to swap pictures keeps working.
|
|
121
|
+
- To swap content, redraw a source canvas or use `setSource`. To re-register on purpose,
|
|
122
|
+
`remove()` first.
|
|
123
|
+
- `./splat` and `./model` check at their entry, not only in `addScene`: their renderer exists
|
|
124
|
+
before their core window, so a second call during the first one's load is caught too.
|
|
125
|
+
- From a kiosk demo that attached its stage twice per screen visit.
|
|
126
|
+
|
|
127
|
+
### Every session frame presents (`./splat`, `./model`, `./viewer`)
|
|
128
|
+
|
|
129
|
+
- The viewers behind the scene subpaths now draw on **every** session frame they are handed. This
|
|
130
|
+
covers the PlayCanvas viewer (`./splat` `engine: 'playcanvas'`, `./model`'s default) and
|
|
131
|
+
`SceneViewer` (`./splat` on Spark, `./model` `engine: 'three'`, `./viewer`).
|
|
132
|
+
- **Before the first good frame,** a frame they cannot draw (a short view list, a missing or
|
|
133
|
+
degenerate viewport) used to draw nothing. It now draws the mono camera into both halves: the
|
|
134
|
+
subject flat if it is loaded, a cleared frame if not. Afterwards they replay the last good
|
|
135
|
+
frame, as before.
|
|
136
|
+
- **No source, or nothing visible,** still draws a frame.
|
|
137
|
+
- **Before the engine has created its GL context,** nothing can be presented, and creating one
|
|
138
|
+
early would give it the wrong attributes.
|
|
139
|
+
- The dark-blink rule holds: no clear without a draw.
|
|
140
|
+
- **Note for `addScene` pages:** the SDK cannot enforce this for a window your page draws. Draw on
|
|
141
|
+
every `onFrame` ([`woven-canvas-rules.md`](docs/woven-canvas-rules.md), "redraw every frame").
|
|
142
|
+
A fully transparent woven frame weaves **black**: a browser bug (browser-pvt #255), listed there
|
|
143
|
+
as a known limitation.
|
|
144
|
+
|
|
8
145
|
## 1.38.0 — 2026-10-09
|
|
9
146
|
|
|
10
147
|
Touches the **preview tier** (`./call`, `./splat`) only: one default and two additive handle
|