@relu-interactives/spatial-ecs 0.5.0 → 0.5.2

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.
@@ -3869,7 +3869,12 @@ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
3869
3869
  "scriptObject",
3870
3870
  "xrRig",
3871
3871
  "xrInteractor",
3872
- "teleportArea"
3872
+ "teleportArea",
3873
+ "uiPanel",
3874
+ "uiText",
3875
+ "uiButton",
3876
+ "uiToggle",
3877
+ "uiSlider"
3873
3878
  ]);
3874
3879
 
3875
3880
  // core/hydration/hydrateWorld.ts
@@ -8125,6 +8130,11 @@ function debugColorFor(kind, semanticLabel) {
8125
8130
  }
8126
8131
  __name(debugColorFor, "debugColorFor");
8127
8132
  var GLOBAL_MESH_DEBUG_OPACITY = 0.35;
8133
+ var GLOBAL_MESH_SWITCH_MARGIN = 1.5;
8134
+ function isGlobalMeshSurface(mesh) {
8135
+ return (mesh.semanticLabel ?? null) === "global mesh";
8136
+ }
8137
+ __name(isGlobalMeshSurface, "isGlobalMeshSurface");
8128
8138
  var DEBUG_RENDER_ORDER = 900;
8129
8139
  var ROOM_CAPTURE_DELAY_SECONDS = 3;
8130
8140
  var SYNTHETIC_FLOOR_EXTENT = 50;
@@ -8163,6 +8173,10 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
8163
8173
  this.roomCaptureRequested = false;
8164
8174
  /** This frame's inverse viewer matrix, or null when unavailable. */
8165
8175
  this.viewerInverse = null;
8176
+ /** This frame's viewer position in reference space, for room election. */
8177
+ this.viewerPos = null;
8178
+ /** The ONE global room mesh currently allowed to spawn. */
8179
+ this.electedGlobalMesh = null;
8166
8180
  this.tmpViewerMatrix = new THREE19.Matrix4();
8167
8181
  this.tmpViewPos = new THREE19.Vector3();
8168
8182
  }
@@ -8203,7 +8217,14 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
8203
8217
  const useMesh = (mode === "mesh" || mode === "auto") && meshesAvailable;
8204
8218
  const usePlanes = mode === "planes" || mode === "auto" && !useMesh;
8205
8219
  const viewer = frame.getViewerPose?.(referenceSpace);
8206
- this.viewerInverse = viewer ? this.tmpViewerMatrix.fromArray(viewer.transform.matrix).invert() : null;
8220
+ if (viewer) {
8221
+ const vm = viewer.transform.matrix;
8222
+ this.viewerPos = { x: vm[12], y: vm[13], z: vm[14] };
8223
+ this.viewerInverse = this.tmpViewerMatrix.fromArray(vm).invert();
8224
+ } else {
8225
+ this.viewerPos = null;
8226
+ this.viewerInverse = null;
8227
+ }
8207
8228
  if (usePlanes) {
8208
8229
  this.syncPlanes(world, frame, referenceSpace, deltaTime);
8209
8230
  } else if (this.planes.size > 0) {
@@ -8358,7 +8379,17 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
8358
8379
  for (const mesh of this.pendingMeshes.keys()) {
8359
8380
  if (!detected.has(mesh)) this.pendingMeshes.delete(mesh);
8360
8381
  }
8382
+ const electedGlobal = this.electGlobalMesh(frame, detected, referenceSpace);
8361
8383
  for (const mesh of detected) {
8384
+ if (isGlobalMeshSurface(mesh) && mesh !== electedGlobal) {
8385
+ const stale = this.meshes.get(mesh);
8386
+ if (stale) {
8387
+ this.destroyEntry(world, stale);
8388
+ this.meshes.delete(mesh);
8389
+ }
8390
+ this.pendingMeshes.delete(mesh);
8391
+ continue;
8392
+ }
8362
8393
  const pose = frame.getPose(mesh.meshSpace, referenceSpace);
8363
8394
  if (!pose) continue;
8364
8395
  const emulated = pose.emulatedPosition === true;
@@ -8382,6 +8413,45 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
8382
8413
  if (allowed) this.applyPose(world, entry.entityId, pose);
8383
8414
  }
8384
8415
  }
8416
+ /**
8417
+ * Pick THE room's global mesh: the one whose scan origin is nearest the
8418
+ * viewer, sticky to the current choice within a margin so origin jitter
8419
+ * can't flap the room. Without a viewer pose (or with a single candidate)
8420
+ * the first candidate stands; ties are impossible to break anyway.
8421
+ */
8422
+ electGlobalMesh(frame, detected, referenceSpace) {
8423
+ let nearest = null;
8424
+ let nearestDist = Number.POSITIVE_INFINITY;
8425
+ let currentDist = Number.POSITIVE_INFINITY;
8426
+ let currentStillDetected = false;
8427
+ for (const mesh of detected) {
8428
+ if (!isGlobalMeshSurface(mesh)) continue;
8429
+ if (!this.viewerPos) {
8430
+ return this.electedGlobalMesh && detected.has(this.electedGlobalMesh) ? this.electedGlobalMesh : mesh;
8431
+ }
8432
+ const pose = frame.getPose(mesh.meshSpace, referenceSpace);
8433
+ if (!pose) continue;
8434
+ const m = pose.transform.matrix;
8435
+ const d = Math.hypot(
8436
+ m[12] - this.viewerPos.x,
8437
+ m[13] - this.viewerPos.y,
8438
+ m[14] - this.viewerPos.z
8439
+ );
8440
+ if (mesh === this.electedGlobalMesh) {
8441
+ currentDist = d;
8442
+ currentStillDetected = true;
8443
+ }
8444
+ if (d < nearestDist) {
8445
+ nearestDist = d;
8446
+ nearest = mesh;
8447
+ }
8448
+ }
8449
+ if (currentStillDetected && currentDist < nearestDist + GLOBAL_MESH_SWITCH_MARGIN) {
8450
+ return this.electedGlobalMesh;
8451
+ }
8452
+ this.electedGlobalMesh = nearest;
8453
+ return nearest;
8454
+ }
8385
8455
  /**
8386
8456
  * Admission control for a NOT-yet-spawned surface. With a viewer pose
8387
8457
  * available, the surface must behave world-anchored for a few frames before
@@ -8593,6 +8663,7 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
8593
8663
  this.clearMap(world, this.meshes);
8594
8664
  this.pendingPlanes.clear();
8595
8665
  this.pendingMeshes.clear();
8666
+ this.electedGlobalMesh = null;
8596
8667
  }
8597
8668
  dispose(world) {
8598
8669
  this.clearAll(world);
@@ -10985,5 +11056,5 @@ __name(_XRHoverVisualSystem, "XRHoverVisualSystem");
10985
11056
  var XRHoverVisualSystem = _XRHoverVisualSystem;
10986
11057
 
10987
11058
  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, UIInteractionSystem, UIPanelSystem, 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 };
10988
- //# sourceMappingURL=chunk-Z6ZMR3CS.js.map
10989
- //# sourceMappingURL=chunk-Z6ZMR3CS.js.map
11059
+ //# sourceMappingURL=chunk-DF5SSRN6.js.map
11060
+ //# sourceMappingURL=chunk-DF5SSRN6.js.map