gps-plus-slam-app-framework 1.0.7 → 1.1.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-CR9OWodf.d.ts} +1 -1
- package/dist/ar/camera-blit-capture.d.ts +1 -1
- 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 +2 -2
- 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/index.d.ts +15 -11
- package/dist/ar/index.js +7 -3
- package/dist/ar/replay-scene.d.ts +1 -1
- package/dist/ar/scene-node-names.d.ts +1 -1
- package/dist/ar/webxr-session.d.ts +4 -4
- package/dist/ar/webxr-session.js +23 -38
- 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-world-group-alignment-Dn4rQk_c.d.ts +43 -0
- package/dist/capability-checker-BTCmZRL4.d.ts +43 -0
- package/dist/chromium-camera-access-workaround-MifIwK9x.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-B76AGaI0.d.ts} +5 -5
- package/dist/{depth-sampler-xg8vna6c.d.ts → depth-sampler-CqrkRr2N.d.ts} +1 -1
- package/dist/enable-gps-ar-DNbO0zbg.d.ts +95 -0
- package/dist/{file-system-DTApEv_Q.d.ts → file-system-TIsDfamK.d.ts} +1 -1
- package/dist/frame-conversions-D2EYjeNa.d.ts +54 -0
- package/dist/{frame-loop-QJIxLin0.d.ts → frame-loop-BTeRpDm4.d.ts} +5 -0
- package/dist/{fused-path-CB4DwWOG.d.ts → fused-path-BdVHmDW9.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-CISLPQIb.d.ts} +12 -1
- package/dist/{gps-ar-pose-sampler-DsM1Kb2N.d.ts → gps-ar-pose-sampler-BypXZUqC.d.ts} +1 -1
- package/dist/{gps-event-coordinator-DBx9I1YX.d.ts → gps-event-coordinator-BKVZbS1M.d.ts} +3 -3
- package/dist/hit-test-reticle-BGXOxrUh.d.ts +45 -0
- package/dist/{image-capture-DZLxHDN9.d.ts → image-capture-BXZUmj7j.d.ts} +1 -1
- package/dist/index-22v8MXJX.d.ts +23 -0
- package/dist/index-BB2KEWbN2.d.ts +37 -0
- package/dist/index.d.ts +63 -57
- package/dist/index.js +14 -7
- package/dist/{leaflet-map-overlay-Cew7XAoO.d.ts → leaflet-map-overlay-jNt-kcUr.d.ts} +1 -1
- package/dist/{map-data-sih4g64v.d.ts → map-data-BGIBM5rv.d.ts} +1 -1
- package/dist/{map-overlay-draw-B3R1c9Xp.d.ts → map-overlay-draw-DcGs9UV3.d.ts} +1 -1
- package/dist/{null-storage-backend-BKOS7JpL.d.ts → null-storage-backend-BPQJSaMw.d.ts} +2 -2
- package/dist/{opfs-storage-backend-Cj_7PWoq.d.ts → opfs-storage-backend-u4QKvgvP.d.ts} +2 -2
- package/dist/{persistence-middleware-BkHIqvaA.d.ts → persistence-middleware-xB5sTllJ.d.ts} +1 -1
- package/dist/{recording-options-Dq6IsKAv.d.ts → recording-options-BSFpBSZH.d.ts} +10 -4
- package/dist/{recording-replayer-CmCIIZ02.d.ts → recording-replayer-CTL2cUE0.d.ts} +2 -2
- package/dist/{recording-slice-d6OtCrza.d.ts → recording-slice-Cb888P6d.d.ts} +2 -2
- package/dist/{replay-engine-BGBRQyXs.d.ts → replay-engine-B-5GIZtc.d.ts} +1 -1
- package/dist/{replay-scene-DpAGcAKY.d.ts → replay-scene-DkNfldPh.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-replayer.d.ts +2 -2
- package/dist/state/recording-slice.d.ts +1 -1
- 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-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-yDSKafAQ.d.ts} +1 -1
- package/dist/{store-subscribers-Dce_CoJF.d.ts → store-subscribers-swlbtg_z.d.ts} +2 -2
- package/dist/{subscribe-to-selector-DIHm3BRZ.d.ts → subscribe-to-selector--KQpgLXG.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-CDREeoZ_.d.ts} +1 -1
- package/dist/types/ar-types.d.ts +1 -1
- package/dist/types/geo-types.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- 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/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-BbdqhqY6.js +54 -0
- package/dist/{webxr-session-DB5cIZnN.d.ts → webxr-session-BnArFCew.d.ts} +29 -8
- package/dist/xr-frame-loop-BKckC7xC.d.ts +70 -0
- package/package.json +1 -1
- package/dist/chromium-camera-access-workaround-NvChXsi8.d.ts +0 -61
- 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-DEKr0Hoh.d.ts} +0 -0
- /package/dist/{alignment-lerper-L1RbWHQ4.d.ts → alignment-lerper-CCZJf-Xb.d.ts} +0 -0
- /package/dist/{ar-types-Ck8LEq8k.d.ts → ar-types-isPsQptb.d.ts} +0 -0
- /package/dist/{camera-blit-capture-C1V9I1Z6.d.ts → camera-blit-capture-75WWa9Xb.d.ts} +0 -0
- /package/dist/{camera-follower-1k8mnw5J.d.ts → camera-follower-B-nS1sr6.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-JKb1ST8E.d.ts → capture-failure-tracker-D4HYJNOj.d.ts} +0 -0
- /package/dist/{concurrency-CMw8pSaG.d.ts → concurrency-Bsmv53qw.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-CkjCb2HW.d.ts → css3d-renderer-manager-EDED3nvg.d.ts} +0 -0
- /package/dist/{failure-tracker-DnHXOIRa.d.ts → failure-tracker-D7ELffm0.d.ts} +0 -0
- /package/dist/{file-system-utils-CtKiiw27.d.ts → file-system-utils-BH6uIs2i.d.ts} +0 -0
- /package/dist/{format-file-size-BTS5H62-.d.ts → format-file-size-B7gJb3Md.d.ts} +0 -0
- /package/dist/{frustum-visibility-BHnFrSKQ.d.ts → frustum-visibility-DGnJqls0.d.ts} +0 -0
- /package/dist/{geo-types-CTuF23gG.d.ts → geo-types-clgzl8b5.d.ts} +0 -0
- /package/dist/{gps-DXoQb9Kf.d.ts → gps-B7AlMPz5.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-CsLtFv4B.d.ts → gps-compass-cubes-Ys6Hf1nc.d.ts} +0 -0
- /package/dist/{gps-error-handler-Dg3ziRVY.d.ts → gps-error-handler-BLDhUlw5.d.ts} +0 -0
- /package/dist/{gps-event-markers-BGr-iLvi.d.ts → gps-event-markers-BlHq3jYV.d.ts} +0 -0
- /package/dist/{h3-proximity-BhfgNbdW.d.ts → h3-proximity-DJnghtir.d.ts} +0 -0
- /package/dist/{index-gzWJMVpo.d.ts → index--ldLph4V.d.ts} +0 -0
- /package/dist/{lerp-utils-B8MM8zCR.d.ts → lerp-utils-DNcSmKVX.d.ts} +0 -0
- /package/dist/{list-formatter-CNqi-E2j.d.ts → list-formatter-CsqcU4v5.d.ts} +0 -0
- /package/dist/{logger-C9vugiQb.d.ts → logger-BZ44Dhd3.d.ts} +0 -0
- /package/dist/{map-overlay-DAmreyA3.d.ts → map-overlay-yrFsUtGv.d.ts} +0 -0
- /package/dist/{opfs-storage-DOPkzgeT.d.ts → opfs-storage-LsLY6VZV.d.ts} +0 -0
- /package/dist/{permission-checker-DPJl_RU6.d.ts → permission-checker-CfV7INCa.d.ts} +0 -0
- /package/dist/{scene-node-names-6LBjPmwz.d.ts → scene-node-names-IHW7HR4S.d.ts} +0 -0
- /package/dist/{three-dispose-C2drkp6f.d.ts → three-dispose-WTBAfaWU.d.ts} +0 -0
- /package/dist/{vis-colors-CHQhjal3.d.ts → vis-colors-Djnyg_UH.d.ts} +0 -0
- /package/dist/{xr-error-handler-CDY5QxGb.d.ts → xr-error-handler-DcUFshNF.d.ts} +0 -0
- /package/dist/{zip-export-QO4iLIi7.d.ts → zip-export-C0_ErAqT.d.ts} +0 -0
- /package/dist/{zip-reader-D1105idz.d.ts → zip-reader-B2lzN8F5.d.ts} +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { t as WEBXR_TO_NUE } from "../webxr-nue-basis-BbdqhqY6.js";
|
|
2
|
+
import { Matrix4, Mesh, MeshBasicMaterial, RingGeometry } from "three";
|
|
3
|
+
//#region ../src/visualization/hit-test-reticle.ts
|
|
4
|
+
/**
|
|
5
|
+
* Hit-test reticle — the small, deterministic "reticle view-model" shared by
|
|
6
|
+
* the framework's example/starter apps.
|
|
7
|
+
*
|
|
8
|
+
* A faithful port of the reticle from the stock three.js `webxr_ar_hittest`
|
|
9
|
+
* example: a flat ring laid on whatever real-world surface the WebXR
|
|
10
|
+
* `hit-test` API reports under the screen centre. The framework delta is
|
|
11
|
+
* *where* the mesh is parented and *which frame the hit pose is in*: apps add
|
|
12
|
+
* the mesh under `getArWorldGroup()` (NUE local space) rather than the
|
|
13
|
+
* GPS-aligned scene root, so the reticle rides the same lerped `arWorldGroup`
|
|
14
|
+
* alignment as the camera — but the WebXR hit pose arrives in the WebXR
|
|
15
|
+
* reference space, so `updateReticle` applies the `WEBXR_TO_NUE` basis change
|
|
16
|
+
* to it (see that function for the full rationale).
|
|
17
|
+
*
|
|
18
|
+
* The per-frame XR plumbing (requesting the hit-test source, reading
|
|
19
|
+
* `frame.getHitTestResults(...)`) stays in each app's WebXR glue and is
|
|
20
|
+
* verified manually on-device. The two functions here are the unit-tested core:
|
|
21
|
+
* given the latest hit pose (a column-major 4x4 transform matrix) or `null`,
|
|
22
|
+
* drive the mesh's visibility + transform. They are unit tested because that is
|
|
23
|
+
* the logic a porting developer is most likely to get subtly wrong (e.g.
|
|
24
|
+
* forgetting the basis change so the reticle drifts off-centre, forgetting to
|
|
25
|
+
* hide the reticle when no surface is found, or letting Three.js overwrite the
|
|
26
|
+
* matrix).
|
|
27
|
+
*/
|
|
28
|
+
const hitPoseMatrix = /* @__PURE__ */ new Matrix4();
|
|
29
|
+
/**
|
|
30
|
+
* Build the reticle mesh: a thin ring oriented flat (rotated to lie in the
|
|
31
|
+
* XZ plane) so it reads as a marker on the ground/wall.
|
|
32
|
+
*
|
|
33
|
+
* `matrixAutoUpdate` is disabled because the reticle's world transform is
|
|
34
|
+
* written wholesale from the hit-test pose every frame; letting Three.js
|
|
35
|
+
* recompose it from position/quaternion/scale would discard that pose.
|
|
36
|
+
*
|
|
37
|
+
* The mesh starts hidden (`visible = false`) — there is no surface yet.
|
|
38
|
+
*/
|
|
39
|
+
function createReticleMesh() {
|
|
40
|
+
const reticle = new Mesh(new RingGeometry(.07, .09, 32).rotateX(-Math.PI / 2), new MeshBasicMaterial({ color: 5213439 }));
|
|
41
|
+
reticle.matrixAutoUpdate = false;
|
|
42
|
+
reticle.visible = false;
|
|
43
|
+
return reticle;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Apply the latest hit-test pose to the reticle.
|
|
47
|
+
*
|
|
48
|
+
* - When `matrix` is a 16-element transform, the reticle adopts it (after the
|
|
49
|
+
* WebXR→NUE basis change, see below) and becomes visible.
|
|
50
|
+
* - When `matrix` is `null` (no surface under the screen centre, or the
|
|
51
|
+
* hit-test source is not ready yet), the reticle is hidden.
|
|
52
|
+
*
|
|
53
|
+
* Frame handling — the part a porting developer must not get wrong. The
|
|
54
|
+
* hit-test pose is expressed in the **WebXR reference space** (`X=East, Y=Up,
|
|
55
|
+
* Z=South`), the same frame as the live camera pose. The reticle, however, is
|
|
56
|
+
* parented under `getArWorldGroup()`, whose local space is **NUE** (`X=North,
|
|
57
|
+
* Y=Up, Z=East`) — the camera reaches that frame through the static
|
|
58
|
+
* `basisChangeNode` that holds `WEBXR_TO_NUE`. The reticle has no such
|
|
59
|
+
* intermediate node, so we apply the same basis change here:
|
|
60
|
+
* `reticle.matrix = WEBXR_TO_NUE · hitPose`. The reticle's resulting world pose
|
|
61
|
+
* is then `arWorldGroup.matrix · WEBXR_TO_NUE · hitPose` — identical to the
|
|
62
|
+
* transform chain the camera rides, so it stays pinned under the screen centre.
|
|
63
|
+
*
|
|
64
|
+
* Without the basis change the WebXR coordinates were interpreted as NUE: the
|
|
65
|
+
* Up axis matched (both are Y) but East/North were swapped, so the reticle
|
|
66
|
+
* drifted sideways instead of tracking the screen centre.
|
|
67
|
+
*
|
|
68
|
+
* Works on any `Object3D` (not just the mesh from `createReticleMesh`) so it can
|
|
69
|
+
* be unit tested without a WebGL context.
|
|
70
|
+
*/
|
|
71
|
+
function updateReticle(reticle, matrix) {
|
|
72
|
+
if (matrix === null) {
|
|
73
|
+
reticle.visible = false;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
hitPoseMatrix.fromArray(matrix);
|
|
77
|
+
reticle.matrix.multiplyMatrices(WEBXR_TO_NUE, hitPoseMatrix);
|
|
78
|
+
reticle.visible = true;
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { createReticleMesh, updateReticle };
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as
|
|
3
|
-
import { n as
|
|
4
|
-
import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-
|
|
5
|
-
import {
|
|
6
|
-
import { i as
|
|
7
|
-
import { t as
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { a as
|
|
11
|
-
import { n as
|
|
12
|
-
import { a as
|
|
13
|
-
import {
|
|
14
|
-
import { a as
|
|
15
|
-
import { n as
|
|
16
|
-
import { t as
|
|
17
|
-
|
|
1
|
+
import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../css3d-renderer-manager-EDED3nvg.js";
|
|
2
|
+
import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-B-nS1sr6.js";
|
|
3
|
+
import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-CCZJf-Xb.js";
|
|
4
|
+
import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-BGIBM5rv.js";
|
|
5
|
+
import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "../ar-world-group-alignment-Dn4rQk_c.js";
|
|
6
|
+
import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "../gps-compass-cubes-Ys6Hf1nc.js";
|
|
7
|
+
import { i as isSphereInCameraFrustum, n as isObjectInCameraFrustum, r as isPointInCameraFrustum, t as buildCameraFrustum } from "../frustum-visibility-DGnJqls0.js";
|
|
8
|
+
import { n as worldNueToGps, t as nueToArLocal } from "../frame-conversions-D2EYjeNa.js";
|
|
9
|
+
import { n as createReticleMesh, r as updateReticle, t as HitMatrix } from "../hit-test-reticle-BGXOxrUh.js";
|
|
10
|
+
import { a as GpsAnchorSamplePoint, i as GpsAnchorPhase, n as GpsAnchorMode, o as createGpsAnchor, r as GpsAnchorOptions, t as GpsAnchor } from "../gps-anchor-CISLPQIb.js";
|
|
11
|
+
import { n as GpsEventVisualizer, r as gpsEventVisualizer } from "../gps-event-markers-BlHq3jYV.js";
|
|
12
|
+
import { a as DEFAULT_Z_OFFSET, n as DEFAULT_LEAFLET_MAP_SIZE_PX, o as LeafletMapOverlay, r as DEFAULT_WORLD_SIZE, s as LeafletMapOverlayOptions } from "../leaflet-map-overlay-jNt-kcUr.js";
|
|
13
|
+
import { n as clampedAlpha, t as DEFAULT_LERP_RATE } from "../lerp-utils-DNcSmKVX.js";
|
|
14
|
+
import { a as addAccuracyCircles, i as AccuracyCircleSample, n as ACCURACY_CIRCLE_STROKE_OPACITY, r as ACCURACY_CIRCLE_WEIGHT, t as ACCURACY_CIRCLE_FILL_OPACITY } from "../accuracy-circles-DEKr0Hoh.js";
|
|
15
|
+
import { a as MAP_PATH_POLYLINE_OPACITY, c as USER_POSITION_COLOR, i as FUSED_PATH_COLOR, l as drawMapData, n as DrawMapDataOptions, o as MAP_PATH_POLYLINE_WEIGHT, r as DrawnMapData, s as RAW_GPS_COLOR, t as ALIGNMENT_SNAPSHOT_COLOR } from "../map-overlay-draw-DcGs9UV3.js";
|
|
16
|
+
import { a as MapOverlayOptions, c as tileXYToLatLon, i as MapOverlay, n as DEFAULT_MAP_SIZE, o as TextureLoaderInterface, r as DEFAULT_ZOOM, s as latLonToTileXY, t as DEFAULT_HEIGHT_OFFSET } from "../map-overlay-yrFsUtGv.js";
|
|
17
|
+
import { n as disposeMeshArray, r as disposeObject3D, t as DisposeOptions } from "../three-dispose-WTBAfaWU.js";
|
|
18
|
+
import { t as VIS_COLORS } from "../vis-colors-Djnyg_UH.js";
|
|
19
|
+
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, ALIGNMENT_SNAPSHOT_COLOR, type AccuracyCircleSample, type AlignmentLerper, type ArWorldGroupAlignmentHandle, type ArWorldGroupAlignmentOptions, COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, type CameraFollower, type Css3dRendererManager, DEFAULT_HEIGHT_OFFSET, DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_LERP_RATE, DEFAULT_MAP_SIZE, DEFAULT_WORLD_SIZE, DEFAULT_ZOOM, DEFAULT_Z_OFFSET, type DisposeOptions, type DrawMapDataOptions, type DrawnMapData, FUSED_PATH_COLOR, type GpsAnchor, type GpsAnchorMode, type GpsAnchorOptions, type GpsAnchorPhase, type GpsAnchorSamplePoint, type GpsCompassCubes, GpsEventVisualizer, type HitMatrix, LeafletMapOverlay, type LeafletMapOverlayOptions, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, type MapData, type MapDataInput, MapOverlay, type MapOverlayOptions, RAW_GPS_COLOR, type TextureLoaderInterface, USER_POSITION_COLOR, VIS_COLORS, addAccuracyCircles, buildCameraFrustum, buildMapData, clampedAlpha, createAlignmentLerper, createCameraFollower, createCss3dRendererManager, createGpsAnchor, createGpsCompassCubes, createReticleMesh, disposeMeshArray, disposeObject3D, drawMapData, enableArWorldGroupAlignment, gpsEventVisualizer, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum, latLonToTileXY, nueToArLocal, tileXYToLatLon, updateReticle, worldNueToGps };
|
|
@@ -6,11 +6,14 @@ import { createAlignmentLerper } from "./alignment-lerper.js";
|
|
|
6
6
|
import { VIS_COLORS } from "./vis-colors.js";
|
|
7
7
|
import { COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, createGpsCompassCubes } from "./gps-compass-cubes.js";
|
|
8
8
|
import { buildMapData } from "./map-data.js";
|
|
9
|
+
import { enableArWorldGroupAlignment } from "./ar-world-group-alignment.js";
|
|
9
10
|
import { buildCameraFrustum, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum } from "./frustum-visibility.js";
|
|
10
|
-
import {
|
|
11
|
+
import { nueToArLocal, worldNueToGps } from "./frame-conversions.js";
|
|
12
|
+
import { createReticleMesh, updateReticle } from "./hit-test-reticle.js";
|
|
13
|
+
import { createGpsAnchor } from "./gps-anchor.js";
|
|
11
14
|
import { GpsEventVisualizer, gpsEventVisualizer } from "./gps-event-markers.js";
|
|
12
15
|
import { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, addAccuracyCircles } from "./accuracy-circles.js";
|
|
13
16
|
import { ALIGNMENT_SNAPSHOT_COLOR, FUSED_PATH_COLOR, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, RAW_GPS_COLOR, USER_POSITION_COLOR, drawMapData } from "./map-overlay-draw.js";
|
|
14
17
|
import { DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_WORLD_SIZE, DEFAULT_Z_OFFSET, LeafletMapOverlay } from "./leaflet-map-overlay.js";
|
|
15
18
|
import { DEFAULT_HEIGHT_OFFSET, DEFAULT_MAP_SIZE, DEFAULT_ZOOM, MapOverlay, latLonToTileXY, tileXYToLatLon } from "./map-overlay.js";
|
|
16
|
-
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, ALIGNMENT_SNAPSHOT_COLOR, COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, DEFAULT_HEIGHT_OFFSET, DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_LERP_RATE, DEFAULT_MAP_SIZE, DEFAULT_WORLD_SIZE, DEFAULT_ZOOM, DEFAULT_Z_OFFSET, FUSED_PATH_COLOR, GpsEventVisualizer, LeafletMapOverlay, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, MapOverlay, RAW_GPS_COLOR, USER_POSITION_COLOR, VIS_COLORS, addAccuracyCircles, buildCameraFrustum, buildMapData, clampedAlpha, createAlignmentLerper, createCameraFollower, createCss3dRendererManager, createGpsAnchor, createGpsCompassCubes, disposeMeshArray, disposeObject3D, drawMapData, gpsEventVisualizer, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum, latLonToTileXY, nueToArLocal, tileXYToLatLon };
|
|
19
|
+
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, ALIGNMENT_SNAPSHOT_COLOR, COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, DEFAULT_HEIGHT_OFFSET, DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_LERP_RATE, DEFAULT_MAP_SIZE, DEFAULT_WORLD_SIZE, DEFAULT_ZOOM, DEFAULT_Z_OFFSET, FUSED_PATH_COLOR, GpsEventVisualizer, LeafletMapOverlay, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, MapOverlay, RAW_GPS_COLOR, USER_POSITION_COLOR, VIS_COLORS, addAccuracyCircles, buildCameraFrustum, buildMapData, clampedAlpha, createAlignmentLerper, createCameraFollower, createCss3dRendererManager, createGpsAnchor, createGpsCompassCubes, createReticleMesh, disposeMeshArray, disposeObject3D, drawMapData, enableArWorldGroupAlignment, gpsEventVisualizer, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum, latLonToTileXY, nueToArLocal, tileXYToLatLon, updateReticle, worldNueToGps };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as DEFAULT_Z_OFFSET, i as DEFAULT_ZOOM, n as DEFAULT_LEAFLET_MAP_SIZE_PX, o as LeafletMapOverlay, r as DEFAULT_WORLD_SIZE, s as LeafletMapOverlayOptions, t as DEFAULT_HEIGHT_OFFSET } from "../leaflet-map-overlay-
|
|
1
|
+
import { a as DEFAULT_Z_OFFSET, i as DEFAULT_ZOOM, n as DEFAULT_LEAFLET_MAP_SIZE_PX, o as LeafletMapOverlay, r as DEFAULT_WORLD_SIZE, s as LeafletMapOverlayOptions, t as DEFAULT_HEIGHT_OFFSET } from "../leaflet-map-overlay-jNt-kcUr.js";
|
|
2
2
|
export { DEFAULT_HEIGHT_OFFSET, DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_WORLD_SIZE, DEFAULT_ZOOM, DEFAULT_Z_OFFSET, LeafletMapOverlay, LeafletMapOverlayOptions };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as clampedAlpha, t as DEFAULT_LERP_RATE } from "../lerp-utils-
|
|
1
|
+
import { n as clampedAlpha, t as DEFAULT_LERP_RATE } from "../lerp-utils-DNcSmKVX.js";
|
|
2
2
|
export { DEFAULT_LERP_RATE, clampedAlpha };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-
|
|
1
|
+
import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-BGIBM5rv.js";
|
|
2
2
|
export { MapData, MapDataInput, buildMapData };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as MAP_PATH_POLYLINE_OPACITY, c as USER_POSITION_COLOR, i as FUSED_PATH_COLOR, l as drawMapData, n as DrawMapDataOptions, o as MAP_PATH_POLYLINE_WEIGHT, r as DrawnMapData, s as RAW_GPS_COLOR, t as ALIGNMENT_SNAPSHOT_COLOR } from "../map-overlay-draw-
|
|
1
|
+
import { a as MAP_PATH_POLYLINE_OPACITY, c as USER_POSITION_COLOR, i as FUSED_PATH_COLOR, l as drawMapData, n as DrawMapDataOptions, o as MAP_PATH_POLYLINE_WEIGHT, r as DrawnMapData, s as RAW_GPS_COLOR, t as ALIGNMENT_SNAPSHOT_COLOR } from "../map-overlay-draw-DcGs9UV3.js";
|
|
2
2
|
export { ALIGNMENT_SNAPSHOT_COLOR, DrawMapDataOptions, DrawnMapData, FUSED_PATH_COLOR, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, RAW_GPS_COLOR, USER_POSITION_COLOR, drawMapData };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as MapOverlayOptions, c as tileXYToLatLon, i as MapOverlay, n as DEFAULT_MAP_SIZE, o as TextureLoaderInterface, r as DEFAULT_ZOOM, s as latLonToTileXY, t as DEFAULT_HEIGHT_OFFSET } from "../map-overlay-
|
|
1
|
+
import { a as MapOverlayOptions, c as tileXYToLatLon, i as MapOverlay, n as DEFAULT_MAP_SIZE, o as TextureLoaderInterface, r as DEFAULT_ZOOM, s as latLonToTileXY, t as DEFAULT_HEIGHT_OFFSET } from "../map-overlay-yrFsUtGv.js";
|
|
2
2
|
export { DEFAULT_HEIGHT_OFFSET, DEFAULT_MAP_SIZE, DEFAULT_ZOOM, MapOverlay, MapOverlayOptions, TextureLoaderInterface, latLonToTileXY, tileXYToLatLon };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as disposeMeshArray, r as disposeObject3D, t as DisposeOptions } from "../three-dispose-
|
|
1
|
+
import { n as disposeMeshArray, r as disposeObject3D, t as DisposeOptions } from "../three-dispose-WTBAfaWU.js";
|
|
2
2
|
export { DisposeOptions, disposeMeshArray, disposeObject3D };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as VIS_COLORS } from "../vis-colors-
|
|
1
|
+
import { t as VIS_COLORS } from "../vis-colors-Djnyg_UH.js";
|
|
2
2
|
export { VIS_COLORS };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Matrix4 } from "three";
|
|
2
|
+
//#region ../src/ar/webxr-nue-basis.ts
|
|
3
|
+
/**
|
|
4
|
+
* `webxr-nue-basis` — the single source of truth for the WebXR↔NUE basis
|
|
5
|
+
* change.
|
|
6
|
+
*
|
|
7
|
+
* The framework's scene graph keeps GPS-world content in the **NUE**
|
|
8
|
+
* convention (X=North, Y=Up, Z=East) while WebXR reports poses in its own
|
|
9
|
+
* convention (X=East, Y=Up, Z=South). `WEBXR_TO_NUE` converts a transform
|
|
10
|
+
* expressed in the WebXR reference space into the NUE frame.
|
|
11
|
+
*
|
|
12
|
+
* It lives in its own tiny module (depending only on three) so it can be shared
|
|
13
|
+
* by both `webxr-session.ts` (which parents it permanently as the static
|
|
14
|
+
* `basisChangeNode`) and `visualization/hit-test-reticle.ts` (which applies it
|
|
15
|
+
* to the live hit-test pose) without either pulling the other's heavy
|
|
16
|
+
* transitive dependencies into a unit-test import graph.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Constant matrix converting WebXR local-floor coordinates to the internal
|
|
20
|
+
* NUE (North-Up-East) convention.
|
|
21
|
+
*
|
|
22
|
+
* WebXR: X=East, Y=Up, Z=South (right-handed, toward viewer)
|
|
23
|
+
* NUE: X=North, Y=Up, Z=East (right-handed)
|
|
24
|
+
*
|
|
25
|
+
* Mapping: NUE_X = -WebXR_Z, NUE_Y = WebXR_Y, NUE_Z = WebXR_X
|
|
26
|
+
*
|
|
27
|
+
* Row-major:
|
|
28
|
+
* [ 0 0 -1 0 ]
|
|
29
|
+
* [ 0 1 0 0 ]
|
|
30
|
+
* [ 1 0 0 0 ]
|
|
31
|
+
* [ 0 0 0 1 ]
|
|
32
|
+
*
|
|
33
|
+
* Stored column-major (Three.js / gl-matrix convention).
|
|
34
|
+
*/
|
|
35
|
+
const WEBXR_TO_NUE = /* @__PURE__ */ new Matrix4().fromArray([
|
|
36
|
+
0,
|
|
37
|
+
0,
|
|
38
|
+
1,
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
1,
|
|
42
|
+
0,
|
|
43
|
+
0,
|
|
44
|
+
-1,
|
|
45
|
+
0,
|
|
46
|
+
0,
|
|
47
|
+
0,
|
|
48
|
+
0,
|
|
49
|
+
0,
|
|
50
|
+
0,
|
|
51
|
+
1
|
|
52
|
+
]);
|
|
53
|
+
//#endregion
|
|
54
|
+
export { WEBXR_TO_NUE as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { i as DepthSample, t as ARPose } from "./ar-types-
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import { a as TrackingSliceState, r as ResetTransformData } from "./tracking-slice-
|
|
5
|
-
import { t as
|
|
1
|
+
import { i as DepthSample, t as ARPose } from "./ar-types-isPsQptb.js";
|
|
2
|
+
import { t as ArCrashIsolationOptions } from "./recording-options-BSFpBSZH.js";
|
|
3
|
+
import { i as ImageCaptureConfig, t as CapturedImage } from "./image-capture-BXZUmj7j.js";
|
|
4
|
+
import { a as TrackingSliceState, r as ResetTransformData } from "./tracking-slice-CDREeoZ_.js";
|
|
5
|
+
import { t as Css3dRendererManager } from "./css3d-renderer-manager-EDED3nvg.js";
|
|
6
6
|
import { r as XRCameraLike } from "./xr-camera-texture-BU5YvKAM.js";
|
|
7
7
|
import * as THREE from "three";
|
|
8
8
|
import { OdometryTrackingRestartedPayload } from "gps-plus-slam-js";
|
|
@@ -102,15 +102,33 @@ declare function extractPoseFromViewer(pose: XRViewerPose | null): ARPose | null
|
|
|
102
102
|
* @returns The latest AR pose, or null if no pose available yet
|
|
103
103
|
*/
|
|
104
104
|
declare function getCurrentArPose(): ARPose | null;
|
|
105
|
+
/**
|
|
106
|
+
* Opt-in standard WebXR session features that are independent of the
|
|
107
|
+
* crash-isolation diagnostic flags. Kept separate from
|
|
108
|
+
* `ArCrashIsolationOptions` because requesting `hit-test` is a normal app
|
|
109
|
+
* capability, not a crash-isolation toggle.
|
|
110
|
+
*/
|
|
111
|
+
interface SessionFeatureOptions {
|
|
112
|
+
/**
|
|
113
|
+
* Request the WebXR `hit-test` feature (as an *optional* feature) so app
|
|
114
|
+
* code can drive a reticle via `registerXrFrameUpdate`. Default `false` —
|
|
115
|
+
* existing recorder/anchor sessions are unaffected.
|
|
116
|
+
*/
|
|
117
|
+
requestHitTest?: boolean;
|
|
118
|
+
}
|
|
105
119
|
/**
|
|
106
120
|
* Build XR session init options.
|
|
107
121
|
* Extracted as a pure function for testability.
|
|
108
122
|
*
|
|
109
123
|
* @param rootElement - The DOM element for DOM overlay
|
|
124
|
+
* @param isolationOptions - Crash-isolation diagnostic flags (DOM overlay,
|
|
125
|
+
* depth-sensing, camera-access)
|
|
126
|
+
* @param sessionFeatures - Opt-in standard WebXR features that are independent
|
|
127
|
+
* of crash isolation (currently `requestHitTest`)
|
|
110
128
|
* @returns XRSessionInit options
|
|
111
129
|
* @throws Error if rootElement is null
|
|
112
130
|
*/
|
|
113
|
-
declare function buildSessionOptions(rootElement: Element | null, isolationOptions?: Partial<ArCrashIsolationOptions
|
|
131
|
+
declare function buildSessionOptions(rootElement: Element | null, isolationOptions?: Partial<ArCrashIsolationOptions>, sessionFeatures?: SessionFeatureOptions): XRSessionInit;
|
|
114
132
|
/**
|
|
115
133
|
* Check if WebXR immersive-ar is supported
|
|
116
134
|
*/
|
|
@@ -159,8 +177,11 @@ declare function createSceneHierarchy(): {
|
|
|
159
177
|
/**
|
|
160
178
|
* Initialize the AR session and Three.js renderer.
|
|
161
179
|
* @param container - DOM element to host the AR canvas and CSS3D overlay.
|
|
180
|
+
* @param isolationOptions - Crash-isolation diagnostic flags.
|
|
181
|
+
* @param sessionFeatures - Opt-in standard WebXR features (e.g.
|
|
182
|
+
* `requestHitTest`) forwarded to the session negotiation.
|
|
162
183
|
*/
|
|
163
|
-
declare function initAR(container: HTMLElement, isolationOptions?: Partial<ArCrashIsolationOptions
|
|
184
|
+
declare function initAR(container: HTMLElement, isolationOptions?: Partial<ArCrashIsolationOptions>, sessionFeatures?: SessionFeatureOptions): Promise<void>;
|
|
164
185
|
/**
|
|
165
186
|
* Get the current Three.js scene (for adding objects like map)
|
|
166
187
|
*/
|
|
@@ -354,4 +375,4 @@ declare function setFrameCallback(callback: (() => void) | null): void;
|
|
|
354
375
|
*/
|
|
355
376
|
declare function getLiveCss3dManager(): Css3dRendererManager | null;
|
|
356
377
|
//#endregion
|
|
357
|
-
export {
|
|
378
|
+
export { setScene as A, resetWebXRState as C, setDepthCaptureCallback as D, setCamera as E, shouldLogCameraAccessDiagnostic as F, startDepthCapture as I, startImageCapture as L, setTrackingLostCallback as M, setTrackingRecoveredCallback as N, setFrameCallback as O, setTrackingStore as P, stopDepthCapture as R, nueQuaternionToWebXR$1 as S, setArWorldGroup as T, getXrCameraFromPose as _, createSceneHierarchy as a, isXRCameraLike as b, extractResetTransformData as c, getCamera as d, getCurrentArPose as f, getScene as g, getLiveCss3dManager as h, buildSessionOptions as i, setTrackingCallbacks as j, setImageCaptureCallback as k, getArPose as l, getImageCaptureFrameCount as m, TrackingSubscribableStore as n, endARSession as o, getDepthSampleCount as p, applyAlignmentMatrix as r, extractPoseFromViewer as s, SessionFeatureOptions as t, getArWorldGroup as u, initAR as v, setArPose as w, nuePositionToWebXR as x, isWebXRSupported as y, stopImageCapture as z };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region ../src/ar/xr-frame-loop.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Per-frame **XR-access** callback registry — the safe seam that lets app
|
|
4
|
+
* code run standard WebXR work (hit-test, light estimation, depth, the WebXR
|
|
5
|
+
* Anchors API, …) without the framework wrapping each capability.
|
|
6
|
+
*
|
|
7
|
+
* The framework owns the single `renderer.setAnimationLoop(onXRFrame)` hook,
|
|
8
|
+
* and the live `XRFrame` never leaves `onXRFrame`. The plain `FrameUpdate`
|
|
9
|
+
* registry (`frame-loop.ts`) only passes `(dt, elapsed)`, which is enough for
|
|
10
|
+
* pose-free ticks but cannot drive hit-test. This registry additionally hands
|
|
11
|
+
* the callback the live `frame`, `referenceSpace`, and `session`.
|
|
12
|
+
*
|
|
13
|
+
* SAFETY CONTRACT (non-negotiable): `frame` / `referenceSpace` / `session` are
|
|
14
|
+
* valid **only synchronously inside the callback**. The `XRFrame` is
|
|
15
|
+
* use-after-frame-unsafe — storing it and reading it on a later tick throws or
|
|
16
|
+
* crashes. Passing them as arguments (never a stashable `getXrFrame()` getter)
|
|
17
|
+
* makes correct use the easy path and stashing the awkward one. Do NOT retain
|
|
18
|
+
* `ctx` or its fields beyond the callback's synchronous execution.
|
|
19
|
+
*
|
|
20
|
+
* See `2026-06-03-threejs-arbutton-minimal-ar-example-user-feedback.md`
|
|
21
|
+
* §6.2/§6.3 (option H-A2) for the design rationale.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Live, frame-scoped WebXR context. Valid only synchronously inside the
|
|
25
|
+
* `XrFrameUpdate` callback it is passed to.
|
|
26
|
+
*/
|
|
27
|
+
interface XrFrameContext {
|
|
28
|
+
/** The live `XRFrame` for this animation-frame. Use-after-frame-unsafe. */
|
|
29
|
+
readonly frame: XRFrame;
|
|
30
|
+
/** The session's reference space (e.g. for `frame.getPose` / hit-test results). */
|
|
31
|
+
readonly referenceSpace: XRReferenceSpace;
|
|
32
|
+
/** The active `XRSession` (e.g. to call `requestHitTestSource` once). */
|
|
33
|
+
readonly session: XRSession;
|
|
34
|
+
/** Seconds since the previous frame (0 on the first frame after a reset). */
|
|
35
|
+
readonly dt: number;
|
|
36
|
+
/** Seconds since the session started. */
|
|
37
|
+
readonly elapsed: number;
|
|
38
|
+
}
|
|
39
|
+
/** A per-frame callback that needs live XR access. See the safety contract. */
|
|
40
|
+
type XrFrameUpdate = (ctx: XrFrameContext) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Register a per-frame XR-access callback. Returns an unregister function.
|
|
43
|
+
*
|
|
44
|
+
* Registration is idempotent — registering the same `fn` twice is a no-op
|
|
45
|
+
* (it remains a single entry in the underlying `Set`).
|
|
46
|
+
*/
|
|
47
|
+
declare function registerXrFrameUpdate(fn: XrFrameUpdate): () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Invoke all registered XR-access callbacks. Called by the WebXR session's
|
|
50
|
+
* `onXRFrame` once per frame, only when a live `frame` / `referenceSpace` /
|
|
51
|
+
* `session` are all available.
|
|
52
|
+
*
|
|
53
|
+
* The set is snapshotted before iterating so that
|
|
54
|
+
* `registerXrFrameUpdate` / unregister calls made by a handler during the
|
|
55
|
+
* same frame are deferred to the next tick — mirroring `runFrameUpdates`.
|
|
56
|
+
*
|
|
57
|
+
* Each callback is invoked in its own `try/catch`: this registry is the public
|
|
58
|
+
* app seam, so a bug in one app-registered callback (which throws every frame)
|
|
59
|
+
* must not abort the remaining callbacks nor propagate up through `onXRFrame`
|
|
60
|
+
* and kill the scene render for the whole session. Failures are logged and the
|
|
61
|
+
* loop continues — mirroring `runFrameUpdates`.
|
|
62
|
+
*/
|
|
63
|
+
declare function runXrFrameUpdates(ctx: XrFrameContext): void;
|
|
64
|
+
/**
|
|
65
|
+
* Clear all registrations. Called from `resetWebXRState()` so a fresh
|
|
66
|
+
* session starts with an empty registry.
|
|
67
|
+
*/
|
|
68
|
+
declare function clearXrFrameUpdates(): void;
|
|
69
|
+
//#endregion
|
|
70
|
+
export { runXrFrameUpdates as a, registerXrFrameUpdate as i, XrFrameUpdate as n, clearXrFrameUpdates as r, XrFrameContext as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gps-plus-slam-app-framework",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Reusable AR+GPS app framework layer — WebXR session management, Three.js visualization, GPS sensors, storage abstractions, replay engine, and store wiring for gps-plus-slam-js.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -1,61 +0,0 @@
|
|
|
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 recent Android
|
|
7
|
-
* Chrome versions causes a fatal renderer-process crash (`CrRendererMain`)
|
|
8
|
-
* 1–2 seconds after entering AR. The crash reproduces in the upstream
|
|
9
|
-
* three.js `webxr_ar_hittest.html` example with `optionalFeatures:
|
|
10
|
-
* ['camera-access']` added — i.e. it is not specific to this app's session
|
|
11
|
-
* setup. See:
|
|
12
|
-
*
|
|
13
|
-
* - GpsPlusSlamJs_Docs/docs/2026-04-22-camera-access-reproducer-plan.md
|
|
14
|
-
* - GpsPlusSlamJs_Docs/docs/2026-04-23-webxr-camera-access-crash-bug-report.html
|
|
15
|
-
* - https://github.com/mrdoob/three.js/issues/33404
|
|
16
|
-
*
|
|
17
|
-
* Workaround (from the upstream issue thread):
|
|
18
|
-
* Three.js's `WebXRManager` chooses between the newer `XRProjectionLayer`
|
|
19
|
-
* and the older `XRWebGLLayer` based on whether
|
|
20
|
-
* `XRWebGLBinding.prototype.createProjectionLayer` is available. The crash
|
|
21
|
-
* appears to involve the projection-layer + camera-access combination, so
|
|
22
|
-
* removing the prototype method forces three.js to fall back to
|
|
23
|
-
* `XRWebGLLayer`, which sidesteps the bug.
|
|
24
|
-
*
|
|
25
|
-
* `XRRenderState.prototype.layers` is the equivalent capability check used
|
|
26
|
-
* by older three.js (r158-era) and is included for completeness.
|
|
27
|
-
*
|
|
28
|
-
* Caveats:
|
|
29
|
-
* - This is a Chromium-specific hack and the upstream comment explicitly
|
|
30
|
-
* warns it "might break webxr on other devices" — keep it opt-in.
|
|
31
|
-
* - Must run BEFORE any WebXR session setup. Three.js reads these prototype
|
|
32
|
-
* members lazily when the first session starts, so calling this at app
|
|
33
|
-
* bootstrap (before `initAR()`) is sufficient.
|
|
34
|
-
* - Idempotent: safe to call repeatedly. Safe on environments where the
|
|
35
|
-
* prototypes do not exist (e.g. desktop browsers, jsdom).
|
|
36
|
-
*/
|
|
37
|
-
/**
|
|
38
|
-
* Result of {@link applyChromiumProjectionLayerWorkaround}.
|
|
39
|
-
* Useful for logging and tests.
|
|
40
|
-
*/
|
|
41
|
-
interface ChromiumProjectionLayerWorkaroundResult {
|
|
42
|
-
/** True if `XRWebGLBinding.prototype.createProjectionLayer` was deleted on this call. */
|
|
43
|
-
deletedCreateProjectionLayer: boolean;
|
|
44
|
-
/** True if `XRRenderState.prototype.layers` was deleted on this call. */
|
|
45
|
-
deletedRenderStateLayers: boolean;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Apply the Chromium camera-access tab-crash workaround.
|
|
49
|
-
*
|
|
50
|
-
* Removes `XRWebGLBinding.prototype.createProjectionLayer` (three.js r184)
|
|
51
|
-
* and `XRRenderState.prototype.layers` (three.js r158) so three.js falls
|
|
52
|
-
* back to `XRWebGLLayer`, which avoids the renderer-process crash that
|
|
53
|
-
* happens when both projection layers and `camera-access` are enabled.
|
|
54
|
-
*
|
|
55
|
-
* Call once during bootstrap, before any `requestSession()` call.
|
|
56
|
-
*
|
|
57
|
-
* @returns which prototype members were actually deleted on this call.
|
|
58
|
-
*/
|
|
59
|
-
declare function applyChromiumProjectionLayerWorkaround(): ChromiumProjectionLayerWorkaroundResult;
|
|
60
|
-
//#endregion
|
|
61
|
-
export { applyChromiumProjectionLayerWorkaround as n, ChromiumProjectionLayerWorkaroundResult as t };
|