@displayxr/inline3d 1.49.2 → 1.50.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 +59 -0
- package/README.md +3 -0
- package/camera.d.ts +5 -0
- package/dist/call.js +6 -6
- package/hands.d.ts +198 -0
- package/js/camera/capture.js +9 -0
- package/js/camera/half-sbs.js +83 -0
- package/js/inline3d-call.js +1 -1
- package/js/inline3d-camera.js +30 -1
- package/js/inline3d-hands.js +618 -0
- package/js/inline3d-model-entry.js +3 -1
- package/js/inline3d-splat-playcanvas.js +61 -14
- package/js/inline3d-splat-shared.js +12 -1
- package/js/inline3d-viewer.js +39 -8
- package/js/inline3d.js +16 -1
- package/model.d.ts +10 -0
- package/package.json +7 -1
- package/splat.d.ts +16 -0
- package/viewer.d.ts +12 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,65 @@ 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
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 1.50.0 — 2026-11-04
|
|
11
|
+
|
|
12
|
+
### Fixed — `./camera`, `./call`: half-width side-by-side webcams keep their aspect ratio
|
|
13
|
+
|
|
14
|
+
A USB stereo webcam that sends 3840x2160 half-SBS came through as a 3840x1080 centre crop: each eye
|
|
15
|
+
2x too tall, with half the vertical view. Such a camera (listed by USB id, since its shape matches
|
|
16
|
+
a 4K webcam's) is now read in its native mode and sent as 2560x720 with square-pixel eyes. Needs
|
|
17
|
+
`MediaStreamTrackProcessor`; without it the camera opens as before. `prefer: 'mono'` stays raw.
|
|
18
|
+
|
|
19
|
+
### Added — `@displayxr/inline3d/hands`: tracked hands, and pinch controls for every viewer (`./hands`, `./viewer`, `./model`, `./splat`)
|
|
20
|
+
|
|
21
|
+
Preview tier. The DisplayXR Browser 1.8.0+ (Windows, with a hand provider such as an Ultraleap
|
|
22
|
+
tracker) exposes standard WebXR Hand Input on an inline-3D session: one `XRInputSource` per hand
|
|
23
|
+
with a 25-joint `XRHand`, located in the same rig frame as the eye views. The new subpath reads it
|
|
24
|
+
and turns it into controls:
|
|
25
|
+
|
|
26
|
+
- `watchHands(wall, onFrame)` — the tracked hands every session frame (`poses`, `radii`,
|
|
27
|
+
`joint(name)`, `thumbTip`, `indexTip`, `palmLength`), the browser's per-frame gate
|
|
28
|
+
(`state.gate`: `'available'` or why hands are withheld) and the hand `inputsourceschange`.
|
|
29
|
+
- `HandGestureController` / `PinchDetector` — the DisplayXR Model Viewer's gesture math, ported:
|
|
30
|
+
hand-relative throughout — the pinch thresholds (2.5 cm enter / 4 cm exit), the orbit gain
|
|
31
|
+
(10 rad/m) and the two-hand separation guard are all stated for a 9.5 cm palm and scale by the
|
|
32
|
+
hand's own palm length, so a hand that arrives scaled turns the subject by the same angle for
|
|
33
|
+
the same finger travel; one pinched hand orbits, two pinched hands zoom (separation ratio), roll
|
|
34
|
+
(twist) and orbit (midpoint drag); EMA-smoothed, anchored on every mode change.
|
|
35
|
+
- `handControls(wall, target)` — drives anything with the viewer pose surface from those
|
|
36
|
+
gestures; and the option **`hands: true`** on `addModel` / `addSplat` (both engines, every
|
|
37
|
+
entry) wires it for you, exposed as `handle.hands`. Pointer and wheel keep working alongside.
|
|
38
|
+
- `SceneViewer.nudgePose(delta)` and `PlayCanvasSplatViewer.nudgePose(delta)` — move the pose by
|
|
39
|
+
an eased delta, counting as input for the idle turntable (what the hands call; a page may too).
|
|
40
|
+
- `OrbitPose.roll` on both viewers — degrees about the view axis, outside yaw and pitch (Euler
|
|
41
|
+
order `'ZXY'`; the PlayCanvas pivot quaternion gains the same Rz factor), bit-identical to
|
|
42
|
+
before at roll 0; `getPose()` now reports `roll`. (The first cut left the PlayCanvas viewer
|
|
43
|
+
without a roll axis, so the two-hand twist did nothing on the default engine — found on the
|
|
44
|
+
panel 2026-11-04.)
|
|
45
|
+
|
|
46
|
+
Inert everywhere else: no hands, nothing moves, no errors. New sample `samples/hands/` (the raw
|
|
47
|
+
surface), and `?hands` on `samples/model/` and `samples/splat/`. The porting guide's "no input
|
|
48
|
+
sources" row is corrected (web#229). Tracks DisplayXR/displayxr-web#228.
|
|
49
|
+
## 1.49.3 — 2026-11-04
|
|
50
|
+
|
|
51
|
+
### Fixed — a camera view is not "woven" before the camera's first frame; `frameAgeMs` tells a stalled track (`.`, `./camera`, `./call`)
|
|
52
|
+
|
|
53
|
+
Core and preview tier. A camera view (`addCameraView`, and the call's self view, which is one)
|
|
54
|
+
registers its tile on the wall with an SBS buffer it fills from the camera. That buffer started
|
|
55
|
+
as a blank default 300x150 canvas, and the wall counted any image source as a stereo frame, so
|
|
56
|
+
`firstWoven` settled `woven: true` (`hold-elapsed`) on a tile that had never shown the camera.
|
|
57
|
+
On an Android 3D tablet whose camera track was `live` but delivered no frames, the call reported
|
|
58
|
+
the self view woven over a black tile.
|
|
59
|
+
|
|
60
|
+
- **Core:** an `addImage` source that is a canvas or image with no pixels (0x0) is not a stereo
|
|
61
|
+
frame: `firstWoven` / `rewoven()` wait for one. Sources that report no size keep the old rule.
|
|
62
|
+
- **`./camera`:** the woven buffer starts 0x0 until the first camera frame is painted into it.
|
|
63
|
+
- **New: `view.frameAgeMs`** and `weaveState().frameAgeMs` (also `call.diagnostics().self`): ms
|
|
64
|
+
since the camera last delivered a new frame to the view, null before the first. A stalled track
|
|
65
|
+
keeps its last frame on screen; a growing age is how a page shows "no video".
|
|
66
|
+
|
|
8
67
|
## 1.49.2 — 2026-11-04
|
|
9
68
|
|
|
10
69
|
### Fixed — the camera probe waits for the DisplayXR 3D camera before opening a plain lens (`./camera`, `./call`)
|
package/README.md
CHANGED
|
@@ -35,6 +35,9 @@ import { addModel } from '@displayxr/inline3d/model'; // experimen
|
|
|
35
35
|
import { addPlayer } from '@displayxr/inline3d/player'; // preview: a media player, built
|
|
36
36
|
// on addVideo, with transport
|
|
37
37
|
import { SceneViewer } from '@displayxr/inline3d/viewer'; // experimental: framing + orbit
|
|
38
|
+
import { handControls } from '@displayxr/inline3d/hands'; // experimental: tracked hands,
|
|
39
|
+
// pinch to orbit (or `hands: true`
|
|
40
|
+
// on addModel / addSplat)
|
|
38
41
|
```
|
|
39
42
|
|
|
40
43
|
No build step or bundler required — it's plain ES modules. You can also import a pinned version by
|
package/camera.d.ts
CHANGED
|
@@ -285,6 +285,11 @@ export interface CameraViewWeaveState {
|
|
|
285
285
|
firstWoven: { woven: boolean; confirmed: boolean; reason: string | null; ms: number } | 'pending' | null;
|
|
286
286
|
/** Layer re-registrations attempted after a `'layer-failed'` (bounded; reset by a woven result). */
|
|
287
287
|
layerRetries: number;
|
|
288
|
+
/**
|
|
289
|
+
* Milliseconds since the camera last delivered a new frame to the view, or null before the first.
|
|
290
|
+
* A stalled track keeps its last frame on screen; a growing age is how a page shows "no video".
|
|
291
|
+
*/
|
|
292
|
+
frameAgeMs: number | null;
|
|
288
293
|
}
|
|
289
294
|
|
|
290
295
|
/** A self view from {@link addCameraView}. */
|