@relu-interactives/spatial-ecs 0.4.2 → 0.4.4

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.
@@ -7710,6 +7710,8 @@ var _XRSessionSystem = class _XRSessionSystem {
7710
7710
  this.capabilities = NO_XR_CAPABILITIES;
7711
7711
  /** Y compensation applied when a floor-relative space was requested but not granted. */
7712
7712
  this.appliedOriginOffset = 0;
7713
+ /** The live session, so an async floor probe can tell if it has been replaced. */
7714
+ this.session = null;
7713
7715
  this.inputSystem = inputSystem ?? null;
7714
7716
  }
7715
7717
  update(world) {
@@ -7728,6 +7730,7 @@ var _XRSessionSystem = class _XRSessionSystem {
7728
7730
  }
7729
7731
  handleSessionStart(world) {
7730
7732
  const session = world.getRenderer().xr.getSession();
7733
+ this.session = session ?? null;
7731
7734
  const mode = session && session.environmentBlendMode !== "opaque" ? "immersive-ar" : "immersive-vr";
7732
7735
  this.capabilities = readXrCapabilities(session ?? null, mode);
7733
7736
  if (session && this.inputSystem) {
@@ -7766,16 +7769,16 @@ var _XRSessionSystem = class _XRSessionSystem {
7766
7769
  renderer.xr.setReferenceSpaceType(wantsFloor ? "local-floor" : "local");
7767
7770
  } catch {
7768
7771
  }
7769
- const granted = session?.enabledFeatures;
7770
- const floorGranted = Array.isArray(granted) ? granted.includes("local-floor") : (
7771
- // No report at all: trust the request, since a wrong offset is worse
7772
- // than none on devices that did honour it.
7773
- true
7774
- );
7775
- this.appliedOriginOffset = wantsFloor && !floorGranted ? rig.fallbackEyeHeight : 0;
7776
- if (this.appliedOriginOffset !== 0) {
7772
+ this.appliedOriginOffset = 0;
7773
+ if (!wantsFloor || !session) return;
7774
+ const sessionAtRequest = session;
7775
+ session.requestReferenceSpace("local-floor").then(() => {
7776
+ }).catch(() => {
7777
+ if (this.session !== sessionAtRequest) return;
7778
+ if (this.appliedOriginOffset !== 0) return;
7779
+ this.appliedOriginOffset = rig.fallbackEyeHeight;
7777
7780
  transform.position.y -= this.appliedOriginOffset;
7778
- }
7781
+ });
7779
7782
  }
7780
7783
  handleSessionEnd(world) {
7781
7784
  if (this.appliedOriginOffset !== 0) {
@@ -7786,6 +7789,7 @@ var _XRSessionSystem = class _XRSessionSystem {
7786
7789
  }
7787
7790
  this.appliedOriginOffset = 0;
7788
7791
  }
7792
+ this.session = null;
7789
7793
  this.capabilities = NO_XR_CAPABILITIES;
7790
7794
  this.inputSystem?.detachSession();
7791
7795
  this.forEachBehaviour(world, (behaviour) => {
@@ -7902,6 +7906,7 @@ __name(decomposeXrPose, "decomposeXrPose");
7902
7906
 
7903
7907
  // core/systems/XREnvironmentSystem.ts
7904
7908
  var DEBUG_COLOR = 5088255;
7909
+ var ROOM_CAPTURE_DELAY_SECONDS = 3;
7905
7910
  var _XREnvironmentSystem = class _XREnvironmentSystem {
7906
7911
  constructor() {
7907
7912
  /** Keyed by the XRPlane/XRMesh object itself — the runtime's own identity. */
@@ -7909,17 +7914,24 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
7909
7914
  this.meshes = /* @__PURE__ */ new Map();
7910
7915
  this.presenting = false;
7911
7916
  this.debugVisible = false;
7917
+ /** Seconds presenting, used to decide the room has genuinely nothing in it. */
7918
+ this.elapsed = 0;
7919
+ /** `initiateRoomCapture` may be called only ONCE per session. */
7920
+ this.roomCaptureRequested = false;
7912
7921
  }
7913
- update(world) {
7922
+ update(world, deltaTime = 0) {
7914
7923
  const presenting = world.isXrPresenting();
7915
7924
  if (!presenting) {
7916
7925
  if (this.presenting) {
7917
7926
  this.presenting = false;
7927
+ this.elapsed = 0;
7928
+ this.roomCaptureRequested = false;
7918
7929
  this.clearAll(world);
7919
7930
  }
7920
7931
  return;
7921
7932
  }
7922
7933
  this.presenting = true;
7934
+ this.elapsed += deltaTime;
7923
7935
  const rig = this.findRig(world);
7924
7936
  const mode = rig?.environmentPhysics ?? "none";
7925
7937
  if (mode === "none") {
@@ -7948,6 +7960,34 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
7948
7960
  } else if (this.meshes.size > 0) {
7949
7961
  this.clearMap(world, this.meshes);
7950
7962
  }
7963
+ this.maybeCaptureRoom(world, frame);
7964
+ }
7965
+ /**
7966
+ * Ask the runtime to scan the room when it turns out we have no room.
7967
+ *
7968
+ * Plane and mesh detection do NOT scan anything — they replay a scan the user
7969
+ * captured earlier through the system's own room setup. Most people have
7970
+ * never run it, and those who have may have run it in a DIFFERENT room, so a
7971
+ * mixed-reality experience opens against either nothing at all or someone
7972
+ * else's furniture, with no prompt and no error.
7973
+ *
7974
+ * `XRSession.initiateRoomCapture()` (Meta's extension) launches that setup
7975
+ * from inside the session, and exists precisely for this case. Contract, from
7976
+ * Meta's docs: callable ONCE per session, and only worth calling once we are
7977
+ * confident the room really is empty — the arrays populate a beat after the
7978
+ * session starts, so a check on frame one would fire for everyone.
7979
+ */
7980
+ maybeCaptureRoom(world, frame) {
7981
+ if (this.roomCaptureRequested) return;
7982
+ if (this.elapsed < ROOM_CAPTURE_DELAY_SECONDS) return;
7983
+ if (this.planes.size > 0 || this.meshes.size > 0) return;
7984
+ if ((frame.detectedPlanes?.size ?? 0) > 0) return;
7985
+ if ((frame.detectedMeshes?.size ?? 0) > 0) return;
7986
+ const session = world.getRenderer().xr.getSession?.();
7987
+ if (typeof session?.initiateRoomCapture !== "function") return;
7988
+ this.roomCaptureRequested = true;
7989
+ session.initiateRoomCapture()?.catch(() => {
7990
+ });
7951
7991
  }
7952
7992
  /** How many pieces of real geometry are currently colliding. Script-facing. */
7953
7993
  getDetectedCount() {
@@ -9601,5 +9641,5 @@ __name(_XRHoverVisualSystem, "XRHoverVisualSystem");
9601
9641
  var XRHoverVisualSystem = _XRHoverVisualSystem;
9602
9642
 
9603
9643
  export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_DIRECTION_TOLERANCE, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, TeleportAimGate, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRAnchorSystem, XRControllerVisualSystem, XREnvironmentSystem, XRHandPoseSystem, XRHitTestSystem, XRHoverVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, XR_HOVER_SHELL_FLAG, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
9604
- //# sourceMappingURL=chunk-6UZC6M7V.js.map
9605
- //# sourceMappingURL=chunk-6UZC6M7V.js.map
9644
+ //# sourceMappingURL=chunk-OY2OONRR.js.map
9645
+ //# sourceMappingURL=chunk-OY2OONRR.js.map