gps-plus-slam-app-framework 1.0.0 → 1.0.7
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/LICENSE +4 -4
- package/README.md +249 -108
- package/dist/accuracy-circles-CsxE_7x1.d.ts +43 -0
- package/dist/{app-selectors-DyMzxCEC.d.ts → app-selectors-BeU0_ab8.d.ts} +14 -15
- package/dist/ar/camera-blit-capture.d.ts +1 -1
- package/dist/ar/capture-failure-tracker.d.ts +1 -1
- package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
- package/dist/ar/depth-sampler.d.ts +2 -2
- package/dist/ar/depth-sampler.js +1 -1
- package/dist/ar/frame-loop.d.ts +2 -0
- package/dist/ar/frame-loop.js +40 -0
- package/dist/ar/image-capture.d.ts +1 -1
- package/dist/ar/image-capture.js +1 -1
- package/dist/ar/index.d.ts +12 -12
- package/dist/ar/index.js +3 -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 +151 -56
- package/dist/ar/xr-camera-texture.d.ts +1 -1
- package/dist/ar/xr-error-handler.d.ts +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/create-slam-app-store-CNsZ3rcX.d.ts +371 -0
- package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-xg8vna6c.d.ts} +1 -1
- package/dist/file-system-DTApEv_Q.d.ts +114 -0
- package/dist/frame-loop-QJIxLin0.d.ts +42 -0
- package/dist/frustum-visibility-BHnFrSKQ.d.ts +58 -0
- package/dist/{fused-path-DtqCSqJh.d.ts → fused-path-CB4DwWOG.d.ts} +1 -1
- package/dist/geo/h3-proximity.d.ts +2 -0
- package/dist/{ref-points/h3-ref-point.js → geo/h3-proximity.js} +16 -12
- package/dist/geo/index.d.ts +2 -0
- package/dist/geo/index.js +2 -0
- package/dist/{geo-types-Xx-LVcnw.d.ts → geo-types-CTuF23gG.d.ts} +16 -1
- package/dist/{gps-Ddzr2KlX.d.ts → gps-DXoQb9Kf.d.ts} +1 -1
- package/dist/gps-anchor-CnWY61XK.d.ts +48 -0
- package/dist/gps-anchor-DjC_3MoT.js +257 -0
- package/dist/gps-ar-pose-sampler-DsM1Kb2N.d.ts +43 -0
- package/dist/{recording-coordinator-DzflP07_.d.ts → gps-event-coordinator-DBx9I1YX.d.ts} +7 -6
- package/dist/gps-event-markers-BGr-iLvi.d.ts +103 -0
- package/dist/{h3-ref-point-CFhayNSZ.d.ts → h3-proximity-BhfgNbdW.d.ts} +16 -12
- package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-DZLxHDN9.d.ts} +1 -1
- package/dist/index-gzWJMVpo.d.ts +2 -0
- package/dist/index-pOjUCKEP.d.ts +24 -0
- package/dist/index.d.ts +59 -56
- package/dist/index.js +22 -21
- package/dist/{leaflet-map-overlay-CvfQXTye.d.ts → leaflet-map-overlay-Cew7XAoO.d.ts} +32 -17
- package/dist/licensing/index.d.ts +1 -1
- package/dist/licensing/index.js +1 -1
- package/dist/{logger-B81iwxx0.d.ts → logger-C9vugiQb.d.ts} +7 -1
- package/dist/map-data-sih4g64v.d.ts +49 -0
- package/dist/map-overlay-draw-B3R1c9Xp.d.ts +42 -0
- package/dist/{null-storage-backend-CsWvQwN8.d.ts → null-storage-backend-BKOS7JpL.d.ts} +4 -2
- package/dist/{opfs-storage-ChOzF_Wp.d.ts → opfs-storage-DOPkzgeT.d.ts} +54 -51
- package/dist/opfs-storage-backend-Cj_7PWoq.d.ts +13 -0
- package/dist/{permission-checker-jO2ziCWC.d.ts → permission-checker-DPJl_RU6.d.ts} +41 -1
- package/dist/persistence-middleware-BkHIqvaA.d.ts +55 -0
- package/dist/{recording-replayer-oOzPITrd.d.ts → recording-replayer-CmCIIZ02.d.ts} +2 -2
- package/dist/recording-slice-d6OtCrza.d.ts +28 -0
- package/dist/{replay-engine-DuX316ae.d.ts → replay-engine-BGBRQyXs.d.ts} +4 -1
- package/dist/{replay-scene-DtUm6bsr.d.ts → replay-scene-DpAGcAKY.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/gps.js +2 -2
- package/dist/sensors/index.d.ts +3 -3
- package/dist/sensors/index.js +1 -1
- package/dist/sensors/permission-checker.d.ts +2 -2
- package/dist/sensors/permission-checker.js +79 -1
- package/dist/state/app-selectors.d.ts +2 -2
- package/dist/state/app-selectors.js +33 -3
- package/dist/state/combined-root-state.d.ts +2 -0
- package/dist/state/combined-root-state.js +1 -0
- package/dist/state/create-slam-app-store.d.ts +2 -0
- package/dist/state/create-slam-app-store.js +75 -0
- package/dist/state/gps-ar-pose-sampler.d.ts +4 -0
- package/dist/state/gps-ar-pose-sampler.js +19 -0
- package/dist/state/{recording-coordinator.d.ts → gps-event-coordinator.d.ts} +1 -1
- package/dist/state/{recording-coordinator.js → gps-event-coordinator.js} +3 -4
- package/dist/state/index.d.ts +17 -17
- package/dist/state/index.js +10 -8
- package/dist/state/persistence-middleware.d.ts +2 -2
- package/dist/state/persistence-middleware.js +39 -11
- package/dist/state/recording-options.d.ts +1 -1
- package/dist/state/recording-replayer.d.ts +3 -2
- package/dist/state/recording-replayer.js +2 -2
- package/dist/state/recording-slice.d.ts +2 -0
- package/dist/state/{recorder-slice.js → recording-slice.js} +7 -15
- package/dist/state/replay-engine.d.ts +1 -1
- package/dist/state/replay-engine.js +3 -3
- package/dist/state/store-subscribers.d.ts +2 -2
- package/dist/state/store-subscribers.js +38 -20
- package/dist/state/subscribe-to-selector.d.ts +1 -1
- package/dist/state/tracking-quality.d.ts +2 -0
- package/dist/state/tracking-quality.js +723 -0
- package/dist/state/tracking-slice.d.ts +2 -0
- package/dist/state/tracking-slice.js +147 -0
- package/dist/storage/file-system-utils.d.ts +1 -1
- package/dist/storage/file-system.d.ts +2 -2
- package/dist/storage/file-system.js +154 -94
- package/dist/storage/index.d.ts +9 -11
- package/dist/storage/index.js +5 -7
- package/dist/storage/null-storage-backend.d.ts +1 -1
- package/dist/storage/null-storage-backend.js +7 -0
- package/dist/storage/opfs-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage-backend.js +7 -1
- package/dist/storage/opfs-storage.d.ts +2 -2
- package/dist/storage/opfs-storage.js +69 -85
- package/dist/storage/storage-backend.d.ts +2 -2
- package/dist/storage/zip-export.d.ts +2 -2
- package/dist/storage/zip-export.js +55 -62
- package/dist/storage/zip-reader.d.ts +2 -2
- package/dist/storage/zip-reader.js +32 -5
- package/dist/storage-backend-CT0Il_AB.d.ts +28 -0
- package/dist/{store-subscribers-CuoIzB5T.d.ts → store-subscribers-Dce_CoJF.d.ts} +31 -7
- package/dist/{subscribe-to-selector-UTZ0KkAc.d.ts → subscribe-to-selector-DIHm3BRZ.d.ts} +1 -1
- package/dist/test-utils/browser-mocks.d.ts +1 -1
- package/dist/test-utils/zip-round-trip-helpers.d.ts +7 -1
- package/dist/test-utils/zip-round-trip-helpers.js +6 -5
- package/dist/tracking-slice-utCNND8t.d.ts +86 -0
- package/dist/types/ar-types.d.ts +1 -1
- package/dist/types/geo-types.d.ts +2 -2
- 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/utils/logger.js +68 -8
- package/dist/visualization/accuracy-circles.d.ts +2 -0
- package/dist/visualization/accuracy-circles.js +57 -0
- package/dist/visualization/alignment-lerper.d.ts +1 -1
- package/dist/visualization/camera-follower.d.ts +1 -1
- package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
- package/dist/visualization/frustum-visibility.d.ts +2 -0
- package/dist/visualization/frustum-visibility.js +139 -0
- package/dist/visualization/gps-anchor.d.ts +2 -0
- package/dist/visualization/gps-anchor.js +2 -0
- package/dist/visualization/gps-compass-cubes.d.ts +1 -1
- package/dist/visualization/gps-event-markers.d.ts +2 -2
- package/dist/visualization/gps-event-markers.js +69 -2
- package/dist/visualization/index.d.ts +17 -12
- package/dist/visualization/index.js +6 -2
- package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
- package/dist/visualization/leaflet-map-overlay.js +56 -98
- package/dist/visualization/lerp-utils.d.ts +1 -1
- package/dist/visualization/map-data.d.ts +2 -0
- package/dist/visualization/map-data.js +33 -0
- package/dist/visualization/map-overlay-draw.d.ts +2 -0
- package/dist/visualization/map-overlay-draw.js +107 -0
- 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-session-COlSrXdL.d.ts → webxr-session-DB5cIZnN.d.ts} +53 -12
- package/dist/{zip-export-Rtpi75JJ.d.ts → zip-export-QO4iLIi7.d.ts} +58 -7
- package/dist/{zip-reader-D7pkpX8K.d.ts → zip-reader-D1105idz.d.ts} +38 -1
- package/package.json +29 -18
- package/dist/ar/tracking-state.d.ts +0 -2
- package/dist/ar/tracking-state.js +0 -164
- package/dist/community-license-key-ChZLCJyO.d.ts +0 -21
- package/dist/file-system-BsQgYCU3.d.ts +0 -128
- package/dist/gps-event-markers-DpEy2qRd.d.ts +0 -67
- package/dist/licensing/community-license-key.d.ts +0 -2
- package/dist/licensing/community-license-key.js +0 -21
- package/dist/opfs-storage-backend-CVcmfJHN.d.ts +0 -11
- package/dist/persistence-middleware-DrptY02i.d.ts +0 -31
- package/dist/recorder-slice-fcwAXrsh.d.ts +0 -35
- package/dist/ref-point-importer-B_wn5ABk.d.ts +0 -62
- package/dist/ref-point-loader-Pt1smgHS.d.ts +0 -117
- package/dist/ref-points/h3-ref-point.d.ts +0 -2
- package/dist/ref-points/index.d.ts +0 -2
- package/dist/ref-points/index.js +0 -2
- package/dist/ref-points-slice-tC-Wd6XJ.d.ts +0 -48
- package/dist/reference-points-CFWy8_wj.d.ts +0 -68
- package/dist/routing-slice-BlHTM8eh.d.ts +0 -23
- package/dist/state/recorder-slice.d.ts +0 -2
- package/dist/state/ref-points-slice.d.ts +0 -2
- package/dist/state/ref-points-slice.js +0 -44
- package/dist/state/routing-slice.d.ts +0 -2
- package/dist/state/routing-slice.js +0 -13
- package/dist/state/store.d.ts +0 -9
- package/dist/state/store.js +0 -71
- package/dist/storage/ref-point-importer.d.ts +0 -2
- package/dist/storage/ref-point-importer.js +0 -163
- package/dist/storage/ref-point-loader.d.ts +0 -2
- package/dist/storage/ref-point-loader.js +0 -248
- package/dist/storage/ref-point-recovery.d.ts +0 -28
- package/dist/storage/ref-point-recovery.js +0 -159
- package/dist/storage-backend-BcEItnFr.d.ts +0 -20
- package/dist/store-C7PKOj8S.d.ts +0 -96
- package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
- package/dist/visualization/reference-points.d.ts +0 -2
- package/dist/visualization/reference-points.js +0 -160
- /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-L1RbWHQ4.d.ts} +0 -0
- /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-Ck8LEq8k.d.ts} +0 -0
- /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-C1V9I1Z6.d.ts} +0 -0
- /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-1k8mnw5J.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-JKb1ST8E.d.ts} +0 -0
- /package/dist/{chromium-camera-access-workaround-CU5zSKNr.d.ts → chromium-camera-access-workaround-NvChXsi8.d.ts} +0 -0
- /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-CMw8pSaG.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-CkjCb2HW.d.ts} +0 -0
- /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-DnHXOIRa.d.ts} +0 -0
- /package/dist/{file-system-utils-5cWO8Xyv.d.ts → file-system-utils-CtKiiw27.d.ts} +0 -0
- /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-BTS5H62-.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-C-6JEnpR.d.ts → gps-compass-cubes-CsLtFv4B.d.ts} +0 -0
- /package/dist/{gps-error-handler-VPuNOuf8.d.ts → gps-error-handler-Dg3ziRVY.d.ts} +0 -0
- /package/dist/{lerp-utils-87NWjUOD.d.ts → lerp-utils-B8MM8zCR.d.ts} +0 -0
- /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CNqi-E2j.d.ts} +0 -0
- /package/dist/{map-overlay-DuiZuCTx.d.ts → map-overlay-DAmreyA3.d.ts} +0 -0
- /package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-Dq6IsKAv.d.ts} +0 -0
- /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-6LBjPmwz.d.ts} +0 -0
- /package/dist/{three-dispose-CCBHjE_a.d.ts → three-dispose-C2drkp6f.d.ts} +0 -0
- /package/dist/{vis-colors-Qi2vlRGt.d.ts → vis-colors-CHQhjal3.d.ts} +0 -0
- /package/dist/{xr-camera-texture-BbukNE79.d.ts → xr-camera-texture-BU5YvKAM.d.ts} +0 -0
- /package/dist/{xr-error-handler-DTHfmvrl.d.ts → xr-error-handler-CDY5QxGb.d.ts} +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { t as ARPose } from "./ar-types-Ck8LEq8k.js";
|
|
2
|
+
import { OdometryTrackingRestartedPayload, Quaternion, Vector3 } from "gps-plus-slam-js";
|
|
3
|
+
import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
|
|
4
|
+
|
|
5
|
+
//#region ../src/state/tracking-slice.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* AR tracking phase. String-literal union (not a TS enum) so action payloads
|
|
8
|
+
* and replay JSON stay structurally compatible with non-TS consumers.
|
|
9
|
+
*/
|
|
10
|
+
type TrackingPhase = 'initializing' | 'tracking' | 'lost';
|
|
11
|
+
/**
|
|
12
|
+
* Raw `DeviceOrientationEvent` snapshot captured alongside an AR pose.
|
|
13
|
+
*
|
|
14
|
+
* Identical shape to `RawDeviceOrientation` from `gps-plus-slam-js`, but
|
|
15
|
+
* with non-nullable fields — sensors are required to have resolved for the
|
|
16
|
+
* AR math that consumes this snapshot.
|
|
17
|
+
*/
|
|
18
|
+
interface DeviceOrientation {
|
|
19
|
+
/** Compass heading (0–360). */
|
|
20
|
+
alpha: number;
|
|
21
|
+
/** Pitch (-180 to 180). */
|
|
22
|
+
beta: number;
|
|
23
|
+
/** Roll (-90 to 90). */
|
|
24
|
+
gamma: number;
|
|
25
|
+
/** Whether alpha is relative to magnetic north. */
|
|
26
|
+
absolute: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Serialized `XRReferenceSpaceEvent.transform`.
|
|
30
|
+
*
|
|
31
|
+
* `null` when the XR runtime cannot determine the delta between old and new
|
|
32
|
+
* coordinate systems; `undefined` when no transform was captured (older
|
|
33
|
+
* browsers / no event).
|
|
34
|
+
*/
|
|
35
|
+
interface ResetTransformData {
|
|
36
|
+
position: Vector3;
|
|
37
|
+
orientation: Quaternion;
|
|
38
|
+
}
|
|
39
|
+
interface TrackingSliceState {
|
|
40
|
+
phase: TrackingPhase;
|
|
41
|
+
lastValidPose: ARPose | null;
|
|
42
|
+
lastSensorOrientation: DeviceOrientation | null;
|
|
43
|
+
lostFrameCount: number;
|
|
44
|
+
originResetDuringLoss: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Distinguishes "reset flagged with no transform yet" from "no reset flagged".
|
|
47
|
+
* `undefined` is the default; once `originReset(...)` is dispatched the value
|
|
48
|
+
* is the supplied transform (which may itself be `null`).
|
|
49
|
+
*/
|
|
50
|
+
resetTransform: ResetTransformData | null | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Transient payload set by the LOST → TRACKING transition when an origin
|
|
53
|
+
* reset was flagged during the loss. Host consumes it via the matching
|
|
54
|
+
* selector and then dispatches `clearLastRestartedPayload`.
|
|
55
|
+
*/
|
|
56
|
+
lastRestartedPayload: OdometryTrackingRestartedPayload | null;
|
|
57
|
+
}
|
|
58
|
+
interface PoseReceivedPayload {
|
|
59
|
+
pose: ARPose;
|
|
60
|
+
sensorOrientation: DeviceOrientation;
|
|
61
|
+
}
|
|
62
|
+
declare const poseReceived: _$_reduxjs_toolkit0.ActionCreatorWithPayload<PoseReceivedPayload, "tracking/poseReceived">, poseLost: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"tracking/poseLost">, originReset: _$_reduxjs_toolkit0.ActionCreatorWithPreparedPayload<[transform?: ResetTransformData | null | undefined], ResetTransformData | null | undefined, "tracking/originReset", never, never>, resetTracking: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"tracking/resetTracking">, clearLastRestartedPayload: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"tracking/clearLastRestartedPayload">;
|
|
63
|
+
declare const trackingReducer: _$_reduxjs_toolkit0.Reducer<TrackingSliceState>;
|
|
64
|
+
/**
|
|
65
|
+
* Minimal root-state shape needed by the selectors. Avoids a hard import
|
|
66
|
+
* cycle through `SlamAppRootState`.
|
|
67
|
+
*/
|
|
68
|
+
interface RootWithTracking {
|
|
69
|
+
tracking: TrackingSliceState;
|
|
70
|
+
}
|
|
71
|
+
declare function selectTrackingPhase(state: RootWithTracking): TrackingPhase;
|
|
72
|
+
declare function selectLastValidPose(state: RootWithTracking): ARPose | null;
|
|
73
|
+
declare function selectLostFrameCount(state: RootWithTracking): number;
|
|
74
|
+
declare function selectLastRestartedPayload(state: RootWithTracking): OdometryTrackingRestartedPayload | null;
|
|
75
|
+
/**
|
|
76
|
+
* Selector for the last `DeviceOrientation` captured alongside a valid
|
|
77
|
+
* AR pose. Used by the §4.3 compass / alignment heading cross-check in
|
|
78
|
+
* the tracking-quality reporter (see
|
|
79
|
+
* docs/2026-05-16-tracking-quality-metrics-plan.md).
|
|
80
|
+
*
|
|
81
|
+
* Returns `null` before any pose has been received and after
|
|
82
|
+
* `resetTracking` clears the slice.
|
|
83
|
+
*/
|
|
84
|
+
declare function selectLastSensorOrientation(state: RootWithTracking): DeviceOrientation | null;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { TrackingSliceState as a, poseLost as c, selectLastRestartedPayload as d, selectLastSensorOrientation as f, trackingReducer as g, selectTrackingPhase as h, TrackingPhase as i, poseReceived as l, selectLostFrameCount as m, PoseReceivedPayload as n, clearLastRestartedPayload as o, selectLastValidPose as p, ResetTransformData as r, originReset as s, DeviceOrientation as t, resetTracking as u };
|
package/dist/types/ar-types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as WebXRQuaternion, i as DepthSample, n as ArPoseTuples, o as WebXRVec3, r as DepthPoint, t as ARPose } from "../ar-types-
|
|
1
|
+
import { a as WebXRQuaternion, i as DepthSample, n as ArPoseTuples, o as WebXRVec3, r as DepthPoint, t as ARPose } from "../ar-types-Ck8LEq8k.js";
|
|
2
2
|
export { ARPose, ArPoseTuples, DepthPoint, DepthSample, WebXRQuaternion, WebXRVec3 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as RefPointMarker, t as GpsCoord } from "../geo-types-
|
|
2
|
-
export { GpsCoord, RefPointMarker };
|
|
1
|
+
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-CTuF23gG.js";
|
|
2
|
+
export { GpsCoord, RawGpsSample, RefPointMarker };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as WebXRQuaternion, i as DepthSample, n as ArPoseTuples, o as WebXRVec3, r as DepthPoint, t as ARPose } from "../ar-types-
|
|
2
|
-
import { n as RefPointMarker, t as GpsCoord } from "../geo-types-
|
|
3
|
-
export { ARPose, ArPoseTuples, DepthPoint, DepthSample, GpsCoord, RefPointMarker, WebXRQuaternion, WebXRVec3 };
|
|
1
|
+
import { a as WebXRQuaternion, i as DepthSample, n as ArPoseTuples, o as WebXRVec3, r as DepthPoint, t as ARPose } from "../ar-types-Ck8LEq8k.js";
|
|
2
|
+
import { n as RawGpsSample, r as RefPointMarker, t as GpsCoord } from "../geo-types-CTuF23gG.js";
|
|
3
|
+
export { ARPose, ArPoseTuples, DepthPoint, DepthSample, GpsCoord, RawGpsSample, RefPointMarker, WebXRQuaternion, WebXRVec3 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as mapWithConcurrencyLimit } from "../concurrency-
|
|
1
|
+
import { t as mapWithConcurrencyLimit } from "../concurrency-CMw8pSaG.js";
|
|
2
2
|
export { mapWithConcurrencyLimit };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-
|
|
1
|
+
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-DnHXOIRa.js";
|
|
2
2
|
export { FailureTracker, FailureTrackerConfig, createFailureTracker };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as formatFileSize } from "../format-file-size-
|
|
1
|
+
import { t as formatFileSize } from "../format-file-size-BTS5H62-.js";
|
|
2
2
|
export { formatFileSize };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-
|
|
1
|
+
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-CB4DwWOG.js";
|
|
2
2
|
export { FusedPathInput, computeFusedPath, fusedGpsFromOdom };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-
|
|
2
|
-
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-
|
|
3
|
-
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-
|
|
4
|
-
import { t as mapWithConcurrencyLimit } from "../concurrency-
|
|
5
|
-
import { t as formatFileSize } from "../format-file-size-
|
|
6
|
-
import { t as listFormatter } from "../list-formatter-
|
|
1
|
+
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-C9vugiQb.js";
|
|
2
|
+
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-CB4DwWOG.js";
|
|
3
|
+
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-DnHXOIRa.js";
|
|
4
|
+
import { t as mapWithConcurrencyLimit } from "../concurrency-CMw8pSaG.js";
|
|
5
|
+
import { t as formatFileSize } from "../format-file-size-BTS5H62-.js";
|
|
6
|
+
import { t as listFormatter } from "../list-formatter-CNqi-E2j.js";
|
|
7
7
|
export { type FailureTracker, type FailureTrackerConfig, type FusedPathInput, type LogEntry, LogLevel, type Logger, clearLogBuffer, computeFusedPath, createFailureTracker, createLogger, formatFileSize, fusedGpsFromOdom, getGlobalLogLevel, getLogBuffer, listFormatter, mapWithConcurrencyLimit, setGlobalLogLevel, subscribeToLogs };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as listFormatter } from "../list-formatter-
|
|
1
|
+
import { t as listFormatter } from "../list-formatter-CNqi-E2j.js";
|
|
2
2
|
export { listFormatter };
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-
|
|
1
|
+
import { a as createLogger, c as setGlobalLogLevel, i as clearLogBuffer, l as subscribeToLogs, n as LogLevel, o as getGlobalLogLevel, r as Logger, s as getLogBuffer, t as LogEntry } from "../logger-C9vugiQb.js";
|
|
2
2
|
export { LogEntry, LogLevel, Logger, clearLogBuffer, createLogger, getGlobalLogLevel, getLogBuffer, setGlobalLogLevel, subscribeToLogs };
|
package/dist/utils/logger.js
CHANGED
|
@@ -12,7 +12,13 @@ import * as Sentry from "@sentry/browser";
|
|
|
12
12
|
*
|
|
13
13
|
* Sentry Integration:
|
|
14
14
|
* - All log levels add Sentry breadcrumbs for debugging context
|
|
15
|
-
* - log.
|
|
15
|
+
* - log.warn() reports a standalone Sentry Issue (captureMessage)
|
|
16
|
+
* - log.error() reports a standalone Sentry Issue: captureException for Error
|
|
17
|
+
* arguments, or a captureMessage fallback for string-only errors
|
|
18
|
+
* - warn/error Issues are grouped by a normalized message template
|
|
19
|
+
* (['log', level, tag, template]) so dynamic values (frame indices, sizes,
|
|
20
|
+
* filenames) collapse into one Issue per message kind without merging
|
|
21
|
+
* genuinely different messages that share a tag
|
|
16
22
|
*/
|
|
17
23
|
/**
|
|
18
24
|
* Log levels in order of verbosity (lower = more verbose)
|
|
@@ -180,20 +186,74 @@ function addSentryBreadcrumb(level, tag, args) {
|
|
|
180
186
|
});
|
|
181
187
|
}
|
|
182
188
|
/**
|
|
189
|
+
* Normalize a log message body into a stable "template" for Sentry grouping.
|
|
190
|
+
*
|
|
191
|
+
* Replaces the dynamic tokens that typically vary between otherwise-identical
|
|
192
|
+
* log lines (numbers, UUIDs, quoted strings) with placeholders. This makes the
|
|
193
|
+
* fingerprint depend on the *kind* of message rather than its concrete values,
|
|
194
|
+
* so that:
|
|
195
|
+
* - the same message with different dynamic values collapses into one Issue
|
|
196
|
+
* (e.g. `frame 12` / `frame 87` -> `frame {n}`), and
|
|
197
|
+
* - two genuinely different messages under the same tag stay as separate
|
|
198
|
+
* Issues (because their templates differ).
|
|
199
|
+
*
|
|
200
|
+
* Order matters: UUIDs are replaced before bare numbers, otherwise the number
|
|
201
|
+
* rule would shred the digit groups inside a UUID first.
|
|
202
|
+
*/
|
|
203
|
+
function toFingerprintTemplate(body) {
|
|
204
|
+
return body.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, "{uuid}").replace(/-?\d+(?:\.\d+)?(?:e[+-]?\d+)?/gi, "{n}").replace(/"[^"]*"/g, "\"{str}\"").replace(/'[^']*'/g, "'{str}'");
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Capture a log line as a standalone Sentry Issue (message event).
|
|
208
|
+
*
|
|
209
|
+
* Shared by `reportWarningToSentry` and the string-only branch of
|
|
210
|
+
* `reportErrorsToSentry`. The fingerprint is
|
|
211
|
+
* `['log', level, tag, <normalized template>]` so that dynamic values in the
|
|
212
|
+
* message do not fragment one logical problem into many Issues, while distinct
|
|
213
|
+
* messages from the same tag remain distinct Issues (see
|
|
214
|
+
* {@link toFingerprintTemplate}).
|
|
215
|
+
*/
|
|
216
|
+
function captureLogMessage(level, tag, args) {
|
|
217
|
+
const body = args.map((arg) => serializeArg(arg)).join(" ");
|
|
218
|
+
const message = `[${tag}] ${body}`;
|
|
219
|
+
Sentry.captureMessage(message, {
|
|
220
|
+
level,
|
|
221
|
+
fingerprint: [
|
|
222
|
+
"log",
|
|
223
|
+
level,
|
|
224
|
+
tag,
|
|
225
|
+
toFingerprintTemplate(body)
|
|
226
|
+
]
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
183
230
|
* Report a warning to Sentry as a standalone message.
|
|
184
231
|
* Called for log.warn() so warnings are independently visible in the
|
|
185
232
|
* Sentry dashboard, not only as breadcrumbs attached to later exceptions.
|
|
186
233
|
*/
|
|
187
234
|
function reportWarningToSentry(tag, args) {
|
|
188
|
-
|
|
189
|
-
Sentry.captureMessage(message, "warning");
|
|
235
|
+
captureLogMessage("warning", tag, args);
|
|
190
236
|
}
|
|
191
237
|
/**
|
|
192
|
-
* Report
|
|
193
|
-
*
|
|
238
|
+
* Report log.error() arguments to Sentry as standalone Issues.
|
|
239
|
+
*
|
|
240
|
+
* - For every argument that is an `Error`, calls `captureException` so the
|
|
241
|
+
* Issue carries a full stack trace.
|
|
242
|
+
* - If NO argument is an `Error` (a string-only `log.error(...)`), falls back
|
|
243
|
+
* to a message event so the error still surfaces as an Issue instead of only
|
|
244
|
+
* a breadcrumb/Log.
|
|
245
|
+
*
|
|
246
|
+
* The fallback is mutually exclusive with `captureException` to avoid duplicate
|
|
247
|
+
* Issues when an Error is present, and groups via the same normalized template
|
|
248
|
+
* fingerprint as warnings (see {@link captureLogMessage}).
|
|
194
249
|
*/
|
|
195
|
-
function reportErrorsToSentry(args) {
|
|
196
|
-
|
|
250
|
+
function reportErrorsToSentry(tag, args) {
|
|
251
|
+
let capturedError = false;
|
|
252
|
+
for (const arg of args) if (arg instanceof Error) {
|
|
253
|
+
Sentry.captureException(arg);
|
|
254
|
+
capturedError = true;
|
|
255
|
+
}
|
|
256
|
+
if (!capturedError) captureLogMessage("error", tag, args);
|
|
197
257
|
}
|
|
198
258
|
function createLogger(tag) {
|
|
199
259
|
const prefix = `[${tag}]`;
|
|
@@ -217,7 +277,7 @@ function createLogger(tag) {
|
|
|
217
277
|
error: (...args) => {
|
|
218
278
|
addToBuffer(3, tag, args);
|
|
219
279
|
addSentryBreadcrumb(3, tag, args);
|
|
220
|
-
reportErrorsToSentry(args);
|
|
280
|
+
reportErrorsToSentry(tag, args);
|
|
221
281
|
if (globalLogLevel <= 3) console.error(prefix, ...args);
|
|
222
282
|
}
|
|
223
283
|
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
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-CsxE_7x1.js";
|
|
2
|
+
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, AccuracyCircleSample, addAccuracyCircles };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import L from "leaflet";
|
|
2
|
+
//#region ../src/visualization/accuracy-circles.ts
|
|
3
|
+
/**
|
|
4
|
+
* Shared helper for drawing per-event GPS accuracy circles on a Leaflet map.
|
|
5
|
+
*
|
|
6
|
+
* Lives in the app-framework (D4 of the unified-map plan,
|
|
7
|
+
* gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-05-31-unified-trajectory-map-phase3-plan.md)
|
|
8
|
+
* so BOTH the framework's shared map-overlay-draw module AND the recorder
|
|
9
|
+
* app's preview/summary maps can reuse it. The recorder's
|
|
10
|
+
* `ui/accuracy-circles.ts` now re-exports from here.
|
|
11
|
+
*
|
|
12
|
+
* Future style changes only need to happen in one place.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Style for per-event GPS accuracy circles. Radius comes from the GPS event's
|
|
16
|
+
* horizontal accuracy in meters; larger circles mean lower-quality fixes.
|
|
17
|
+
* Filled and stroked with a highly transparent variant of the path color so
|
|
18
|
+
* overlapping circles remain legible without obscuring the basemap or the
|
|
19
|
+
* polyline drawn on top.
|
|
20
|
+
*/
|
|
21
|
+
const ACCURACY_CIRCLE_FILL_OPACITY = .12;
|
|
22
|
+
const ACCURACY_CIRCLE_STROKE_OPACITY = .5;
|
|
23
|
+
const ACCURACY_CIRCLE_WEIGHT = 1;
|
|
24
|
+
/**
|
|
25
|
+
* Draw one transparent circle per sample whose `accuracy` is a finite
|
|
26
|
+
* positive number. Samples without a usable accuracy value are skipped so
|
|
27
|
+
* pre-accuracy recordings still render their polyline.
|
|
28
|
+
*
|
|
29
|
+
* Circles are added to `map` immediately. The caller is responsible for
|
|
30
|
+
* draw-order: invoke this BEFORE adding the polyline so the line stays
|
|
31
|
+
* visually on top of the circles.
|
|
32
|
+
*
|
|
33
|
+
* @param map - The Leaflet map to add circles to.
|
|
34
|
+
* @param samples - GPS samples to consider; non-positive / non-finite
|
|
35
|
+
* `accuracy` values are silently skipped.
|
|
36
|
+
* @param color - CSS color string used for both stroke and fill.
|
|
37
|
+
* @returns The created `L.Circle` instances, in the order they were added.
|
|
38
|
+
* Callers that track layers for cleanup can append these to their list.
|
|
39
|
+
*/
|
|
40
|
+
function addAccuracyCircles(map, samples, color) {
|
|
41
|
+
const circles = [];
|
|
42
|
+
for (const sample of samples) {
|
|
43
|
+
if (typeof sample.accuracy !== "number" || !Number.isFinite(sample.accuracy) || sample.accuracy <= 0) continue;
|
|
44
|
+
const circle = L.circle([sample.lat, sample.lng], {
|
|
45
|
+
radius: sample.accuracy,
|
|
46
|
+
color,
|
|
47
|
+
weight: 1,
|
|
48
|
+
opacity: ACCURACY_CIRCLE_STROKE_OPACITY,
|
|
49
|
+
fillColor: color,
|
|
50
|
+
fillOpacity: ACCURACY_CIRCLE_FILL_OPACITY
|
|
51
|
+
}).addTo(map);
|
|
52
|
+
circles.push(circle);
|
|
53
|
+
}
|
|
54
|
+
return circles;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, addAccuracyCircles };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-
|
|
1
|
+
import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-L1RbWHQ4.js";
|
|
2
2
|
export { AlignmentLerper, createAlignmentLerper };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-
|
|
1
|
+
import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-1k8mnw5J.js";
|
|
2
2
|
export { CameraFollower, createCameraFollower };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../css3d-renderer-manager-
|
|
1
|
+
import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../css3d-renderer-manager-CkjCb2HW.js";
|
|
2
2
|
export { Css3dRendererManager, createCss3dRendererManager };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
//#region ../src/visualization/frustum-visibility.ts
|
|
3
|
+
/**
|
|
4
|
+
* Frustum-visibility predicates used by GPS-anchored components and any other
|
|
5
|
+
* caller that needs to know whether a world-space point/sphere/object is
|
|
6
|
+
* currently visible to a camera. Three.js's `Frustum` has the primitives we
|
|
7
|
+
* need; this module wraps them so:
|
|
8
|
+
*
|
|
9
|
+
* - All three predicates share a module-level scratch `Frustum`/`Matrix4`
|
|
10
|
+
* so a single frame's worth of checks pays the matrix multiply once.
|
|
11
|
+
* - Each predicate accepts an optional `frustum` parameter for callers that
|
|
12
|
+
* already have one built (e.g. via `buildCameraFrustum`) and want to
|
|
13
|
+
* keep doing many checks against it without rebuilding.
|
|
14
|
+
*
|
|
15
|
+
* The Three.js convention here is that `Frustum.containsPoint` is strict
|
|
16
|
+
* (point must be inside all six planes) while `intersectsSphere`/
|
|
17
|
+
* `intersectsObject` accept overlap with any plane, which is the right
|
|
18
|
+
* notion for "is this object at least partially on screen".
|
|
19
|
+
*/
|
|
20
|
+
const scratchMatrix = new THREE.Matrix4();
|
|
21
|
+
const scratchFrustum = new THREE.Frustum();
|
|
22
|
+
/**
|
|
23
|
+
* Build (or refresh) a Three.js `Frustum` from `camera`'s current world
|
|
24
|
+
* transform and projection matrix. If `out` is provided, the frustum is
|
|
25
|
+
* written into it and returned; otherwise the module-level scratch frustum
|
|
26
|
+
* is used. Callers MUST treat the returned frustum as immutable until they
|
|
27
|
+
* next call this function or use one of the predicates without an injected
|
|
28
|
+
* frustum (both reuse the same scratch).
|
|
29
|
+
*/
|
|
30
|
+
function buildCameraFrustum(camera, out) {
|
|
31
|
+
scratchMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
32
|
+
const target = out ?? scratchFrustum;
|
|
33
|
+
target.setFromProjectionMatrix(scratchMatrix);
|
|
34
|
+
return target;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Strictly check whether a single world-space point lies inside all six
|
|
38
|
+
* frustum planes. Useful for HUD/follow logic where the caller already has
|
|
39
|
+
* the target world position and wants the cheapest possible check.
|
|
40
|
+
*/
|
|
41
|
+
function isPointInCameraFrustum(camera, point, frustum) {
|
|
42
|
+
return (frustum ?? buildCameraFrustum(camera)).containsPoint(point);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check whether a world-space bounding sphere intersects the camera frustum
|
|
46
|
+
* (returns true even for partial overlap). Useful for callers that maintain
|
|
47
|
+
* a precomputed bounding sphere (LOD systems, instanced meshes, future
|
|
48
|
+
* `ArPowerSaver`).
|
|
49
|
+
*/
|
|
50
|
+
function isSphereInCameraFrustum(camera, sphere, frustum) {
|
|
51
|
+
return (frustum ?? buildCameraFrustum(camera)).intersectsSphere(sphere);
|
|
52
|
+
}
|
|
53
|
+
const objectScratchSphere = new THREE.Sphere();
|
|
54
|
+
const objectScratchBox = new THREE.Box3();
|
|
55
|
+
const objectScratchVec = new THREE.Vector3();
|
|
56
|
+
/**
|
|
57
|
+
* Check whether an `Object3D` is currently (at least partially) inside the
|
|
58
|
+
* camera frustum. The world bounding volume is resolved in tiers, cheapest
|
|
59
|
+
* first, so each common Three.js object type is gated by where it actually
|
|
60
|
+
* draws:
|
|
61
|
+
*
|
|
62
|
+
* 1. **Sprites** (`isSprite`) are screen-space billboards with no meaningful
|
|
63
|
+
* world geometry, so their world-space origin is tested as a point.
|
|
64
|
+
* 2. **Objects carrying an object-level `boundingSphere`** (`InstancedMesh`,
|
|
65
|
+
* `SkinnedMesh`, or any caller that pre-populates one) use that sphere,
|
|
66
|
+
* which reflects the instance spread / posed extent — unlike the base
|
|
67
|
+
* geometry sphere. It is computed lazily via `computeBoundingSphere()`
|
|
68
|
+
* when missing.
|
|
69
|
+
* 3. **Single renderables carrying a `geometry`** (`Mesh`, `Points`, `Line`,
|
|
70
|
+
* …) use the geometry's local bounding sphere × `matrixWorld`.
|
|
71
|
+
* 4. **Containers with children** (`Group`, `LOD`, …) use the world-space
|
|
72
|
+
* union of their descendants' bounding boxes (`Box3.setFromObject`),
|
|
73
|
+
* converted to a sphere.
|
|
74
|
+
* 5. **Truly empty / geometry-less objects** have no bounding volume and are
|
|
75
|
+
* treated as visible (`true`) — the conservative default for visibility
|
|
76
|
+
* gating.
|
|
77
|
+
*
|
|
78
|
+
* This deliberately avoids `Frustum.intersectsObject`, which unconditionally
|
|
79
|
+
* dereferences `object.geometry.boundingSphere` and therefore throws a
|
|
80
|
+
* `TypeError` for geometry-less objects such as `Group`s.
|
|
81
|
+
*
|
|
82
|
+
* Callers should ensure `object.updateMatrixWorld()` (with descendants, for
|
|
83
|
+
* containers: `updateMatrixWorld(true)`) has already run this frame (it
|
|
84
|
+
* normally has, via `renderer.render`).
|
|
85
|
+
*/
|
|
86
|
+
function isObjectInCameraFrustum(camera, object, frustum) {
|
|
87
|
+
const f = frustum ?? buildCameraFrustum(camera);
|
|
88
|
+
if (object.isSprite) {
|
|
89
|
+
object.getWorldPosition(objectScratchVec);
|
|
90
|
+
return f.containsPoint(objectScratchVec);
|
|
91
|
+
}
|
|
92
|
+
if (!resolveObjectWorldSphere(object, objectScratchSphere)) return true;
|
|
93
|
+
return f.intersectsSphere(objectScratchSphere);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resolve the world-space bounding sphere for `object` into `out`, returning
|
|
97
|
+
* `true` when a bounding volume was found and `false` for objects that have
|
|
98
|
+
* none (e.g. an empty `Group`). Resolution order mirrors the tiers documented
|
|
99
|
+
* on {@link isObjectInCameraFrustum}: object-level `boundingSphere`
|
|
100
|
+
* (`InstancedMesh`/`SkinnedMesh`), then geometry bounding sphere, then the
|
|
101
|
+
* world-space union of descendant bounding boxes.
|
|
102
|
+
*/
|
|
103
|
+
function resolveObjectWorldSphere(object, out) {
|
|
104
|
+
if (tryObjectLevelSphere(object, out)) return true;
|
|
105
|
+
const geometry = object.geometry;
|
|
106
|
+
if (geometry) {
|
|
107
|
+
if (!geometry.boundingSphere) geometry.computeBoundingSphere();
|
|
108
|
+
if (geometry.boundingSphere) {
|
|
109
|
+
out.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (object.children.length > 0) {
|
|
114
|
+
objectScratchBox.setFromObject(object);
|
|
115
|
+
if (!objectScratchBox.isEmpty()) {
|
|
116
|
+
objectScratchBox.getBoundingSphere(out);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Tier 2 of {@link resolveObjectWorldSphere}: use an object-level
|
|
124
|
+
* `boundingSphere` when the object is an `InstancedMesh`/`SkinnedMesh` (whose
|
|
125
|
+
* sphere reflects instance spread / posed extent) or already carries a
|
|
126
|
+
* populated sphere. Computes it lazily via `computeBoundingSphere()` when
|
|
127
|
+
* missing. Writes the world-space sphere into `out` and returns `true` on
|
|
128
|
+
* success, `false` when no object-level sphere applies.
|
|
129
|
+
*/
|
|
130
|
+
function tryObjectLevelSphere(object, out) {
|
|
131
|
+
const withSphere = object;
|
|
132
|
+
if (!(withSphere.isInstancedMesh || withSphere.isSkinnedMesh || withSphere.boundingSphere)) return false;
|
|
133
|
+
if (!withSphere.boundingSphere && typeof withSphere.computeBoundingSphere === "function") withSphere.computeBoundingSphere();
|
|
134
|
+
if (!withSphere.boundingSphere) return false;
|
|
135
|
+
out.copy(withSphere.boundingSphere).applyMatrix4(object.matrixWorld);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { buildCameraFrustum, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as GpsAnchorSamplePoint, i as GpsAnchorPhase, n as GpsAnchorMode, o as createGpsAnchor, r as GpsAnchorOptions, t as GpsAnchor } from "../gps-anchor-CnWY61XK.js";
|
|
2
|
+
export { GpsAnchor, GpsAnchorMode, GpsAnchorOptions, GpsAnchorPhase, GpsAnchorSamplePoint, createGpsAnchor };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "../gps-compass-cubes-
|
|
1
|
+
import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "../gps-compass-cubes-CsLtFv4B.js";
|
|
2
2
|
export { COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, GpsCompassCubes, createGpsCompassCubes };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as gpsEventVisualizer, t as
|
|
2
|
-
export { GpsEventVisualizer, gpsEventVisualizer };
|
|
1
|
+
import { n as GpsEventVisualizer, r as gpsEventVisualizer, t as GpsEventAccuracy } from "../gps-event-markers-BGr-iLvi.js";
|
|
2
|
+
export { GpsEventAccuracy, GpsEventVisualizer, gpsEventVisualizer };
|
|
@@ -25,6 +25,38 @@ const GPS_MARKER_RADIUS = .08;
|
|
|
25
25
|
/** Slightly larger radius for alignment snapshots to stand out */
|
|
26
26
|
const SNAPSHOT_MARKER_RADIUS = .1;
|
|
27
27
|
/**
|
|
28
|
+
* Default opacity for the yellow raw-GPS sphere when it is rendered at the
|
|
29
|
+
* legacy fixed 8 cm radius (no accuracy passed). Matches the original 30 %
|
|
30
|
+
* value so live recording sessions look unchanged.
|
|
31
|
+
*/
|
|
32
|
+
const RAW_GPS_FIXED_OPACITY = .3;
|
|
33
|
+
/**
|
|
34
|
+
* Reduced opacity for the yellow raw-GPS sphere when it is scaled by GPS
|
|
35
|
+
* accuracy (replay mode). At metre-scale ellipsoids the sphere can land on
|
|
36
|
+
* top of the cyan fused / red snapshot markers; a lower alpha keeps those
|
|
37
|
+
* smaller markers visible inside the ellipsoid.
|
|
38
|
+
*/
|
|
39
|
+
const RAW_GPS_ACCURACY_OPACITY = .13;
|
|
40
|
+
/**
|
|
41
|
+
* Validate a {@link GpsEventAccuracy} hint and return the concrete
|
|
42
|
+
* {horizontal, vertical} scale when both axes are usable, or `null` to signal
|
|
43
|
+
* "fall back to the legacy fixed 8 cm sphere". A half-populated, non-positive,
|
|
44
|
+
* or non-finite (`NaN`/`Infinity`) accuracy must NOT produce an ellipsoid:
|
|
45
|
+
* a degenerate or infinite axis would corrupt the mesh transform and can
|
|
46
|
+
* crash Three.js rendering.
|
|
47
|
+
*/
|
|
48
|
+
function resolveEllipsoidScale(accuracy) {
|
|
49
|
+
if (accuracy == null) return null;
|
|
50
|
+
const { horizontal, vertical } = accuracy;
|
|
51
|
+
if (typeof horizontal !== "number" || typeof vertical !== "number") return null;
|
|
52
|
+
if (!Number.isFinite(horizontal) || !Number.isFinite(vertical)) return null;
|
|
53
|
+
if (horizontal <= 0 || vertical <= 0) return null;
|
|
54
|
+
return {
|
|
55
|
+
horizontal,
|
|
56
|
+
vertical
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
28
60
|
* Manager for GPS event visualization
|
|
29
61
|
*/
|
|
30
62
|
var GpsEventVisualizer = class {
|
|
@@ -55,8 +87,14 @@ var GpsEventVisualizer = class {
|
|
|
55
87
|
*
|
|
56
88
|
* @param gpsCoords - GPS position as [x, y, z] meters from zero reference
|
|
57
89
|
* @param odomPosition - AR odometry position at the time of GPS reading
|
|
90
|
+
* @param accuracy - Optional 1σ GPS accuracy. When both fields are positive,
|
|
91
|
+
* the raw-GPS marker is rendered as a non-uniform-scaled ellipsoid:
|
|
92
|
+
* `mesh.scale.set(horizontal, vertical, horizontal)` over a unit sphere.
|
|
93
|
+
* When missing, zero, or negative, the marker falls back to the legacy
|
|
94
|
+
* fixed 8 cm sphere (same defensive policy as `preview-map.ts`).
|
|
95
|
+
* Cyan fused and red snapshot markers are never affected by this argument.
|
|
58
96
|
*/
|
|
59
|
-
addGpsEvent(gpsCoords, odomPosition) {
|
|
97
|
+
addGpsEvent(gpsCoords, odomPosition, accuracy) {
|
|
60
98
|
if (!this.zeroRef) {
|
|
61
99
|
log.warn("No zero reference set");
|
|
62
100
|
return;
|
|
@@ -67,8 +105,13 @@ var GpsEventVisualizer = class {
|
|
|
67
105
|
return;
|
|
68
106
|
}
|
|
69
107
|
const eventId = this.eventCounter++;
|
|
70
|
-
const
|
|
108
|
+
const ellipsoidScale = resolveEllipsoidScale(accuracy);
|
|
109
|
+
const rawMesh = this.createMarkerMesh(VIS_COLORS.RAW_GPS.hex, "raw-gps", eventId, ellipsoidScale ? 1 : GPS_MARKER_RADIUS, ellipsoidScale ? RAW_GPS_ACCURACY_OPACITY : RAW_GPS_FIXED_OPACITY);
|
|
71
110
|
rawMesh.position.set(gpsCoords[0], gpsCoords[1], gpsCoords[2]);
|
|
111
|
+
if (ellipsoidScale) {
|
|
112
|
+
rawMesh.scale.set(ellipsoidScale.horizontal, ellipsoidScale.vertical, ellipsoidScale.horizontal);
|
|
113
|
+
rawMesh.renderOrder = -1;
|
|
114
|
+
}
|
|
72
115
|
scene.add(rawMesh);
|
|
73
116
|
this.rawGpsMarkers.push(rawMesh);
|
|
74
117
|
const arWorldGroup = getArWorldGroup();
|
|
@@ -149,6 +192,30 @@ var GpsEventVisualizer = class {
|
|
|
149
192
|
snapshots: this.snapshotMarkers.length
|
|
150
193
|
};
|
|
151
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Diagnostic accessor: returns the world-space size (`THREE.Box3.setFromObject`)
|
|
197
|
+
* of each raw-GPS marker, in insertion order.
|
|
198
|
+
*
|
|
199
|
+
* Used by the rec31 accuracy-ellipsoid Playwright spec (§3c) to verify the
|
|
200
|
+
* relative scaling of two events with different `latLongAccuracy`. This is
|
|
201
|
+
* the size of the rendered ellipsoid in scene units (= metres in replay
|
|
202
|
+
* mode), not the underlying geometry radius — so it correctly reflects the
|
|
203
|
+
* `mesh.scale.set(h, v, h)` applied for accuracy-aware markers.
|
|
204
|
+
*
|
|
205
|
+
* @returns array of `{ x, y, z }` sizes — empty array if there are no markers.
|
|
206
|
+
*/
|
|
207
|
+
getRawMarkerWorldSizes() {
|
|
208
|
+
const tmpBox = new THREE.Box3();
|
|
209
|
+
return this.rawGpsMarkers.map((mesh) => {
|
|
210
|
+
tmpBox.setFromObject(mesh);
|
|
211
|
+
const size = tmpBox.getSize(new THREE.Vector3());
|
|
212
|
+
return {
|
|
213
|
+
x: size.x,
|
|
214
|
+
y: size.y,
|
|
215
|
+
z: size.z
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
}
|
|
152
219
|
};
|
|
153
220
|
/**
|
|
154
221
|
* Singleton instance for global use.
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-
|
|
2
|
-
import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-
|
|
3
|
-
import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../css3d-renderer-manager-
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { a as
|
|
9
|
-
import { n as
|
|
10
|
-
import { n as
|
|
11
|
-
import { t as
|
|
12
|
-
|
|
1
|
+
import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-1k8mnw5J.js";
|
|
2
|
+
import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-L1RbWHQ4.js";
|
|
3
|
+
import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../css3d-renderer-manager-CkjCb2HW.js";
|
|
4
|
+
import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-sih4g64v.js";
|
|
5
|
+
import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "../gps-compass-cubes-CsLtFv4B.js";
|
|
6
|
+
import { i as isSphereInCameraFrustum, n as isObjectInCameraFrustum, r as isPointInCameraFrustum, t as buildCameraFrustum } from "../frustum-visibility-BHnFrSKQ.js";
|
|
7
|
+
import { t as nueToArLocal } from "../index-pOjUCKEP.js";
|
|
8
|
+
import { a as GpsAnchorSamplePoint, i as GpsAnchorPhase, n as GpsAnchorMode, o as createGpsAnchor, r as GpsAnchorOptions, t as GpsAnchor } from "../gps-anchor-CnWY61XK.js";
|
|
9
|
+
import { n as GpsEventVisualizer, r as gpsEventVisualizer } from "../gps-event-markers-BGr-iLvi.js";
|
|
10
|
+
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-Cew7XAoO.js";
|
|
11
|
+
import { n as clampedAlpha, t as DEFAULT_LERP_RATE } from "../lerp-utils-B8MM8zCR.js";
|
|
12
|
+
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-CsxE_7x1.js";
|
|
13
|
+
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-B3R1c9Xp.js";
|
|
14
|
+
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-DAmreyA3.js";
|
|
15
|
+
import { n as disposeMeshArray, r as disposeObject3D, t as DisposeOptions } from "../three-dispose-C2drkp6f.js";
|
|
16
|
+
import { t as VIS_COLORS } from "../vis-colors-CHQhjal3.js";
|
|
17
|
+
export { ACCURACY_CIRCLE_FILL_OPACITY, ACCURACY_CIRCLE_STROKE_OPACITY, ACCURACY_CIRCLE_WEIGHT, ALIGNMENT_SNAPSHOT_COLOR, AccuracyCircleSample, AlignmentLerper, COMPASS_CUBE_DISTANCE, COMPASS_CUBE_SIZE, CameraFollower, Css3dRendererManager, DEFAULT_HEIGHT_OFFSET, DEFAULT_LEAFLET_MAP_SIZE_PX, DEFAULT_LERP_RATE, DEFAULT_MAP_SIZE, DEFAULT_WORLD_SIZE, DEFAULT_ZOOM, DEFAULT_Z_OFFSET, DisposeOptions, DrawMapDataOptions, DrawnMapData, FUSED_PATH_COLOR, GpsAnchor, GpsAnchorMode, GpsAnchorOptions, GpsAnchorPhase, GpsAnchorSamplePoint, GpsCompassCubes, GpsEventVisualizer, LeafletMapOverlay, LeafletMapOverlayOptions, MAP_PATH_POLYLINE_OPACITY, MAP_PATH_POLYLINE_WEIGHT, MapData, MapDataInput, MapOverlay, MapOverlayOptions, RAW_GPS_COLOR, TextureLoaderInterface, USER_POSITION_COLOR, VIS_COLORS, addAccuracyCircles, buildCameraFrustum, buildMapData, clampedAlpha, createAlignmentLerper, createCameraFollower, createCss3dRendererManager, createGpsAnchor, createGpsCompassCubes, disposeMeshArray, disposeObject3D, drawMapData, gpsEventVisualizer, isObjectInCameraFrustum, isPointInCameraFrustum, isSphereInCameraFrustum, latLonToTileXY, nueToArLocal, tileXYToLatLon };
|