gps-plus-slam-app-framework 1.0.7 → 1.2.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/README.md +69 -15
- package/dist/{app-selectors-BeU0_ab8.d.ts → app-selectors-CcZ5UV-8.d.ts} +1 -1
- package/dist/ar/bresenham3d.d.ts +2 -0
- package/dist/ar/bresenham3d.js +81 -0
- package/dist/ar/camera-blit-capture.d.ts +1 -1
- package/dist/ar/camera-blit-capture.js +30 -2
- package/dist/ar/capability-checker.d.ts +2 -0
- package/dist/ar/capability-checker.js +25 -0
- package/dist/ar/capture-failure-tracker.d.ts +1 -1
- package/dist/ar/chromium-camera-access-workaround.d.ts +2 -2
- package/dist/ar/chromium-camera-access-workaround.js +197 -8
- package/dist/ar/depth-sampler.d.ts +3 -3
- package/dist/ar/depth-sampler.js +63 -8
- package/dist/ar/depth-unprojection.d.ts +2 -0
- package/dist/ar/depth-unprojection.js +94 -0
- package/dist/ar/enable-gps-ar.d.ts +2 -0
- package/dist/ar/enable-gps-ar.js +137 -0
- package/dist/ar/frame-loop.d.ts +1 -1
- package/dist/ar/frame-loop.js +24 -1
- package/dist/ar/image-capture.d.ts +1 -1
- package/dist/ar/image-capture.js +2 -1
- package/dist/ar/index.d.ts +19 -12
- package/dist/ar/index.js +11 -4
- package/dist/ar/occupancy-grid.d.ts +2 -0
- package/dist/ar/occupancy-grid.js +164 -0
- package/dist/ar/replay-scene.d.ts +1 -1
- package/dist/ar/replay-scene.js +1 -1
- package/dist/ar/scene-node-names.d.ts +1 -1
- package/dist/ar/webxr-nue-basis.d.ts +2 -0
- package/dist/ar/webxr-nue-basis.js +54 -0
- package/dist/ar/webxr-session.d.ts +4 -4
- package/dist/ar/webxr-session.js +1 -984
- package/dist/ar/xr-camera-texture.d.ts +1 -1
- package/dist/ar/xr-error-handler.d.ts +1 -1
- package/dist/ar/xr-frame-loop.d.ts +2 -0
- package/dist/ar/xr-frame-loop.js +69 -0
- package/dist/{ar-types-Ck8LEq8k.d.ts → ar-types-Dan1MVTi.d.ts} +28 -5
- package/dist/ar-world-group-alignment-ColHB_5A.d.ts +43 -0
- package/dist/bresenham3d-CFfd7n6B.d.ts +59 -0
- package/dist/{camera-blit-capture-C1V9I1Z6.d.ts → camera-blit-capture-D5_mNhla.d.ts} +20 -0
- package/dist/capability-checker-CQXJHxXg.d.ts +43 -0
- package/dist/chromium-camera-access-workaround-Jqbn0apH.d.ts +137 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/{create-slam-app-store-CNsZ3rcX.d.ts → create-slam-app-store-qNXQ-tq5.d.ts} +5 -5
- package/dist/depth-sampler-Bhanfwla.d.ts +169 -0
- package/dist/depth-unprojection-Y6i_mJuT.d.ts +52 -0
- package/dist/enable-gps-ar-CapmADVN.d.ts +95 -0
- package/dist/{file-system-DTApEv_Q.d.ts → file-system-C_eqiEA8.d.ts} +1 -1
- package/dist/frame-conversions-BfsafGWR.d.ts +54 -0
- package/dist/{frame-loop-QJIxLin0.d.ts → frame-loop-CMewS8cY.d.ts} +5 -0
- package/dist/{fused-path-CB4DwWOG.d.ts → fused-path-DJoVu98b.d.ts} +1 -1
- package/dist/geo/h3-proximity.d.ts +1 -1
- package/dist/geo/index.d.ts +1 -1
- package/dist/{gps-anchor-CnWY61XK.d.ts → gps-anchor-dYeCvvp5.d.ts} +12 -1
- package/dist/{gps-ar-pose-sampler-DsM1Kb2N.d.ts → gps-ar-pose-sampler-DVb96iOy.d.ts} +1 -1
- package/dist/{gps-event-coordinator-DBx9I1YX.d.ts → gps-event-coordinator-BDIQde2x.d.ts} +3 -3
- package/dist/hit-test-reticle-BEzEybxZ.d.ts +45 -0
- package/dist/{image-capture-DZLxHDN9.d.ts → image-capture-DZ4HFRgS.d.ts} +15 -2
- package/dist/index-KJq2amHF.d.ts +37 -0
- package/dist/index.d.ts +67 -58
- package/dist/index.js +18 -8
- package/dist/{leaflet-map-overlay-Cew7XAoO.d.ts → leaflet-map-overlay-6CJC-E1l.d.ts} +1 -1
- package/dist/{map-data-sih4g64v.d.ts → map-data-CkloBxIl.d.ts} +1 -1
- package/dist/{map-overlay-draw-B3R1c9Xp.d.ts → map-overlay-draw-krOKwDAq.d.ts} +1 -1
- package/dist/{null-storage-backend-BKOS7JpL.d.ts → null-storage-backend-CxEjZHRW.d.ts} +2 -2
- package/dist/occupancy-grid-BRNRaPyT.d.ts +72 -0
- package/dist/{opfs-storage-backend-Cj_7PWoq.d.ts → opfs-storage-backend-CjSAuqg_.d.ts} +2 -2
- package/dist/{persistence-middleware-BkHIqvaA.d.ts → persistence-middleware-DwyzgfWr.d.ts} +1 -1
- package/dist/{recording-options-Dq6IsKAv.d.ts → recording-options-DJBXuMxV.d.ts} +22 -6
- package/dist/{recording-replayer-CmCIIZ02.d.ts → recording-replayer-BL-x-7k0.d.ts} +2 -2
- package/dist/{recording-slice-d6OtCrza.d.ts → recording-slice-89O07ebs.d.ts} +10 -2
- package/dist/{replay-engine-BGBRQyXs.d.ts → replay-engine-BRqszuQ9.d.ts} +1 -1
- package/dist/{replay-scene-DpAGcAKY.d.ts → replay-scene-Bw58VL6p.d.ts} +3 -3
- package/dist/sensors/gps-error-handler.d.ts +1 -1
- package/dist/sensors/gps.d.ts +1 -1
- package/dist/sensors/index.d.ts +3 -3
- package/dist/sensors/index.js +1 -1
- package/dist/sensors/permission-checker.d.ts +1 -1
- package/dist/session-disposers-M-oashRH.js +57 -0
- package/dist/state/app-selectors.d.ts +1 -1
- package/dist/state/combined-root-state.d.ts +1 -1
- package/dist/state/create-slam-app-store.d.ts +1 -1
- package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
- package/dist/state/gps-event-coordinator.d.ts +1 -1
- package/dist/state/index.d.ts +17 -17
- package/dist/state/index.js +2 -2
- package/dist/state/persistence-middleware.d.ts +1 -1
- package/dist/state/persistence-middleware.js +9 -3
- package/dist/state/recording-options.d.ts +1 -1
- package/dist/state/recording-options.js +5 -3
- package/dist/state/recording-replayer.d.ts +2 -2
- package/dist/state/recording-slice.d.ts +1 -1
- package/dist/state/recording-slice.js +11 -2
- package/dist/state/replay-engine.d.ts +1 -1
- package/dist/state/store-subscribers.d.ts +2 -2
- package/dist/state/subscribe-to-selector.d.ts +1 -1
- package/dist/state/tracking-quality.d.ts +1 -1
- package/dist/state/tracking-quality.js +1 -1
- package/dist/state/tracking-slice.d.ts +1 -1
- package/dist/state-BkIfpiyA.js +87 -0
- package/dist/storage/file-system-utils.d.ts +1 -1
- package/dist/storage/file-system.d.ts +1 -1
- package/dist/storage/index.d.ts +8 -8
- package/dist/storage/null-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage.d.ts +1 -1
- package/dist/storage/storage-backend.d.ts +1 -1
- package/dist/storage/zip-export.d.ts +1 -1
- package/dist/storage/zip-reader.d.ts +1 -1
- package/dist/{storage-backend-CT0Il_AB.d.ts → storage-backend-C9HLFtgz.d.ts} +1 -1
- package/dist/{store-subscribers-Dce_CoJF.d.ts → store-subscribers-rrkLkFTt.d.ts} +2 -2
- package/dist/{subscribe-to-selector-DIHm3BRZ.d.ts → subscribe-to-selector-CP3BKSbF.d.ts} +1 -1
- package/dist/test-utils/browser-mocks.d.ts +1 -1
- package/dist/test-utils/zip-round-trip-helpers.d.ts +1 -1
- package/dist/{tracking-slice-utCNND8t.d.ts → tracking-slice-CdK8c-8P.d.ts} +1 -1
- package/dist/types/ar-types.d.ts +2 -2
- package/dist/types/geo-types.d.ts +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/utils/concurrency.d.ts +1 -1
- package/dist/utils/failure-tracker.d.ts +1 -1
- package/dist/utils/format-file-size.d.ts +1 -1
- package/dist/utils/fused-path.d.ts +1 -1
- package/dist/utils/index.d.ts +6 -6
- package/dist/utils/list-formatter.d.ts +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/visualization/accuracy-circles.d.ts +1 -1
- package/dist/visualization/alignment-lerper.d.ts +1 -1
- package/dist/visualization/ar-world-group-alignment.d.ts +2 -0
- package/dist/visualization/ar-world-group-alignment.js +51 -0
- package/dist/visualization/camera-follower.d.ts +1 -1
- package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
- package/dist/visualization/frame-conversions.d.ts +2 -0
- package/dist/visualization/frame-conversions.js +88 -0
- package/dist/visualization/frustum-visibility.d.ts +1 -1
- package/dist/visualization/gps-anchor.d.ts +1 -1
- package/dist/visualization/gps-anchor.js +216 -1
- package/dist/visualization/gps-compass-cubes.d.ts +1 -1
- package/dist/visualization/gps-event-markers.d.ts +1 -1
- package/dist/visualization/gps-event-markers.js +1 -1
- package/dist/visualization/hit-test-reticle.d.ts +2 -0
- package/dist/visualization/hit-test-reticle.js +81 -0
- package/dist/visualization/index.d.ts +19 -17
- package/dist/visualization/index.js +5 -2
- package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
- package/dist/visualization/lerp-utils.d.ts +1 -1
- package/dist/visualization/map-data.d.ts +1 -1
- package/dist/visualization/map-overlay-draw.d.ts +1 -1
- package/dist/visualization/map-overlay.d.ts +1 -1
- package/dist/visualization/three-dispose.d.ts +1 -1
- package/dist/visualization/vis-colors.d.ts +1 -1
- package/dist/webxr-nue-basis-CqKQmZzT.d.ts +23 -0
- package/dist/{webxr-session-DB5cIZnN.d.ts → webxr-session-DtAG9srK.d.ts} +45 -13
- package/dist/webxr-session-QhcSSub5.js +1041 -0
- package/dist/xr-frame-loop-BtYytZJg.d.ts +70 -0
- package/package.json +1 -1
- package/dist/chromium-camera-access-workaround-NvChXsi8.d.ts +0 -61
- package/dist/depth-sampler-xg8vna6c.d.ts +0 -108
- package/dist/gps-anchor-DjC_3MoT.js +0 -257
- package/dist/index-pOjUCKEP.d.ts +0 -24
- /package/dist/{accuracy-circles-CsxE_7x1.d.ts → accuracy-circles-BpwWAs8G.d.ts} +0 -0
- /package/dist/{alignment-lerper-L1RbWHQ4.d.ts → alignment-lerper-Dm9G7JJO.d.ts} +0 -0
- /package/dist/{camera-follower-1k8mnw5J.d.ts → camera-follower-C2mwEn7c.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-JKb1ST8E.d.ts → capture-failure-tracker-CUeU3L_M.d.ts} +0 -0
- /package/dist/{concurrency-CMw8pSaG.d.ts → concurrency-CO1FQvs3.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-CkjCb2HW.d.ts → css3d-renderer-manager-ptu_t3B3.d.ts} +0 -0
- /package/dist/{failure-tracker-DnHXOIRa.d.ts → failure-tracker-Cn8Fo9D4.d.ts} +0 -0
- /package/dist/{file-system-utils-CtKiiw27.d.ts → file-system-utils-DyAmcuvX.d.ts} +0 -0
- /package/dist/{format-file-size-BTS5H62-.d.ts → format-file-size-CLCZz3lC.d.ts} +0 -0
- /package/dist/{frustum-visibility-BHnFrSKQ.d.ts → frustum-visibility-CmI96ESS.d.ts} +0 -0
- /package/dist/{geo-types-CTuF23gG.d.ts → geo-types-SaPnIEUM.d.ts} +0 -0
- /package/dist/{gps-DXoQb9Kf.d.ts → gps-VuezJWK3.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-CsLtFv4B.d.ts → gps-compass-cubes-BM1uGiYV.d.ts} +0 -0
- /package/dist/{gps-error-handler-Dg3ziRVY.d.ts → gps-error-handler-CJl_2MVm.d.ts} +0 -0
- /package/dist/{gps-event-markers-BGr-iLvi.d.ts → gps-event-markers-Dc9FT-q1.d.ts} +0 -0
- /package/dist/{h3-proximity-BhfgNbdW.d.ts → h3-proximity-I1msGPgE.d.ts} +0 -0
- /package/dist/{index-gzWJMVpo.d.ts → index-CF05QV2m.d.ts} +0 -0
- /package/dist/{lerp-utils-B8MM8zCR.d.ts → lerp-utils-BpV-0Dtk.d.ts} +0 -0
- /package/dist/{list-formatter-CNqi-E2j.d.ts → list-formatter-RRcBe8Vg.d.ts} +0 -0
- /package/dist/{logger-C9vugiQb.d.ts → logger-BEHXsnnq.d.ts} +0 -0
- /package/dist/{map-overlay-DAmreyA3.d.ts → map-overlay-bcogY5fK.d.ts} +0 -0
- /package/dist/{opfs-storage-DOPkzgeT.d.ts → opfs-storage-DYm8WHq7.d.ts} +0 -0
- /package/dist/{permission-checker-DPJl_RU6.d.ts → permission-checker-GpAiSCwd.d.ts} +0 -0
- /package/dist/{scene-node-names-6LBjPmwz.d.ts → scene-node-names-Bu0S66H1.d.ts} +0 -0
- /package/dist/{three-dispose-C2drkp6f.d.ts → three-dispose-D950t71B.d.ts} +0 -0
- /package/dist/{vis-colors-CHQhjal3.d.ts → vis-colors-D6omC64K.d.ts} +0 -0
- /package/dist/{xr-camera-texture-BU5YvKAM.d.ts → xr-camera-texture-DBwCaKTd.d.ts} +0 -0
- /package/dist/{xr-error-handler-CDY5QxGb.d.ts → xr-error-handler-C0AQRmxs.d.ts} +0 -0
- /package/dist/{zip-export-QO4iLIi7.d.ts → zip-export-D_5HAvFz.d.ts} +0 -0
- /package/dist/{zip-reader-D1105idz.d.ts → zip-reader-DSEXt7K6.d.ts} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-
|
|
1
|
+
import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-DBwCaKTd.js";
|
|
2
2
|
export { CameraTextureResult, RendererLike, XRCameraLike, acquireCameraTexture };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-
|
|
1
|
+
import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-C0AQRmxs.js";
|
|
2
2
|
export { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger.js";
|
|
2
|
+
//#region ../src/ar/xr-frame-loop.ts
|
|
3
|
+
/**
|
|
4
|
+
* Per-frame **XR-access** callback registry — the safe seam that lets app
|
|
5
|
+
* code run standard WebXR work (hit-test, light estimation, depth, the WebXR
|
|
6
|
+
* Anchors API, …) without the framework wrapping each capability.
|
|
7
|
+
*
|
|
8
|
+
* The framework owns the single `renderer.setAnimationLoop(onXRFrame)` hook,
|
|
9
|
+
* and the live `XRFrame` never leaves `onXRFrame`. The plain `FrameUpdate`
|
|
10
|
+
* registry (`frame-loop.ts`) only passes `(dt, elapsed)`, which is enough for
|
|
11
|
+
* pose-free ticks but cannot drive hit-test. This registry additionally hands
|
|
12
|
+
* the callback the live `frame`, `referenceSpace`, and `session`.
|
|
13
|
+
*
|
|
14
|
+
* SAFETY CONTRACT (non-negotiable): `frame` / `referenceSpace` / `session` are
|
|
15
|
+
* valid **only synchronously inside the callback**. The `XRFrame` is
|
|
16
|
+
* use-after-frame-unsafe — storing it and reading it on a later tick throws or
|
|
17
|
+
* crashes. Passing them as arguments (never a stashable `getXrFrame()` getter)
|
|
18
|
+
* makes correct use the easy path and stashing the awkward one. Do NOT retain
|
|
19
|
+
* `ctx` or its fields beyond the callback's synchronous execution.
|
|
20
|
+
*
|
|
21
|
+
* See `2026-06-03-threejs-arbutton-minimal-ar-example-user-feedback.md`
|
|
22
|
+
* §6.2/§6.3 (option H-A2) for the design rationale.
|
|
23
|
+
*/
|
|
24
|
+
const log = createLogger("XrFrameLoop");
|
|
25
|
+
const updates = /* @__PURE__ */ new Set();
|
|
26
|
+
/**
|
|
27
|
+
* Register a per-frame XR-access callback. Returns an unregister function.
|
|
28
|
+
*
|
|
29
|
+
* Registration is idempotent — registering the same `fn` twice is a no-op
|
|
30
|
+
* (it remains a single entry in the underlying `Set`).
|
|
31
|
+
*/
|
|
32
|
+
function registerXrFrameUpdate(fn) {
|
|
33
|
+
updates.add(fn);
|
|
34
|
+
return () => {
|
|
35
|
+
updates.delete(fn);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Invoke all registered XR-access callbacks. Called by the WebXR session's
|
|
40
|
+
* `onXRFrame` once per frame, only when a live `frame` / `referenceSpace` /
|
|
41
|
+
* `session` are all available.
|
|
42
|
+
*
|
|
43
|
+
* The set is snapshotted before iterating so that
|
|
44
|
+
* `registerXrFrameUpdate` / unregister calls made by a handler during the
|
|
45
|
+
* same frame are deferred to the next tick — mirroring `runFrameUpdates`.
|
|
46
|
+
*
|
|
47
|
+
* Each callback is invoked in its own `try/catch`: this registry is the public
|
|
48
|
+
* app seam, so a bug in one app-registered callback (which throws every frame)
|
|
49
|
+
* must not abort the remaining callbacks nor propagate up through `onXRFrame`
|
|
50
|
+
* and kill the scene render for the whole session. Failures are logged and the
|
|
51
|
+
* loop continues — mirroring `runFrameUpdates`.
|
|
52
|
+
*/
|
|
53
|
+
function runXrFrameUpdates(ctx) {
|
|
54
|
+
const snapshot = Array.from(updates);
|
|
55
|
+
for (const fn of snapshot) try {
|
|
56
|
+
fn(ctx);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
log.error("A registered XrFrameUpdate threw; continuing the loop", error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Clear all registrations. Called from `resetWebXRState()` so a fresh
|
|
63
|
+
* session starts with an empty registry.
|
|
64
|
+
*/
|
|
65
|
+
function clearXrFrameUpdates() {
|
|
66
|
+
updates.clear();
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
export { clearXrFrameUpdates, registerXrFrameUpdate, runXrFrameUpdates };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Quaternion, Vector3 } from "gps-plus-slam-js";
|
|
1
|
+
import { Matrix4, Quaternion, Vector3 } from "gps-plus-slam-js";
|
|
2
2
|
|
|
3
3
|
//#region ../src/types/ar-types.d.ts
|
|
4
4
|
/**
|
|
@@ -43,6 +43,11 @@ interface ARPose {
|
|
|
43
43
|
readonly position: WebXRVec3;
|
|
44
44
|
readonly orientation: WebXRQuaternion;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* An sRGB color triple, 0–255 integers per channel. Kept as plain ints so
|
|
48
|
+
* persisted JSON stays compact (~3 bytes/point in practice).
|
|
49
|
+
*/
|
|
50
|
+
type RgbTuple = readonly [number, number, number];
|
|
46
51
|
/**
|
|
47
52
|
* A single depth point sample from WebXR Depth API.
|
|
48
53
|
* Used for 3D reconstruction and validating AR tracking accuracy.
|
|
@@ -54,6 +59,14 @@ interface DepthPoint {
|
|
|
54
59
|
readonly screenY: number;
|
|
55
60
|
/** Depth value in meters */
|
|
56
61
|
readonly depthM: number;
|
|
62
|
+
/**
|
|
63
|
+
* Camera color at (screenX, screenY), sampled from the same XR frame as
|
|
64
|
+
* the depth read (occupancy-grid port plan Iter 8). Optional + additive:
|
|
65
|
+
* recordings made before 2026-06 (or with the RGB recording option off)
|
|
66
|
+
* carry no color; consumers must fall back (e.g. height-based cube
|
|
67
|
+
* coloring).
|
|
68
|
+
*/
|
|
69
|
+
readonly rgb?: RgbTuple;
|
|
57
70
|
}
|
|
58
71
|
/**
|
|
59
72
|
* A complete depth sample with camera pose and grid of depth points.
|
|
@@ -66,8 +79,10 @@ interface DepthSample {
|
|
|
66
79
|
readonly timestamp: number;
|
|
67
80
|
/**
|
|
68
81
|
* Camera position in **raw WebXR** convention [x=East, y=Up, z=South].
|
|
69
|
-
* NOT in NUE — the recordDepthSample reducer is
|
|
70
|
-
*
|
|
82
|
+
* NOT in NUE — the recordDepthSample reducer is conversion-free (it only
|
|
83
|
+
* stores the latest sample for subscribers), so no webxrToNUE conversion
|
|
84
|
+
* is ever applied. Consumers needing NUE must convert themselves; the
|
|
85
|
+
* occupancy-grid pipeline works directly in this raw frame.
|
|
71
86
|
*/
|
|
72
87
|
readonly cameraPos: Vector3;
|
|
73
88
|
/**
|
|
@@ -76,7 +91,15 @@ interface DepthSample {
|
|
|
76
91
|
*/
|
|
77
92
|
readonly cameraRot: Quaternion;
|
|
78
93
|
/** Grid of depth points */
|
|
79
|
-
readonly points: DepthPoint[];
|
|
94
|
+
readonly points: readonly DepthPoint[];
|
|
95
|
+
/**
|
|
96
|
+
* Projection matrix of the capturing XRView (16 floats, column-major,
|
|
97
|
+
* serializable tuple — not a THREE.Matrix4). Camera intrinsics needed to
|
|
98
|
+
* unproject (screenX, screenY, depthM) back into a 3D AR-space point.
|
|
99
|
+
* Optional: recordings made before 2026-06 do not carry it; consumers
|
|
100
|
+
* must skip unprojection for such samples.
|
|
101
|
+
*/
|
|
102
|
+
readonly projectionMatrix?: Matrix4;
|
|
80
103
|
}
|
|
81
104
|
//#endregion
|
|
82
|
-
export {
|
|
105
|
+
export { RgbTuple as a, DepthSample as i, ArPoseTuples as n, WebXRQuaternion as o, DepthPoint as r, WebXRVec3 as s, ARPose as t };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { t as SubscribableStore } from "./subscribe-to-selector-CP3BKSbF.js";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
|
|
4
|
+
//#region ../src/visualization/ar-world-group-alignment.d.ts
|
|
5
|
+
interface ArWorldGroupAlignmentOptions {
|
|
6
|
+
/** The store whose alignment selector drives the lerper. */
|
|
7
|
+
readonly store: SubscribableStore;
|
|
8
|
+
/** The AR world group whose `.matrix` is lerped toward each alignment. */
|
|
9
|
+
readonly arWorldGroup: THREE.Object3D;
|
|
10
|
+
/**
|
|
11
|
+
* Lerp speed multiplier forwarded to {@link createAlignmentLerper}
|
|
12
|
+
* (default matches the lerper's own `DEFAULT_LERP_RATE`).
|
|
13
|
+
*/
|
|
14
|
+
readonly lerpRate?: number;
|
|
15
|
+
}
|
|
16
|
+
interface ArWorldGroupAlignmentHandle {
|
|
17
|
+
/** Stop the subscription and the per-frame update. */
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Begin applying the store's (lerped) alignment to `arWorldGroup`. Returns a
|
|
22
|
+
* handle whose `dispose()` removes both the store subscription and the
|
|
23
|
+
* per-frame update.
|
|
24
|
+
*
|
|
25
|
+
* Disposal is tied to the AR session lifecycle: the binding registers itself
|
|
26
|
+
* with the session-disposer registry that `resetWebXRState()` flushes on
|
|
27
|
+
* teardown, so a caller can `enableArWorldGroupAlignment(...)` once and never
|
|
28
|
+
* hold the handle — the binding cannot outlive the session (which is what two
|
|
29
|
+
* apps independently leaked: the store subscription survives a teardown because
|
|
30
|
+
* `clearFrameUpdates` only drops the per-frame tick). Because `initAR()` throws
|
|
31
|
+
* while a prior session is live, every restart passes through that flush. The
|
|
32
|
+
* handle is still returned for callers that want to stop alignment mid-session,
|
|
33
|
+
* and is idempotent + self-deregistering so a manual `dispose()` and the
|
|
34
|
+
* teardown flush never double-run. See
|
|
35
|
+
* gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-08-arworldgroup-alignment-session-scoped-disposal.md.
|
|
36
|
+
*
|
|
37
|
+
* Double-drive is still the caller's concern: the recorder owns its own lerper
|
|
38
|
+
* and must NOT also call this (it would double-lerp the same group). It does not
|
|
39
|
+
* call this helper, so flushing the registry on teardown never affects it.
|
|
40
|
+
*/
|
|
41
|
+
declare function enableArWorldGroupAlignment(options: ArWorldGroupAlignmentOptions): ArWorldGroupAlignmentHandle;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { ArWorldGroupAlignmentOptions as n, enableArWorldGroupAlignment as r, ArWorldGroupAlignmentHandle as t };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region ../src/ar/bresenham3d.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* 3D Bresenham Line Tracer
|
|
4
|
+
*
|
|
5
|
+
* Direct port of the Unity occupancy-grid helper
|
|
6
|
+
* (`PointCloudHelpers.BresenhamsLineAlgorithm`, after
|
|
7
|
+
* http://members.chello.at/~easyfilter/bresenham.html): walks integer grid
|
|
8
|
+
* cells from `start` to `end`, invoking a visitor per cell. Used by the
|
|
9
|
+
* occupancy grid for free-space carving and raycasting.
|
|
10
|
+
*
|
|
11
|
+
* Semantics preserved from the Unity original:
|
|
12
|
+
* - The visitor runs on the start cell BEFORE the stop-distance check.
|
|
13
|
+
* - `stopDistance` is measured in dominant-axis (Chebyshev) steps from the
|
|
14
|
+
* end cell: tracing stops once the remaining distance reaches it, so the
|
|
15
|
+
* end cell and its `stopDistance`-neighborhood are not visited (except
|
|
16
|
+
* the unconditional start visit).
|
|
17
|
+
* - Error offsets use integer division (`floor(dm / 2)`).
|
|
18
|
+
*
|
|
19
|
+
* @see bresenham3d.ts.md for detailed documentation
|
|
20
|
+
*/
|
|
21
|
+
/** Integer grid cell coordinate triple. */
|
|
22
|
+
type GridCell = readonly [number, number, number];
|
|
23
|
+
/**
|
|
24
|
+
* Main-thread safety cap: the maximum dominant-axis (Chebyshev) span a single
|
|
25
|
+
* trace may cover. The trace runs synchronously, one iteration per
|
|
26
|
+
* dominant-axis step, so an unbounded span freezes the UI. Finite-but-absurd
|
|
27
|
+
* coordinates (a tracking glitch, a corrupt projectionMatrix unprojecting to a
|
|
28
|
+
* huge world point) quantize to safe integers and pass the integer check, so
|
|
29
|
+
* this is the only thing standing between such input and a multi-second
|
|
30
|
+
* (potentially multi-billion-iteration) freeze.
|
|
31
|
+
*
|
|
32
|
+
* Chosen generously — at the grid's 0.15 m cells this is ~150 km, far beyond
|
|
33
|
+
* any real AR scene, so it never trips on legitimate carving or raycasting.
|
|
34
|
+
* It is a circuit breaker against programmer/data error, not a ray-length
|
|
35
|
+
* policy: exceeding it throws (loud — surfaces the upstream bug) rather than
|
|
36
|
+
* silently truncating the trace.
|
|
37
|
+
*/
|
|
38
|
+
declare const MAX_TRACE_STEPS = 1000000;
|
|
39
|
+
/**
|
|
40
|
+
* Trace the line from `start` to `end`, calling `visitCell` per cell.
|
|
41
|
+
*
|
|
42
|
+
* @param visitCell - return `false` to stop the trace early.
|
|
43
|
+
* @param stopDistance - dominant-axis steps before `end` at which to stop
|
|
44
|
+
* (default 0 = trace all the way to `end`).
|
|
45
|
+
* @throws TypeError when a coordinate is not a safe integer (cells must be
|
|
46
|
+
* quantized before tracing — programmer error, not a data error).
|
|
47
|
+
* @throws RangeError when `stopDistance` is not a non-negative safe integer.
|
|
48
|
+
* The loop terminates on a counter (`i--`) that decrements unconditionally,
|
|
49
|
+
* so a negative or fractional value still terminates (it merely traces past
|
|
50
|
+
* `end`); but `NaN`/`-Infinity` never satisfy `i <= stopDistance` and would
|
|
51
|
+
* spin forever. Rejecting up front both prevents that freeze and enforces
|
|
52
|
+
* the "dominant-axis steps before end" contract.
|
|
53
|
+
* @throws RangeError when the dominant-axis span exceeds {@link MAX_TRACE_STEPS}
|
|
54
|
+
* (circuit breaker against a synchronous main-thread freeze from
|
|
55
|
+
* finite-but-absurd coordinates).
|
|
56
|
+
*/
|
|
57
|
+
declare function bresenham3d(start: GridCell, end: GridCell, visitCell: (cell: GridCell) => boolean, stopDistance?: number): void;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { MAX_TRACE_STEPS as n, bresenham3d as r, GridCell as t };
|
|
@@ -63,6 +63,26 @@ declare class CameraBlitCapture {
|
|
|
63
63
|
* @returns JPEG Blob, or null if capture fails
|
|
64
64
|
*/
|
|
65
65
|
captureToBlob(renderer: THREE.WebGLRenderer, cameraTexture: THREE.Texture, quality: number): Promise<Blob | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Run the blit + readback (steps A+B of {@link captureToBlob}) and return
|
|
68
|
+
* the raw RGBA pixel buffer without JPEG encoding — the cheap path for
|
|
69
|
+
* per-point color sampling (occupancy-grid port plan Iter 8).
|
|
70
|
+
*
|
|
71
|
+
* IMPORTANT: Must be called within the XR animation frame callback, while
|
|
72
|
+
* the camera texture is valid. The returned `pixels` is the INTERNAL
|
|
73
|
+
* buffer — valid only until the next capture or `resizeIfNeeded`; consume
|
|
74
|
+
* it synchronously (e.g. via `createRgbLookup`) or copy it.
|
|
75
|
+
*
|
|
76
|
+
* Note: the buffer is in WebGL readback order (bottom-row-first / RGBA);
|
|
77
|
+
* `createRgbLookup` handles the y-flip.
|
|
78
|
+
*
|
|
79
|
+
* @returns the buffer with its dimensions, or null on failure/dispose.
|
|
80
|
+
*/
|
|
81
|
+
captureToPixels(renderer: THREE.WebGLRenderer, cameraTexture: THREE.Texture): {
|
|
82
|
+
pixels: Uint8Array;
|
|
83
|
+
width: number;
|
|
84
|
+
height: number;
|
|
85
|
+
} | null;
|
|
66
86
|
/**
|
|
67
87
|
* Check if a pixel buffer is entirely black (all zeros).
|
|
68
88
|
* Uses sampling for performance (checks BLACK_CHECK_SAMPLE_COUNT evenly-spaced pixels).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region ../src/ar/capability-checker.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Pure capability-gating helpers, promoted from the AnchorStarter app so the
|
|
4
|
+
* minimal AR example and AnchorStarter share the *decision* and *message*
|
|
5
|
+
* without sharing app-specific copy.
|
|
6
|
+
*
|
|
7
|
+
* The async feature probing (`isWebXRSupported()` / geolocation availability)
|
|
8
|
+
* stays in each app's `main.ts`; only the browser-free decision and the
|
|
9
|
+
* user-facing message live here so they can be unit-tested without a browser.
|
|
10
|
+
*
|
|
11
|
+
* See `2026-06-03-threejs-arbutton-minimal-ar-example-user-feedback.md` §6.4.
|
|
12
|
+
*/
|
|
13
|
+
/** The two capabilities every GPS+AR demo requires to run. */
|
|
14
|
+
interface CapabilitySupport {
|
|
15
|
+
/** Browser supports a WebXR `immersive-ar` session. */
|
|
16
|
+
readonly webxr: boolean;
|
|
17
|
+
/** Geolocation API is available. */
|
|
18
|
+
readonly geolocation: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Options that let an app flavour the otherwise-neutral gating message. */
|
|
21
|
+
interface CapabilityMessageOptions {
|
|
22
|
+
/**
|
|
23
|
+
* App-specific "what this demo lets you do" phrase, appended as
|
|
24
|
+
* `…outdoors, to try ${contextLabel}.`. Omit for a neutral message that
|
|
25
|
+
* ends at `…outdoors.`. Example: `'the persistent-anchor flow'`.
|
|
26
|
+
*/
|
|
27
|
+
readonly contextLabel?: string;
|
|
28
|
+
}
|
|
29
|
+
/** True only when both AR and GPS are available — the demo can run. */
|
|
30
|
+
declare function isFullySupported(support: CapabilitySupport): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Build the capability-gated message shown when the demo cannot run. Names
|
|
33
|
+
* exactly which capabilities are missing so the user understands *why*, and
|
|
34
|
+
* always points them at the supported environment (an AR phone, outdoors).
|
|
35
|
+
* Returns `null` when everything is supported (no message needed).
|
|
36
|
+
*
|
|
37
|
+
* The trailing "to try …" clause is app-specific and supplied via
|
|
38
|
+
* `options.contextLabel`; without it the message ends neutrally at
|
|
39
|
+
* "…outdoors.".
|
|
40
|
+
*/
|
|
41
|
+
declare function capabilityMessage(support: CapabilitySupport, options?: CapabilityMessageOptions): string | null;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { isFullySupported as i, CapabilitySupport as n, capabilityMessage as r, CapabilityMessageOptions as t };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
//#region ../src/ar/chromium-camera-access-workaround.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Chromium WebXR camera-access tab-crash workaround.
|
|
4
|
+
*
|
|
5
|
+
* Background:
|
|
6
|
+
* Requesting `camera-access` as an optional WebXR feature on Android Chrome
|
|
7
|
+
* 147+ causes a fatal renderer-process crash (`CrRendererMain`) 1–2 seconds
|
|
8
|
+
* after entering AR. The crash reproduces in the upstream three.js
|
|
9
|
+
* `webxr_ar_hittest.html` example with `optionalFeatures: ['camera-access']`
|
|
10
|
+
* added — i.e. it is not specific to this app's session setup. See:
|
|
11
|
+
*
|
|
12
|
+
* - GpsPlusSlamJs_Docs/docs/2026-04-22-camera-access-reproducer-plan.md
|
|
13
|
+
* - GpsPlusSlamJs_Docs/docs/2026-06-04-camera-access-crash-regression-chrome-148.md
|
|
14
|
+
* - https://github.com/mrdoob/three.js/issues/33404
|
|
15
|
+
* - https://issues.chromium.org/issues/507508099 (root-cause, marked Fixed)
|
|
16
|
+
*
|
|
17
|
+
* There is NOT a single crash here — the Chromium tracker notes the crash on
|
|
18
|
+
* Chrome 147 is different from the crash on 148+, and the simple workaround
|
|
19
|
+
* below only helped on a subset of versions. The empirically-verified
|
|
20
|
+
* (on-device) timeline is:
|
|
21
|
+
*
|
|
22
|
+
* - 147 : deleting `createProjectionLayer` / `layers` forces three.js onto
|
|
23
|
+
* `XRWebGLLayer` and sidesteps the crash (deletes-only is sufficient).
|
|
24
|
+
* - 148.0.7778.12 .. 149.0.7821 : the delete-only trick is NOT sufficient on
|
|
25
|
+
* its own. An ADDITIONAL patch is needed: persist the `baseLayer`
|
|
26
|
+
* reference across `XRSession.prototype.updateRenderState` so three.js's
|
|
27
|
+
* later `depthNear`/`depthFar` update does not drop the active
|
|
28
|
+
* `glBaseLayer`. (Confirmed on-device on `148.0.7778.215`: BOTH the
|
|
29
|
+
* deletes and the baseLayer patch are required for the page not to
|
|
30
|
+
* crash. Earlier 148 builds (`< .7778.12`) are below the window per the
|
|
31
|
+
* tracker, which reported delete-only worked there.)
|
|
32
|
+
* - > 149.0.7821 (incl. Chrome 150) : the delete-only path is STILL required
|
|
33
|
+
* (confirmed on-device: Chrome 150 only stops crashing when the deletes
|
|
34
|
+
* are applied), but the extra baseLayer-persistence patch is NOT needed.
|
|
35
|
+
* The earlier assumption that Chromium fully fixed this on patched
|
|
36
|
+
* builds did not hold on real devices, so we no longer skip the
|
|
37
|
+
* workaround on "patched" Chrome.
|
|
38
|
+
*
|
|
39
|
+
* Resulting policy (see {@link applyChromiumProjectionLayerWorkaround}):
|
|
40
|
+
* - ALWAYS apply the deletes (every Chrome build, and unknown/non-Chromium
|
|
41
|
+
* environments — restoring the original always-on behavior).
|
|
42
|
+
* - Apply the baseLayer-persistence patch ONLY when a detected Chrome build
|
|
43
|
+
* falls inside the affected window
|
|
44
|
+
* [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}].
|
|
45
|
+
*
|
|
46
|
+
* Caveats:
|
|
47
|
+
* - This is a Chromium-specific hack and the upstream comment explicitly
|
|
48
|
+
* warns it "might break webxr on other devices" — keep it opt-in.
|
|
49
|
+
* - Must run BEFORE any WebXR session setup. Three.js reads these prototype
|
|
50
|
+
* members lazily when the first session starts, so calling this at app
|
|
51
|
+
* bootstrap (before `initAR()`) is sufficient.
|
|
52
|
+
* - Idempotent: safe to call repeatedly. Safe on environments where the
|
|
53
|
+
* prototypes do not exist (e.g. desktop browsers, jsdom).
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Parsed Chrome version as `[major, minor, build, patch]`.
|
|
57
|
+
*/
|
|
58
|
+
type ChromeVersion = [number, number, number, number];
|
|
59
|
+
/**
|
|
60
|
+
* Inclusive lower bound of the Chrome window that additionally needs the
|
|
61
|
+
* `baseLayer`-persistence patch (on top of the deletes).
|
|
62
|
+
*
|
|
63
|
+
* Set to `148.0.7778.12`, the issue tracker's figure for when the delete-only
|
|
64
|
+
* trick stopped being sufficient. On-device confirmation: `148.0.7778.215`
|
|
65
|
+
* (well inside this window) crashes with deletes-only and needs BOTH patches.
|
|
66
|
+
* Earlier 148 builds (`< .7778.12`) and all of Chrome 147 stay below this
|
|
67
|
+
* bound (deletes-only) per the documented timeline — we have no on-device
|
|
68
|
+
* evidence that they need the baseLayer patch, so we do not apply it there.
|
|
69
|
+
*/
|
|
70
|
+
declare const BASELAYER_WINDOW_MIN: ChromeVersion;
|
|
71
|
+
/**
|
|
72
|
+
* Inclusive upper bound of the Chrome window that additionally needs the
|
|
73
|
+
* `baseLayer`-persistence patch. The crash is fixed after `149.0.7819.0` and
|
|
74
|
+
* the camera image is correctly populated after `149.0.7821.0`; above this
|
|
75
|
+
* build the extra patch is no longer required (the deletes still are — see
|
|
76
|
+
* the module header and the on-device matrix for Chrome 150).
|
|
77
|
+
*
|
|
78
|
+
* @see https://github.com/mrdoob/three.js/issues/33404
|
|
79
|
+
*/
|
|
80
|
+
declare const BASELAYER_WINDOW_MAX: ChromeVersion;
|
|
81
|
+
/**
|
|
82
|
+
* Result of {@link applyChromiumProjectionLayerWorkaround}.
|
|
83
|
+
* Useful for logging and tests.
|
|
84
|
+
*/
|
|
85
|
+
interface ChromiumProjectionLayerWorkaroundResult {
|
|
86
|
+
/** True if `XRWebGLBinding.prototype.createProjectionLayer` was deleted on this call. */
|
|
87
|
+
deletedCreateProjectionLayer: boolean;
|
|
88
|
+
/** True if `XRRenderState.prototype.layers` was deleted on this call. */
|
|
89
|
+
deletedRenderStateLayers: boolean;
|
|
90
|
+
/** True if `XRSession.prototype.updateRenderState` was wrapped on this call. */
|
|
91
|
+
patchedUpdateRenderState: boolean;
|
|
92
|
+
/** The detected Chrome version (`"major.minor.build.patch"`), or null. */
|
|
93
|
+
detectedChromeVersion: string | null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Parse a Chrome/Chromium version from a user-agent string.
|
|
97
|
+
*
|
|
98
|
+
* Matches the `Chrome/<major>.<minor>.<build>.<patch>` token (and the iOS
|
|
99
|
+
* `CriOS/...` variant). Returns null for non-Chromium user agents.
|
|
100
|
+
*/
|
|
101
|
+
declare function parseChromeVersion(userAgent: string): ChromeVersion | null;
|
|
102
|
+
/**
|
|
103
|
+
* True when the detected Chrome build falls inside the affected window
|
|
104
|
+
* [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}] (inclusive)
|
|
105
|
+
* and therefore additionally needs the `baseLayer`-persistence patch. Outside
|
|
106
|
+
* the window (including non-Chromium user agents) returns false — only the
|
|
107
|
+
* deletes are needed there.
|
|
108
|
+
*/
|
|
109
|
+
declare function needsBaseLayerPersistence(userAgent: string): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Apply the Chromium camera-access tab-crash workaround.
|
|
112
|
+
*
|
|
113
|
+
* Policy (derived from on-device testing — see the module header):
|
|
114
|
+
*
|
|
115
|
+
* - ALWAYS removes `XRWebGLBinding.prototype.createProjectionLayer`
|
|
116
|
+
* (three.js r184) and `XRRenderState.prototype.layers` (three.js r158) so
|
|
117
|
+
* three.js falls back to `XRWebGLLayer`. This is required on every affected
|
|
118
|
+
* Chrome build observed so far, including Chrome 150, and is also applied
|
|
119
|
+
* on unknown/non-Chromium environments (restoring the original always-on
|
|
120
|
+
* behavior).
|
|
121
|
+
* - ADDITIONALLY persists the `baseLayer` across
|
|
122
|
+
* `XRSession.prototype.updateRenderState`, but ONLY when a detected Chrome
|
|
123
|
+
* build falls inside the affected window
|
|
124
|
+
* [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}]. Outside
|
|
125
|
+
* that window the extra patch is unnecessary (and is skipped on unknown
|
|
126
|
+
* environments to avoid touching projection-layer devices like Quest).
|
|
127
|
+
*
|
|
128
|
+
* Call once during bootstrap, before any `requestSession()` call.
|
|
129
|
+
*
|
|
130
|
+
* @param options.userAgent override the detected user agent (for testing).
|
|
131
|
+
* @returns which prototype members were actually changed on this call.
|
|
132
|
+
*/
|
|
133
|
+
declare function applyChromiumProjectionLayerWorkaround(options?: {
|
|
134
|
+
userAgent?: string;
|
|
135
|
+
}): ChromiumProjectionLayerWorkaroundResult;
|
|
136
|
+
//#endregion
|
|
137
|
+
export { applyChromiumProjectionLayerWorkaround as a, ChromiumProjectionLayerWorkaroundResult as i, BASELAYER_WINDOW_MIN as n, needsBaseLayerPersistence as o, ChromeVersion as r, parseChromeVersion as s, BASELAYER_WINDOW_MAX as t };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as LibraryRootState, c as RootState, d as calcRelativeCoordsInMeters, f as createGpsSlamStore, g as webxrToNUE, h as validateLicenseKey, i as LatLongAlt, l as Vector3, m as odometryTrackingRestarted, n as GpsPoint, o as Matrix4, p as isIdentityMatrix4, r as LatLong, s as Quaternion, t as ArImageCapture, u as calcGpsCoords } from "../index-
|
|
1
|
+
import { a as LibraryRootState, c as RootState, d as calcRelativeCoordsInMeters, f as createGpsSlamStore, g as webxrToNUE, h as validateLicenseKey, i as LatLongAlt, l as Vector3, m as odometryTrackingRestarted, n as GpsPoint, o as Matrix4, p as isIdentityMatrix4, r as LatLong, s as Quaternion, t as ArImageCapture, u as calcGpsCoords } from "../index-CF05QV2m.js";
|
|
2
2
|
export { ArImageCapture, GpsPoint, LatLong, LatLongAlt, LibraryRootState, Matrix4, Quaternion, RootState, Vector3, calcGpsCoords, calcRelativeCoordsInMeters, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as ARPose } from "./ar-types-
|
|
2
|
-
import { a as TrackingSliceState, t as DeviceOrientation } from "./tracking-slice-
|
|
3
|
-
import { t as RecordingState } from "./recording-slice-
|
|
4
|
-
import { n as SessionMetadata } from "./opfs-storage-
|
|
5
|
-
import { n as StorageBackend } from "./storage-backend-
|
|
1
|
+
import { t as ARPose } from "./ar-types-Dan1MVTi.js";
|
|
2
|
+
import { a as TrackingSliceState, t as DeviceOrientation } from "./tracking-slice-CdK8c-8P.js";
|
|
3
|
+
import { t as RecordingState } from "./recording-slice-89O07ebs.js";
|
|
4
|
+
import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
|
|
5
|
+
import { n as StorageBackend } from "./storage-backend-C9HLFtgz.js";
|
|
6
6
|
import { GpsPoint, LatLong, Matrix4, RootState, Vector3 } from "gps-plus-slam-js";
|
|
7
7
|
import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
|
|
8
8
|
import { Middleware, Reducer, ReducersMapObject, configureStore } from "@reduxjs/toolkit";
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { a as RgbTuple, i as DepthSample, t as ARPose } from "./ar-types-Dan1MVTi.js";
|
|
2
|
+
import { Matrix4 } from "gps-plus-slam-js";
|
|
3
|
+
|
|
4
|
+
//#region ../src/ar/depth-rgb-lookup.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Sample the camera color at normalized view coordinates (0–1, y=0 top).
|
|
7
|
+
* Returns null for out-of-range or non-finite coordinates.
|
|
8
|
+
*/
|
|
9
|
+
type RgbLookup = (screenX: number, screenY: number) => RgbTuple | null;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region ../src/ar/depth-sampler.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for depth sampling behavior.
|
|
14
|
+
*/
|
|
15
|
+
interface DepthSamplerConfig {
|
|
16
|
+
/** Interval between samples in milliseconds. Default: 1000ms */
|
|
17
|
+
intervalMs: number;
|
|
18
|
+
/**
|
|
19
|
+
* Number of points per dimension (gridSize x gridSize). Default: 16
|
|
20
|
+
* (256 pts at 1 Hz — dense enough to populate the AR-space occupancy
|
|
21
|
+
* grid for on-device verification, see the 2026-06-11 port plan §1).
|
|
22
|
+
*/
|
|
23
|
+
gridSize: number;
|
|
24
|
+
/** Time in ms to wait before declaring depth unavailable. Default: 5000ms */
|
|
25
|
+
unavailabilityThresholdMs: number;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to enrich each sampled point with the camera color at its view
|
|
28
|
+
* coordinates (occupancy-grid port plan Iter 8). Requires the
|
|
29
|
+
* `acquireRgbLookup` callback; gates the per-sample GPU blit+readback.
|
|
30
|
+
* Default: true.
|
|
31
|
+
*/
|
|
32
|
+
rgb: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Callbacks for depth sampler events.
|
|
36
|
+
*/
|
|
37
|
+
interface DepthSamplerCallbacks {
|
|
38
|
+
/** Called when a depth sample is captured */
|
|
39
|
+
onSampleCaptured: (sample: DepthSample) => void;
|
|
40
|
+
/** Returns the current AR pose, or null if not available */
|
|
41
|
+
getCurrentPose: () => ARPose | null;
|
|
42
|
+
/**
|
|
43
|
+
* Called once when depth is determined to be unavailable.
|
|
44
|
+
* Triggered after unavailabilityThresholdMs with no depth data.
|
|
45
|
+
* Field Test Readiness Issue #8.
|
|
46
|
+
*/
|
|
47
|
+
onDepthUnavailable?: () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Lazily acquire a camera-color lookup for the CURRENT XR frame
|
|
50
|
+
* (occupancy-grid port plan Iter 8). Invoked at most once per *emitted*
|
|
51
|
+
* sample (never per frame or per point — acquisition is a GPU-stall
|
|
52
|
+
* blit+readback) and only while `config.rgb` is true. Returning `null`
|
|
53
|
+
* (or throwing) yields color-less points; the returned lookup is used
|
|
54
|
+
* synchronously within the same frame callback.
|
|
55
|
+
*/
|
|
56
|
+
acquireRgbLookup?: () => RgbLookup | null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* WebXR depth info interface (subset of XRDepthInformation), extended with
|
|
60
|
+
* the capturing view's projection matrix so each emitted DepthSample carries
|
|
61
|
+
* the intrinsics needed for unprojection. Build via {@link wrapXRDepthInfo}.
|
|
62
|
+
*/
|
|
63
|
+
interface DepthInfo {
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
getDepthInMeters: (x: number, y: number) => number;
|
|
67
|
+
/** Column-major projection matrix of the capturing XRView, if known. */
|
|
68
|
+
projectionMatrix?: Matrix4;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Wrap a raw browser XRDepthInformation object into a {@link DepthInfo}.
|
|
72
|
+
*
|
|
73
|
+
* - `getDepthInMeters` is bound to the source object (browser
|
|
74
|
+
* implementations are this-sensitive).
|
|
75
|
+
* - `projectionMatrix` (typically `XRView.projectionMatrix`, a Float32Array
|
|
76
|
+
* the UA may reuse across frames) is defensively validated and copied into
|
|
77
|
+
* a plain serializable 16-tuple; invalid input (wrong length, non-finite
|
|
78
|
+
* entries) yields a DepthInfo without a matrix rather than an error.
|
|
79
|
+
*/
|
|
80
|
+
declare function wrapXRDepthInfo(raw: {
|
|
81
|
+
width: number;
|
|
82
|
+
height: number;
|
|
83
|
+
getDepthInMeters: (x: number, y: number) => number;
|
|
84
|
+
}, projectionMatrix: ArrayLike<number> | undefined): DepthInfo;
|
|
85
|
+
/**
|
|
86
|
+
* Samples sparse depth points from WebXR depth sensing.
|
|
87
|
+
*
|
|
88
|
+
* Usage:
|
|
89
|
+
* ```ts
|
|
90
|
+
* const sampler = new DepthSampler({
|
|
91
|
+
* onSampleCaptured: (sample) => saveSample(sample),
|
|
92
|
+
* getCurrentPose: () => arSession.getCurrentPose(),
|
|
93
|
+
* });
|
|
94
|
+
* sampler.start();
|
|
95
|
+
* // In frame loop:
|
|
96
|
+
* sampler.onFrame(timestamp, depthInfo);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare class DepthSampler {
|
|
100
|
+
private readonly callbacks;
|
|
101
|
+
private readonly config;
|
|
102
|
+
private running;
|
|
103
|
+
private sampleCount;
|
|
104
|
+
private lastSampleTime;
|
|
105
|
+
/** Timestamp when sampling started (for unavailability detection) */
|
|
106
|
+
private startTime;
|
|
107
|
+
/** Whether we've ever received valid depth data */
|
|
108
|
+
private depthReceived;
|
|
109
|
+
/** Whether we've already fired the unavailable callback */
|
|
110
|
+
private unavailableCallbackFired;
|
|
111
|
+
constructor(callbacks: DepthSamplerCallbacks, config?: Partial<DepthSamplerConfig>);
|
|
112
|
+
/**
|
|
113
|
+
* Start depth sampling.
|
|
114
|
+
*/
|
|
115
|
+
start(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Stop depth sampling.
|
|
118
|
+
*/
|
|
119
|
+
stop(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Check if sampler is currently running.
|
|
122
|
+
*/
|
|
123
|
+
isRunning(): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Get the number of samples captured since start.
|
|
126
|
+
*/
|
|
127
|
+
getSampleCount(): number;
|
|
128
|
+
/**
|
|
129
|
+
* Get the current configuration.
|
|
130
|
+
*/
|
|
131
|
+
getConfig(): DepthSamplerConfig;
|
|
132
|
+
/**
|
|
133
|
+
* Apply partial configuration overrides (e.g. the user's recording
|
|
134
|
+
* options, plumbed in by `startDepthCapture` just before sampling
|
|
135
|
+
* starts). Invalid values are ignored defensively: every key requires a
|
|
136
|
+
* finite positive number, and `gridSize` additionally an integer.
|
|
137
|
+
*/
|
|
138
|
+
updateConfig(config: Partial<DepthSamplerConfig>): void;
|
|
139
|
+
/**
|
|
140
|
+
* Called each frame with depth information.
|
|
141
|
+
*
|
|
142
|
+
* @param timestamp - Current frame timestamp in milliseconds
|
|
143
|
+
* @param depthInfo - WebXR depth information, or null if unavailable
|
|
144
|
+
*/
|
|
145
|
+
onFrame(timestamp: number, depthInfo: DepthInfo | null): void;
|
|
146
|
+
/**
|
|
147
|
+
* Acquire the per-sample RGB lookup, gated by `config.rgb` and guarded so
|
|
148
|
+
* a failing acquisition (e.g. GL context loss during the blit) can never
|
|
149
|
+
* break the sample emission in the XR frame loop.
|
|
150
|
+
*/
|
|
151
|
+
private acquireRgbLookupSafely;
|
|
152
|
+
/**
|
|
153
|
+
* Sample a grid of depth points from the depth buffer, attaching the
|
|
154
|
+
* camera color per point when a lookup is available.
|
|
155
|
+
*/
|
|
156
|
+
private sampleGrid;
|
|
157
|
+
/**
|
|
158
|
+
* Check if depth has been unavailable for longer than the threshold.
|
|
159
|
+
* If so, fire the onDepthUnavailable callback (once).
|
|
160
|
+
*/
|
|
161
|
+
private checkDepthUnavailability;
|
|
162
|
+
/**
|
|
163
|
+
* Check if depth data has ever been received.
|
|
164
|
+
* Useful for testing and status display.
|
|
165
|
+
*/
|
|
166
|
+
hasReceivedDepth(): boolean;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { wrapXRDepthInfo as a, DepthSamplerConfig as i, DepthSampler as n, DepthSamplerCallbacks as r, DepthInfo as t };
|