@relu-interactives/spatial-ecs 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -3,8 +3,8 @@ export { A as AssetInput, t as CheckboxInput, u as ColorInput, v as ComponentFac
3
3
  import * as THREE from 'three';
4
4
  import { O as Object3DRef, ar as XrHandPreset } from './XRHandPose-CxPv-LBo.cjs';
5
5
  export { aD as AnimationStateCallbacks, aE as AnimationStateMachine, aF as AnimationStateManager, aG as StateMachine } from './XRHandPose-CxPv-LBo.cjs';
6
- import { X as XrCapabilities, a as XrInputState, b as XrHandPoseEventDetail } from './index-7YCk4cmQ.cjs';
7
- export { A as AnimationSystem, c as AudioSystem, C as CameraSyncSystem, E as EnvironmentSyncSystem, I as InstancedMeshSystem, L as LightSyncSystem, M as MaterialSyncSystem, d as MeshGeometrySystem, e as ModuleLoader, N as NO_XR_CAPABILITIES, O as ObjectVisibilitySystem, P as PhysicsSyncSystem, f as PostprocessingSyncSystem, S as SCRIPT_OBJECT_ROOT_FLAG, g as ScriptBehaviourSystem, h as ScriptObjectSystem, i as SelectionContext, V as VRTeleportAreaSystem, j as VideoSystem, k as XRAnchorSystem, l as XRControllerVisualSystem, m as XREnvironmentSystem, n as XRHandPoseSystem, o as XRHitTestSystem, p as XRHoverVisualSystem, q as XRInputSystem, r as XRInteractionSystem, s as XRLocomotionSystem, t as XRSessionSystem, u as XRTeleportVisualSystem, v as XR_HOVER_SHELL_FLAG, w as XrHandedness, x as XrHitResult, y as XrInputKind, z as readXrCapabilities } from './index-7YCk4cmQ.cjs';
6
+ import { X as XrCapabilities, a as XrInputState, b as XrHandPoseEventDetail } from './index-CH7qMsQT.cjs';
7
+ export { A as AnimationSystem, c as AudioSystem, C as CameraSyncSystem, E as EnvironmentSyncSystem, I as InstancedMeshSystem, L as LightSyncSystem, M as MaterialSyncSystem, d as MeshGeometrySystem, e as ModuleLoader, N as NO_XR_CAPABILITIES, O as ObjectVisibilitySystem, P as PhysicsSyncSystem, f as PostprocessingSyncSystem, S as SCRIPT_OBJECT_ROOT_FLAG, g as ScriptBehaviourSystem, h as ScriptObjectSystem, i as SelectionContext, V as VRTeleportAreaSystem, j as VideoSystem, k as XRAnchorSystem, l as XRControllerVisualSystem, m as XREnvironmentSystem, n as XRHandPoseSystem, o as XRHitTestSystem, p as XRHoverVisualSystem, q as XRInputSystem, r as XRInteractionSystem, s as XRLocomotionSystem, t as XRSessionSystem, u as XRTeleportVisualSystem, v as XR_HOVER_SHELL_FLAG, w as XrHandedness, x as XrHitResult, y as XrInputKind, z as readXrCapabilities } from './index-CH7qMsQT.cjs';
8
8
  export { i as CoreComponents } from './index-CQsHUez3.cjs';
9
9
  export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRAnchorComponent, createXRHandPoseComponent, createXRInteractableComponent, createXRInteractorComponent, createXRInteractorSideComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories } from './factories/index.cjs';
10
10
  import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
package/dist/index.d.ts CHANGED
@@ -3,8 +3,8 @@ export { A as AssetInput, t as CheckboxInput, u as ColorInput, v as ComponentFac
3
3
  import * as THREE from 'three';
4
4
  import { O as Object3DRef, ar as XrHandPreset } from './XRHandPose-BImIa4ZS.js';
5
5
  export { aD as AnimationStateCallbacks, aE as AnimationStateMachine, aF as AnimationStateManager, aG as StateMachine } from './XRHandPose-BImIa4ZS.js';
6
- import { X as XrCapabilities, a as XrInputState, b as XrHandPoseEventDetail } from './index-B2oHfqkj.js';
7
- export { A as AnimationSystem, c as AudioSystem, C as CameraSyncSystem, E as EnvironmentSyncSystem, I as InstancedMeshSystem, L as LightSyncSystem, M as MaterialSyncSystem, d as MeshGeometrySystem, e as ModuleLoader, N as NO_XR_CAPABILITIES, O as ObjectVisibilitySystem, P as PhysicsSyncSystem, f as PostprocessingSyncSystem, S as SCRIPT_OBJECT_ROOT_FLAG, g as ScriptBehaviourSystem, h as ScriptObjectSystem, i as SelectionContext, V as VRTeleportAreaSystem, j as VideoSystem, k as XRAnchorSystem, l as XRControllerVisualSystem, m as XREnvironmentSystem, n as XRHandPoseSystem, o as XRHitTestSystem, p as XRHoverVisualSystem, q as XRInputSystem, r as XRInteractionSystem, s as XRLocomotionSystem, t as XRSessionSystem, u as XRTeleportVisualSystem, v as XR_HOVER_SHELL_FLAG, w as XrHandedness, x as XrHitResult, y as XrInputKind, z as readXrCapabilities } from './index-B2oHfqkj.js';
6
+ import { X as XrCapabilities, a as XrInputState, b as XrHandPoseEventDetail } from './index-BphKHaV-.js';
7
+ export { A as AnimationSystem, c as AudioSystem, C as CameraSyncSystem, E as EnvironmentSyncSystem, I as InstancedMeshSystem, L as LightSyncSystem, M as MaterialSyncSystem, d as MeshGeometrySystem, e as ModuleLoader, N as NO_XR_CAPABILITIES, O as ObjectVisibilitySystem, P as PhysicsSyncSystem, f as PostprocessingSyncSystem, S as SCRIPT_OBJECT_ROOT_FLAG, g as ScriptBehaviourSystem, h as ScriptObjectSystem, i as SelectionContext, V as VRTeleportAreaSystem, j as VideoSystem, k as XRAnchorSystem, l as XRControllerVisualSystem, m as XREnvironmentSystem, n as XRHandPoseSystem, o as XRHitTestSystem, p as XRHoverVisualSystem, q as XRInputSystem, r as XRInteractionSystem, s as XRLocomotionSystem, t as XRSessionSystem, u as XRTeleportVisualSystem, v as XR_HOVER_SHELL_FLAG, w as XrHandedness, x as XrHitResult, y as XrInputKind, z as readXrCapabilities } from './index-BphKHaV-.js';
8
8
  export { i as CoreComponents } from './index-CuGqxuk-.js';
9
9
  export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRAnchorComponent, createXRHandPoseComponent, createXRInteractableComponent, createXRInteractorComponent, createXRInteractorSideComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories } from './factories/index.js';
10
10
  import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { MeshGeometrySystem, InstancedMeshSystem, EnvironmentSyncSystem, PostprocessingSyncSystem, LightSyncSystem, MaterialSyncSystem, VRTeleportAreaSystem, PhysicsSyncSystem, AnimationSystem, AudioSystem, VideoSystem, CameraSyncSystem, TransformSyncSystem, ObjectVisibilitySystem, RenderSystem, spawnPrefab, despawnPrefab, buildNodeKeyMapsFromSnapshot, indexSnapshotByEntity, findTopLevelNestedRegions, collectSnapshotSubtreeIds, groupOverridePaths, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, canonicalizeComponentValue, mergeComponentValue, decanonicalizeComponentValue, computeInstanceOverrides, collectEntitySubtree, ADDED_NODE_MARKER_COMPONENT } from './chunk-OY2OONRR.js';
2
- 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 } from './chunk-OY2OONRR.js';
1
+ import { MeshGeometrySystem, InstancedMeshSystem, EnvironmentSyncSystem, PostprocessingSyncSystem, LightSyncSystem, MaterialSyncSystem, VRTeleportAreaSystem, PhysicsSyncSystem, AnimationSystem, AudioSystem, VideoSystem, CameraSyncSystem, TransformSyncSystem, ObjectVisibilitySystem, RenderSystem, spawnPrefab, despawnPrefab, buildNodeKeyMapsFromSnapshot, indexSnapshotByEntity, findTopLevelNestedRegions, collectSnapshotSubtreeIds, groupOverridePaths, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, canonicalizeComponentValue, mergeComponentValue, decanonicalizeComponentValue, computeInstanceOverrides, collectEntitySubtree, ADDED_NODE_MARKER_COMPONENT } from './chunk-QIIWFP3V.js';
2
+ 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 } from './chunk-QIIWFP3V.js';
3
3
  import { registerDefaultFactories } from './chunk-SGADE55G.js';
4
4
  export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRAnchorComponent, createXRHandPoseComponent, createXRInteractableComponent, createXRInteractorComponent, createXRInteractorSideComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories } from './chunk-SGADE55G.js';
5
5
  import { ObjectManagementSystem } from './chunk-4DWZK4X4.js';
@@ -9348,6 +9348,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
9348
9348
  const rig = world.getComponent(rigEntityId, XRRigComponent);
9349
9349
  const rigTransform = world.getComponent(rigEntityId, TransformComponent);
9350
9350
  if (!rig || !rigTransform) return;
9351
+ if (world.isXrPassthrough()) return;
9351
9352
  const inputs = this.inputSystem.getInputs();
9352
9353
  if (inputs.length === 0) return;
9353
9354
  if (rig.snapTurn) {
@@ -9610,6 +9611,32 @@ var _XRSessionSystem = class _XRSessionSystem {
9610
9611
  }
9611
9612
  if (presenting) {
9612
9613
  this.dispatchInputEdges(world);
9614
+ this.muteDepthOcclusionColor(world);
9615
+ }
9616
+ }
9617
+ /**
9618
+ * Stop three's depth-occlusion pass from writing COLOR.
9619
+ *
9620
+ * With depth sensing granted, three draws a full-screen, head-locked mesh
9621
+ * every frame whose fragment shader assigns ONLY `gl_FragDepth` — that is
9622
+ * the whole occlusion mechanism — but its material never sets
9623
+ * `colorWrite: false`, so the colour output is UNDEFINED per GLSL. Desktop
9624
+ * drivers happen to zero it, which is why this ships unnoticed; Quest's
9625
+ * mobile GPU frequently leaves the last-computed temporary in the register —
9626
+ * the sampled DEPTH value — so the pass paints the depth camera's view over
9627
+ * the screen as faint head-locked contour bands. On device that reads as "a
9628
+ * large wireframe dome that follows my head".
9629
+ *
9630
+ * The mesh is created lazily inside three's render, so this is re-checked
9631
+ * every frame rather than hooked once; the write is idempotent and the
9632
+ * check is two property reads. Depth-only is the mesh's entire purpose —
9633
+ * occlusion is unaffected.
9634
+ */
9635
+ muteDepthOcclusionColor(world) {
9636
+ const xr = world.getRenderer().xr;
9637
+ const material = xr.getDepthSensingMesh?.()?.material;
9638
+ if (material && material.colorWrite !== false) {
9639
+ material.colorWrite = false;
9613
9640
  }
9614
9641
  }
9615
9642
  handleSessionStart(world) {
@@ -9763,8 +9790,12 @@ function planeColliderFromPolygon(polygon) {
9763
9790
  __name(planeColliderFromPolygon, "planeColliderFromPolygon");
9764
9791
  function writeXrMeshGeometry(vertices, indices, existing) {
9765
9792
  const geometry = existing ?? new THREE26__namespace.BufferGeometry();
9766
- geometry.setAttribute("position", new THREE26__namespace.BufferAttribute(vertices, 3));
9767
- geometry.setIndex(new THREE26__namespace.BufferAttribute(indices, 1));
9793
+ geometry.setAttribute(
9794
+ "position",
9795
+ new THREE26__namespace.BufferAttribute(vertices.slice(), 3)
9796
+ );
9797
+ geometry.setIndex(new THREE26__namespace.BufferAttribute(indices.slice(), 1));
9798
+ geometry.deleteAttribute("normal");
9768
9799
  geometry.computeBoundingSphere();
9769
9800
  geometry.computeVertexNormals();
9770
9801
  return geometry;
@@ -9790,7 +9821,42 @@ __name(decomposeXrPose, "decomposeXrPose");
9790
9821
 
9791
9822
  // core/systems/XREnvironmentSystem.ts
9792
9823
  var DEBUG_COLOR = 5088255;
9824
+ function debugColorFor(kind, semanticLabel) {
9825
+ switch (semanticLabel) {
9826
+ case "floor":
9827
+ return 5100666;
9828
+ // green — the surface everything should rest on
9829
+ case "ceiling":
9830
+ return 11693055;
9831
+ // purple
9832
+ case "wall":
9833
+ case "wall face":
9834
+ return DEBUG_COLOR;
9835
+ // blue, the family's base colour
9836
+ case "global mesh":
9837
+ return 9079442;
9838
+ // dim gray — raw scan, not an object
9839
+ default:
9840
+ return semanticLabel ? 16747594 : DEBUG_COLOR;
9841
+ }
9842
+ }
9843
+ __name(debugColorFor, "debugColorFor");
9844
+ var GLOBAL_MESH_DEBUG_OPACITY = 0.35;
9845
+ var DEBUG_RENDER_ORDER = 900;
9793
9846
  var ROOM_CAPTURE_DELAY_SECONDS = 3;
9847
+ var SYNTHETIC_FLOOR_EXTENT = 50;
9848
+ var SYNTHETIC_FLOOR_PLANE = {
9849
+ planeSpace: {},
9850
+ polygon: [
9851
+ { x: -SYNTHETIC_FLOOR_EXTENT / 2, y: 0, z: -SYNTHETIC_FLOOR_EXTENT / 2 },
9852
+ { x: SYNTHETIC_FLOOR_EXTENT / 2, y: 0, z: -SYNTHETIC_FLOOR_EXTENT / 2 },
9853
+ { x: SYNTHETIC_FLOOR_EXTENT / 2, y: 0, z: SYNTHETIC_FLOOR_EXTENT / 2 },
9854
+ { x: -SYNTHETIC_FLOOR_EXTENT / 2, y: 0, z: SYNTHETIC_FLOOR_EXTENT / 2 }
9855
+ ],
9856
+ orientation: "horizontal",
9857
+ semanticLabel: "floor",
9858
+ lastChangedTime: 0
9859
+ };
9794
9860
  var _XREnvironmentSystem = class _XREnvironmentSystem {
9795
9861
  constructor() {
9796
9862
  /** Keyed by the XRPlane/XRMesh object itself — the runtime's own identity. */
@@ -9831,6 +9897,11 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9831
9897
  const frame = xr.getFrame?.();
9832
9898
  const referenceSpace = xr.getReferenceSpace();
9833
9899
  if (!frame || !referenceSpace) return;
9900
+ if (frame.detectedPlanes === void 0 && frame.detectedMeshes === void 0) {
9901
+ this.ensureSyntheticFloor(world);
9902
+ return;
9903
+ }
9904
+ this.removeSyntheticFloor(world);
9834
9905
  const meshesAvailable = Boolean(frame.detectedMeshes);
9835
9906
  const useMesh = (mode === "mesh" || mode === "auto") && meshesAvailable;
9836
9907
  const usePlanes = mode === "planes" || mode === "auto" && !useMesh;
@@ -9877,6 +9948,51 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9877
9948
  getDetectedCount() {
9878
9949
  return { planes: this.planes.size, meshes: this.meshes.size };
9879
9950
  }
9951
+ /**
9952
+ * A census of every surface currently spawned: what it is, where it sits and
9953
+ * roughly how big it is. Built for the template's post-session readout, so a
9954
+ * mystery shape on the headset can be looked up by its label instead of
9955
+ * guessed at — a small-radius entry at head height IS the mystery shape, and
9956
+ * a clean list means whatever was seen did not come from this system.
9957
+ */
9958
+ getDebugSnapshot(world) {
9959
+ const snapshot = [];
9960
+ for (const [plane, entry] of this.planes) {
9961
+ const transform = world.getComponent(entry.entityId, TransformComponent);
9962
+ const collider = planeColliderFromPolygon(plane.polygon);
9963
+ snapshot.push({
9964
+ kind: "plane",
9965
+ label: plane.semanticLabel ?? null,
9966
+ position: transform ? { ...transform.position } : { x: 0, y: 0, z: 0 },
9967
+ radius: collider ? Math.hypot(collider.size.x, collider.size.z) / 2 : 0,
9968
+ emulated: entry.emulated
9969
+ });
9970
+ }
9971
+ for (const [mesh, entry] of this.meshes) {
9972
+ const transform = world.getComponent(entry.entityId, TransformComponent);
9973
+ snapshot.push({
9974
+ kind: "mesh",
9975
+ label: mesh.semanticLabel ?? null,
9976
+ position: transform ? { ...transform.position } : { x: 0, y: 0, z: 0 },
9977
+ radius: entry.geometry?.boundingSphere?.radius ?? 0,
9978
+ emulated: entry.emulated
9979
+ });
9980
+ }
9981
+ return snapshot;
9982
+ }
9983
+ /** Create the no-scan floor once; it lives in the ordinary plane map. */
9984
+ ensureSyntheticFloor(world) {
9985
+ if (this.planes.has(SYNTHETIC_FLOOR_PLANE)) return;
9986
+ const created = this.createPlaneEntity(world, SYNTHETIC_FLOOR_PLANE);
9987
+ if (created) this.planes.set(SYNTHETIC_FLOOR_PLANE, created);
9988
+ }
9989
+ /** Real scene data exists (or arrived) — the stand-in must go. */
9990
+ removeSyntheticFloor(world) {
9991
+ const entry = this.planes.get(SYNTHETIC_FLOOR_PLANE);
9992
+ if (!entry) return;
9993
+ this.destroyEntry(world, entry);
9994
+ this.planes.delete(SYNTHETIC_FLOOR_PLANE);
9995
+ }
9880
9996
  findRig(world) {
9881
9997
  const ids = world.query(XRRigComponent);
9882
9998
  if (ids.length === 0) return null;
@@ -9894,9 +10010,11 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9894
10010
  for (const plane of detected) {
9895
10011
  const pose = frame.getPose(plane.planeSpace, referenceSpace);
9896
10012
  if (!pose) continue;
10013
+ const emulated = pose.emulatedPosition === true;
9897
10014
  let entry = this.planes.get(plane);
9898
10015
  const changed = plane.lastChangedTime ?? 0;
9899
10016
  if (!entry) {
10017
+ if (emulated) continue;
9900
10018
  const created = this.createPlaneEntity(world, plane);
9901
10019
  if (!created) continue;
9902
10020
  entry = created;
@@ -9909,11 +10027,17 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9909
10027
  if (collider) {
9910
10028
  entry.geometry?.dispose();
9911
10029
  entry.geometry = null;
9912
- this.attachPlaneDebug(world, entry, collider);
10030
+ this.attachPlaneDebug(
10031
+ world,
10032
+ entry,
10033
+ collider,
10034
+ plane.semanticLabel ?? null
10035
+ );
9913
10036
  }
9914
10037
  }
9915
10038
  }
9916
- this.applyPose(world, entry.entityId, pose);
10039
+ entry.emulated = emulated;
10040
+ if (!emulated) this.applyPose(world, entry.entityId, pose);
9917
10041
  }
9918
10042
  }
9919
10043
  syncMeshes(world, frame, referenceSpace) {
@@ -9928,9 +10052,11 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9928
10052
  for (const mesh of detected) {
9929
10053
  const pose = frame.getPose(mesh.meshSpace, referenceSpace);
9930
10054
  if (!pose) continue;
10055
+ const emulated = pose.emulatedPosition === true;
9931
10056
  let entry = this.meshes.get(mesh);
9932
10057
  const changed = mesh.lastChangedTime ?? 0;
9933
10058
  if (!entry) {
10059
+ if (emulated) continue;
9934
10060
  const created = this.createMeshEntity(world, mesh);
9935
10061
  if (!created) continue;
9936
10062
  entry = created;
@@ -9939,7 +10065,8 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9939
10065
  entry.lastChangedTime = changed;
9940
10066
  writeXrMeshGeometry(mesh.vertices, mesh.indices, entry.geometry);
9941
10067
  }
9942
- this.applyPose(world, entry.entityId, pose);
10068
+ entry.emulated = emulated;
10069
+ if (!emulated) this.applyPose(world, entry.entityId, pose);
9943
10070
  }
9944
10071
  }
9945
10072
  createPlaneEntity(world, plane) {
@@ -9959,9 +10086,12 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9959
10086
  entityId,
9960
10087
  lastChangedTime: plane.lastChangedTime ?? 0,
9961
10088
  geometry: null,
9962
- material: null
10089
+ material: null,
10090
+ emulated: false
9963
10091
  };
9964
- if (this.debugVisible) this.attachPlaneDebug(world, entry, collider);
10092
+ if (this.debugVisible) {
10093
+ this.attachPlaneDebug(world, entry, collider, plane.semanticLabel ?? null);
10094
+ }
9965
10095
  return entry;
9966
10096
  }
9967
10097
  applyPlaneCollider(world, entityId, plane) {
@@ -9986,15 +10116,36 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
9986
10116
  createMeshEntity(world, mesh) {
9987
10117
  if (!mesh.vertices?.length || !mesh.indices?.length) return null;
9988
10118
  const geometry = writeXrMeshGeometry(mesh.vertices, mesh.indices);
10119
+ const label = mesh.semanticLabel ?? null;
10120
+ const isGlobalMesh = label === "global mesh";
9989
10121
  const material = new THREE26__namespace.MeshBasicMaterial({
9990
- color: DEBUG_COLOR,
9991
- wireframe: true
10122
+ color: debugColorFor("mesh", label),
10123
+ wireframe: true,
10124
+ // The global scan is a coarse triangle soup of the whole room; at full
10125
+ // strength it reads as phantom objects rather than as context.
10126
+ transparent: isGlobalMesh,
10127
+ opacity: isGlobalMesh ? GLOBAL_MESH_DEBUG_OPACITY : 1,
10128
+ // Depth-TESTED, deliberately. The overlay was X-ray for one release —
10129
+ // introduced on the theory that depth occlusion was carving it into a
10130
+ // head-locked dome — but that theory was falsified (the dome was the
10131
+ // depth mesh's unset colour output, plus emulated poses; both fixed).
10132
+ // X-ray had its own on-device failure: the global scan is DENSE, and a
10133
+ // dense wireframe at 0.35 opacity fuses into a translucent sheet — with
10134
+ // no depth test the walls' sheets drew through everything, stacked in
10135
+ // front of the user's eyes ("planes covering my face"). With the depth
10136
+ // buffer now holding CORRECT real-world depth, normal testing gives the
10137
+ // right picture: the near wall hides the far one. depthWrite stays off
10138
+ // so the overlay never occludes actual content.
10139
+ depthTest: true,
10140
+ depthWrite: false
9992
10141
  });
9993
10142
  const root = new THREE26__namespace.Group();
9994
10143
  const child = new THREE26__namespace.Mesh(geometry, material);
9995
10144
  child.visible = this.debugVisible;
10145
+ child.renderOrder = DEBUG_RENDER_ORDER;
9996
10146
  root.add(child);
9997
10147
  const entityId = world.createEntity();
10148
+ root.userData.entityId = entityId;
9998
10149
  world.addComponents(entityId, [
9999
10150
  new TransformComponent(),
10000
10151
  new Object3DRef(root),
@@ -10008,29 +10159,37 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
10008
10159
  entityId,
10009
10160
  lastChangedTime: mesh.lastChangedTime ?? 0,
10010
10161
  geometry,
10011
- material
10162
+ material,
10163
+ emulated: false
10012
10164
  };
10013
10165
  }
10014
10166
  /** A thin box so a detected plane can be SEEN, not just collided with. */
10015
- attachPlaneDebug(world, entry, collider) {
10016
- const geometry = new THREE26__namespace.BoxGeometry(
10167
+ attachPlaneDebug(world, entry, collider, semanticLabel) {
10168
+ const box = new THREE26__namespace.BoxGeometry(
10017
10169
  collider.size.x,
10018
10170
  collider.size.y,
10019
10171
  collider.size.z
10020
10172
  );
10021
- const material = new THREE26__namespace.MeshBasicMaterial({
10022
- color: DEBUG_COLOR,
10023
- wireframe: true
10173
+ const geometry = new THREE26__namespace.EdgesGeometry(box);
10174
+ box.dispose();
10175
+ const material = new THREE26__namespace.LineBasicMaterial({
10176
+ color: debugColorFor("plane", semanticLabel),
10177
+ // Same depth policy as the mesh overlay — see createMeshEntity.
10178
+ depthTest: true,
10179
+ depthWrite: false
10024
10180
  });
10025
10181
  const root = new THREE26__namespace.Group();
10026
- const child = new THREE26__namespace.Mesh(geometry, material);
10182
+ const child = new THREE26__namespace.LineSegments(geometry, material);
10183
+ child.renderOrder = DEBUG_RENDER_ORDER;
10027
10184
  child.position.set(collider.offset.x, collider.offset.y, collider.offset.z);
10028
10185
  child.visible = this.debugVisible;
10029
10186
  root.add(child);
10030
10187
  entry.geometry = geometry;
10031
10188
  entry.material = material;
10189
+ root.userData.entityId = entry.entityId;
10032
10190
  const existing = world.getComponent(entry.entityId, Object3DRef);
10033
10191
  if (existing) {
10192
+ existing.object.removeFromParent();
10034
10193
  existing.object = root;
10035
10194
  } else {
10036
10195
  world.addComponent(entry.entityId, new Object3DRef(root));
@@ -10046,19 +10205,31 @@ var _XREnvironmentSystem = class _XREnvironmentSystem {
10046
10205
  for (const [plane, entry] of this.planes) {
10047
10206
  if (entry.geometry) continue;
10048
10207
  const collider = planeColliderFromPolygon(plane.polygon);
10049
- if (collider) this.attachPlaneDebug(world, entry, collider);
10208
+ if (collider) {
10209
+ this.attachPlaneDebug(
10210
+ world,
10211
+ entry,
10212
+ collider,
10213
+ plane.semanticLabel ?? null
10214
+ );
10215
+ }
10050
10216
  }
10051
10217
  }
10052
10218
  for (const map of [this.planes, this.meshes]) {
10053
10219
  for (const entry of map.values()) {
10054
10220
  const ref = world.getComponent(entry.entityId, Object3DRef);
10055
10221
  ref?.object.traverse((child) => {
10056
- if (child.isMesh) child.visible = this.debugVisible;
10222
+ const drawable = child;
10223
+ if (drawable.isMesh || drawable.isLine) {
10224
+ child.visible = this.debugVisible;
10225
+ }
10057
10226
  });
10058
10227
  }
10059
10228
  }
10060
10229
  }
10061
10230
  destroyEntry(world, entry) {
10231
+ const ref = world.getComponent(entry.entityId, Object3DRef);
10232
+ ref?.object.removeFromParent();
10062
10233
  entry.geometry?.dispose();
10063
10234
  entry.material?.dispose();
10064
10235
  world.destroyEntity(entry.entityId);
@@ -10235,7 +10406,9 @@ var _XRAnchorSystem = class _XRAnchorSystem {
10235
10406
  continue;
10236
10407
  }
10237
10408
  const pose = frame.getPose(anchor.anchorSpace, referenceSpace);
10238
- if (pose) decomposeXrPose(pose.transform.matrix, transform);
10409
+ if (pose && pose.emulatedPosition !== true) {
10410
+ decomposeXrPose(pose.transform.matrix, transform);
10411
+ }
10239
10412
  }
10240
10413
  }
10241
10414
  /** Whether this entity's pose is currently being driven by an anchor. */