gps-plus-slam-app-framework 1.0.6 → 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/LICENSE +4 -4
- package/README.md +310 -115
- package/dist/accuracy-circles-DEKr0Hoh.d.ts +43 -0
- package/dist/{app-selectors-CHt7DLuq.d.ts → app-selectors-CR9OWodf.d.ts} +8 -10
- 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 +2 -0
- package/dist/ar/frame-loop.js +63 -0
- package/dist/ar/image-capture.d.ts +1 -1
- package/dist/ar/image-capture.js +1 -1
- package/dist/ar/index.d.ts +16 -12
- package/dist/ar/index.js +8 -4
- 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 +173 -93
- package/dist/ar/xr-camera-texture.d.ts +1 -1
- package/dist/ar/xr-error-handler.d.ts +1 -1
- package/dist/ar/xr-frame-loop.d.ts +2 -0
- package/dist/ar/xr-frame-loop.js +69 -0
- package/dist/ar-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 +2 -2
- package/dist/core/index.js +2 -2
- package/dist/create-slam-app-store-B76AGaI0.d.ts +371 -0
- package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-CqrkRr2N.d.ts} +1 -1
- package/dist/enable-gps-ar-DNbO0zbg.d.ts +95 -0
- package/dist/{file-system-DD5TczSO.d.ts → file-system-TIsDfamK.d.ts} +32 -2
- package/dist/frame-conversions-D2EYjeNa.d.ts +54 -0
- package/dist/frame-loop-BTeRpDm4.d.ts +47 -0
- package/dist/frustum-visibility-DGnJqls0.d.ts +58 -0
- package/dist/{fused-path-DtqCSqJh.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/{geo-types-Xx-LVcnw.d.ts → geo-types-clgzl8b5.d.ts} +16 -1
- package/dist/{gps-GKc6_Cly.d.ts → gps-B7AlMPz5.d.ts} +1 -1
- package/dist/gps-anchor-CISLPQIb.d.ts +59 -0
- package/dist/{gps-ar-pose-sampler-D_Zso40V.d.ts → gps-ar-pose-sampler-BypXZUqC.d.ts} +1 -1
- package/dist/{gps-event-coordinator-fwvmVfku.d.ts → gps-event-coordinator-BKVZbS1M.d.ts} +3 -3
- package/dist/gps-event-markers-BlHq3jYV.d.ts +103 -0
- package/dist/hit-test-reticle-BGXOxrUh.d.ts +45 -0
- package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-BXZUmj7j.d.ts} +1 -1
- package/dist/index--ldLph4V.d.ts +2 -0
- package/dist/index-22v8MXJX.d.ts +23 -0
- package/dist/index-BB2KEWbN2.d.ts +37 -0
- package/dist/index.d.ts +64 -52
- package/dist/index.js +21 -8
- package/dist/{leaflet-map-overlay-CQZcnxbc.d.ts → leaflet-map-overlay-jNt-kcUr.d.ts} +22 -11
- package/dist/{logger-B81iwxx0.d.ts → logger-BZ44Dhd3.d.ts} +7 -1
- package/dist/map-data-BGIBM5rv.d.ts +49 -0
- package/dist/map-overlay-draw-DcGs9UV3.d.ts +42 -0
- package/dist/{null-storage-backend-C0TiwwzQ.d.ts → null-storage-backend-BPQJSaMw.d.ts} +2 -2
- package/dist/{opfs-storage-backend-Gt3rd76D.d.ts → opfs-storage-backend-u4QKvgvP.d.ts} +2 -2
- package/dist/{permission-checker-Cu3nbH1S.d.ts → permission-checker-CfV7INCa.d.ts} +41 -1
- package/dist/persistence-middleware-xB5sTllJ.d.ts +55 -0
- package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-BSFpBSZH.d.ts} +10 -4
- package/dist/{recording-replayer-BFhFs7Mc.d.ts → recording-replayer-CTL2cUE0.d.ts} +2 -2
- package/dist/{recording-slice-BiktUIWF.d.ts → recording-slice-Cb888P6d.d.ts} +2 -2
- package/dist/{replay-engine-B88Va62x.d.ts → replay-engine-B-5GIZtc.d.ts} +1 -1
- package/dist/{replay-scene-DtUm6bsr.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/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/session-disposers-M-oashRH.js +57 -0
- 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 +1 -1
- package/dist/state/create-slam-app-store.js +27 -13
- 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 -16
- package/dist/state/index.js +6 -4
- package/dist/state/persistence-middleware.d.ts +2 -2
- package/dist/state/persistence-middleware.js +43 -9
- 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/store-subscribers.js +38 -12
- 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/state-BkIfpiyA.js +87 -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 +52 -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/zip-reader.js +8 -4
- package/dist/{storage-backend-yVnuWGTr.d.ts → storage-backend-yDSKafAQ.d.ts} +1 -1
- package/dist/{store-subscribers-DKKHld49.d.ts → store-subscribers-swlbtg_z.d.ts} +31 -6
- package/dist/{subscribe-to-selector-ghDKYtap.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 +7 -1
- package/dist/test-utils/zip-round-trip-helpers.js +2 -1
- package/dist/tracking-slice-CDREeoZ_.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/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 +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 +217 -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/hit-test-reticle.d.ts +2 -0
- package/dist/visualization/hit-test-reticle.js +81 -0
- package/dist/visualization/index.d.ts +19 -12
- package/dist/visualization/index.js +9 -2
- package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
- package/dist/visualization/leaflet-map-overlay.js +33 -79
- 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-nue-basis-BbdqhqY6.js +54 -0
- package/dist/{webxr-session-COlSrXdL.d.ts → webxr-session-BnArFCew.d.ts} +76 -14
- package/dist/xr-frame-loop-BKckC7xC.d.ts +70 -0
- package/dist/{zip-reader-KgJEXbca.d.ts → zip-reader-B2lzN8F5.d.ts} +5 -0
- package/package.json +16 -16
- package/dist/ar/tracking-state.d.ts +0 -2
- package/dist/ar/tracking-state.js +0 -164
- package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +0 -61
- package/dist/combined-root-state-B3SvPNjU.d.ts +0 -6
- package/dist/create-slam-app-store-DBm7g2Zd.d.ts +0 -85
- package/dist/gps-anchored-mesh-manager-CovAFK4g.d.ts +0 -56
- package/dist/gps-event-markers-sVyO9utS.d.ts +0 -67
- package/dist/persistence-middleware-z-75iisb.d.ts +0 -31
- package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
- package/dist/visualization/gps-anchored-mesh-manager.d.ts +0 -2
- package/dist/visualization/gps-anchored-mesh-manager.js +0 -128
- /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-CCZJf-Xb.d.ts} +0 -0
- /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-isPsQptb.d.ts} +0 -0
- /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-75WWa9Xb.d.ts} +0 -0
- /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-B-nS1sr6.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-D4HYJNOj.d.ts} +0 -0
- /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-Bsmv53qw.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-EDED3nvg.d.ts} +0 -0
- /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-D7ELffm0.d.ts} +0 -0
- /package/dist/{file-system-utils-BH8FdyIu.d.ts → file-system-utils-BH6uIs2i.d.ts} +0 -0
- /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-B7gJb3Md.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-jRIJMOuh.d.ts → gps-compass-cubes-Ys6Hf1nc.d.ts} +0 -0
- /package/dist/{gps-error-handler-CH1S528z.d.ts → gps-error-handler-BLDhUlw5.d.ts} +0 -0
- /package/dist/{h3-proximity-GwesPTFT.d.ts → h3-proximity-DJnghtir.d.ts} +0 -0
- /package/dist/{lerp-utils-CZgQlrmu.d.ts → lerp-utils-DNcSmKVX.d.ts} +0 -0
- /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CsqcU4v5.d.ts} +0 -0
- /package/dist/{map-overlay-C9ifl_4-.d.ts → map-overlay-yrFsUtGv.d.ts} +0 -0
- /package/dist/{opfs-storage-Dlq1I_Gb.d.ts → opfs-storage-LsLY6VZV.d.ts} +0 -0
- /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-IHW7HR4S.d.ts} +0 -0
- /package/dist/{three-dispose-qt_r5wR1.d.ts → three-dispose-WTBAfaWU.d.ts} +0 -0
- /package/dist/{vis-colors-BKkdTIKb.d.ts → vis-colors-Djnyg_UH.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-DcUFshNF.d.ts} +0 -0
- /package/dist/{zip-export-BjrQPv0X.d.ts → zip-export-C0_ErAqT.d.ts} +0 -0
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-BZ44Dhd3.js";
|
|
2
|
+
import { n as computeFusedPath, r as fusedGpsFromOdom, t as FusedPathInput } from "../fused-path-BdVHmDW9.js";
|
|
3
|
+
import { n as FailureTrackerConfig, r as createFailureTracker, t as FailureTracker } from "../failure-tracker-D7ELffm0.js";
|
|
4
|
+
import { t as mapWithConcurrencyLimit } from "../concurrency-Bsmv53qw.js";
|
|
5
|
+
import { t as formatFileSize } from "../format-file-size-B7gJb3Md.js";
|
|
6
|
+
import { t as listFormatter } from "../list-formatter-CsqcU4v5.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-CsqcU4v5.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-BZ44Dhd3.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-DEKr0Hoh.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-CCZJf-Xb.js";
|
|
2
2
|
export { AlignmentLerper, createAlignmentLerper };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { registerFrameUpdate } from "../ar/frame-loop.js";
|
|
2
|
+
import { t as registerSessionDisposer } from "../session-disposers-M-oashRH.js";
|
|
3
|
+
import { createAlignmentLerper } from "./alignment-lerper.js";
|
|
4
|
+
import { selectAlignmentMatrix } from "../state/app-selectors.js";
|
|
5
|
+
import { subscribeToSelector } from "../state/subscribe-to-selector.js";
|
|
6
|
+
//#region ../src/visualization/ar-world-group-alignment.ts
|
|
7
|
+
/**
|
|
8
|
+
* Begin applying the store's (lerped) alignment to `arWorldGroup`. Returns a
|
|
9
|
+
* handle whose `dispose()` removes both the store subscription and the
|
|
10
|
+
* per-frame update.
|
|
11
|
+
*
|
|
12
|
+
* Disposal is tied to the AR session lifecycle: the binding registers itself
|
|
13
|
+
* with the session-disposer registry that `resetWebXRState()` flushes on
|
|
14
|
+
* teardown, so a caller can `enableArWorldGroupAlignment(...)` once and never
|
|
15
|
+
* hold the handle — the binding cannot outlive the session (which is what two
|
|
16
|
+
* apps independently leaked: the store subscription survives a teardown because
|
|
17
|
+
* `clearFrameUpdates` only drops the per-frame tick). Because `initAR()` throws
|
|
18
|
+
* while a prior session is live, every restart passes through that flush. The
|
|
19
|
+
* handle is still returned for callers that want to stop alignment mid-session,
|
|
20
|
+
* and is idempotent + self-deregistering so a manual `dispose()` and the
|
|
21
|
+
* teardown flush never double-run. See
|
|
22
|
+
* gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-08-arworldgroup-alignment-session-scoped-disposal.md.
|
|
23
|
+
*
|
|
24
|
+
* Double-drive is still the caller's concern: the recorder owns its own lerper
|
|
25
|
+
* and must NOT also call this (it would double-lerp the same group). It does not
|
|
26
|
+
* call this helper, so flushing the registry on teardown never affects it.
|
|
27
|
+
*/
|
|
28
|
+
function enableArWorldGroupAlignment(options) {
|
|
29
|
+
const lerper = createAlignmentLerper(options.arWorldGroup, options.lerpRate);
|
|
30
|
+
const current = selectAlignmentMatrix(options.store.getState());
|
|
31
|
+
if (current !== null && current !== void 0) lerper.setTarget(current);
|
|
32
|
+
const unsubscribe = subscribeToSelector(options.store, selectAlignmentMatrix, (matrix) => {
|
|
33
|
+
if (matrix !== null && matrix !== void 0) lerper.setTarget(matrix);
|
|
34
|
+
});
|
|
35
|
+
const unregister = registerFrameUpdate((dt) => {
|
|
36
|
+
lerper.update(dt);
|
|
37
|
+
});
|
|
38
|
+
let disposed = false;
|
|
39
|
+
const handle = { dispose() {
|
|
40
|
+
if (disposed) return;
|
|
41
|
+
disposed = true;
|
|
42
|
+
unsubscribe();
|
|
43
|
+
unregister();
|
|
44
|
+
lerper.dispose();
|
|
45
|
+
deregisterSessionDisposer();
|
|
46
|
+
} };
|
|
47
|
+
const deregisterSessionDisposer = registerSessionDisposer(() => handle.dispose());
|
|
48
|
+
return handle;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { enableArWorldGroupAlignment };
|
|
@@ -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-B-nS1sr6.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-EDED3nvg.js";
|
|
2
2
|
export { Css3dRendererManager, createCss3dRendererManager };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { calcGpsCoords } from "../core/index.js";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
//#region ../src/visualization/frame-conversions.ts
|
|
4
|
+
/**
|
|
5
|
+
* `frame-conversions` — small, pure coordinate-frame helpers for the AR scene
|
|
6
|
+
* graph. Currently a single function, `nueToArLocal`, that converts a
|
|
7
|
+
* GPS-world NUE point into the AR-odometry local frame of `arWorldGroup`.
|
|
8
|
+
*
|
|
9
|
+
* Background: the scene root is GPS-world NUE; `arWorldGroup.matrix` IS the
|
|
10
|
+
* alignment matrix, which maps **AR-odometry NUE → GPS-world NUE**. So a
|
|
11
|
+
* direct child of `arWorldGroup` whose WORLD position must equal a GPS-world
|
|
12
|
+
* point `nue` has to store `alignment⁻¹ · nue` as its LOCAL position —
|
|
13
|
+
* writing raw `nue` double-applies the alignment. Getting this wrong was the
|
|
14
|
+
* alignment-frame bug
|
|
15
|
+
* (gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-05-31-gps-anchor-alignment-frame-bug.md);
|
|
16
|
+
* this helper centralises the conversion behind one tested, well-named seam.
|
|
17
|
+
*
|
|
18
|
+
* Design (see the plan
|
|
19
|
+
* gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-05-31-nue-to-ar-local-helper-plan.md):
|
|
20
|
+
* - **Takes the explicit alignment matrix array**, NOT `Object3D.worldToLocal`.
|
|
21
|
+
* `worldToLocal` would read the live, mid-lerp `matrixWorld` and break
|
|
22
|
+
* replay determinism; the explicit target matrix keeps the result a pure
|
|
23
|
+
* function of its inputs. Full rationale in the review doc
|
|
24
|
+
* (gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-05-31-worldtolocal-frame-helper-review.md).
|
|
25
|
+
* - **Positions only.** No pose/quaternion variant exists until a caller
|
|
26
|
+
* needs one (YAGNI). No caller currently sets a GPS-world rotation.
|
|
27
|
+
*/
|
|
28
|
+
const scratchMatrix = new THREE.Matrix4();
|
|
29
|
+
/**
|
|
30
|
+
* Convert a GPS-world NUE point into the AR-local position to write into a
|
|
31
|
+
* direct child of `arWorldGroup`, given the current alignment matrix.
|
|
32
|
+
*
|
|
33
|
+
* Computes `alignment⁻¹ · nue`. When the result is later composed back by the
|
|
34
|
+
* group's matrix (the same `alignment`), the child's WORLD position equals
|
|
35
|
+
* `nue` exactly.
|
|
36
|
+
*
|
|
37
|
+
* @param alignment - The alignment matrix as a 16-element **column-major**
|
|
38
|
+
* array (AR-odometry NUE → GPS-world NUE), e.g. from `getAlignmentMatrix()`
|
|
39
|
+
* or `THREE.Matrix4.toArray()`. Not mutated.
|
|
40
|
+
* @param nue - The GPS-world NUE point `[north, up, east]` in metres. Not
|
|
41
|
+
* mutated.
|
|
42
|
+
* @param out - Optional target vector to write into and return (pass a reused
|
|
43
|
+
* scratch to avoid allocation on hot paths). Defaults to a fresh
|
|
44
|
+
* `THREE.Vector3`.
|
|
45
|
+
* @returns `out`, set to the AR-local position.
|
|
46
|
+
*/
|
|
47
|
+
function nueToArLocal(alignment, nue, out = new THREE.Vector3()) {
|
|
48
|
+
scratchMatrix.fromArray(alignment).invert();
|
|
49
|
+
return out.set(nue[0], nue[1], nue[2]).applyMatrix4(scratchMatrix);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert an object's **GPS-world NUE world position** back into a GPS
|
|
53
|
+
* coordinate, for the GPS-anchor bootstrap that medians where an object was
|
|
54
|
+
* actually placed (mirrors the C# `DetermineAndStoreGpsWorldPose`, which
|
|
55
|
+
* medians the object's world pose and converts via `zero.CalcGpsCoordsOf`).
|
|
56
|
+
*
|
|
57
|
+
* Precondition: `worldNue` must already be in GPS-world NUE — i.e. the object
|
|
58
|
+
* lives under an `arWorldGroup` whose `.matrix` carries the alignment (see
|
|
59
|
+
* `enableArWorldGroupAlignment`), so `object3D.getWorldPosition()` is the
|
|
60
|
+
* GPS-world position. Sampling a pure-VIO (identity-`arWorldGroup`) world
|
|
61
|
+
* position would yield a wrong GPS coordinate.
|
|
62
|
+
*
|
|
63
|
+
* Altitude round-trip: `calcGpsCoords` returns only `lat`/`lon` (it derives
|
|
64
|
+
* them from the North/East axes and ignores Up). The Up axis (`worldNue.y`,
|
|
65
|
+
* NUE index 1) is carried through verbatim as `altitude`, so a later
|
|
66
|
+
* `calcRelativeCoordsInMeters(zero, result, result.altitude, 0)` reproduces the
|
|
67
|
+
* same Up value — keeping the steady-state vertical target consistent with
|
|
68
|
+
* where the object was sampled.
|
|
69
|
+
*
|
|
70
|
+
* @param worldNue - The object's world position in GPS-world NUE metres
|
|
71
|
+
* (`x = North`, `y = Up`, `z = East`). A `THREE.Vector3` satisfies this.
|
|
72
|
+
* @param zero - The GPS zero reference (origin for the conversion).
|
|
73
|
+
* @returns The GPS coordinate of `worldNue`, with `altitude = worldNue.y`.
|
|
74
|
+
*/
|
|
75
|
+
function worldNueToGps(worldNue, zero) {
|
|
76
|
+
const gps = calcGpsCoords(zero, [
|
|
77
|
+
worldNue.x,
|
|
78
|
+
worldNue.y,
|
|
79
|
+
worldNue.z
|
|
80
|
+
]);
|
|
81
|
+
return {
|
|
82
|
+
lat: gps.lat,
|
|
83
|
+
lon: gps.lon,
|
|
84
|
+
altitude: worldNue.y
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { nueToArLocal, worldNueToGps };
|
|
@@ -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-CISLPQIb.js";
|
|
2
|
+
export { GpsAnchor, GpsAnchorMode, GpsAnchorOptions, GpsAnchorPhase, GpsAnchorSamplePoint, createGpsAnchor };
|