@multisetai/vps 1.0.7-beta.2 → 1.0.7-beta.3

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.

Potentially problematic release.


This version of @multisetai/vps might be problematic. Click here for more details.

@@ -2,6 +2,7 @@ import * as THREE3 from 'three';
2
2
  import { ARButton } from 'three/examples/jsm/webxr/ARButton.js';
3
3
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
4
4
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
5
+ import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
5
6
 
6
7
  // src/lib/webxr/controller.ts
7
8
 
@@ -32,7 +33,7 @@ async function compressToJpeg(buffer, width, height, quality = 0.8) {
32
33
  const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);
33
34
  ctx.putImageData(imageData, 0, 0);
34
35
  return new Promise((resolve) => {
35
- canvas.toBlob((blob) => resolve(blob != null ? blob : new Blob()), "image/jpeg", quality);
36
+ canvas.toBlob((blob) => resolve(blob ?? new Blob()), "image/jpeg", quality);
36
37
  });
37
38
  }
38
39
  async function getCameraTextureAsImage(renderer, webGLTexture, width, height) {
@@ -218,21 +219,20 @@ void main() {
218
219
  }
219
220
  `;
220
221
  function createGridMaterial(options = {}) {
221
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
222
- const color = (_a = options.color) != null ? _a : "#7B2CBF";
223
- const opacity = (_b = options.opacity) != null ? _b : 0.6;
224
- const gridColor = (_c = options.gridColor) != null ? _c : "#ffeb3b";
225
- const gridScale = (_d = options.gridScale) != null ? _d : 2;
226
- const gridLineWidth = (_e = options.gridLineWidth) != null ? _e : 0.02;
227
- const showGrid = (_f = options.showGrid) != null ? _f : 1;
228
- const center = (_g = options.center) != null ? _g : new THREE3.Vector3(0, 0, 0);
229
- const radius = (_h = options.radius) != null ? _h : 1;
230
- const progress = (_i = options.progress) != null ? _i : 1;
231
- const glowColor = (_j = options.glowColor) != null ? _j : "#00ffff";
232
- const glowWidth = (_k = options.glowWidth) != null ? _k : 0.05;
233
- const glowIntensity = (_l = options.glowIntensity) != null ? _l : 2;
234
- const lightColor = (_m = options.lightColor) != null ? _m : "#ffffff";
235
- const lightDirection = (_n = options.lightDirection) != null ? _n : new THREE3.Vector3(0.3, 1, 0.3).normalize();
222
+ const color = options.color ?? "#7B2CBF";
223
+ const opacity = options.opacity ?? 0.6;
224
+ const gridColor = options.gridColor ?? "#ffeb3b";
225
+ const gridScale = options.gridScale ?? 2;
226
+ const gridLineWidth = options.gridLineWidth ?? 0.02;
227
+ const showGrid = options.showGrid ?? 1;
228
+ const center = options.center ?? new THREE3.Vector3(0, 0, 0);
229
+ const radius = options.radius ?? 1;
230
+ const progress = options.progress ?? 1;
231
+ const glowColor = options.glowColor ?? "#00ffff";
232
+ const glowWidth = options.glowWidth ?? 0.05;
233
+ const glowIntensity = options.glowIntensity ?? 2;
234
+ const lightColor = options.lightColor ?? "#ffffff";
235
+ const lightDirection = options.lightDirection ?? new THREE3.Vector3(0.3, 1, 0.3).normalize();
236
236
  return new THREE3.ShaderMaterial({
237
237
  vertexShader: VERTEX,
238
238
  fragmentShader: FRAGMENT,
@@ -266,9 +266,13 @@ function createGridMaterial(options = {}) {
266
266
  // src/lib/webxr/mapMeshVisualizer.ts
267
267
  var LARGE_MAP_THRESHOLD = 50;
268
268
  var MapMeshVisualizer = class {
269
- constructor(scene, client) {
269
+ constructor(scene, client, renderer, camera) {
270
270
  this.scene = scene;
271
271
  this.client = client;
272
+ this.renderer = renderer;
273
+ this.camera = camera;
274
+ this.gizmoControl = null;
275
+ this.gizmoHelper = null;
272
276
  this.meshMaterial = null;
273
277
  this.localCenter = new THREE3.Vector3();
274
278
  this.localRadius = 0;
@@ -290,12 +294,29 @@ var MapMeshVisualizer = class {
290
294
  getMeshGroup() {
291
295
  return this.meshGroup;
292
296
  }
297
+ async ensureGizmoLoaded() {
298
+ const cfg = this.client.getConfig();
299
+ if (cfg.showGizmo === false) {
300
+ return;
301
+ }
302
+ if (!this.gizmoControl) {
303
+ const gizmo = new TransformControls(this.camera, this.renderer.domElement);
304
+ gizmo.setMode("translate");
305
+ gizmo.setSpace("local");
306
+ gizmo.enabled = false;
307
+ const helper = gizmo.getHelper();
308
+ this.scene.add(helper);
309
+ gizmo.attach(this.meshGroup);
310
+ this.gizmoControl = gizmo;
311
+ this.gizmoHelper = helper;
312
+ }
313
+ this.gizmoHelper.visible = true;
314
+ }
293
315
  async ensureMeshLoaded(mapDetails) {
294
- var _a, _b;
295
316
  if (this.scene.getObjectByName(mapDetails._id)) {
296
317
  return;
297
318
  }
298
- const meshKey = (_b = (_a = mapDetails.mapMesh) == null ? void 0 : _a.rawMesh) == null ? void 0 : _b.meshLink;
319
+ const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;
299
320
  if (!meshKey) {
300
321
  return;
301
322
  }
@@ -379,7 +400,6 @@ var MapMeshVisualizer = class {
379
400
  }
380
401
  }
381
402
  update(deltaSeconds, viewerWorldPosition) {
382
- var _a;
383
403
  if (!this.meshMaterial) {
384
404
  return;
385
405
  }
@@ -390,7 +410,7 @@ var MapMeshVisualizer = class {
390
410
  if (!uniforms.uProgress) {
391
411
  return;
392
412
  }
393
- const current = (_a = uniforms.uProgress.value) != null ? _a : 0;
413
+ const current = uniforms.uProgress.value ?? 0;
394
414
  if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {
395
415
  uniforms.uCenter.value.copy(this.lastViewerWorldPosition);
396
416
  }
@@ -424,13 +444,22 @@ var MapMeshVisualizer = class {
424
444
  });
425
445
  this.scene.remove(this.meshGroup);
426
446
  this.dracoLoader.dispose();
447
+ if (this.gizmoHelper) {
448
+ this.scene.remove(this.gizmoHelper);
449
+ }
450
+ if (this.gizmoControl) {
451
+ this.gizmoControl.dispose();
452
+ }
427
453
  }
428
454
  };
429
455
 
430
456
  // src/lib/webxr/world/World.ts
431
457
  var World = class {
432
- constructor(scene, client) {
433
- this.meshVisualizer = new MapMeshVisualizer(scene, client);
458
+ constructor(scene, client, renderer, camera) {
459
+ this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);
460
+ }
461
+ async ensureGizmoLoaded() {
462
+ await this.meshVisualizer.ensureGizmoLoaded();
434
463
  }
435
464
  async ensureMeshLoaded(mapDetails) {
436
465
  await this.meshVisualizer.ensureMeshLoaded(mapDetails);
@@ -467,23 +496,21 @@ var WebxrController = class {
467
496
  this.trackerSpace = null;
468
497
  }
469
498
  async initialize(buttonContainer) {
470
- var _a, _b, _c, _d;
471
499
  if (this.experience) {
472
500
  return this.arButton;
473
501
  }
474
502
  if (!window.isSecureContext) {
475
503
  throw new Error("WebXR requires a secure context (HTTPS).");
476
504
  }
477
- const canvas = (_a = this.options.canvas) != null ? _a : document.createElement("canvas");
505
+ const canvas = this.options.canvas ?? document.createElement("canvas");
478
506
  this.experience = new Experience(canvas);
479
- this.world = new World(this.experience.getScene(), this.options.client);
480
507
  const renderer = this.experience.getRenderer();
481
508
  const camera = this.experience.getCamera();
482
509
  const scene = this.experience.getScene();
510
+ this.world = new World(scene, this.options.client, renderer, camera);
483
511
  renderer.xr.addEventListener("sessionstart", () => {
484
- var _a2, _b2;
485
512
  this.isSessionActive = true;
486
- (_b2 = (_a2 = this.options).onSessionStart) == null ? void 0 : _b2.call(_a2);
513
+ this.options.onSessionStart?.();
487
514
  const cfg = this.options.client.getConfig();
488
515
  if (cfg.autoLocalize) {
489
516
  const session = renderer.xr.getSession();
@@ -497,9 +524,8 @@ var WebxrController = class {
497
524
  }
498
525
  });
499
526
  renderer.xr.addEventListener("sessionend", () => {
500
- var _a2, _b2;
501
527
  this.isSessionActive = false;
502
- (_b2 = (_a2 = this.options).onSessionEnd) == null ? void 0 : _b2.call(_a2);
528
+ this.options.onSessionEnd?.();
503
529
  });
504
530
  let lastTime = 0;
505
531
  const animationLoop = (time, frame) => {
@@ -544,11 +570,10 @@ var WebxrController = class {
544
570
  };
545
571
  renderer.setAnimationLoop(animationLoop);
546
572
  const resizeHandler = () => {
547
- var _a2;
548
- (_a2 = this.experience) == null ? void 0 : _a2.resize();
573
+ this.experience?.resize();
549
574
  };
550
575
  window.addEventListener("resize", resizeHandler);
551
- const overlayRoot = (_b = this.options.overlayRoot) != null ? _b : document.body;
576
+ const overlayRoot = this.options.overlayRoot ?? document.body;
552
577
  const arButton = ARButton.createButton(renderer, {
553
578
  requiredFeatures: ["camera-access", "dom-overlay"],
554
579
  domOverlay: { root: overlayRoot }
@@ -559,7 +584,7 @@ var WebxrController = class {
559
584
  }
560
585
  this.arButton = arButton;
561
586
  this.resizeHandler = resizeHandler;
562
- (_d = (_c = this.options).onARButtonCreated) == null ? void 0 : _d.call(_c, arButton);
587
+ this.options.onARButtonCreated?.(arButton);
563
588
  return arButton;
564
589
  }
565
590
  getScene() {
@@ -581,8 +606,7 @@ var WebxrController = class {
581
606
  return this.experience.getRenderer();
582
607
  }
583
608
  hasActiveSession() {
584
- var _a;
585
- return this.isSessionActive && ((_a = this.experience) == null ? void 0 : _a.getRenderer().xr.isPresenting) === true;
609
+ return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;
586
610
  }
587
611
  /**
588
612
  * Runs a single-frame localization: captures one frame, evaluates the result
@@ -591,24 +615,23 @@ var WebxrController = class {
591
615
  * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().
592
616
  */
593
617
  async localizeFrame() {
594
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
595
618
  if (!this.experience) {
596
619
  throw new Error("WebXR: WebXR controller has not been initialized.");
597
620
  }
598
621
  const renderer = this.experience.getRenderer();
599
- const session = (_b = (_a = renderer.xr).getSession) == null ? void 0 : _b.call(_a);
622
+ const session = renderer.xr.getSession?.();
600
623
  if (!session) {
601
624
  throw new Error(
602
625
  "WebXR Session: No active WebXR session. Start AR before calling localizeFrame()."
603
626
  );
604
627
  }
605
628
  const cfg = this.options.client.getConfig();
606
- const confidenceCheck = (_c = cfg.confidenceCheck) != null ? _c : false;
629
+ const confidenceCheck = cfg.confidenceCheck ?? false;
607
630
  const confidenceThreshold = Math.max(
608
631
  CONFIDENCE_THRESHOLD_MIN,
609
- Math.min((_d = cfg.confidenceThreshold) != null ? _d : 0.5, CONFIDENCE_THRESHOLD_MAX)
632
+ Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)
610
633
  );
611
- (_e = cfg.onLocalizationInit) == null ? void 0 : _e.call(cfg);
634
+ cfg.onLocalizationInit?.();
612
635
  this.isLocalizing = true;
613
636
  let best = null;
614
637
  let failureReason;
@@ -619,20 +642,27 @@ var WebxrController = class {
619
642
  } finally {
620
643
  this.isLocalizing = false;
621
644
  }
622
- const accepted = best && (!confidenceCheck || ((_f = best.localizeData.confidence) != null ? _f : 0) >= confidenceThreshold);
645
+ const accepted = best && (!confidenceCheck || (best.localizeData.confidence ?? 0) >= confidenceThreshold);
623
646
  if (accepted && best) {
624
- (_g = cfg.onLocalizationSuccess) == null ? void 0 : _g.call(cfg, best);
625
- if (cfg.showMesh && best.mapDetails && this.world && this.trackerSpace) {
626
- try {
627
- await this.world.ensureMeshLoaded(best.mapDetails);
628
- this.world.applyMeshTransform(best, this.trackerSpace);
629
- } catch {
647
+ cfg.onLocalizationSuccess?.(best);
648
+ if (this.world && this.trackerSpace) {
649
+ const willShowMesh = cfg.showMesh && !!best.mapDetails;
650
+ const willShowGizmo = cfg.showGizmo !== false;
651
+ if (willShowMesh || willShowGizmo) {
652
+ try {
653
+ await this.world.ensureGizmoLoaded();
654
+ if (willShowMesh) {
655
+ await this.world.ensureMeshLoaded(best.mapDetails);
656
+ }
657
+ this.world.applyMeshTransform(best, this.trackerSpace);
658
+ } catch {
659
+ }
630
660
  }
631
661
  }
632
662
  return best;
633
663
  }
634
- const reason = failureReason != null ? failureReason : !best ? "All attempts failed to produce a pose." : confidenceCheck ? `Best confidence ${(_h = best.localizeData.confidence) != null ? _h : 0} below threshold ${confidenceThreshold}.` : void 0;
635
- (_i = cfg.onLocalizationFailure) == null ? void 0 : _i.call(cfg, reason);
664
+ const reason = failureReason ?? (!best ? "All attempts failed to produce a pose." : confidenceCheck ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.` : void 0);
665
+ cfg.onLocalizationFailure?.(reason);
636
666
  return null;
637
667
  }
638
668
  /**
@@ -642,12 +672,11 @@ var WebxrController = class {
642
672
  * result, apiCalled, and an optional failureReason for onLocalizationFailure.
643
673
  */
644
674
  async captureFrame() {
645
- var _a, _b, _c;
646
675
  if (!this.experience) {
647
676
  throw new Error("WebXR: WebXR controller has not been initialized.");
648
677
  }
649
678
  const renderer = this.experience.getRenderer();
650
- const session = (_b = (_a = renderer.xr).getSession) == null ? void 0 : _b.call(_a);
679
+ const session = renderer.xr.getSession?.();
651
680
  if (!session) {
652
681
  throw new Error(
653
682
  "WebXR Session: No active WebXR session. Start AR before capturing."
@@ -661,12 +690,11 @@ var WebxrController = class {
661
690
  }
662
691
  const gl = renderer.getContext();
663
692
  const cfg = this.options.client.getConfig();
664
- const timeoutMs = (_c = cfg.localizationTrackingTimeoutMs) != null ? _c : DEFAULT_TRACKING_TIMEOUT_MS;
693
+ const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;
665
694
  return new Promise((resolve, reject) => {
666
695
  const startTime = Date.now();
667
696
  const tryFrame = (attempt, cameraAttemptsWithPose) => {
668
697
  session.requestAnimationFrame(async (_time, xrFrame) => {
669
- var _a2, _b2, _c2, _d;
670
698
  try {
671
699
  const elapsed = Date.now() - startTime;
672
700
  const viewerPose = xrFrame.getViewerPose(referenceSpace);
@@ -691,7 +719,7 @@ var WebxrController = class {
691
719
  const gl2 = gl;
692
720
  const bindingCtor = XRWebGLBinding;
693
721
  const binding = new bindingCtor(session, gl2);
694
- const cameraTexture = (_b2 = (_a2 = binding.getCameraImage) == null ? void 0 : _a2.call(binding, xrCamera)) != null ? _b2 : null;
722
+ const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;
695
723
  if (!cameraTexture) continue;
696
724
  const width = xrCamera.width;
697
725
  const height = xrCamera.height;
@@ -732,7 +760,7 @@ var WebxrController = class {
732
760
  } finally {
733
761
  gl.bindFramebuffer(
734
762
  gl.FRAMEBUFFER,
735
- (_d = (_c2 = session.renderState.baseLayer) == null ? void 0 : _c2.framebuffer) != null ? _d : null
763
+ session.renderState.baseLayer?.framebuffer ?? null
736
764
  );
737
765
  }
738
766
  });
@@ -741,18 +769,17 @@ var WebxrController = class {
741
769
  });
742
770
  }
743
771
  dispose() {
744
- var _a, _b, _c, _d;
745
772
  if (this.resizeHandler) {
746
773
  window.removeEventListener("resize", this.resizeHandler);
747
774
  }
748
- (_a = this.experience) == null ? void 0 : _a.getRenderer().setAnimationLoop(null);
749
- (_b = this.experience) == null ? void 0 : _b.dispose();
775
+ this.experience?.getRenderer().setAnimationLoop(null);
776
+ this.experience?.dispose();
750
777
  this.experience = null;
751
- (_c = this.world) == null ? void 0 : _c.dispose();
778
+ this.world?.dispose();
752
779
  this.world = null;
753
780
  this.trackingLossFrames = 0;
754
781
  this.hadTrackingLoss = false;
755
- if ((_d = this.arButton) == null ? void 0 : _d.parentElement) {
782
+ if (this.arButton?.parentElement) {
756
783
  this.arButton.parentElement.removeChild(this.arButton);
757
784
  }
758
785
  this.arButton = null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/webxr/internal/cameraIntrinsics.ts","../../src/lib/webxr/internal/frameCapture.ts","../../src/lib/webxr/experience/Experience.ts","../../src/lib/webxr/materials/gridMaterial.ts","../../src/lib/webxr/mapMeshVisualizer.ts","../../src/lib/webxr/world/World.ts","../../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","_a","_b","THREE4","_c"],"mappings":"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","file":"index.js","sourcesContent":["import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? 0.6;\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#00ffff';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.4,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#00ffff',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(scene: THREE.Scene, client: MultisetClient) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client);\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n this.world = new World(this.experience.getScene(), this.options.client);\n\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (cfg.showMesh && best.mapDetails && this.world && this.trackerSpace) {\n try {\n await this.world.ensureMeshLoaded(best.mapDetails);\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh loading failure must not prevent returning the localization result\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/lib/webxr/internal/cameraIntrinsics.ts","../../src/lib/webxr/internal/frameCapture.ts","../../src/lib/webxr/experience/Experience.ts","../../src/lib/webxr/materials/gridMaterial.ts","../../src/lib/webxr/mapMeshVisualizer.ts","../../src/lib/webxr/world/World.ts","../../src/lib/webxr/controller.ts"],"names":["THREE","THREE2","THREE4"],"mappings":"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","file":"index.js","sourcesContent":["import type { ICameraIntrinsicsEvent } from '../../core';\n\nexport function getCameraIntrinsics(\n projectionMatrix: Float32Array,\n viewport: XRViewport\n): ICameraIntrinsicsEvent {\n const p = projectionMatrix;\n const u0 = ((1 - p[8]) * viewport.width) / 2 + viewport.x;\n const v0 = ((1 - p[9]) * viewport.height) / 2 + viewport.y;\n const ax = (viewport.width / 2) * p[0];\n const ay = (viewport.height / 2) * p[5];\n\n return {\n fx: ax,\n fy: ay,\n px: u0,\n py: v0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import * as THREE from 'three';\nimport type { IFrameCaptureEvent } from '../../core';\n\nexport async function compressToJpeg(\n buffer: ArrayBuffer,\n width: number,\n height: number,\n quality = 0.8\n): Promise<Blob> {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return new Blob();\n\n const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height);\n ctx.putImageData(imageData, 0, 0);\n\n return new Promise((resolve) => {\n canvas.toBlob((blob) => resolve(blob ?? new Blob()), 'image/jpeg', quality);\n });\n}\n\nexport async function getCameraTextureAsImage(\n renderer: THREE.WebGLRenderer,\n webGLTexture: WebGLTexture,\n width: number,\n height: number\n): Promise<IFrameCaptureEvent | null> {\n const gl = renderer.getContext();\n if (!gl) return null;\n\n const framebuffer = gl.createFramebuffer();\n if (!framebuffer) return null;\n\n let pixelBuffer: Uint8Array;\n try {\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n webGLTexture,\n 0\n );\n\n pixelBuffer = new Uint8Array(width * height * 4);\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);\n } finally {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.deleteFramebuffer(framebuffer);\n }\n\n const flippedData = new Uint8ClampedArray(pixelBuffer.length);\n for (let row = 0; row < height; row += 1) {\n const sourceStart = row * width * 4;\n const destStart = (height - row - 1) * width * 4;\n flippedData.set(\n pixelBuffer.subarray(sourceStart, sourceStart + width * 4),\n destStart\n );\n }\n\n const blob = await compressToJpeg(flippedData.buffer, width, height, 0.7);\n\n if (!blob.size) {\n return null;\n }\n\n return {\n blob,\n width,\n height,\n };\n}\n","import * as THREE from 'three';\n\n/**\n * Owns the Three.js scene, camera, and renderer for the AR session.\n * Handles resize and dispose; animation loop remains in the controller.\n */\nexport class Experience {\n private scene: THREE.Scene;\n private camera: THREE.PerspectiveCamera;\n private renderer: THREE.WebGLRenderer;\n\n constructor(canvas: HTMLCanvasElement) {\n this.renderer = new THREE.WebGLRenderer({\n canvas,\n antialias: true,\n alpha: true,\n });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.xr.enabled = true;\n\n this.camera = new THREE.PerspectiveCamera(\n 45,\n window.innerWidth / window.innerHeight,\n 0.2,\n 10000\n );\n\n this.scene = new THREE.Scene();\n this.setupLights();\n }\n\n private setupLights(): void {\n const light = new THREE.HemisphereLight(0xffffff, 0xf8f0ff, 1);\n light.position.set(0.5, 2, 0.25);\n this.scene.add(light);\n\n const diLight = new THREE.DirectionalLight('#7B2CBF');\n diLight.position.set(0, 2, 0);\n this.scene.add(diLight);\n }\n\n getScene(): THREE.Scene {\n return this.scene;\n }\n\n getCamera(): THREE.PerspectiveCamera {\n return this.camera;\n }\n\n getRenderer(): THREE.WebGLRenderer {\n return this.renderer;\n }\n\n resize(): void {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n dispose(): void {\n this.renderer.dispose();\n (this as unknown as { scene: THREE.Scene | null }).scene = null;\n (this as unknown as { camera: THREE.PerspectiveCamera | null }).camera = null;\n (this as unknown as { renderer: THREE.WebGLRenderer | null }).renderer = null;\n }\n}\n","import * as THREE from 'three';\n\nconst VERTEX = `\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nvoid main() {\n vec4 worldPos = modelMatrix * vec4(position, 1.0);\n vWorldPosition = worldPos.xyz;\n vWorldNormal = normalize(mat3(modelMatrix) * normal);\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nconst FRAGMENT = `\nuniform vec3 uColor;\nuniform float uOpacity;\n\nuniform vec3 uGridColor;\nuniform float uGridSize;\nuniform float uGridLineWidth;\nuniform float uShowGrid;\n\nuniform vec3 uCenter;\nuniform float uRadius;\nuniform float uProgress;\n\nuniform vec3 uGlowColor;\nuniform float uGlowWidth;\nuniform float uGlowIntensity;\n\nuniform vec3 uLightColor;\nuniform vec3 uLightDirection;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vWorldNormal;\n\nfloat getGridFactor(vec3 worldPos, vec3 worldNormal, float gridSize, float lineWidth) {\n vec3 absNormal = abs(worldNormal);\n vec2 gridCoord;\n\n if (absNormal.y > absNormal.x && absNormal.y > absNormal.z) {\n gridCoord = worldPos.xz / gridSize;\n } else if (absNormal.x > absNormal.z) {\n gridCoord = worldPos.yz / gridSize;\n } else {\n gridCoord = worldPos.xy / gridSize;\n }\n\n vec2 gridFract = fract(abs(gridCoord));\n vec2 distToLine = min(gridFract, 1.0 - gridFract);\n float minDist = min(distToLine.x, distToLine.y);\n float gridFactor = 1.0 - smoothstep(0.0, lineWidth, minDist);\n\n return gridFactor;\n}\n\nvoid main() {\n vec3 baseColor = uColor;\n float baseAlpha = uOpacity;\n\n float distanceFromCenter = length(vWorldPosition - uCenter);\n float normalizedDistance = distanceFromCenter / max(uRadius, 0.001);\n float threshold = uProgress;\n\n if (threshold - normalizedDistance - 0.001 < 0.0) {\n discard;\n }\n\n float distanceFromEdge = threshold - normalizedDistance;\n\n float gridFactor = getGridFactor(vWorldPosition, normalize(vWorldNormal), uGridSize, uGridLineWidth);\n\n vec3 colorGridMixed = mix(baseColor, uGridColor, gridFactor * uShowGrid);\n float alphaGridMixed = max(baseAlpha, gridFactor * uShowGrid);\n\n float glowFactor = clamp(1.0 - clamp(distanceFromEdge / max(uGlowWidth, 0.001), 0.0, 1.0), 0.0, 1.0);\n glowFactor *= glowFactor;\n\n vec3 glowContribution = uGlowColor * glowFactor * uGlowIntensity;\n\n float alphaWithGlow = max(alphaGridMixed, glowFactor);\n alphaWithGlow = max(alphaWithGlow, 0.3);\n\n vec3 N = normalize(vWorldNormal);\n vec3 L = normalize(uLightDirection);\n float ndotl = max(0.3, dot(N, L));\n vec3 ambient = vec3(0.4);\n vec3 lighting = uLightColor * ndotl + ambient;\n\n vec3 litColor = colorGridMixed * lighting;\n vec3 finalColor = litColor + glowContribution * 0.5;\n\n gl_FragColor = vec4(finalColor, alphaWithGlow);\n}\n`;\n\nexport interface IGridMaterialOptions {\n color?: string | THREE.Color;\n opacity?: number;\n\n gridColor?: string | THREE.Color;\n gridScale?: number;\n gridLineWidth?: number;\n showGrid?: number;\n\n /** Center of radial effect (world space; can be updated after creation). */\n center?: THREE.Vector3;\n /** Max radius for radial progress (world units). */\n radius?: number;\n /** Progress 0–1; 1 = fully visible. */\n progress?: number;\n\n glowColor?: string | THREE.Color;\n glowWidth?: number;\n glowIntensity?: number;\n\n lightColor?: string | THREE.Color;\n /** Direction from surface toward light (world space). */\n lightDirection?: THREE.Vector3;\n}\n\n/**\n * Creates a ShaderMaterial with radial progress reveal, grid overlay, edge glow,\n * and simple directional lighting (Unity-style).\n */\nexport function createGridMaterial(\n options: IGridMaterialOptions = {}\n): THREE.ShaderMaterial {\n const color = options.color ?? '#7B2CBF';\n const opacity = options.opacity ?? 0.6;\n\n const gridColor = options.gridColor ?? '#ffeb3b';\n const gridScale = options.gridScale ?? 2.0;\n const gridLineWidth = options.gridLineWidth ?? 0.02;\n const showGrid = options.showGrid ?? 1.0;\n\n const center = options.center ?? new THREE.Vector3(0, 0, 0);\n const radius = options.radius ?? 1.0;\n const progress = options.progress ?? 1.0;\n\n const glowColor = options.glowColor ?? '#00ffff';\n const glowWidth = options.glowWidth ?? 0.05;\n const glowIntensity = options.glowIntensity ?? 2.0;\n\n const lightColor = options.lightColor ?? '#ffffff';\n const lightDirection =\n options.lightDirection ?? new THREE.Vector3(0.3, 1.0, 0.3).normalize();\n\n return new THREE.ShaderMaterial({\n vertexShader: VERTEX,\n fragmentShader: FRAGMENT,\n transparent: true,\n side: THREE.DoubleSide,\n uniforms: {\n uColor: { value: typeof color === 'string' ? new THREE.Color(color) : color },\n uOpacity: { value: opacity },\n\n uGridColor: {\n value: typeof gridColor === 'string' ? new THREE.Color(gridColor) : gridColor,\n },\n uGridSize: { value: gridScale },\n uGridLineWidth: { value: gridLineWidth },\n uShowGrid: { value: showGrid },\n\n uCenter: { value: center.clone() },\n uRadius: { value: radius },\n uProgress: { value: progress },\n\n uGlowColor: {\n value: typeof glowColor === 'string' ? new THREE.Color(glowColor) : glowColor,\n },\n uGlowWidth: { value: glowWidth },\n uGlowIntensity: { value: glowIntensity },\n\n uLightColor: {\n value: typeof lightColor === 'string' ? new THREE.Color(lightColor) : lightColor,\n },\n uLightDirection: { value: lightDirection.clone() },\n },\n });\n}\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../core';\nimport type { IGetMapsDetailsResponse } from '../core';\nimport { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';\nimport { createGridMaterial } from './materials/gridMaterial';\n\nconst LARGE_MAP_THRESHOLD = 50.0;\n\nexport class MapMeshVisualizer {\n private readonly meshGroup: THREE.Group;\n private readonly gltfLoader: GLTFLoader;\n private readonly dracoLoader: DRACOLoader;\n\n private gizmoControl: TransformControls | null = null;\n private gizmoHelper: THREE.Object3D | null = null;\n private meshMaterial: THREE.ShaderMaterial | null = null;\n private readonly localCenter = new THREE.Vector3();\n private localRadius = 0;\n private readonly radialDuration = 4.0; // seconds for full radial reveal\n private readonly radialRepeatInterval = 20.0; // seconds before replaying the effect\n private idleTimeAfterReveal = 0; // seconds since progress reached 1\n private readonly lastViewerWorldPosition = new THREE.Vector3();\n\n constructor(\n private readonly scene: THREE.Scene,\n private readonly client: MultisetClient,\n private readonly renderer: THREE.WebGLRenderer,\n private readonly camera: THREE.Camera\n ) {\n this.meshGroup = new THREE.Group();\n this.meshGroup.visible = false;\n this.scene.add(this.meshGroup);\n\n this.dracoLoader = new DRACOLoader();\n this.dracoLoader.setDecoderPath('/draco/');\n\n this.gltfLoader = new GLTFLoader();\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n }\n\n getMeshGroup(): THREE.Group {\n return this.meshGroup;\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n const cfg = this.client.getConfig();\n if (cfg.showGizmo === false) {\n return;\n }\n if (!this.gizmoControl) {\n const gizmo = new TransformControls(this.camera, this.renderer.domElement);\n gizmo.setMode('translate');\n gizmo.setSpace('local');\n gizmo.enabled = false;\n const helper = gizmo.getHelper();\n this.scene.add(helper);\n gizmo.attach(this.meshGroup);\n this.gizmoControl = gizmo;\n this.gizmoHelper = helper;\n }\n this.gizmoHelper!.visible = true;\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n if (this.scene.getObjectByName(mapDetails._id)) {\n return;\n }\n\n const meshKey = mapDetails.mapMesh?.rawMesh?.meshLink;\n if (!meshKey) {\n return;\n }\n\n const url = await this.client.downloadFile(meshKey);\n if (!url) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.gltfLoader.load(\n url,\n (gltf) => {\n const box = new THREE.Box3().setFromObject(gltf.scene);\n const sizeVec = box.getSize(new THREE.Vector3());\n let size = sizeVec.length();\n const center = box.getCenter(new THREE.Vector3());\n\n if (size > LARGE_MAP_THRESHOLD) {\n size = LARGE_MAP_THRESHOLD;\n }\n\n this.localCenter.copy(center);\n this.localRadius = Math.max(size / 2, 0.001);\n\n const meshMaterial = createGridMaterial({\n color: '#7B2CBF',\n opacity: 0.4,\n gridColor: '#ffeb3b',\n gridScale: 2.0,\n gridLineWidth: 0.02,\n showGrid: 1.0,\n center: this.localCenter.clone(),\n radius: this.localRadius,\n progress: 0.0,\n glowColor: '#00ffff',\n glowWidth: 0.05,\n glowIntensity: 2.0,\n });\n\n this.meshMaterial = meshMaterial;\n\n gltf.scene.traverse((child) => {\n if ((child as THREE.Mesh).isMesh) {\n (child as THREE.Mesh).material = meshMaterial;\n }\n });\n\n gltf.scene.name = mapDetails._id;\n this.meshGroup.add(gltf.scene);\n resolve();\n },\n undefined,\n (error) => {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n );\n });\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n const pose = best.localizeData;\n\n const resPosition = new THREE.Vector3(\n pose.position.x,\n pose.position.y,\n pose.position.z\n );\n\n const resRotation = new THREE.Quaternion(\n pose.rotation.x,\n pose.rotation.y,\n pose.rotation.z,\n pose.rotation.w\n );\n\n const responseMatrix = new THREE.Matrix4();\n responseMatrix.compose(resPosition, resRotation, new THREE.Vector3(1, 1, 1));\n\n const inverseResponseMatrix = responseMatrix.clone().invert();\n\n const resultantMatrix = new THREE.Matrix4();\n resultantMatrix.multiplyMatrices(trackerSpace, inverseResponseMatrix);\n\n const position = new THREE.Vector3();\n const rotation = new THREE.Quaternion();\n const scale = new THREE.Vector3();\n resultantMatrix.decompose(position, rotation, scale);\n\n this.meshGroup.position.copy(position);\n this.meshGroup.quaternion.copy(rotation);\n this.meshGroup.scale.set(1, 1, 1);\n this.meshGroup.visible = true;\n this.meshGroup.updateMatrix();\n\n if (this.meshMaterial) {\n this.meshMaterial.uniforms.uCenter.value\n .copy(this.localCenter)\n .applyMatrix4(this.meshGroup.matrixWorld);\n }\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n if (!this.meshMaterial) {\n return;\n }\n\n if (viewerWorldPosition) {\n this.lastViewerWorldPosition.copy(viewerWorldPosition);\n }\n\n const uniforms = this.meshMaterial.uniforms as {\n uProgress?: { value: number };\n uCenter?: { value: THREE.Vector3 };\n };\n\n if (!uniforms.uProgress) {\n return;\n }\n\n const current = uniforms.uProgress.value ?? 0;\n\n if (current === 0 && uniforms.uCenter && this.lastViewerWorldPosition.lengthSq() > 0) {\n uniforms.uCenter.value.copy(this.lastViewerWorldPosition);\n }\n\n if (current >= 1) {\n this.idleTimeAfterReveal += deltaSeconds;\n if (this.idleTimeAfterReveal >= this.radialRepeatInterval) {\n uniforms.uProgress.value = 0;\n this.idleTimeAfterReveal = 0;\n }\n return;\n }\n\n this.idleTimeAfterReveal = 0;\n const next = Math.min(\n current + deltaSeconds / this.radialDuration,\n 1\n );\n\n uniforms.uProgress.value = next;\n }\n\n dispose(): void {\n this.meshMaterial = null;\n this.meshGroup.traverse((child) => {\n const mesh = child as THREE.Mesh;\n if (mesh.isMesh) {\n mesh.geometry.dispose();\n if (Array.isArray(mesh.material)) {\n mesh.material.forEach((m) => m.dispose());\n } else {\n (mesh.material as THREE.Material).dispose();\n }\n }\n });\n this.scene.remove(this.meshGroup);\n this.dracoLoader.dispose();\n if (this.gizmoHelper) {\n this.scene.remove(this.gizmoHelper);\n }\n if (this.gizmoControl) {\n this.gizmoControl.dispose();\n }\n }\n}\n\n","import * as THREE from 'three';\nimport type { MultisetClient, ILocalizeAndMapDetails } from '../../core';\nimport type { IGetMapsDetailsResponse } from '../../core';\nimport { MapMeshVisualizer } from '../mapMeshVisualizer';\n\n/**\n * Composes scene content for the AR session (e.g. map mesh).\n * Delegates to MapMeshVisualizer for mesh load and transform.\n */\nexport class World {\n private readonly meshVisualizer: MapMeshVisualizer;\n\n constructor(\n scene: THREE.Scene,\n client: MultisetClient,\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera\n ) {\n this.meshVisualizer = new MapMeshVisualizer(scene, client, renderer, camera);\n }\n\n async ensureGizmoLoaded(): Promise<void> {\n await this.meshVisualizer.ensureGizmoLoaded();\n }\n\n async ensureMeshLoaded(mapDetails: IGetMapsDetailsResponse): Promise<void> {\n await this.meshVisualizer.ensureMeshLoaded(mapDetails);\n }\n\n applyMeshTransform(\n best: ILocalizeAndMapDetails,\n trackerSpace: THREE.Matrix4\n ): void {\n this.meshVisualizer.applyMeshTransform(best, trackerSpace);\n }\n\n update(\n deltaSeconds: number,\n viewerWorldPosition?: THREE.Vector3 | null\n ): void {\n this.meshVisualizer.update(deltaSeconds, viewerWorldPosition);\n }\n\n dispose(): void {\n this.meshVisualizer.dispose();\n }\n}\n","import * as THREE from 'three';\nimport { ARButton } from 'three/examples/jsm/webxr/ARButton.js';\n\nimport type {\n MultisetClient,\n ILocalizeAndMapDetails,\n} from '../core';\nimport { getCameraIntrinsics } from './internal/cameraIntrinsics';\nimport { getCameraTextureAsImage } from './internal/frameCapture';\nimport { Experience } from './experience/Experience';\nimport { World } from './world/World';\nconst CONFIDENCE_THRESHOLD_MIN = 0.2;\nconst CONFIDENCE_THRESHOLD_MAX = 0.8;\nconst TRACKING_LOSS_FRAME_THRESHOLD = 60;\n/** Default max time (ms) to wait for a valid viewer pose before failing. */\nconst DEFAULT_TRACKING_TIMEOUT_MS = 10_000;\n/** Max XR frames to wait for viewer pose (backup cap; ~10s at 30fps). */\nconst TRACKING_FRAME_CAP = 300;\n/** Max frames with valid pose but no camera image before failing. */\nconst CAMERA_IMAGE_MAX_ATTEMPTS = 10;\n\n/**\n * Options for WebxrController. Property names align with Unity SingleFrameLocalizationManager\n * where applicable (see https://docs.multiset.ai/unity-sdk/api-reference/singleframelocalizationmanager).\n */\nexport interface IWebxrControllerOptions {\n client: MultisetClient;\n canvas?: HTMLCanvasElement;\n overlayRoot?: HTMLElement;\n buttonContainer?: HTMLElement;\n onARButtonCreated?: (button: HTMLButtonElement) => void;\n onSessionStart?: () => void;\n onSessionEnd?: () => void;\n}\n\ntype XRViewWithCamera = XRView & {\n camera?: {\n width: number;\n height: number;\n [key: string]: unknown;\n };\n};\n\ntype XRWebGLBindingLike = {\n getCameraImage: (camera: XRViewWithCamera['camera']) => WebGLTexture | null;\n};\n\nexport class WebxrController {\n private experience: Experience | null = null;\n private world: World | null = null;\n private arButton: HTMLButtonElement | null = null;\n private resizeHandler: (() => void) | null = null;\n private isSessionActive: boolean = false;\n private trackingLossFrames: number = 0;\n private hadTrackingLoss: boolean = false;\n private isLocalizing: boolean = false;\n private trackerSpace: THREE.Matrix4 | null = null;\n\n constructor(private readonly options: IWebxrControllerOptions) { }\n\n async initialize(buttonContainer?: HTMLElement): Promise<HTMLButtonElement> {\n if (this.experience) {\n return this.arButton!;\n }\n\n if (!window.isSecureContext) {\n throw new Error('WebXR requires a secure context (HTTPS).');\n }\n\n const canvas = this.options.canvas ?? document.createElement('canvas');\n\n this.experience = new Experience(canvas);\n const renderer = this.experience.getRenderer();\n const camera = this.experience.getCamera();\n const scene = this.experience.getScene();\n\n this.world = new World(scene, this.options.client, renderer, camera);\n\n renderer.xr.addEventListener('sessionstart', () => {\n this.isSessionActive = true;\n this.options.onSessionStart?.();\n const cfg = this.options.client.getConfig();\n if (cfg.autoLocalize) {\n const session = renderer.xr.getSession();\n if (session) {\n session.requestAnimationFrame(() => {\n void this.localizeFrame();\n });\n } else {\n void this.localizeFrame();\n }\n }\n });\n\n renderer.xr.addEventListener('sessionend', () => {\n this.isSessionActive = false;\n this.options.onSessionEnd?.();\n });\n\n let lastTime = 0;\n\n const animationLoop = (time: number, frame: XRFrame | null) => {\n const deltaSeconds = lastTime === 0 ? 0 : (time - lastTime) / 1000;\n lastTime = time;\n\n let viewerWorldPosition: THREE.Vector3 | null = null;\n if (frame) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (viewerPose) {\n const p = viewerPose.transform.position;\n viewerWorldPosition = new THREE.Vector3(p.x, p.y, p.z);\n }\n }\n }\n\n if (this.world && deltaSeconds > 0) {\n this.world.update(deltaSeconds, viewerWorldPosition);\n }\n\n renderer.render(scene, camera);\n const cfg = this.options.client.getConfig();\n if (cfg.relocalization && frame && !this.isLocalizing) {\n const refSpace = renderer.xr.getReferenceSpace();\n if (refSpace) {\n const viewerPose = frame.getViewerPose(refSpace);\n if (!viewerPose) {\n this.trackingLossFrames += 1;\n if (this.trackingLossFrames >= TRACKING_LOSS_FRAME_THRESHOLD) {\n this.hadTrackingLoss = true;\n }\n } else {\n if (this.hadTrackingLoss) {\n this.hadTrackingLoss = false;\n this.trackingLossFrames = 0;\n void this.localizeFrame();\n } else {\n this.trackingLossFrames = 0;\n }\n }\n }\n }\n };\n renderer.setAnimationLoop(animationLoop);\n\n const resizeHandler = () => {\n this.experience?.resize();\n };\n window.addEventListener('resize', resizeHandler);\n\n const overlayRoot = this.options.overlayRoot ?? document.body;\n const arButton = ARButton.createButton(renderer, {\n requiredFeatures: ['camera-access', 'dom-overlay'],\n domOverlay: { root: overlayRoot },\n }) as HTMLButtonElement;\n\n const buttonParent =\n buttonContainer && buttonContainer instanceof HTMLElement\n ? buttonContainer\n : this.options.buttonContainer &&\n this.options.buttonContainer instanceof HTMLElement\n ? this.options.buttonContainer\n : overlayRoot;\n\n if (!buttonParent.contains(arButton)) {\n buttonParent.appendChild(arButton);\n }\n\n this.arButton = arButton;\n this.resizeHandler = resizeHandler;\n\n this.options.onARButtonCreated?.(arButton);\n return arButton;\n }\n\n getScene(): THREE.Scene {\n if (!this.experience) {\n throw new Error('Scene: WebXR controller has not been initialized.');\n }\n return this.experience.getScene();\n }\n\n getCamera(): THREE.PerspectiveCamera {\n if (!this.experience) {\n throw new Error('Camera: WebXR controller has not been initialized.');\n }\n return this.experience.getCamera();\n }\n\n getRenderer(): THREE.WebGLRenderer {\n if (!this.experience) {\n throw new Error('Renderer: WebXR controller has not been initialized.');\n }\n return this.experience.getRenderer();\n }\n\n hasActiveSession(): boolean {\n return this.isSessionActive && this.experience?.getRenderer().xr.isPresenting === true;\n }\n\n /**\n * Runs a single-frame localization: captures one frame, evaluates the result\n * against the optional confidenceThreshold, and fires\n * onLocalizationInit / onLocalizationSuccess / onLocalizationFailure.\n * Aligns with Unity SingleFrameLocalizationManager.LocalizeFrame().\n */\n async localizeFrame(): Promise<ILocalizeAndMapDetails | null> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before calling localizeFrame().'\n );\n }\n\n const cfg = this.options.client.getConfig();\n const confidenceCheck = cfg.confidenceCheck ?? false;\n const confidenceThreshold = Math.max(\n CONFIDENCE_THRESHOLD_MIN,\n Math.min(cfg.confidenceThreshold ?? 0.5, CONFIDENCE_THRESHOLD_MAX)\n );\n\n cfg.onLocalizationInit?.();\n this.isLocalizing = true;\n\n let best: ILocalizeAndMapDetails | null = null;\n\n let failureReason: string | undefined;\n try {\n const captureResult = await this.captureFrame();\n best = captureResult.result;\n failureReason = captureResult.failureReason;\n } finally {\n this.isLocalizing = false;\n }\n\n const accepted =\n best &&\n (!confidenceCheck ||\n (best.localizeData.confidence ?? 0) >= confidenceThreshold);\n\n if (accepted && best) {\n cfg.onLocalizationSuccess?.(best);\n\n if (this.world && this.trackerSpace) {\n const willShowMesh = cfg.showMesh && !!best.mapDetails;\n const willShowGizmo = cfg.showGizmo !== false;\n if (willShowMesh || willShowGizmo) {\n try {\n await this.world.ensureGizmoLoaded();\n if (willShowMesh) {\n await this.world.ensureMeshLoaded(best.mapDetails!);\n }\n this.world.applyMeshTransform(best, this.trackerSpace);\n } catch {\n // Mesh/gizmo loading failure must not prevent returning the localization result\n }\n }\n }\n return best;\n }\n\n const reason =\n failureReason ??\n (!best\n ? 'All attempts failed to produce a pose.'\n : confidenceCheck\n ? `Best confidence ${best.localizeData.confidence ?? 0} below threshold ${confidenceThreshold}.`\n : undefined);\n cfg.onLocalizationFailure?.(reason);\n return null;\n }\n\n /**\n * Internal: captures one frame and calls the localization API. Waits for a\n * valid viewer pose up to localizationTrackingTimeoutMs (and TRACKING_FRAME_CAP),\n * then tries to get a camera image (up to CAMERA_IMAGE_MAX_ATTEMPTS). Returns\n * result, apiCalled, and an optional failureReason for onLocalizationFailure.\n */\n private async captureFrame(): Promise<{\n result: ILocalizeAndMapDetails | null;\n apiCalled: boolean;\n failureReason?: string;\n }> {\n if (!this.experience) {\n throw new Error('WebXR: WebXR controller has not been initialized.');\n }\n const renderer = this.experience.getRenderer();\n\n const session = renderer.xr.getSession?.();\n if (!session) {\n throw new Error(\n 'WebXR Session: No active WebXR session. Start AR before capturing.'\n );\n }\n\n const referenceSpace = renderer.xr.getReferenceSpace();\n if (!referenceSpace) {\n throw new Error(\n 'WebXR Reference Space: Unable to acquire XR reference space.'\n );\n }\n\n const gl = renderer.getContext();\n const cfg = this.options.client.getConfig();\n const timeoutMs = cfg.localizationTrackingTimeoutMs ?? DEFAULT_TRACKING_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n\n const tryFrame = (attempt: number, cameraAttemptsWithPose: number) => {\n session.requestAnimationFrame(async (_time: number, xrFrame: XRFrame) => {\n try {\n const elapsed = Date.now() - startTime;\n const viewerPose = xrFrame.getViewerPose(referenceSpace);\n if (!viewerPose) {\n if (elapsed >= timeoutMs || attempt + 1 >= TRACKING_FRAME_CAP) {\n const sec = (timeoutMs / 1000).toFixed(1);\n resolve({\n result: null,\n apiCalled: false,\n failureReason: `Tracking unavailable: no viewer pose within ${sec}s. Try moving the device or ensuring good lighting.`,\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose);\n }\n return;\n }\n\n const views = viewerPose.views as XRViewWithCamera[];\n for (let i = 0; i < views.length; i += 1) {\n const view = views[i];\n const xrCamera = view.camera;\n if (!xrCamera) continue;\n\n const gl2 = gl as unknown as WebGL2RenderingContext;\n const bindingCtor = XRWebGLBinding as unknown as {\n new(\n session: XRSession,\n context: WebGL2RenderingContext\n ): XRWebGLBindingLike;\n };\n const binding = new bindingCtor(session, gl2);\n const cameraTexture = binding.getCameraImage?.(xrCamera) ?? null;\n if (!cameraTexture) continue;\n\n const width = xrCamera.width;\n const height = xrCamera.height;\n if (!width || !height) continue;\n\n const frameData = await getCameraTextureAsImage(\n renderer,\n cameraTexture,\n width,\n height\n );\n\n const intrinsics = getCameraIntrinsics(view.projectionMatrix, {\n width,\n height,\n x: 0,\n y: 0,\n });\n\n if (frameData && intrinsics) {\n // Capture the camera pose from the current XRFrame's view transform\n // (column-major Float32Array, same convention as THREE.Matrix4.fromArray).\n // Using camera.matrix would give the previous render frame's pose.\n this.trackerSpace = new THREE.Matrix4().fromArray(view.transform.matrix);\n\n const result = await this.options.client.localizeWithFrame(\n frameData,\n intrinsics\n );\n resolve({ result, apiCalled: true });\n return;\n }\n }\n\n if (cameraAttemptsWithPose + 1 >= CAMERA_IMAGE_MAX_ATTEMPTS) {\n resolve({\n result: null,\n apiCalled: false,\n failureReason:\n 'Camera image not available. The device or browser may not support camera access in AR.',\n });\n } else {\n tryFrame(attempt + 1, cameraAttemptsWithPose + 1);\n }\n } catch (error) {\n reject(error);\n } finally {\n gl.bindFramebuffer(\n gl.FRAMEBUFFER,\n session.renderState.baseLayer?.framebuffer ?? null\n );\n }\n });\n };\n tryFrame(0, 0);\n });\n }\n\n dispose(): void {\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n }\n\n this.experience?.getRenderer().setAnimationLoop(null);\n this.experience?.dispose();\n this.experience = null;\n this.world?.dispose();\n this.world = null;\n this.trackingLossFrames = 0;\n this.hadTrackingLoss = false;\n\n if (this.arButton?.parentElement) {\n this.arButton.parentElement.removeChild(this.arButton);\n }\n this.arButton = null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multisetai/vps",
3
- "version": "1.0.7-beta.2",
3
+ "version": "1.0.7-beta.3",
4
4
  "description": "Multiset VPS WebXR SDK - Core client and WebXR controller.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",