@relu-interactives/spatial-ecs 0.2.25 → 0.3.1

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.
Files changed (276) hide show
  1. package/dist/{System-CYWZ_Zx5.d.cts → System-vrU46Vuw.d.cts} +16 -2
  2. package/dist/{System-CYWZ_Zx5.d.ts → System-vrU46Vuw.d.ts} +16 -2
  3. package/dist/{Video-AIQYTAAr.d.cts → XRRig-CAmf04NX.d.ts} +131 -4
  4. package/dist/{Video-DlZ4G9ig.d.ts → XRRig-Cu-EyliG.d.cts} +131 -4
  5. package/dist/{chunk-XFD74BQL.js → chunk-67WGASUJ.js} +3 -3
  6. package/dist/{chunk-XFD74BQL.js.map → chunk-67WGASUJ.js.map} +1 -1
  7. package/dist/{chunk-RJ4J5UEX.js → chunk-PCOZLCXS.js} +160 -83
  8. package/dist/chunk-PCOZLCXS.js.map +1 -0
  9. package/dist/{chunk-J6736FFO.js → chunk-U3MDYKPV.js} +90 -14
  10. package/dist/chunk-U3MDYKPV.js.map +1 -0
  11. package/dist/{chunk-3P3ZBP7K.js → chunk-VXUVNC7S.js} +634 -6
  12. package/dist/chunk-VXUVNC7S.js.map +1 -0
  13. package/dist/components/index.cjs +87 -11
  14. package/dist/components/index.cjs.map +1 -1
  15. package/dist/components/index.d.cts +3 -3
  16. package/dist/components/index.d.ts +3 -3
  17. package/dist/components/index.js +1 -1
  18. package/dist/docs/api/Behaviour/classes/Behaviour.md +98 -51
  19. package/dist/docs/api/Component/classes/Component.md +4 -1
  20. package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
  21. package/dist/docs/api/components/classes/AudioComponent.md +19 -19
  22. package/dist/docs/api/components/classes/CameraComponent.md +14 -14
  23. package/dist/docs/api/components/classes/EntityType.md +4 -4
  24. package/dist/docs/api/components/classes/Environment.md +3 -3
  25. package/dist/docs/api/components/classes/ImageComponent.md +7 -7
  26. package/dist/docs/api/components/classes/ImageTarget.md +7 -7
  27. package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
  28. package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
  29. package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
  30. package/dist/docs/api/components/classes/LightComponent.md +6 -6
  31. package/dist/docs/api/components/classes/MaterialComponent.md +57 -11
  32. package/dist/docs/api/components/classes/MeshComponent.md +3 -3
  33. package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
  34. package/dist/docs/api/components/classes/ModelComponent.md +4 -4
  35. package/dist/docs/api/components/classes/Name.md +3 -3
  36. package/dist/docs/api/components/classes/Object3DRef.md +4 -4
  37. package/dist/docs/api/components/classes/ParentId.md +3 -3
  38. package/dist/docs/api/components/classes/PhysicsComponent.md +12 -13
  39. package/dist/docs/api/components/classes/Postprocessing.md +3 -3
  40. package/dist/docs/api/components/classes/PrefabInstance.md +80 -0
  41. package/dist/docs/api/components/classes/PrefabNode.md +54 -0
  42. package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
  43. package/dist/docs/api/components/classes/ScriptObjectComponent.md +55 -0
  44. package/dist/docs/api/components/classes/Selectable.md +3 -3
  45. package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
  46. package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
  47. package/dist/docs/api/components/classes/TransformComponent.md +12 -12
  48. package/dist/docs/api/components/classes/VideoComponent.md +28 -28
  49. package/dist/docs/api/components/functions/defaultMaterialValue.md +17 -0
  50. package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
  51. package/dist/docs/api/components/functions/setPhysicsLiveRef.md +34 -0
  52. package/dist/docs/api/components/index.md +8 -1
  53. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
  54. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
  55. package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
  56. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +1 -1
  57. package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
  58. package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
  59. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
  60. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
  61. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
  62. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
  63. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
  64. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +7 -7
  65. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
  66. package/dist/docs/api/components/type-aliases/EnvironmentState.md +5 -5
  67. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
  68. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
  69. package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
  70. package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
  71. package/dist/docs/api/components/type-aliases/LightValueState.md +11 -11
  72. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
  73. package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
  74. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
  75. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
  76. package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
  77. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
  78. package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
  79. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
  80. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
  81. package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
  82. package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
  83. package/dist/docs/api/components/type-aliases/ScriptEntry.md +8 -10
  84. package/dist/docs/api/components/type-aliases/ScriptObjectComponentInput.md +20 -0
  85. package/dist/docs/api/components/type-aliases/ScriptObjectRuntimeState.md +13 -0
  86. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
  87. package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
  88. package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
  89. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
  90. package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
  91. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
  92. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
  93. package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
  94. package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
  95. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
  96. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
  97. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
  98. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
  99. package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
  100. package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
  101. package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
  102. package/dist/docs/api/index/classes/AudioSystem.md +4 -4
  103. package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
  104. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +4 -4
  105. package/dist/docs/api/index/classes/InputSystem.md +33 -33
  106. package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
  107. package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
  108. package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
  109. package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
  110. package/dist/docs/api/index/classes/ObjectManagementSystem.md +14 -14
  111. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
  112. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
  113. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +4 -4
  114. package/dist/docs/api/index/classes/RenderSystem.md +3 -3
  115. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +5 -5
  116. package/dist/docs/api/index/classes/ScriptObject.md +156 -0
  117. package/dist/docs/api/index/classes/ScriptObjectSystem.md +129 -0
  118. package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
  119. package/dist/docs/api/index/classes/VideoSystem.md +4 -4
  120. package/dist/docs/api/index/classes/World.md +183 -86
  121. package/dist/docs/api/index/functions/applyPrefabToSnapshotInstances.md +32 -0
  122. package/dist/docs/api/index/functions/buildComponentValueMaps.md +23 -0
  123. package/dist/docs/api/index/functions/buildNodeKeyMapsFromSnapshot.md +25 -0
  124. package/dist/docs/api/index/functions/buildNodeMapsFromSnapshot.md +23 -0
  125. package/dist/docs/api/index/functions/canonicalizeComponentValue.md +38 -0
  126. package/dist/docs/api/index/functions/clearModelCache.md +26 -0
  127. package/dist/docs/api/index/functions/clearPrefabCache.md +25 -0
  128. package/dist/docs/api/index/functions/collectDiffPaths.md +38 -0
  129. package/dist/docs/api/index/functions/collectDirectPrefabDependencies.md +27 -0
  130. package/dist/docs/api/index/functions/collectEntitySubtree.md +29 -0
  131. package/dist/docs/api/index/functions/collectSnapshotSubtreeIds.md +26 -0
  132. package/dist/docs/api/index/functions/computeInstanceOverrides.md +44 -0
  133. package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
  134. package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
  135. package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
  136. package/dist/docs/api/index/functions/createEntityTypeComponent.md +2 -2
  137. package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
  138. package/dist/docs/api/index/functions/createImageComponent.md +1 -1
  139. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
  140. package/dist/docs/api/index/functions/createImageTargetComponent.md +1 -1
  141. package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
  142. package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
  143. package/dist/docs/api/index/functions/createLightComponent.md +1 -1
  144. package/dist/docs/api/index/functions/createMaterialComponent.md +1 -1
  145. package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
  146. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
  147. package/dist/docs/api/index/functions/createModelComponent.md +1 -1
  148. package/dist/docs/api/index/functions/createNameComponent.md +1 -1
  149. package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
  150. package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
  151. package/dist/docs/api/index/functions/createPhysicsComponent.md +2 -4
  152. package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
  153. package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
  154. package/dist/docs/api/index/functions/createScriptObjectComponent.md +28 -0
  155. package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
  156. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
  157. package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
  158. package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
  159. package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
  160. package/dist/docs/api/index/functions/decanonicalizeComponentValue.md +28 -0
  161. package/dist/docs/api/index/functions/despawnPrefab.md +32 -0
  162. package/dist/docs/api/index/functions/encodeOverride.md +28 -0
  163. package/dist/docs/api/index/functions/findSnapshotRootEntityIds.md +25 -0
  164. package/dist/docs/api/index/functions/findTopLevelNestedRegions.md +28 -0
  165. package/dist/docs/api/index/functions/groupOverridePaths.md +25 -0
  166. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
  167. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +4 -2
  168. package/dist/docs/api/index/functions/indexSnapshotByEntity.md +25 -0
  169. package/dist/docs/api/index/functions/instantiateSubtree.md +32 -0
  170. package/dist/docs/api/index/functions/loadPrefab.md +28 -0
  171. package/dist/docs/api/index/functions/loadSharedGltf.md +29 -0
  172. package/dist/docs/api/index/functions/mergeComponentValue.md +32 -0
  173. package/dist/docs/api/index/functions/parseOverride.md +34 -0
  174. package/dist/docs/api/index/functions/parsePrefabAsset.md +25 -0
  175. package/dist/docs/api/index/functions/prefabFileVersionFor.md +25 -0
  176. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
  177. package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
  178. package/dist/docs/api/index/functions/remapSnapshotEntityIds.md +46 -0
  179. package/dist/docs/api/index/functions/resolveDracoDecoderPath.md +17 -0
  180. package/dist/docs/api/index/functions/restoreComponentState.md +34 -0
  181. package/dist/docs/api/index/functions/restorePostCreateComponents.md +36 -0
  182. package/dist/docs/api/index/functions/serializeEntitySubtree.md +35 -0
  183. package/dist/docs/api/index/functions/setDracoDecoderPath.md +30 -0
  184. package/dist/docs/api/index/functions/setPrefabAssetUrlResolver.md +30 -0
  185. package/dist/docs/api/index/functions/spawnPrefab.md +36 -0
  186. package/dist/docs/api/index/index.md +65 -0
  187. package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
  188. package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
  189. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
  190. package/dist/docs/api/index/type-aliases/ApplyPrefabToSnapshotResult.md +23 -0
  191. package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
  192. package/dist/docs/api/index/type-aliases/ComponentValueMaps.md +69 -0
  193. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +2 -1
  194. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
  195. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
  196. package/dist/docs/api/index/type-aliases/ExternalRefWarning.md +27 -0
  197. package/dist/docs/api/index/type-aliases/HydrateOptions.md +27 -0
  198. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +7 -5
  199. package/dist/docs/api/index/type-aliases/InstantiateSubtreeResult.md +23 -0
  200. package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
  201. package/dist/docs/api/index/type-aliases/ModuleLoader.md +25 -0
  202. package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
  203. package/dist/docs/api/index/type-aliases/NestedRegion.md +27 -0
  204. package/dist/docs/api/index/type-aliases/NodeKeyMaps.md +30 -0
  205. package/dist/docs/api/index/type-aliases/NodeMaps.md +25 -0
  206. package/dist/docs/api/index/type-aliases/PrefabAsset.md +32 -0
  207. package/dist/docs/api/index/type-aliases/RemapSnapshotOptions.md +21 -0
  208. package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
  209. package/dist/docs/api/index/type-aliases/SerializeEntitySubtreeResult.md +25 -0
  210. package/dist/docs/api/index/type-aliases/SpawnPrefabOptions.md +27 -0
  211. package/dist/docs/api/index/type-aliases/SpawnPrefabSource.md +19 -0
  212. package/dist/docs/api/index/type-aliases/SubtreeSnapshot.md +43 -0
  213. package/dist/docs/api/index/variables/ADDED_NODE_MARKER_COMPONENT.md +19 -0
  214. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
  215. package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
  216. package/dist/docs/api/index/variables/NODE_KEY_SEPARATOR.md +13 -0
  217. package/dist/docs/api/index/variables/OVERRIDE_DIFF_EXCLUDED_COMPONENTS.md +15 -0
  218. package/dist/docs/api/index/variables/OVERRIDE_ROOT_EXCLUDED_COMPONENTS.md +16 -0
  219. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION.md +13 -0
  220. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION_NESTED.md +15 -0
  221. package/dist/docs/api/index/variables/SCRIPT_OBJECT_ROOT_FLAG.md +15 -0
  222. package/dist/docs/api/index/variables/SHARED_MODEL_RESOURCE_FLAG.md +17 -0
  223. package/dist/docs/api/typedoc-sidebar.json +1 -1
  224. package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
  225. package/dist/docs/api/types/type-aliases/CheckboxInput.md +3 -3
  226. package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
  227. package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
  228. package/dist/docs/api/types/type-aliases/ComponentKind.md +2 -1
  229. package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
  230. package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
  231. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
  232. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +3 -2
  233. package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
  234. package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
  235. package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
  236. package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
  237. package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
  238. package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
  239. package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
  240. package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
  241. package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
  242. package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
  243. package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
  244. package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
  245. package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
  246. package/dist/docs/guide/components/_sidebar.json +4 -0
  247. package/dist/docs/guide/components/material.md +1 -0
  248. package/dist/docs/guide/components/script-object.md +32 -0
  249. package/dist/factories/index.cjs +271 -118
  250. package/dist/factories/index.cjs.map +1 -1
  251. package/dist/factories/index.d.cts +9 -3
  252. package/dist/factories/index.d.ts +9 -3
  253. package/dist/factories/index.js +3 -3
  254. package/dist/{index-Gr8aCPRM.d.cts → index-CUFd71ri.d.cts} +12 -3
  255. package/dist/index-D84o_UA6.d.ts +488 -0
  256. package/dist/index-YYypJaVw.d.cts +488 -0
  257. package/dist/{index-BwiRJNIT.d.ts → index-w1oqWl_M.d.ts} +12 -3
  258. package/dist/index.cjs +1014 -208
  259. package/dist/index.cjs.map +1 -1
  260. package/dist/index.d.cts +42 -8
  261. package/dist/index.d.ts +42 -8
  262. package/dist/index.js +24 -8
  263. package/dist/index.js.map +1 -1
  264. package/dist/systems/index.cjs +717 -12
  265. package/dist/systems/index.cjs.map +1 -1
  266. package/dist/systems/index.d.cts +3 -278
  267. package/dist/systems/index.d.ts +3 -278
  268. package/dist/systems/index.js +3 -3
  269. package/dist/types.d.cts +1 -1
  270. package/dist/types.d.ts +1 -1
  271. package/dist/worldSnapshotUtils.d.cts +1 -1
  272. package/dist/worldSnapshotUtils.d.ts +1 -1
  273. package/package.json +4 -4
  274. package/dist/chunk-3P3ZBP7K.js.map +0 -1
  275. package/dist/chunk-J6736FFO.js.map +0 -1
  276. package/dist/chunk-RJ4J5UEX.js.map +0 -1
@@ -1719,6 +1719,22 @@ function getMaterialType(material) {
1719
1719
  return "standard";
1720
1720
  }
1721
1721
  __name(getMaterialType, "getMaterialType");
1722
+ function textureImageSrc(texture) {
1723
+ const src = texture?.image?.src;
1724
+ return typeof src === "string" ? src : void 0;
1725
+ }
1726
+ __name(textureImageSrc, "textureImageSrc");
1727
+ function textureSourceUrl(texture) {
1728
+ if (!texture?.image) {
1729
+ return void 0;
1730
+ }
1731
+ const currentSrc = texture.source?.data?.currentSrc;
1732
+ if (typeof currentSrc === "string" && currentSrc) {
1733
+ return currentSrc;
1734
+ }
1735
+ return textureImageSrc(texture);
1736
+ }
1737
+ __name(textureSourceUrl, "textureSourceUrl");
1722
1738
  function createMaterialValue(material) {
1723
1739
  const materialRecord = material;
1724
1740
  const normalScale = materialRecord.normalScale;
@@ -1738,17 +1754,33 @@ function createMaterialValue(material) {
1738
1754
  depthWrite: materialRecord.depthWrite !== false,
1739
1755
  wireframe: Boolean(materialRecord.wireframe),
1740
1756
  transparent: Boolean(materialRecord.transparent),
1741
- textureMap: map?.image ? map.source?.data?.currentSrc || map.image?.src : void 0,
1742
- alphaTextureMap: materialRecord.alphaMap?.image?.src,
1743
- normalMap: materialRecord.normalMap?.image?.src,
1744
- roughnessMap: materialRecord.roughnessMap?.image?.src,
1745
- metalnessMap: materialRecord.metalnessMap?.image?.src,
1746
- aoMap: materialRecord.aoMap?.image?.src,
1747
- emissiveMap: materialRecord.emissiveMap?.image?.src,
1748
- bumpMap: materialRecord.bumpMap?.image?.src,
1749
- displacementMap: materialRecord.displacementMap?.image?.src,
1750
- lightMap: materialRecord.lightMap?.image?.src,
1751
- envMap: materialRecord.envMap?.image?.src,
1757
+ textureMap: textureSourceUrl(map),
1758
+ alphaTextureMap: textureImageSrc(
1759
+ materialRecord.alphaMap
1760
+ ),
1761
+ normalMap: textureImageSrc(
1762
+ materialRecord.normalMap
1763
+ ),
1764
+ roughnessMap: textureImageSrc(
1765
+ materialRecord.roughnessMap
1766
+ ),
1767
+ metalnessMap: textureImageSrc(
1768
+ materialRecord.metalnessMap
1769
+ ),
1770
+ aoMap: textureImageSrc(materialRecord.aoMap),
1771
+ emissiveMap: textureImageSrc(
1772
+ materialRecord.emissiveMap
1773
+ ),
1774
+ bumpMap: textureImageSrc(
1775
+ materialRecord.bumpMap
1776
+ ),
1777
+ displacementMap: textureImageSrc(
1778
+ materialRecord.displacementMap
1779
+ ),
1780
+ lightMap: textureImageSrc(
1781
+ materialRecord.lightMap
1782
+ ),
1783
+ envMap: textureImageSrc(materialRecord.envMap),
1752
1784
  textureFiltering: map?.magFilter === THREE14__namespace.NearestFilter ? "sharp" : "smooth",
1753
1785
  useMipmaps: map?.generateMipmaps !== false
1754
1786
  };
@@ -2043,6 +2075,47 @@ var _VideoComponent = class _VideoComponent extends Component {
2043
2075
  __name(_VideoComponent, "VideoComponent");
2044
2076
  var VideoComponent = _VideoComponent;
2045
2077
 
2078
+ // core/components/VRTeleportArea.ts
2079
+ var _VRTeleportAreaComponent = class _VRTeleportAreaComponent extends Component {
2080
+ constructor(options) {
2081
+ super();
2082
+ this.enabled = options?.enabled ?? true;
2083
+ this.shape = options?.shape ?? "plane";
2084
+ this.width = options?.width ?? 10;
2085
+ this.depth = options?.depth ?? 10;
2086
+ }
2087
+ };
2088
+ __name(_VRTeleportAreaComponent, "VRTeleportAreaComponent");
2089
+ var VRTeleportAreaComponent = _VRTeleportAreaComponent;
2090
+
2091
+ // core/components/XRInteractable.ts
2092
+ var _XRInteractableComponent = class _XRInteractableComponent extends Component {
2093
+ constructor(options) {
2094
+ super();
2095
+ this.enabled = options?.enabled ?? true;
2096
+ this.grabbable = options?.grabbable ?? true;
2097
+ this.pointable = options?.pointable ?? true;
2098
+ this.grabMode = options?.grabMode ?? "kinematic";
2099
+ this.highlightOnHover = options?.highlightOnHover ?? true;
2100
+ }
2101
+ };
2102
+ __name(_XRInteractableComponent, "XRInteractableComponent");
2103
+ var XRInteractableComponent = _XRInteractableComponent;
2104
+
2105
+ // core/components/XRRig.ts
2106
+ var _XRRigComponent = class _XRRigComponent extends Component {
2107
+ constructor(options) {
2108
+ super();
2109
+ this.locomotion = options?.locomotion ?? "teleport";
2110
+ this.moveSpeed = options?.moveSpeed ?? 2;
2111
+ this.snapTurn = options?.snapTurn ?? true;
2112
+ this.snapTurnDegrees = options?.snapTurnDegrees ?? 30;
2113
+ this.fallbackEyeHeight = options?.fallbackEyeHeight ?? 1.6;
2114
+ }
2115
+ };
2116
+ __name(_XRRigComponent, "XRRigComponent");
2117
+ var XRRigComponent = _XRRigComponent;
2118
+
2046
2119
  // core/utils/dracoDecoderPath.ts
2047
2120
  var LOCAL_DRACO_DECODER_RELATIVE_PATH = "./assets/draco/";
2048
2121
  var DRACO_DECODER_CDN_PATH = "https://www.gstatic.com/draco/versioned/decoders/1.5.7/";
@@ -2549,6 +2622,7 @@ var _CameraSyncSystem = class _CameraSyncSystem {
2549
2622
  update(world) {
2550
2623
  const entityIds = world.query(CameraComponent, Object3DRef);
2551
2624
  const windowAspect = readWindowAspect();
2625
+ const xrCamera = world.isXrPresenting() ? world.getCamera() : null;
2552
2626
  const alive = new Set(entityIds);
2553
2627
  for (const trackedId of this.signatures.keys()) {
2554
2628
  if (!alive.has(trackedId)) {
@@ -2565,6 +2639,9 @@ var _CameraSyncSystem = class _CameraSyncSystem {
2565
2639
  if (!(camera instanceof THREE14__namespace.Camera)) {
2566
2640
  continue;
2567
2641
  }
2642
+ if (xrCamera !== null && camera === xrCamera) {
2643
+ continue;
2644
+ }
2568
2645
  const nextSignature = buildSignature(component, camera, windowAspect);
2569
2646
  if (this.signatures.get(entityId) === nextSignature) {
2570
2647
  continue;
@@ -4067,6 +4144,7 @@ function applyMaterialState(material, value, textureCache) {
4067
4144
  }
4068
4145
  target.side = value.side;
4069
4146
  target.blending = value.blending;
4147
+ target.premultipliedAlpha = value.blending === THREE14__namespace.MultiplyBlending || value.blending === THREE14__namespace.SubtractiveBlending;
4070
4148
  target.depthTest = value.depthTest;
4071
4149
  target.depthWrite = value.depthWrite;
4072
4150
  target.wireframe = value.wireframe;
@@ -5535,7 +5613,9 @@ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
5535
5613
  "areaLight",
5536
5614
  "instancedMesh",
5537
5615
  "instanceSlot",
5538
- "scriptObject"
5616
+ "scriptObject",
5617
+ "xrRig",
5618
+ "teleportArea"
5539
5619
  ]);
5540
5620
 
5541
5621
  // core/hydration/hydrateWorld.ts
@@ -6239,6 +6319,49 @@ var _Behaviour = class _Behaviour {
6239
6319
  */
6240
6320
  onTargetLost(target) {
6241
6321
  }
6322
+ // ─── WebXR (VR / MR) hooks ────────────────────────────────────────────────
6323
+ // Dispatched by XRSessionSystem / XRInteractionSystem, following the same
6324
+ // pattern as the AR hooks above: public no-op methods that subclasses opt
6325
+ // into by overriding. They never fire outside an immersive session.
6326
+ /**
6327
+ * Called once when an immersive session starts. Optional XR hook.
6328
+ *
6329
+ * Use it to set up XR-only state. Inspect `capabilities` rather than guessing
6330
+ * by device: feature support differs sharply per headset (for example Vision
6331
+ * Pro grants no passthrough on the web today).
6332
+ *
6333
+ * @param capabilities - What the session actually granted, read from
6334
+ * `XRSession.enabledFeatures`.
6335
+ */
6336
+ onXRSessionStart(capabilities) {
6337
+ }
6338
+ /** Called once when the immersive session ends. Optional XR hook. */
6339
+ onXRSessionEnd() {
6340
+ }
6341
+ /**
6342
+ * Called when a primary action begins — controller trigger, hand pinch, or
6343
+ * Vision Pro gaze-pinch. Optional XR hook.
6344
+ *
6345
+ * @param input - Normalized state for the source that acted.
6346
+ */
6347
+ onSelectStart(input) {
6348
+ }
6349
+ /** Called when the primary action ends. Optional XR hook. */
6350
+ onSelectEnd(input) {
6351
+ }
6352
+ /**
6353
+ * Called when this entity is grabbed. Optional XR hook.
6354
+ *
6355
+ * Only fires for entities carrying an enabled, grabbable
6356
+ * `XRInteractableComponent`.
6357
+ *
6358
+ * @param input - The source doing the grabbing.
6359
+ */
6360
+ onGrab(input) {
6361
+ }
6362
+ /** Called when this entity is released. Optional XR hook. */
6363
+ onRelease(input) {
6364
+ }
6242
6365
  };
6243
6366
  __name(_Behaviour, "Behaviour");
6244
6367
  /**
@@ -7086,12 +7209,16 @@ var ScriptObjectSystem = _ScriptObjectSystem;
7086
7209
  var _TransformSyncSystem = class _TransformSyncSystem {
7087
7210
  update(world) {
7088
7211
  const entities = world.query(TransformComponent, Object3DRef);
7212
+ const xrCamera = world.isXrPresenting() ? world.getCamera() : null;
7089
7213
  for (const entityId of entities) {
7090
7214
  const transform = world.getComponent(entityId, TransformComponent);
7091
7215
  const object = world.getComponent(entityId, Object3DRef)?.object;
7092
7216
  if (!transform || !object) {
7093
7217
  continue;
7094
7218
  }
7219
+ if (xrCamera !== null && object === xrCamera) {
7220
+ continue;
7221
+ }
7095
7222
  applyTransform(object, transform);
7096
7223
  object.updateMatrixWorld(true);
7097
7224
  }
@@ -7342,6 +7469,580 @@ var _VideoSystem = class _VideoSystem {
7342
7469
  };
7343
7470
  __name(_VideoSystem, "VideoSystem");
7344
7471
  var VideoSystem = _VideoSystem;
7472
+ function handednessOf(source) {
7473
+ const value = source.handedness;
7474
+ return value === "left" || value === "right" ? value : "none";
7475
+ }
7476
+ __name(handednessOf, "handednessOf");
7477
+ function kindOf(source) {
7478
+ const mode = source.targetRayMode;
7479
+ if (mode === "transient-pointer") return "transient-pointer";
7480
+ if (mode === "gaze") return "gaze";
7481
+ if (source.hand) return "hand";
7482
+ return "controller";
7483
+ }
7484
+ __name(kindOf, "kindOf");
7485
+ function blankState(source) {
7486
+ return {
7487
+ handedness: handednessOf(source),
7488
+ kind: kindOf(source),
7489
+ connected: true,
7490
+ rayOrigin: new THREE14__namespace.Vector3(),
7491
+ rayDirection: new THREE14__namespace.Vector3(0, 0, -1),
7492
+ gripPosition: null,
7493
+ gripQuaternion: null,
7494
+ select: false,
7495
+ selectStart: false,
7496
+ selectEnd: false,
7497
+ squeeze: false,
7498
+ squeezeStart: false,
7499
+ squeezeEnd: false,
7500
+ axes: [],
7501
+ hasAxes: false,
7502
+ buttons: []
7503
+ };
7504
+ }
7505
+ __name(blankState, "blankState");
7506
+ var _XRInputSystem = class _XRInputSystem {
7507
+ constructor() {
7508
+ this.records = /* @__PURE__ */ new Map();
7509
+ this.session = null;
7510
+ this.onSelectStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectStart"), "onSelectStart");
7511
+ this.onSelectEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSelectEnd"), "onSelectEnd");
7512
+ this.onSqueezeStart = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSqueezeStart"), "onSqueezeStart");
7513
+ this.onSqueezeEnd = /* @__PURE__ */ __name((event) => this.mark(event, "pendingSqueezeEnd"), "onSqueezeEnd");
7514
+ }
7515
+ mark(event, flag) {
7516
+ const record = this.ensureRecord(event.inputSource);
7517
+ record[flag] = true;
7518
+ }
7519
+ ensureRecord(source) {
7520
+ let record = this.records.get(source);
7521
+ if (!record) {
7522
+ record = {
7523
+ source,
7524
+ state: blankState(source),
7525
+ pendingSelectStart: false,
7526
+ pendingSelectEnd: false,
7527
+ pendingSqueezeStart: false,
7528
+ pendingSqueezeEnd: false,
7529
+ removed: false
7530
+ };
7531
+ this.records.set(source, record);
7532
+ }
7533
+ return record;
7534
+ }
7535
+ /** Bind to a session. Called by {@link XRSessionSystem} on session start. */
7536
+ attachSession(session) {
7537
+ this.detachSession();
7538
+ this.session = session;
7539
+ session.addEventListener("selectstart", this.onSelectStart);
7540
+ session.addEventListener("selectend", this.onSelectEnd);
7541
+ session.addEventListener(
7542
+ "squeezestart",
7543
+ this.onSqueezeStart
7544
+ );
7545
+ session.addEventListener("squeezeend", this.onSqueezeEnd);
7546
+ }
7547
+ /** Unbind and drop all per-source state. */
7548
+ detachSession() {
7549
+ const session = this.session;
7550
+ if (session) {
7551
+ session.removeEventListener(
7552
+ "selectstart",
7553
+ this.onSelectStart
7554
+ );
7555
+ session.removeEventListener(
7556
+ "selectend",
7557
+ this.onSelectEnd
7558
+ );
7559
+ session.removeEventListener(
7560
+ "squeezestart",
7561
+ this.onSqueezeStart
7562
+ );
7563
+ session.removeEventListener(
7564
+ "squeezeend",
7565
+ this.onSqueezeEnd
7566
+ );
7567
+ }
7568
+ this.session = null;
7569
+ this.records.clear();
7570
+ }
7571
+ update(world) {
7572
+ for (const [source, record] of this.records) {
7573
+ if (record.removed) {
7574
+ this.records.delete(source);
7575
+ continue;
7576
+ }
7577
+ record.state.selectStart = false;
7578
+ record.state.selectEnd = false;
7579
+ record.state.squeezeStart = false;
7580
+ record.state.squeezeEnd = false;
7581
+ }
7582
+ const session = this.session;
7583
+ if (!session || !world.isXrPresenting()) return;
7584
+ const renderer = world.getRenderer();
7585
+ const referenceSpace = renderer.xr.getReferenceSpace();
7586
+ const frame = renderer.xr.getFrame?.();
7587
+ const live = /* @__PURE__ */ new Set();
7588
+ for (const source of session.inputSources) {
7589
+ live.add(source);
7590
+ const record = this.ensureRecord(source);
7591
+ const state = record.state;
7592
+ state.connected = true;
7593
+ state.handedness = handednessOf(source);
7594
+ state.kind = kindOf(source);
7595
+ if (frame && referenceSpace && source.targetRaySpace) {
7596
+ const pose = frame.getPose(source.targetRaySpace, referenceSpace);
7597
+ if (pose) {
7598
+ const m = new THREE14__namespace.Matrix4().fromArray(pose.transform.matrix);
7599
+ state.rayOrigin.setFromMatrixPosition(m);
7600
+ state.rayDirection.set(0, 0, -1).applyQuaternion(
7601
+ new THREE14__namespace.Quaternion().setFromRotationMatrix(m)
7602
+ ).normalize();
7603
+ }
7604
+ }
7605
+ if (frame && referenceSpace && source.gripSpace) {
7606
+ const gripPose = frame.getPose(source.gripSpace, referenceSpace);
7607
+ if (gripPose) {
7608
+ const m = new THREE14__namespace.Matrix4().fromArray(gripPose.transform.matrix);
7609
+ state.gripPosition ?? (state.gripPosition = new THREE14__namespace.Vector3());
7610
+ state.gripQuaternion ?? (state.gripQuaternion = new THREE14__namespace.Quaternion());
7611
+ state.gripPosition.setFromMatrixPosition(m);
7612
+ state.gripQuaternion.setFromRotationMatrix(m);
7613
+ }
7614
+ } else {
7615
+ state.gripPosition = null;
7616
+ state.gripQuaternion = null;
7617
+ }
7618
+ const gamepad = source.gamepad;
7619
+ if (gamepad) {
7620
+ state.axes = Array.from(gamepad.axes);
7621
+ state.hasAxes = gamepad.axes.some((axis) => Number.isFinite(axis));
7622
+ state.buttons = gamepad.buttons.map((button) => button.pressed);
7623
+ } else {
7624
+ state.axes = [];
7625
+ state.hasAxes = false;
7626
+ state.buttons = [];
7627
+ }
7628
+ if (record.pendingSelectStart) {
7629
+ state.select = true;
7630
+ state.selectStart = true;
7631
+ record.pendingSelectStart = false;
7632
+ }
7633
+ if (record.pendingSelectEnd) {
7634
+ state.select = false;
7635
+ state.selectEnd = true;
7636
+ record.pendingSelectEnd = false;
7637
+ }
7638
+ if (record.pendingSqueezeStart) {
7639
+ state.squeeze = true;
7640
+ state.squeezeStart = true;
7641
+ record.pendingSqueezeStart = false;
7642
+ }
7643
+ if (record.pendingSqueezeEnd) {
7644
+ state.squeeze = false;
7645
+ state.squeezeEnd = true;
7646
+ record.pendingSqueezeEnd = false;
7647
+ }
7648
+ }
7649
+ for (const [source, record] of this.records) {
7650
+ if (live.has(source)) continue;
7651
+ record.state.connected = false;
7652
+ record.removed = true;
7653
+ }
7654
+ }
7655
+ /** Every input source active this frame. */
7656
+ getInputs() {
7657
+ return Array.from(this.records.values(), (record) => record.state);
7658
+ }
7659
+ /** The first source for a hand, or null. Prefer this for hand-specific logic. */
7660
+ getInput(handedness) {
7661
+ for (const record of this.records.values()) {
7662
+ if (record.state.handedness === handedness) return record.state;
7663
+ }
7664
+ return null;
7665
+ }
7666
+ /** True while ANY source is selecting — the portable "is the user acting" check. */
7667
+ isSelecting() {
7668
+ for (const record of this.records.values()) {
7669
+ if (record.state.select) return true;
7670
+ }
7671
+ return false;
7672
+ }
7673
+ dispose() {
7674
+ this.detachSession();
7675
+ }
7676
+ };
7677
+ __name(_XRInputSystem, "XRInputSystem");
7678
+ var XRInputSystem = _XRInputSystem;
7679
+ var RAYLESS_HOLD_DISTANCE = 0.5;
7680
+ var _XRInteractionSystem = class _XRInteractionSystem {
7681
+ constructor(inputSystem) {
7682
+ this.raycaster = new THREE14__namespace.Raycaster();
7683
+ /** Which entity each source is holding. Keyed by source state identity. */
7684
+ this.grabs = /* @__PURE__ */ new Map();
7685
+ this.hoveredEntityId = null;
7686
+ this.inputSystem = inputSystem;
7687
+ }
7688
+ update(world) {
7689
+ if (!world.isXrPresenting()) {
7690
+ this.releaseAll(world);
7691
+ return;
7692
+ }
7693
+ const inputs = this.inputSystem.getInputs();
7694
+ const interactables = this.collectInteractables(world);
7695
+ this.hoveredEntityId = null;
7696
+ for (const input of inputs) {
7697
+ if (!input.connected) {
7698
+ this.release(world, input);
7699
+ continue;
7700
+ }
7701
+ const held = this.grabs.get(input);
7702
+ if (held) {
7703
+ this.moveHeld(world, input, held);
7704
+ if (input.selectEnd) this.release(world, input);
7705
+ continue;
7706
+ }
7707
+ const hitEntityId = this.raycast(input, interactables);
7708
+ if (hitEntityId === null) continue;
7709
+ if (this.hoveredEntityId === null) {
7710
+ this.hoveredEntityId = hitEntityId;
7711
+ }
7712
+ const interactable = world.getComponent(
7713
+ hitEntityId,
7714
+ XRInteractableComponent
7715
+ );
7716
+ if (input.selectStart && interactable?.grabbable) {
7717
+ this.grab(world, input, hitEntityId);
7718
+ }
7719
+ }
7720
+ }
7721
+ collectInteractables(world) {
7722
+ const out = [];
7723
+ for (const entityId of world.query(XRInteractableComponent, Object3DRef)) {
7724
+ const interactable = world.getComponent(entityId, XRInteractableComponent);
7725
+ if (!interactable?.enabled || !interactable.pointable) continue;
7726
+ if (!world.isEntityVisible(entityId)) continue;
7727
+ const object = world.getComponent(entityId, Object3DRef)?.object;
7728
+ if (object) out.push({ entityId, object });
7729
+ }
7730
+ return out;
7731
+ }
7732
+ /** Entity id of the nearest pointable hit along this source's ray, or null. */
7733
+ raycast(input, interactables) {
7734
+ if (interactables.length === 0) return null;
7735
+ this.raycaster.set(input.rayOrigin, input.rayDirection);
7736
+ let nearestId = null;
7737
+ let nearestDistance = Number.POSITIVE_INFINITY;
7738
+ for (const entry of interactables) {
7739
+ const hit = this.raycaster.intersectObject(entry.object, true)[0];
7740
+ if (!hit) continue;
7741
+ if (hit.distance < nearestDistance) {
7742
+ nearestDistance = hit.distance;
7743
+ nearestId = entry.entityId;
7744
+ }
7745
+ }
7746
+ return nearestId;
7747
+ }
7748
+ grab(world, input, entityId) {
7749
+ const transform = world.getComponent(entityId, TransformComponent);
7750
+ if (!transform) return;
7751
+ const hand = this.handPosition(input);
7752
+ const offset = new THREE14__namespace.Vector3(
7753
+ transform.position.x - hand.x,
7754
+ transform.position.y - hand.y,
7755
+ transform.position.z - hand.z
7756
+ );
7757
+ const physics = world.getComponent(entityId, PhysicsComponent);
7758
+ let restoreBodyType = null;
7759
+ const interactable = world.getComponent(entityId, XRInteractableComponent);
7760
+ if (physics && interactable?.grabMode === "kinematic") {
7761
+ restoreBodyType = physics.values.rigidbody.type;
7762
+ physics.values.rigidbody.type = "kinematicPosition";
7763
+ }
7764
+ this.grabs.set(input, { entityId, offset, restoreBodyType });
7765
+ this.dispatch(world, entityId, (b) => b.onGrab(input));
7766
+ }
7767
+ moveHeld(world, input, held) {
7768
+ const transform = world.getComponent(held.entityId, TransformComponent);
7769
+ if (!transform) return;
7770
+ const hand = this.handPosition(input);
7771
+ transform.position.x = hand.x + held.offset.x;
7772
+ transform.position.y = hand.y + held.offset.y;
7773
+ transform.position.z = hand.z + held.offset.z;
7774
+ }
7775
+ release(world, input) {
7776
+ const held = this.grabs.get(input);
7777
+ if (!held) return;
7778
+ this.grabs.delete(input);
7779
+ if (held.restoreBodyType !== null) {
7780
+ const physics = world.getComponent(held.entityId, PhysicsComponent);
7781
+ if (physics) {
7782
+ physics.values.rigidbody.type = held.restoreBodyType;
7783
+ }
7784
+ }
7785
+ this.dispatch(world, held.entityId, (b) => b.onRelease(input));
7786
+ }
7787
+ releaseAll(world) {
7788
+ for (const input of Array.from(this.grabs.keys())) {
7789
+ this.release(world, input);
7790
+ }
7791
+ }
7792
+ /**
7793
+ * Where the "hand" is for this source. Controllers and tracked hands report a
7794
+ * grip pose; gaze and transient-pointer sources have none, so we hold the
7795
+ * object a fixed distance along the ray instead.
7796
+ */
7797
+ handPosition(input) {
7798
+ if (input.gripPosition) return input.gripPosition;
7799
+ return new THREE14__namespace.Vector3().copy(input.rayDirection).multiplyScalar(RAYLESS_HOLD_DISTANCE).add(input.rayOrigin);
7800
+ }
7801
+ dispatch(world, entityId, visit) {
7802
+ const script = world.getComponent(entityId, ScriptComponent);
7803
+ const instances = script?.scriptInstances;
7804
+ if (!instances) return;
7805
+ for (const instance of instances.values()) {
7806
+ if (!(instance instanceof Behaviour)) continue;
7807
+ try {
7808
+ visit(instance);
7809
+ } catch (error) {
7810
+ console.error("[XRInteractionSystem] Behaviour hook failed:", error);
7811
+ }
7812
+ }
7813
+ }
7814
+ /** Entity currently under a pointer this frame, or null. */
7815
+ getHoveredEntityId() {
7816
+ return this.hoveredEntityId;
7817
+ }
7818
+ /** True when any source is holding something. */
7819
+ isGrabbing() {
7820
+ return this.grabs.size > 0;
7821
+ }
7822
+ };
7823
+ __name(_XRInteractionSystem, "XRInteractionSystem");
7824
+ var XRInteractionSystem = _XRInteractionSystem;
7825
+ var UP = new THREE14__namespace.Vector3(0, 1, 0);
7826
+ var AXIS_DEADZONE = 0.5;
7827
+ var _XRLocomotionSystem = class _XRLocomotionSystem {
7828
+ constructor(inputSystem) {
7829
+ this.raycaster = new THREE14__namespace.Raycaster();
7830
+ /** Per-source latch so one stick push yields exactly one snap turn. */
7831
+ this.turnLatched = /* @__PURE__ */ new WeakSet();
7832
+ /** Where the pointer currently lands, for the consumer to draw a marker. */
7833
+ this.teleportPoint = null;
7834
+ this.inputSystem = inputSystem;
7835
+ }
7836
+ update(world, deltaTime) {
7837
+ this.teleportPoint = null;
7838
+ if (!world.isXrPresenting()) return;
7839
+ const rigEntityId = world.query(XRRigComponent, TransformComponent)[0];
7840
+ if (typeof rigEntityId !== "number") return;
7841
+ const rig = world.getComponent(rigEntityId, XRRigComponent);
7842
+ const rigTransform = world.getComponent(rigEntityId, TransformComponent);
7843
+ if (!rig || !rigTransform) return;
7844
+ const inputs = this.inputSystem.getInputs();
7845
+ if (inputs.length === 0) return;
7846
+ if (rig.snapTurn) {
7847
+ this.applySnapTurn(rig, rigTransform, inputs);
7848
+ }
7849
+ if (rig.locomotion === "teleport") {
7850
+ this.applyTeleport(world, rigTransform, inputs);
7851
+ } else if (rig.locomotion === "smooth") {
7852
+ this.applySmoothMove(world, rig, rigTransform, inputs, deltaTime);
7853
+ }
7854
+ }
7855
+ /**
7856
+ * Snap turning, not smooth turning — rotating the view continuously is the
7857
+ * single biggest cause of VR nausea, so the comfort-safe option is the one
7858
+ * wired to the stick.
7859
+ */
7860
+ applySnapTurn(rig, transform, inputs) {
7861
+ for (const input of inputs) {
7862
+ if (!input.hasAxes || input.axes.length < 3) continue;
7863
+ const x = input.axes[2] ?? 0;
7864
+ const source = input;
7865
+ if (Math.abs(x) < AXIS_DEADZONE) {
7866
+ this.turnLatched.delete(source);
7867
+ continue;
7868
+ }
7869
+ if (this.turnLatched.has(source)) continue;
7870
+ this.turnLatched.add(source);
7871
+ const step = THREE14__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
7872
+ transform.rotation.y -= Math.sign(x) * step;
7873
+ }
7874
+ }
7875
+ applySmoothMove(world, rig, transform, inputs, deltaTime) {
7876
+ for (const input of inputs) {
7877
+ if (!input.hasAxes || input.axes.length < 2) continue;
7878
+ const x = input.axes[0] ?? 0;
7879
+ const y = input.axes[1] ?? 0;
7880
+ if (Math.abs(x) < 0.15 && Math.abs(y) < 0.15) continue;
7881
+ const camera = world.getCamera();
7882
+ const forward = new THREE14__namespace.Vector3();
7883
+ camera.getWorldDirection(forward);
7884
+ forward.y = 0;
7885
+ if (forward.lengthSq() < 1e-6) continue;
7886
+ forward.normalize();
7887
+ const right = new THREE14__namespace.Vector3().crossVectors(forward, UP).normalize();
7888
+ const step = rig.moveSpeed * Math.max(0, deltaTime);
7889
+ transform.position.x += (forward.x * -y + right.x * x) * step;
7890
+ transform.position.z += (forward.z * -y + right.z * x) * step;
7891
+ }
7892
+ }
7893
+ applyTeleport(world, transform, inputs) {
7894
+ const targets = this.collectTeleportTargets(world);
7895
+ if (targets.length === 0) return;
7896
+ for (const input of inputs) {
7897
+ this.raycaster.set(input.rayOrigin, input.rayDirection);
7898
+ const hit = this.raycaster.intersectObjects(targets, true)[0];
7899
+ if (!hit) continue;
7900
+ this.teleportPoint = hit.point.clone();
7901
+ if (input.selectEnd) {
7902
+ transform.position.x = hit.point.x;
7903
+ transform.position.y = hit.point.y;
7904
+ transform.position.z = hit.point.z;
7905
+ }
7906
+ }
7907
+ }
7908
+ collectTeleportTargets(world) {
7909
+ const objects = [];
7910
+ for (const entityId of world.query(VRTeleportAreaComponent, Object3DRef)) {
7911
+ const area = world.getComponent(entityId, VRTeleportAreaComponent);
7912
+ if (!area?.enabled) continue;
7913
+ if (!world.isEntityVisible(entityId)) continue;
7914
+ const object = world.getComponent(entityId, Object3DRef)?.object;
7915
+ if (object) objects.push(object);
7916
+ }
7917
+ return objects;
7918
+ }
7919
+ /**
7920
+ * Where the teleport pointer currently lands this frame, or null.
7921
+ * Consumers use this to render an aim marker.
7922
+ */
7923
+ getTeleportPoint() {
7924
+ return this.teleportPoint;
7925
+ }
7926
+ };
7927
+ __name(_XRLocomotionSystem, "XRLocomotionSystem");
7928
+ var XRLocomotionSystem = _XRLocomotionSystem;
7929
+
7930
+ // core/xr/types.ts
7931
+ var NO_XR_CAPABILITIES = {
7932
+ mode: "inline",
7933
+ handTracking: false,
7934
+ planeDetection: false,
7935
+ meshDetection: false,
7936
+ depthSensing: false,
7937
+ anchors: false,
7938
+ hitTest: false,
7939
+ enabledFeatures: []
7940
+ };
7941
+ function readXrCapabilities(session, mode = "immersive-vr") {
7942
+ if (!session) return NO_XR_CAPABILITIES;
7943
+ const raw = session.enabledFeatures;
7944
+ const features = Array.isArray(raw) ? Array.from(raw) : [];
7945
+ const has = /* @__PURE__ */ __name((name) => features.includes(name), "has");
7946
+ return {
7947
+ mode,
7948
+ handTracking: has("hand-tracking"),
7949
+ planeDetection: has("plane-detection"),
7950
+ meshDetection: has("mesh-detection"),
7951
+ depthSensing: has("depth-sensing"),
7952
+ anchors: has("anchors"),
7953
+ hitTest: has("hit-test"),
7954
+ enabledFeatures: features
7955
+ };
7956
+ }
7957
+ __name(readXrCapabilities, "readXrCapabilities");
7958
+
7959
+ // core/systems/XRSessionSystem.ts
7960
+ var _XRSessionSystem = class _XRSessionSystem {
7961
+ constructor(inputSystem) {
7962
+ this.presenting = false;
7963
+ this.capabilities = NO_XR_CAPABILITIES;
7964
+ this.inputSystem = inputSystem ?? null;
7965
+ }
7966
+ update(world) {
7967
+ const presenting = world.isXrPresenting();
7968
+ if (presenting !== this.presenting) {
7969
+ this.presenting = presenting;
7970
+ if (presenting) {
7971
+ this.handleSessionStart(world);
7972
+ } else {
7973
+ this.handleSessionEnd(world);
7974
+ }
7975
+ }
7976
+ if (presenting) {
7977
+ this.dispatchInputEdges(world);
7978
+ }
7979
+ }
7980
+ handleSessionStart(world) {
7981
+ const session = world.getRenderer().xr.getSession();
7982
+ const mode = session && session.environmentBlendMode !== "opaque" ? "immersive-ar" : "immersive-vr";
7983
+ this.capabilities = readXrCapabilities(session ?? null, mode);
7984
+ if (session && this.inputSystem) {
7985
+ this.inputSystem.attachSession(session);
7986
+ }
7987
+ this.forEachBehaviour(world, (behaviour) => {
7988
+ behaviour.onXRSessionStart(this.capabilities);
7989
+ });
7990
+ }
7991
+ handleSessionEnd(world) {
7992
+ this.capabilities = NO_XR_CAPABILITIES;
7993
+ this.inputSystem?.detachSession();
7994
+ this.forEachBehaviour(world, (behaviour) => {
7995
+ behaviour.onXRSessionEnd();
7996
+ });
7997
+ }
7998
+ /**
7999
+ * Relay this frame's one-frame select edges. Polling the latched state (rather
8000
+ * than dispatching from the DOM event) keeps hook delivery on the ECS tick, so
8001
+ * a Behaviour's `onSelectStart` always observes the same world state its
8002
+ * `onUpdate` would.
8003
+ */
8004
+ dispatchInputEdges(world) {
8005
+ const inputs = this.inputSystem?.getInputs();
8006
+ if (!inputs || inputs.length === 0) return;
8007
+ for (const input of inputs) {
8008
+ if (input.selectStart) {
8009
+ this.forEachBehaviour(world, (b) => b.onSelectStart(input));
8010
+ }
8011
+ if (input.selectEnd) {
8012
+ this.forEachBehaviour(world, (b) => b.onSelectEnd(input));
8013
+ }
8014
+ }
8015
+ }
8016
+ forEachBehaviour(world, visit) {
8017
+ for (const entityId of world.query(ScriptComponent)) {
8018
+ const script = world.getComponent(entityId, ScriptComponent);
8019
+ const instances = script?.scriptInstances;
8020
+ if (!instances) continue;
8021
+ for (const instance of instances.values()) {
8022
+ if (!(instance instanceof Behaviour)) continue;
8023
+ try {
8024
+ visit(instance);
8025
+ } catch (error) {
8026
+ console.error("[XRSessionSystem] Behaviour hook failed:", error);
8027
+ }
8028
+ }
8029
+ }
8030
+ }
8031
+ /** What the active session granted. `NO_XR_CAPABILITIES` when not presenting. */
8032
+ getCapabilities() {
8033
+ return this.capabilities;
8034
+ }
8035
+ /** True while an immersive session is presenting. */
8036
+ isPresenting() {
8037
+ return this.presenting;
8038
+ }
8039
+ /** Convenience passthrough so consumers need only hold this system. */
8040
+ getInputs() {
8041
+ return this.inputSystem?.getInputs() ?? [];
8042
+ }
8043
+ };
8044
+ __name(_XRSessionSystem, "XRSessionSystem");
8045
+ var XRSessionSystem = _XRSessionSystem;
7345
8046
 
7346
8047
  exports.AnimationSystem = AnimationSystem;
7347
8048
  exports.AudioSystem = AudioSystem;
@@ -7363,5 +8064,9 @@ exports.ScriptBehaviourSystem = ScriptBehaviourSystem;
7363
8064
  exports.ScriptObjectSystem = ScriptObjectSystem;
7364
8065
  exports.TransformSyncSystem = TransformSyncSystem;
7365
8066
  exports.VideoSystem = VideoSystem;
8067
+ exports.XRInputSystem = XRInputSystem;
8068
+ exports.XRInteractionSystem = XRInteractionSystem;
8069
+ exports.XRLocomotionSystem = XRLocomotionSystem;
8070
+ exports.XRSessionSystem = XRSessionSystem;
7366
8071
  //# sourceMappingURL=index.cjs.map
7367
8072
  //# sourceMappingURL=index.cjs.map