@relu-interactives/spatial-ecs 0.5.2 → 0.8.0

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 (511) hide show
  1. package/dist/{System-V_mv07le.d.cts → System-8D-XBDKZ.d.cts} +734 -8
  2. package/dist/{System-V_mv07le.d.ts → System-DPMAW30g.d.ts} +734 -8
  3. package/dist/{XRHandPose-CU3vNFuS.d.ts → XRHandPose-G0Dl-F0w.d.ts} +93 -3
  4. package/dist/{XRHandPose-CQTLGxFC.d.cts → XRHandPose-VQMT1WXj.d.cts} +93 -3
  5. package/dist/animation/index.cjs +252 -0
  6. package/dist/animation/index.cjs.map +1 -0
  7. package/dist/animation/index.d.cts +100 -0
  8. package/dist/animation/index.d.ts +100 -0
  9. package/dist/animation/index.js +4 -0
  10. package/dist/animation/index.js.map +1 -0
  11. package/dist/chunk-CKTHDXPS.js +11 -0
  12. package/dist/chunk-CKTHDXPS.js.map +1 -0
  13. package/dist/chunk-G4XJ53LS.js +1237 -0
  14. package/dist/chunk-G4XJ53LS.js.map +1 -0
  15. package/dist/chunk-GSWC6LLD.js +241 -0
  16. package/dist/chunk-GSWC6LLD.js.map +1 -0
  17. package/dist/{chunk-DF5SSRN6.js → chunk-JIJQFW6P.js} +1216 -2920
  18. package/dist/chunk-JIJQFW6P.js.map +1 -0
  19. package/dist/{chunk-BUEKOSR5.js → chunk-NNDUOQ7O.js} +188 -14
  20. package/dist/chunk-NNDUOQ7O.js.map +1 -0
  21. package/dist/chunk-OHCNPPMX.js +334 -0
  22. package/dist/chunk-OHCNPPMX.js.map +1 -0
  23. package/dist/{chunk-RXBLOO5B.js → chunk-SGF73YTF.js} +105 -715
  24. package/dist/chunk-SGF73YTF.js.map +1 -0
  25. package/dist/chunk-U727NTWQ.js +2856 -0
  26. package/dist/chunk-U727NTWQ.js.map +1 -0
  27. package/dist/{chunk-OY7ZODZP.js → chunk-XE4OXN2W.js} +3 -9
  28. package/dist/chunk-XE4OXN2W.js.map +1 -0
  29. package/dist/{chunk-OWQSESTO.js → chunk-XU2DVWCP.js} +4 -3
  30. package/dist/chunk-XU2DVWCP.js.map +1 -0
  31. package/dist/components/index.cjs +183 -10
  32. package/dist/components/index.cjs.map +1 -1
  33. package/dist/components/index.d.cts +5 -3
  34. package/dist/components/index.d.ts +5 -3
  35. package/dist/components/index.js +3 -2
  36. package/dist/docs/api/Behaviour/classes/Behaviour.md +366 -79
  37. package/dist/docs/api/Behaviour/index.md +7 -3
  38. package/dist/docs/api/Behaviour/type-aliases/UiInteractionEvent.md +35 -0
  39. package/dist/docs/api/Component/classes/Component.md +14 -1
  40. package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
  41. package/dist/docs/api/components/classes/AudioComponent.md +19 -19
  42. package/dist/docs/api/components/classes/CameraComponent.md +14 -14
  43. package/dist/docs/api/components/classes/EntityType.md +4 -4
  44. package/dist/docs/api/components/classes/Environment.md +5 -4
  45. package/dist/docs/api/components/classes/ImageComponent.md +7 -7
  46. package/dist/docs/api/components/classes/ImageTarget.md +8 -8
  47. package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
  48. package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
  49. package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
  50. package/dist/docs/api/components/classes/LightComponent.md +6 -6
  51. package/dist/docs/api/components/classes/MaterialComponent.md +16 -16
  52. package/dist/docs/api/components/classes/MeshComponent.md +3 -3
  53. package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
  54. package/dist/docs/api/components/classes/ModelComponent.md +8 -5
  55. package/dist/docs/api/components/classes/Name.md +3 -3
  56. package/dist/docs/api/components/classes/Object3DRef.md +4 -4
  57. package/dist/docs/api/components/classes/ParentId.md +3 -3
  58. package/dist/docs/api/components/classes/PhysicsComponent.md +7 -6
  59. package/dist/docs/api/components/classes/Postprocessing.md +3 -3
  60. package/dist/docs/api/components/classes/PrefabInstance.md +5 -5
  61. package/dist/docs/api/components/classes/PrefabNode.md +3 -3
  62. package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
  63. package/dist/docs/api/components/classes/ScriptObjectComponent.md +9 -9
  64. package/dist/docs/api/components/classes/Selectable.md +3 -3
  65. package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
  66. package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
  67. package/dist/docs/api/components/classes/TransformComponent.md +12 -12
  68. package/dist/docs/api/components/classes/UIButtonComponent.md +63 -0
  69. package/dist/docs/api/components/classes/UIPanelComponent.md +62 -0
  70. package/dist/docs/api/components/classes/UISliderComponent.md +59 -0
  71. package/dist/docs/api/components/classes/UITextComponent.md +59 -0
  72. package/dist/docs/api/components/classes/UIToggleComponent.md +56 -0
  73. package/dist/docs/api/components/classes/VRTeleportAreaComponent.md +53 -0
  74. package/dist/docs/api/components/classes/VideoComponent.md +28 -28
  75. package/dist/docs/api/components/classes/XRAnchorComponent.md +64 -0
  76. package/dist/docs/api/components/classes/XREnvironmentComponent.md +64 -0
  77. package/dist/docs/api/components/classes/XRHandPoseComponent.md +50 -0
  78. package/dist/docs/api/components/classes/XRInteractableComponent.md +74 -0
  79. package/dist/docs/api/components/classes/XRInteractorComponent.md +57 -0
  80. package/dist/docs/api/components/classes/XRInteractorSideComponent.md +50 -0
  81. package/dist/docs/api/components/classes/XRRigComponent.md +68 -0
  82. package/dist/docs/api/components/functions/createAttachPoint.md +25 -0
  83. package/dist/docs/api/components/functions/createHandPoseEntry.md +25 -0
  84. package/dist/docs/api/components/functions/defaultMaterialValue.md +1 -1
  85. package/dist/docs/api/components/functions/handPoseDefinitionFor.md +33 -0
  86. package/dist/docs/api/components/functions/normalizeEnvironmentLighting.md +30 -0
  87. package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
  88. package/dist/docs/api/components/functions/setModelLoadState.md +33 -0
  89. package/dist/docs/api/components/functions/setPhysicsLiveRef.md +3 -9
  90. package/dist/docs/api/components/index.md +61 -4
  91. package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
  92. package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
  93. package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
  94. package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +5 -3
  95. package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
  96. package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
  97. package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
  98. package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
  99. package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
  100. package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
  101. package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
  102. package/dist/docs/api/components/type-aliases/EnvironmentLightingState.md +40 -0
  103. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxImageProjection.md +22 -0
  104. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +9 -7
  105. package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
  106. package/dist/docs/api/components/type-aliases/EnvironmentState.md +7 -5
  107. package/dist/docs/api/components/type-aliases/EnvironmentToneMapping.md +16 -0
  108. package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
  109. package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
  110. package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
  111. package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
  112. package/dist/docs/api/components/type-aliases/LightShadowState.md +37 -0
  113. package/dist/docs/api/components/type-aliases/LightValueState.md +13 -11
  114. package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
  115. package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
  116. package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
  117. package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
  118. package/dist/docs/api/components/type-aliases/ModelLoadState.md +15 -0
  119. package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
  120. package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
  121. package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
  122. package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
  123. package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
  124. package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
  125. package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
  126. package/dist/docs/api/components/type-aliases/ScriptEntry.md +8 -8
  127. package/dist/docs/api/components/type-aliases/ScriptObjectComponentInput.md +1 -1
  128. package/dist/docs/api/components/type-aliases/ScriptObjectRuntimeState.md +1 -1
  129. package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
  130. package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
  131. package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
  132. package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
  133. package/dist/docs/api/components/type-aliases/UIButtonOptions.md +45 -0
  134. package/dist/docs/api/components/type-aliases/UIPanelOptions.md +39 -0
  135. package/dist/docs/api/components/type-aliases/UISliderOptions.md +39 -0
  136. package/dist/docs/api/components/type-aliases/UITextOptions.md +41 -0
  137. package/dist/docs/api/components/type-aliases/UIToggleOptions.md +35 -0
  138. package/dist/docs/api/components/type-aliases/UiFollowMode.md +15 -0
  139. package/dist/docs/api/components/type-aliases/UiTextAlign.md +13 -0
  140. package/dist/docs/api/components/type-aliases/UiTextVAlign.md +13 -0
  141. package/dist/docs/api/components/type-aliases/VRTeleportAreaOptions.md +29 -0
  142. package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
  143. package/dist/docs/api/components/type-aliases/VrTeleportShape.md +15 -0
  144. package/dist/docs/api/components/type-aliases/XRAnchorOptions.md +23 -0
  145. package/dist/docs/api/components/type-aliases/XRHandPoseOptions.md +23 -0
  146. package/dist/docs/api/components/type-aliases/XRInteractableOptions.md +75 -0
  147. package/dist/docs/api/components/type-aliases/XRInteractorOptions.md +37 -0
  148. package/dist/docs/api/components/type-aliases/XRRigOptions.md +51 -0
  149. package/dist/docs/api/components/type-aliases/XrAttachPoint.md +53 -0
  150. package/dist/docs/api/components/type-aliases/XrDistanceGrabBehavior.md +19 -0
  151. package/dist/docs/api/components/type-aliases/XrEnvironmentKind.md +15 -0
  152. package/dist/docs/api/components/type-aliases/XrEnvironmentOrientation.md +15 -0
  153. package/dist/docs/api/components/type-aliases/XrEnvironmentPhysics.md +25 -0
  154. package/dist/docs/api/components/type-aliases/XrGrabGesture.md +19 -0
  155. package/dist/docs/api/components/type-aliases/XrGrabHands.md +20 -0
  156. package/dist/docs/api/components/type-aliases/XrGrabReach.md +20 -0
  157. package/dist/docs/api/components/type-aliases/XrHandPoseEntry.md +49 -0
  158. package/dist/docs/api/components/type-aliases/XrHandPreset.md +19 -0
  159. package/dist/docs/api/components/type-aliases/XrInteractorSide.md +15 -0
  160. package/dist/docs/api/components/type-aliases/XrInteractorType.md +13 -0
  161. package/dist/docs/api/components/type-aliases/XrLocomotionMode.md +15 -0
  162. package/dist/docs/api/components/type-aliases/XrTrackingOrigin.md +24 -0
  163. package/dist/docs/api/components/type-aliases/XrTwoHandRotation.md +15 -0
  164. package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
  165. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_LIGHTING.md +15 -0
  166. package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
  167. package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
  168. package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
  169. package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
  170. package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
  171. package/dist/docs/api/components/variables/DEFAULT_POSE_CURLS.md +13 -0
  172. package/dist/docs/api/components/variables/DEFAULT_POSE_DIRECTIONS.md +13 -0
  173. package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
  174. package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
  175. package/dist/docs/api/components/variables/MODEL_NO_PATH_MESSAGE.md +15 -0
  176. package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
  177. package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
  178. package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
  179. package/dist/docs/api/index/classes/AudioSystem.md +4 -4
  180. package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
  181. package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +19 -4
  182. package/dist/docs/api/index/classes/HandPoseTracker.md +114 -0
  183. package/dist/docs/api/index/classes/InputSystem.md +33 -33
  184. package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
  185. package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
  186. package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
  187. package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
  188. package/dist/docs/api/index/classes/ObjectManagementSystem.md +14 -14
  189. package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
  190. package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
  191. package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +34 -10
  192. package/dist/docs/api/index/classes/RenderSystem.md +13 -4
  193. package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +9 -5
  194. package/dist/docs/api/index/classes/ScriptObject.md +10 -10
  195. package/dist/docs/api/index/classes/ScriptObjectSystem.md +6 -6
  196. package/dist/docs/api/index/classes/TeleportAimGate.md +114 -0
  197. package/dist/docs/api/index/classes/ThrowVelocityTracker.md +89 -0
  198. package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
  199. package/dist/docs/api/index/classes/UIInteractionSystem.md +60 -0
  200. package/dist/docs/api/index/classes/UIPanelSystem.md +79 -0
  201. package/dist/docs/api/index/classes/VRTeleportAreaSystem.md +49 -0
  202. package/dist/docs/api/index/classes/VideoSystem.md +8 -6
  203. package/dist/docs/api/index/classes/World.md +282 -100
  204. package/dist/docs/api/index/classes/XRAnchorSystem.md +90 -0
  205. package/dist/docs/api/index/classes/XRControllerVisualSystem.md +77 -0
  206. package/dist/docs/api/index/classes/XREnvironmentSystem.md +137 -0
  207. package/dist/docs/api/index/classes/XRHandPoseSystem.md +107 -0
  208. package/dist/docs/api/index/classes/XRHitTestSystem.md +93 -0
  209. package/dist/docs/api/index/classes/XRHoverVisualSystem.md +76 -0
  210. package/dist/docs/api/index/classes/XRInputSystem.md +189 -0
  211. package/dist/docs/api/index/classes/XRInteractionSystem.md +323 -0
  212. package/dist/docs/api/index/classes/XRLocomotionSystem.md +128 -0
  213. package/dist/docs/api/index/classes/XRSessionSystem.md +116 -0
  214. package/dist/docs/api/index/classes/XRTeleportVisualSystem.md +75 -0
  215. package/dist/docs/api/index/functions/angularVelocityFrom.md +33 -0
  216. package/dist/docs/api/index/functions/applyHandMaterial.md +26 -0
  217. package/dist/docs/api/index/functions/applyPrefabToSnapshotInstances.md +1 -1
  218. package/dist/docs/api/index/functions/arcGroundCrossing.md +30 -0
  219. package/dist/docs/api/index/functions/buildComponentValueMaps.md +1 -1
  220. package/dist/docs/api/index/functions/buildNodeKeyMapsFromSnapshot.md +1 -1
  221. package/dist/docs/api/index/functions/buildNodeMapsFromSnapshot.md +1 -1
  222. package/dist/docs/api/index/functions/canonicalizeComponentValue.md +1 -1
  223. package/dist/docs/api/index/functions/clearModelCache.md +1 -1
  224. package/dist/docs/api/index/functions/clearPrefabCache.md +1 -1
  225. package/dist/docs/api/index/functions/cloneHandPose.md +23 -0
  226. package/dist/docs/api/index/functions/collectDiffPaths.md +1 -1
  227. package/dist/docs/api/index/functions/collectDirectPrefabDependencies.md +1 -1
  228. package/dist/docs/api/index/functions/collectEntitySubtree.md +1 -1
  229. package/dist/docs/api/index/functions/collectSnapshotSubtreeIds.md +1 -1
  230. package/dist/docs/api/index/functions/computeFingerCurl.md +29 -0
  231. package/dist/docs/api/index/functions/computeHandShape.md +29 -0
  232. package/dist/docs/api/index/functions/computeInstanceOverrides.md +1 -1
  233. package/dist/docs/api/index/functions/computePalmPose.md +30 -0
  234. package/dist/docs/api/index/functions/computePalmWidth.md +25 -0
  235. package/dist/docs/api/index/functions/computePinch.md +29 -0
  236. package/dist/docs/api/index/functions/computeSpread.md +33 -0
  237. package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
  238. package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
  239. package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
  240. package/dist/docs/api/index/functions/createEntityTypeComponent.md +2 -2
  241. package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
  242. package/dist/docs/api/index/functions/createHandMaterial.md +30 -0
  243. package/dist/docs/api/index/functions/createImageComponent.md +1 -1
  244. package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
  245. package/dist/docs/api/index/functions/createImageTargetComponent.md +2 -2
  246. package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
  247. package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
  248. package/dist/docs/api/index/functions/createLightComponent.md +2 -2
  249. package/dist/docs/api/index/functions/createMaterialComponent.md +2 -2
  250. package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
  251. package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
  252. package/dist/docs/api/index/functions/createModelComponent.md +1 -1
  253. package/dist/docs/api/index/functions/createNameComponent.md +1 -1
  254. package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
  255. package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
  256. package/dist/docs/api/index/functions/createPhysicsComponent.md +1 -1
  257. package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
  258. package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
  259. package/dist/docs/api/index/functions/createScriptObjectComponent.md +1 -1
  260. package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
  261. package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
  262. package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
  263. package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
  264. package/dist/docs/api/index/functions/createUIButtonComponent.md +28 -0
  265. package/dist/docs/api/index/functions/createUIPanelComponent.md +28 -0
  266. package/dist/docs/api/index/functions/createUISliderComponent.md +28 -0
  267. package/dist/docs/api/index/functions/createUITextComponent.md +28 -0
  268. package/dist/docs/api/index/functions/createUIToggleComponent.md +28 -0
  269. package/dist/docs/api/index/functions/createVRTeleportAreaComponent.md +28 -0
  270. package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
  271. package/dist/docs/api/index/functions/createXRAnchorComponent.md +28 -0
  272. package/dist/docs/api/index/functions/createXRHandPoseComponent.md +28 -0
  273. package/dist/docs/api/index/functions/createXRInteractableComponent.md +28 -0
  274. package/dist/docs/api/index/functions/createXRInteractorComponent.md +28 -0
  275. package/dist/docs/api/index/functions/createXRInteractorSideComponent.md +28 -0
  276. package/dist/docs/api/index/functions/createXRRigComponent.md +28 -0
  277. package/dist/docs/api/index/functions/decanonicalizeComponentValue.md +1 -1
  278. package/dist/docs/api/index/functions/despawnPrefab.md +1 -1
  279. package/dist/docs/api/index/functions/encodeOverride.md +1 -1
  280. package/dist/docs/api/index/functions/estimateHandScale.md +28 -0
  281. package/dist/docs/api/index/functions/findSnapshotRootEntityIds.md +1 -1
  282. package/dist/docs/api/index/functions/findTopLevelNestedRegions.md +1 -1
  283. package/dist/docs/api/index/functions/getHandPosePreset.md +31 -0
  284. package/dist/docs/api/index/functions/groupOverridePaths.md +1 -1
  285. package/dist/docs/api/index/functions/handPoseFromCurls.md +42 -0
  286. package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
  287. package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +1 -1
  288. package/dist/docs/api/index/functions/indexSnapshotByEntity.md +1 -1
  289. package/dist/docs/api/index/functions/instantiateSubtree.md +1 -1
  290. package/dist/docs/api/index/functions/loadPrefab.md +1 -1
  291. package/dist/docs/api/index/functions/loadSharedGltf.md +1 -1
  292. package/dist/docs/api/index/functions/matchHandPose.md +34 -0
  293. package/dist/docs/api/index/functions/mergeComponentValue.md +1 -1
  294. package/dist/docs/api/index/functions/parseOverride.md +1 -1
  295. package/dist/docs/api/index/functions/parsePrefabAsset.md +1 -1
  296. package/dist/docs/api/index/functions/prefabFileVersionFor.md +1 -1
  297. package/dist/docs/api/index/functions/readXrCapabilities.md +30 -0
  298. package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
  299. package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
  300. package/dist/docs/api/index/functions/remapSnapshotEntityIds.md +3 -3
  301. package/dist/docs/api/index/functions/resolveDracoDecoderPath.md +1 -1
  302. package/dist/docs/api/index/functions/restoreComponentState.md +1 -1
  303. package/dist/docs/api/index/functions/restorePostCreateComponents.md +1 -1
  304. package/dist/docs/api/index/functions/sampleTeleportArc.md +40 -0
  305. package/dist/docs/api/index/functions/serializeEntitySubtree.md +1 -1
  306. package/dist/docs/api/index/functions/setDracoDecoderPath.md +1 -1
  307. package/dist/docs/api/index/functions/setPrefabAssetUrlResolver.md +1 -1
  308. package/dist/docs/api/index/functions/spawnPrefab.md +1 -1
  309. package/dist/docs/api/index/index.md +116 -4
  310. package/dist/docs/api/index/interfaces/ChromaKeyOptions.md +20 -0
  311. package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
  312. package/dist/docs/api/index/interfaces/PostprocessingBuildContext.md +21 -0
  313. package/dist/docs/api/index/interfaces/PostprocessingPipeline.md +84 -0
  314. package/dist/docs/api/index/interfaces/RenderBackend.md +168 -0
  315. package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
  316. package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
  317. package/dist/docs/api/index/type-aliases/ApplyPrefabToSnapshotResult.md +3 -3
  318. package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
  319. package/dist/docs/api/index/type-aliases/ComponentValueMaps.md +50 -26
  320. package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +14 -2
  321. package/dist/docs/api/index/type-aliases/EcsRenderer.md +17 -0
  322. package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
  323. package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
  324. package/dist/docs/api/index/type-aliases/ExternalRefWarning.md +5 -5
  325. package/dist/docs/api/index/type-aliases/HandMaterialOptions.md +32 -0
  326. package/dist/docs/api/index/type-aliases/HandPoseTrackerOptions.md +27 -0
  327. package/dist/docs/api/index/type-aliases/HydrateOptions.md +3 -3
  328. package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +4 -4
  329. package/dist/docs/api/index/type-aliases/InstantiateSubtreeResult.md +3 -3
  330. package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
  331. package/dist/docs/api/index/type-aliases/ModuleLoader.md +1 -1
  332. package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
  333. package/dist/docs/api/index/type-aliases/NestedRegion.md +5 -5
  334. package/dist/docs/api/index/type-aliases/NodeKeyMaps.md +5 -5
  335. package/dist/docs/api/index/type-aliases/NodeMaps.md +4 -4
  336. package/dist/docs/api/index/type-aliases/PrefabAsset.md +5 -5
  337. package/dist/docs/api/index/type-aliases/RemapSnapshotOptions.md +2 -2
  338. package/dist/docs/api/index/type-aliases/RendererKind.md +15 -0
  339. package/dist/docs/api/index/type-aliases/ScriptBehaviourSystemOptions.md +23 -0
  340. package/dist/docs/api/index/type-aliases/ScriptErrorEvent.md +39 -0
  341. package/dist/docs/api/index/type-aliases/ScriptErrorListener.md +25 -0
  342. package/dist/docs/api/index/type-aliases/ScriptErrorPhase.md +28 -0
  343. package/dist/docs/api/index/type-aliases/ScriptErrorReport.md +31 -0
  344. package/dist/docs/api/index/type-aliases/ScriptErrorSource.md +15 -0
  345. package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
  346. package/dist/docs/api/index/type-aliases/SerializeEntitySubtreeResult.md +4 -4
  347. package/dist/docs/api/index/type-aliases/SpawnPrefabOptions.md +5 -5
  348. package/dist/docs/api/index/type-aliases/SpawnPrefabSource.md +1 -1
  349. package/dist/docs/api/index/type-aliases/SubtreeSnapshot.md +3 -3
  350. package/dist/docs/api/index/type-aliases/UiCanvasLike.md +46 -0
  351. package/dist/docs/api/index/type-aliases/VelocitySample.md +23 -0
  352. package/dist/docs/api/index/type-aliases/XrCapabilities.md +41 -0
  353. package/dist/docs/api/index/type-aliases/XrFinger.md +13 -0
  354. package/dist/docs/api/index/type-aliases/XrFingerCurl.md +27 -0
  355. package/dist/docs/api/index/type-aliases/XrFingerTarget.md +31 -0
  356. package/dist/docs/api/index/type-aliases/XrHandJointName.md +40 -0
  357. package/dist/docs/api/index/type-aliases/XrHandJoints.md +18 -0
  358. package/dist/docs/api/index/type-aliases/XrHandPoseAxis.md +15 -0
  359. package/dist/docs/api/index/type-aliases/XrHandPoseContext.md +23 -0
  360. package/dist/docs/api/index/type-aliases/XrHandPoseDefinition.md +47 -0
  361. package/dist/docs/api/index/type-aliases/XrHandPoseDirection.md +21 -0
  362. package/dist/docs/api/index/type-aliases/XrHandPoseEvent.md +13 -0
  363. package/dist/docs/api/index/type-aliases/XrHandPoseEventDetail.md +27 -0
  364. package/dist/docs/api/index/type-aliases/XrHandPoseMatch.md +25 -0
  365. package/dist/docs/api/index/type-aliases/XrHandPoseOrientation.md +25 -0
  366. package/dist/docs/api/index/type-aliases/XrHandShape.md +46 -0
  367. package/dist/docs/api/index/type-aliases/XrHandedness.md +15 -0
  368. package/dist/docs/api/index/type-aliases/XrHitResult.md +25 -0
  369. package/dist/docs/api/index/type-aliases/XrInputKind.md +19 -0
  370. package/dist/docs/api/index/type-aliases/XrInputState.md +60 -0
  371. package/dist/docs/api/index/type-aliases/XrPalmPose.md +31 -0
  372. package/dist/docs/api/index/variables/ADDED_NODE_MARKER_COMPONENT.md +2 -2
  373. package/dist/docs/api/index/variables/ARC_GRAVITY.md +15 -0
  374. package/dist/docs/api/index/variables/ARC_MAX_TIME.md +15 -0
  375. package/dist/docs/api/index/variables/ARC_SPEED.md +15 -0
  376. package/dist/docs/api/index/variables/ARC_STEPS.md +15 -0
  377. package/dist/docs/api/index/variables/CURLED_COS.md +13 -0
  378. package/dist/docs/api/index/variables/DEFAULT_DIRECTION_TOLERANCE.md +15 -0
  379. package/dist/docs/api/index/variables/DEFAULT_ENTER_CONFIDENCE.md +13 -0
  380. package/dist/docs/api/index/variables/DEFAULT_EXIT_CONFIDENCE.md +13 -0
  381. package/dist/docs/api/index/variables/DEFAULT_LOST_GRACE_SECONDS.md +13 -0
  382. package/dist/docs/api/index/variables/DEFAULT_MIN_HOLD_SECONDS.md +13 -0
  383. package/dist/docs/api/index/variables/DEFAULT_SCRIPT_ERROR_RETRY_DELAY.md +17 -0
  384. package/dist/docs/api/index/variables/FALLBACK_HAND_SCALE.md +15 -0
  385. package/dist/docs/api/index/variables/HAND_POSE_PRESETS.md +19 -0
  386. package/dist/docs/api/index/variables/HAND_POSE_PRESET_IDS.md +15 -0
  387. package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
  388. package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
  389. package/dist/docs/api/index/variables/MATCH_FALLOFF.md +15 -0
  390. package/dist/docs/api/index/variables/MAX_PLAUSIBLE_SPEED.md +25 -0
  391. package/dist/docs/api/index/variables/MAX_SAMPLE_AGE_SECONDS.md +18 -0
  392. package/dist/docs/api/index/variables/NODE_KEY_SEPARATOR.md +1 -1
  393. package/dist/docs/api/index/variables/NO_XR_CAPABILITIES.md +15 -0
  394. package/dist/docs/api/index/variables/OVERRIDE_DIFF_EXCLUDED_COMPONENTS.md +1 -1
  395. package/dist/docs/api/index/variables/OVERRIDE_ROOT_EXCLUDED_COMPONENTS.md +1 -1
  396. package/dist/docs/api/index/variables/PINCH_FINGERS.md +15 -0
  397. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION.md +1 -1
  398. package/dist/docs/api/index/variables/PREFAB_FILE_VERSION_NESTED.md +1 -1
  399. package/dist/docs/api/index/variables/SCRIPT_OBJECT_ROOT_FLAG.md +1 -1
  400. package/dist/docs/api/index/variables/SHARED_MODEL_RESOURCE_FLAG.md +1 -1
  401. package/dist/docs/api/index/variables/STRAIGHT_COS.md +19 -0
  402. package/dist/docs/api/index/variables/VELOCITY_SAMPLES.md +15 -0
  403. package/dist/docs/api/index/variables/XR_FINGERS.md +13 -0
  404. package/dist/docs/api/index/variables/XR_HOVER_SHELL_FLAG.md +15 -0
  405. package/dist/docs/api/index/variables/webglBackend.md +16 -0
  406. package/dist/docs/api/typedoc-sidebar.json +1 -1
  407. package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
  408. package/dist/docs/api/types/type-aliases/CheckboxInput.md +3 -3
  409. package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
  410. package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
  411. package/dist/docs/api/types/type-aliases/ComponentKind.md +1 -1
  412. package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
  413. package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
  414. package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
  415. package/dist/docs/api/types/type-aliases/EcsEntityKind.md +10 -2
  416. package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
  417. package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
  418. package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
  419. package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
  420. package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
  421. package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
  422. package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
  423. package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
  424. package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
  425. package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
  426. package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
  427. package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
  428. package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
  429. package/dist/docs/guide/audio-mixing-and-sound-banks.md +71 -0
  430. package/dist/docs/guide/authoring-a-behaviour.md +3 -3
  431. package/dist/docs/guide/authoring-a-script-object.md +12 -9
  432. package/dist/docs/guide/behaviour-data-binding/index.md +11 -11
  433. package/dist/docs/guide/behaviour-lifecycle.md +9 -0
  434. package/dist/docs/guide/bone-attachments-and-ik.md +128 -0
  435. package/dist/docs/guide/component-catalog.md +10 -2
  436. package/dist/docs/guide/components/light.md +42 -0
  437. package/dist/docs/guide/components/model.md +32 -3
  438. package/dist/docs/guide/concepts.md +2 -2
  439. package/dist/docs/guide/getting-started/creating-objects.md +2 -2
  440. package/dist/docs/guide/getting-started/editing-objects.md +2 -2
  441. package/dist/docs/guide/getting-started/editor/ai-agent.md +227 -0
  442. package/dist/docs/guide/getting-started/editor/hierarchy.md +2 -2
  443. package/dist/docs/guide/getting-started/editor/index.md +3 -2
  444. package/dist/docs/guide/getting-started/editor/inspector.md +2 -2
  445. package/dist/docs/guide/getting-started/editor/scene-inspector.md +3 -3
  446. package/dist/docs/guide/getting-started/editor/toolbar.md +11 -11
  447. package/dist/docs/guide/getting-started/editor/viewport.md +17 -9
  448. package/dist/docs/guide/getting-started/index.md +1 -1
  449. package/dist/docs/guide/getting-started/installation.md +1 -1
  450. package/dist/docs/guide/getting-started/preview-and-test.md +7 -7
  451. package/dist/docs/guide/getting-started/project-types/image-tracking.md +23 -11
  452. package/dist/docs/guide/getting-started/project-types/index.md +4 -4
  453. package/dist/docs/guide/getting-started/project-types/vr.md +270 -2
  454. package/dist/docs/guide/getting-started/projects.md +4 -5
  455. package/dist/docs/guide/getting-started/shortcuts.md +5 -4
  456. package/dist/docs/guide/multiplayer.md +92 -0
  457. package/dist/docs/guide/scene/environment.md +101 -4
  458. package/dist/docs/guide/scene/index.md +4 -4
  459. package/dist/docs/guide/scene/postprocessing.md +67 -5
  460. package/dist/docs/guide/spawning/area-light.md +2 -0
  461. package/dist/docs/guide/systems/environment-sync-system.md +11 -6
  462. package/dist/docs/guide/systems/light-sync-system.md +5 -3
  463. package/dist/docs/guide/systems/postprocessing-sync-system.md +16 -6
  464. package/dist/docs/guide/systems/render-system.md +7 -6
  465. package/dist/docs/guide/systems/script-behaviour-system.md +7 -5
  466. package/dist/docs/guide/systems/script-object-system.md +3 -1
  467. package/dist/docs/guide/systems/video-system.md +1 -1
  468. package/dist/docs/guide/webgpu-and-tsl.md +415 -0
  469. package/dist/docs/guide/world-api.md +52 -2
  470. package/dist/factories/index.cjs +770 -283
  471. package/dist/factories/index.cjs.map +1 -1
  472. package/dist/factories/index.d.cts +14 -3
  473. package/dist/factories/index.d.ts +14 -3
  474. package/dist/factories/index.js +7 -4
  475. package/dist/{index-D2Jt_JzH.d.ts → index-C61n65PE.d.ts} +135 -42
  476. package/dist/{index-DaG03vyN.d.cts → index-C70N4BYG.d.cts} +135 -42
  477. package/dist/{index-C3ik3sA1.d.ts → index-D9DjrUn3.d.cts} +25 -3
  478. package/dist/{index-Dlr-7-4m.d.cts → index-DppafVu4.d.ts} +25 -3
  479. package/dist/index.cjs +3642 -1263
  480. package/dist/index.cjs.map +1 -1
  481. package/dist/index.d.cts +113 -11
  482. package/dist/index.d.ts +113 -11
  483. package/dist/index.js +187 -12
  484. package/dist/index.js.map +1 -1
  485. package/dist/network/index.cjs +4896 -0
  486. package/dist/network/index.cjs.map +1 -0
  487. package/dist/network/index.d.cts +98 -0
  488. package/dist/network/index.d.ts +98 -0
  489. package/dist/network/index.js +493 -0
  490. package/dist/network/index.js.map +1 -0
  491. package/dist/systems/index.cjs +3958 -1762
  492. package/dist/systems/index.cjs.map +1 -1
  493. package/dist/systems/index.d.cts +4 -2
  494. package/dist/systems/index.d.ts +4 -2
  495. package/dist/systems/index.js +8 -4
  496. package/dist/types.d.cts +3 -1
  497. package/dist/types.d.ts +3 -1
  498. package/dist/webgpu/index.d.ts +113 -0
  499. package/dist/webgpu/index.js +302 -0
  500. package/dist/webgpu/index.js.map +1 -0
  501. package/dist/worldSnapshotUtils.d.cts +3 -1
  502. package/dist/worldSnapshotUtils.d.ts +3 -1
  503. package/dist/worldSnapshotUtils.js +3 -2
  504. package/package.json +19 -3
  505. package/dist/chunk-BUEKOSR5.js.map +0 -1
  506. package/dist/chunk-DF5SSRN6.js.map +0 -1
  507. package/dist/chunk-OWQSESTO.js.map +0 -1
  508. package/dist/chunk-OY7ZODZP.js.map +0 -1
  509. package/dist/chunk-RXBLOO5B.js.map +0 -1
  510. package/dist/chunk-WJD2VKEH.js +0 -315
  511. package/dist/chunk-WJD2VKEH.js.map +0 -1
@@ -0,0 +1,4896 @@
1
+ 'use strict';
2
+
3
+ var sdk = require('@colyseus/sdk');
4
+ var THREE5 = require('three');
5
+
6
+ function _interopNamespace(e) {
7
+ if (e && e.__esModule) return e;
8
+ var n = Object.create(null);
9
+ if (e) {
10
+ Object.keys(e).forEach(function (k) {
11
+ if (k !== 'default') {
12
+ var d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: function () { return e[k]; }
16
+ });
17
+ }
18
+ });
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ var THREE5__namespace = /*#__PURE__*/_interopNamespace(THREE5);
25
+
26
+ var __defProp = Object.defineProperty;
27
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
28
+ var view = /* @__PURE__ */ __name((e) => ({
29
+ id: e.id,
30
+ owner: e.owner,
31
+ prefab: e.prefab,
32
+ x: e.x,
33
+ y: e.y,
34
+ z: e.z,
35
+ qx: e.qx,
36
+ qy: e.qy,
37
+ qz: e.qz,
38
+ qw: e.qw,
39
+ props: Object.fromEntries(e.props.entries())
40
+ }), "view");
41
+ var _ColyseusTransport = class _ColyseusTransport {
42
+ constructor(room) {
43
+ this.room = room;
44
+ }
45
+ static async connect(options) {
46
+ const client = new sdk.Client(options.endpoint);
47
+ const room = await client.joinOrCreate(options.room, options.join ?? {});
48
+ return new _ColyseusTransport(room);
49
+ }
50
+ get sessionId() {
51
+ return this.room.sessionId;
52
+ }
53
+ get host() {
54
+ return this.room.state.host;
55
+ }
56
+ get players() {
57
+ return [...this.room.state.players.keys()];
58
+ }
59
+ get $() {
60
+ return sdk.Callbacks.get(this.room);
61
+ }
62
+ onEntityAdd(cb) {
63
+ this.$.onAdd("entities", (entity) => cb(view(entity)));
64
+ }
65
+ onEntityChange(cb) {
66
+ const $ = this.$;
67
+ $.onAdd("entities", (entity) => {
68
+ $.onChange(entity, () => cb(view(entity)));
69
+ $.onChange(entity, "props", () => cb(view(entity)));
70
+ });
71
+ }
72
+ onEntityRemove(cb) {
73
+ this.$.onRemove("entities", (_entity, id) => cb(id));
74
+ }
75
+ onPlayerJoin(cb) {
76
+ this.$.onAdd("players", (_player, id) => cb(id));
77
+ }
78
+ onPlayerLeave(cb) {
79
+ this.$.onRemove("players", (_player, id) => cb(id));
80
+ }
81
+ onMessage(cb) {
82
+ this.room.onMessage(
83
+ "m",
84
+ (m) => cb(m.name, m.payload, m.from)
85
+ );
86
+ }
87
+ onCorrect(cb) {
88
+ this.room.onMessage("correct", (m) => cb(m.id, m));
89
+ }
90
+ onClose(cb) {
91
+ this.room.onLeave(() => cb());
92
+ }
93
+ registerScene(entities) {
94
+ this.room.send("scene", entities);
95
+ }
96
+ spawn(request) {
97
+ this.room.send("spawn", request);
98
+ }
99
+ despawn(id) {
100
+ this.room.send("despawn", { id });
101
+ }
102
+ sendPose(id, pose) {
103
+ this.room.send("pose", { id, ...pose });
104
+ }
105
+ setProp(id, key, json) {
106
+ this.room.send("prop", { id, key, json });
107
+ }
108
+ send(name, payload) {
109
+ this.room.send("m", { name, payload });
110
+ }
111
+ leave() {
112
+ void this.room.leave();
113
+ }
114
+ };
115
+ __name(_ColyseusTransport, "ColyseusTransport");
116
+ var ColyseusTransport = _ColyseusTransport;
117
+
118
+ // core/network/latency.ts
119
+ function withLatency(transport, ms) {
120
+ if (ms <= 0) return transport;
121
+ const oneWay = ms / 2;
122
+ return new Proxy(transport, {
123
+ get(target, key) {
124
+ const value = Reflect.get(target, key);
125
+ if (typeof value !== "function") return value;
126
+ const name = String(key);
127
+ const fn = value;
128
+ if (name === "leave") return fn.bind(target);
129
+ if (name.startsWith("on")) {
130
+ return (cb) => fn.call(target, (...args) => {
131
+ setTimeout(() => cb(...args), oneWay);
132
+ });
133
+ }
134
+ return (...args) => {
135
+ setTimeout(() => fn.apply(target, args), oneWay);
136
+ };
137
+ }
138
+ });
139
+ }
140
+ __name(withLatency, "withLatency");
141
+
142
+ // core/Component.ts
143
+ var _Component = class _Component {
144
+ };
145
+ __name(_Component, "Component");
146
+ var Component = _Component;
147
+
148
+ // core/AnimationStateMachine.ts
149
+ var _AnimationStateMachine = class _AnimationStateMachine {
150
+ constructor(name, clip, callbacks = {}, loop = false, clipId = null) {
151
+ this.isPlaying = false;
152
+ this.isPaused = false;
153
+ this.name = name;
154
+ this.clip = clip;
155
+ this.clipId = clipId;
156
+ this.loop = loop;
157
+ this.callbacks = {
158
+ onStart: callbacks.onStart ?? (() => {
159
+ }),
160
+ onPlaying: callbacks.onPlaying ?? (() => {
161
+ }),
162
+ onEnd: callbacks.onEnd ?? (() => {
163
+ })
164
+ };
165
+ }
166
+ setCallbacks(callbacks) {
167
+ this.callbacks = {
168
+ onStart: callbacks.onStart ?? this.callbacks.onStart,
169
+ onPlaying: callbacks.onPlaying ?? this.callbacks.onPlaying,
170
+ onEnd: callbacks.onEnd ?? this.callbacks.onEnd
171
+ };
172
+ }
173
+ setLoop(loop) {
174
+ this.loop = loop;
175
+ }
176
+ onStart() {
177
+ this.callbacks.onStart();
178
+ }
179
+ onPlaying() {
180
+ this.callbacks.onPlaying();
181
+ }
182
+ onEnd() {
183
+ this.callbacks.onEnd();
184
+ }
185
+ play() {
186
+ const wasPlaying = this.isPlaying;
187
+ this.isPlaying = true;
188
+ this.isPaused = false;
189
+ if (!wasPlaying) {
190
+ this.onStart();
191
+ }
192
+ this.onPlaying();
193
+ }
194
+ pause() {
195
+ if (!this.isPlaying) {
196
+ return;
197
+ }
198
+ this.isPlaying = false;
199
+ this.isPaused = true;
200
+ }
201
+ stop() {
202
+ const shouldNotifyEnd = this.isPlaying || this.isPaused;
203
+ this.isPlaying = false;
204
+ this.isPaused = false;
205
+ if (shouldNotifyEnd) {
206
+ this.onEnd();
207
+ }
208
+ }
209
+ };
210
+ __name(_AnimationStateMachine, "AnimationStateMachine");
211
+ var AnimationStateMachine = _AnimationStateMachine;
212
+ var _AnimationStateManager = class _AnimationStateManager {
213
+ constructor() {
214
+ this.states = /* @__PURE__ */ new Map();
215
+ this.activeState = null;
216
+ }
217
+ addState(state) {
218
+ this.states.set(state.name, state);
219
+ return state;
220
+ }
221
+ createState(name, clip, callbacks = {}, loop = false, clipId = null) {
222
+ const state = new AnimationStateMachine(name, clip, callbacks, loop, clipId);
223
+ this.states.set(name, state);
224
+ return state;
225
+ }
226
+ removeState(name) {
227
+ const state = this.states.get(name);
228
+ if (!state) {
229
+ return false;
230
+ }
231
+ if (this.activeState?.name === name) {
232
+ this.activeState.stop();
233
+ this.activeState = null;
234
+ }
235
+ return this.states.delete(name);
236
+ }
237
+ getState(name) {
238
+ return this.states.get(name) ?? null;
239
+ }
240
+ hasState(name) {
241
+ return this.states.has(name);
242
+ }
243
+ listStates() {
244
+ return [...this.states.values()];
245
+ }
246
+ getActiveState() {
247
+ return this.activeState;
248
+ }
249
+ switchState(name, autoPlay = true) {
250
+ const next = this.states.get(name) ?? null;
251
+ if (!next) {
252
+ return null;
253
+ }
254
+ if (this.activeState && this.activeState !== next) {
255
+ this.activeState.stop();
256
+ }
257
+ this.activeState = next;
258
+ if (autoPlay) {
259
+ next.play();
260
+ }
261
+ return next;
262
+ }
263
+ playState(name) {
264
+ const state = name ? this.switchState(name, false) : this.activeState;
265
+ if (!state) {
266
+ return false;
267
+ }
268
+ this.activeState = state;
269
+ state.play();
270
+ return true;
271
+ }
272
+ pauseState(name) {
273
+ const state = name ? this.states.get(name) : this.activeState;
274
+ if (!state) {
275
+ return false;
276
+ }
277
+ state.pause();
278
+ return true;
279
+ }
280
+ stopState(name) {
281
+ const state = name ? this.states.get(name) : this.activeState;
282
+ if (!state) {
283
+ return false;
284
+ }
285
+ state.stop();
286
+ if (!name || this.activeState?.name === name) {
287
+ this.activeState = null;
288
+ }
289
+ return true;
290
+ }
291
+ clear() {
292
+ this.stopState();
293
+ this.states.clear();
294
+ this.activeState = null;
295
+ }
296
+ };
297
+ __name(_AnimationStateManager, "AnimationStateManager");
298
+ var AnimationStateManager = _AnimationStateManager;
299
+
300
+ // core/components/Animation.ts
301
+ var _AnimationComponent = class _AnimationComponent extends Component {
302
+ constructor(options = {}) {
303
+ super();
304
+ this.modelClips = Array.isArray(options.clips) ? [...options.clips] : [];
305
+ this.importedClips = [];
306
+ this.clipById = /* @__PURE__ */ new Map();
307
+ this.clipEntriesById = /* @__PURE__ */ new Map();
308
+ this.clips = [];
309
+ this.clipCatalog = [];
310
+ this.availableClips = [];
311
+ this.externalClipSources = [];
312
+ this.setExternalClipSources(options.externalClipSources ?? []);
313
+ this.refreshClipCatalog();
314
+ this.paused = options.paused ?? false;
315
+ this.reverse = options.reverse ?? false;
316
+ this.timeScale = options.timeScale ?? 1;
317
+ this.crossFadeDuration = options.crossFadeDuration ?? 0;
318
+ this.stateManager = new AnimationStateManager();
319
+ this.states = this.stateManager.listStates();
320
+ this.active = this.stateManager.getActiveState();
321
+ this.activeStateName = this.active?.name ?? null;
322
+ if (Array.isArray(options.states) && options.states.length > 0) {
323
+ for (const entry of options.states) {
324
+ this.addState(entry.name, entry.clip, entry.loop ?? false);
325
+ }
326
+ }
327
+ if (typeof options.activeState === "string" && options.activeState.length > 0) {
328
+ this.switchState(options.activeState, !this.paused);
329
+ }
330
+ }
331
+ refreshClipCatalog() {
332
+ const catalog = [];
333
+ const nameCounts = /* @__PURE__ */ new Map();
334
+ const nextById = /* @__PURE__ */ new Map();
335
+ const nextEntriesById = /* @__PURE__ */ new Map();
336
+ for (const [index, clip] of this.modelClips.entries()) {
337
+ const name = typeof clip?.name === "string" && clip.name.length > 0 ? clip.name : `Clip ${index + 1}`;
338
+ const id = `model:${index}:${name}`;
339
+ const count = (nameCounts.get(name) ?? 0) + 1;
340
+ nameCounts.set(name, count);
341
+ const entry = {
342
+ id,
343
+ name,
344
+ label: count > 1 ? `${name} (${count})` : name,
345
+ clip,
346
+ source: "model",
347
+ sourceUrl: null
348
+ };
349
+ catalog.push(entry);
350
+ nextById.set(id, clip);
351
+ nextEntriesById.set(id, entry);
352
+ }
353
+ for (const [index, imported] of this.importedClips.entries()) {
354
+ const clip = imported.clip;
355
+ const name = typeof clip?.name === "string" && clip.name.length > 0 ? clip.name : `Clip ${index + 1}`;
356
+ const sourceUrl = imported.sourceUrl;
357
+ const id = `external:${index}:${name}`;
358
+ const count = (nameCounts.get(name) ?? 0) + 1;
359
+ nameCounts.set(name, count);
360
+ const sourceSuffix = sourceUrl ? sourceUrl.split("/").pop() ?? sourceUrl : "external";
361
+ const entry = {
362
+ id,
363
+ name,
364
+ label: count > 1 ? `${name} (${count}) \u2022 ${sourceSuffix}` : `${name} \u2022 ${sourceSuffix}`,
365
+ clip,
366
+ source: "external",
367
+ sourceUrl
368
+ };
369
+ catalog.push(entry);
370
+ nextById.set(id, clip);
371
+ nextEntriesById.set(id, entry);
372
+ }
373
+ this.clipById = nextById;
374
+ this.clipEntriesById = nextEntriesById;
375
+ this.clipCatalog = catalog;
376
+ this.clips = catalog.map((entry) => entry.clip);
377
+ this.availableClips = catalog.map((entry) => entry.name);
378
+ }
379
+ refreshStateRefs() {
380
+ this.states = this.stateManager.listStates();
381
+ this.active = this.stateManager.getActiveState();
382
+ this.activeStateName = this.active?.name ?? null;
383
+ }
384
+ resolveClipRef(clipRef) {
385
+ const trimmed = clipRef.trim();
386
+ if (!trimmed) {
387
+ return null;
388
+ }
389
+ const byId = this.clipById.get(trimmed);
390
+ if (byId) {
391
+ return { id: trimmed, clip: byId };
392
+ }
393
+ const byName = this.clipCatalog.find((entry) => entry.name === trimmed);
394
+ if (!byName) {
395
+ return null;
396
+ }
397
+ return { id: byName.id, clip: byName.clip };
398
+ }
399
+ setModelClips(clips) {
400
+ this.modelClips = Array.isArray(clips) ? [...clips] : [];
401
+ this.refreshClipCatalog();
402
+ }
403
+ setImportedClips(clips) {
404
+ if (!Array.isArray(clips)) {
405
+ this.importedClips = [];
406
+ this.refreshClipCatalog();
407
+ return;
408
+ }
409
+ this.importedClips = clips.map((entry) => {
410
+ if (entry instanceof THREE5__namespace.AnimationClip) {
411
+ return { clip: entry, sourceUrl: null };
412
+ }
413
+ if (!entry || typeof entry !== "object") {
414
+ return null;
415
+ }
416
+ const candidate = entry;
417
+ if (!(candidate.clip instanceof THREE5__namespace.AnimationClip)) {
418
+ return null;
419
+ }
420
+ return {
421
+ clip: candidate.clip,
422
+ sourceUrl: typeof candidate.sourceUrl === "string" && candidate.sourceUrl.length > 0 ? candidate.sourceUrl : null
423
+ };
424
+ }).filter((entry) => entry !== null);
425
+ this.refreshClipCatalog();
426
+ }
427
+ setExternalClipSources(sources) {
428
+ if (!Array.isArray(sources)) {
429
+ this.externalClipSources = [];
430
+ return;
431
+ }
432
+ const seen = /* @__PURE__ */ new Set();
433
+ const normalized = [];
434
+ for (const source of sources) {
435
+ if (typeof source !== "string") {
436
+ continue;
437
+ }
438
+ const trimmed = source.trim();
439
+ if (!trimmed || seen.has(trimmed)) {
440
+ continue;
441
+ }
442
+ seen.add(trimmed);
443
+ normalized.push(trimmed);
444
+ }
445
+ this.externalClipSources = normalized;
446
+ }
447
+ addState(name, clipRef, loop = false) {
448
+ if (!name.trim()) {
449
+ return null;
450
+ }
451
+ const resolved = this.resolveClipRef(clipRef);
452
+ if (!resolved) {
453
+ return null;
454
+ }
455
+ const state = this.stateManager.createState(name, resolved.clip, {}, loop, resolved.id);
456
+ this.refreshStateRefs();
457
+ return state;
458
+ }
459
+ setStates(states) {
460
+ const previousActive = this.activeStateName;
461
+ this.stateManager.clear();
462
+ for (const state of states) {
463
+ if (!state.name.trim()) {
464
+ continue;
465
+ }
466
+ let createdState = null;
467
+ if (typeof state.clipId === "string" && state.clipId.trim().length > 0) {
468
+ createdState = this.addState(state.name, state.clipId, Boolean(state.loop));
469
+ }
470
+ if (!createdState) {
471
+ this.addState(state.name, state.clip, Boolean(state.loop));
472
+ }
473
+ }
474
+ if (previousActive) {
475
+ this.stateManager.switchState(previousActive, !this.paused);
476
+ }
477
+ this.refreshStateRefs();
478
+ }
479
+ getStateConfigs() {
480
+ return this.states.map((state) => ({
481
+ name: state.name,
482
+ clip: state.clip.name,
483
+ clipId: state.clipId,
484
+ loop: state.loop
485
+ }));
486
+ }
487
+ setActiveState(name, autoPlay = true) {
488
+ if (!name) {
489
+ const stopped = this.stateManager.stopState();
490
+ this.paused = true;
491
+ this.refreshStateRefs();
492
+ return stopped;
493
+ }
494
+ return this.switchState(name, autoPlay);
495
+ }
496
+ removeState(name) {
497
+ const removed = this.stateManager.removeState(name);
498
+ if (removed) {
499
+ this.refreshStateRefs();
500
+ }
501
+ return removed;
502
+ }
503
+ switchState(name, autoPlay = true) {
504
+ const state = this.stateManager.switchState(name, autoPlay);
505
+ if (!state) {
506
+ return false;
507
+ }
508
+ this.paused = !state.isPlaying;
509
+ this.refreshStateRefs();
510
+ return true;
511
+ }
512
+ playState(name) {
513
+ const played = this.stateManager.playState(name);
514
+ if (!played) {
515
+ return false;
516
+ }
517
+ this.paused = false;
518
+ this.refreshStateRefs();
519
+ return true;
520
+ }
521
+ pauseState(name) {
522
+ const paused = this.stateManager.pauseState(name);
523
+ if (!paused) {
524
+ return false;
525
+ }
526
+ this.paused = true;
527
+ this.refreshStateRefs();
528
+ return true;
529
+ }
530
+ stopState(name) {
531
+ const stopped = this.stateManager.stopState(name);
532
+ if (!stopped) {
533
+ return false;
534
+ }
535
+ this.paused = true;
536
+ this.refreshStateRefs();
537
+ return true;
538
+ }
539
+ };
540
+ __name(_AnimationComponent, "AnimationComponent");
541
+ var AnimationComponent = _AnimationComponent;
542
+ var DEFAULT_FOV = 50;
543
+ var DEFAULT_NEAR = 0.1;
544
+ var DEFAULT_FAR = 2e3;
545
+ var DEFAULT_ORTHO_LEFT = -5;
546
+ var DEFAULT_ORTHO_RIGHT = 5;
547
+ var DEFAULT_ORTHO_TOP = 5;
548
+ var DEFAULT_ORTHO_BOTTOM = -5;
549
+ var DEFAULT_ZOOM = 1;
550
+ function inferProjection(camera) {
551
+ if (camera instanceof THREE5__namespace.OrthographicCamera) {
552
+ return "orthographic";
553
+ }
554
+ return "perspective";
555
+ }
556
+ __name(inferProjection, "inferProjection");
557
+ function readCameraNear(camera) {
558
+ if (camera && "near" in camera && typeof camera.near === "number" && Number.isFinite(camera.near)) {
559
+ return camera.near;
560
+ }
561
+ return null;
562
+ }
563
+ __name(readCameraNear, "readCameraNear");
564
+ function readCameraFar(camera) {
565
+ if (camera && "far" in camera && typeof camera.far === "number" && Number.isFinite(camera.far)) {
566
+ return camera.far;
567
+ }
568
+ return null;
569
+ }
570
+ __name(readCameraFar, "readCameraFar");
571
+ function inferFov(camera) {
572
+ if (camera instanceof THREE5__namespace.PerspectiveCamera && Number.isFinite(camera.fov)) {
573
+ return camera.fov;
574
+ }
575
+ return DEFAULT_FOV;
576
+ }
577
+ __name(inferFov, "inferFov");
578
+ function inferNear(camera) {
579
+ const near = readCameraNear(camera);
580
+ if (near !== null) {
581
+ return near;
582
+ }
583
+ return DEFAULT_NEAR;
584
+ }
585
+ __name(inferNear, "inferNear");
586
+ function inferFar(camera) {
587
+ const far = readCameraFar(camera);
588
+ if (far !== null) {
589
+ return far;
590
+ }
591
+ return DEFAULT_FAR;
592
+ }
593
+ __name(inferFar, "inferFar");
594
+ function inferOrthoLeft(camera) {
595
+ if (camera instanceof THREE5__namespace.OrthographicCamera && Number.isFinite(camera.left)) {
596
+ return camera.left;
597
+ }
598
+ return DEFAULT_ORTHO_LEFT;
599
+ }
600
+ __name(inferOrthoLeft, "inferOrthoLeft");
601
+ function inferOrthoRight(camera) {
602
+ if (camera instanceof THREE5__namespace.OrthographicCamera && Number.isFinite(camera.right)) {
603
+ return camera.right;
604
+ }
605
+ return DEFAULT_ORTHO_RIGHT;
606
+ }
607
+ __name(inferOrthoRight, "inferOrthoRight");
608
+ function inferOrthoTop(camera) {
609
+ if (camera instanceof THREE5__namespace.OrthographicCamera && Number.isFinite(camera.top)) {
610
+ return camera.top;
611
+ }
612
+ return DEFAULT_ORTHO_TOP;
613
+ }
614
+ __name(inferOrthoTop, "inferOrthoTop");
615
+ function inferOrthoBottom(camera) {
616
+ if (camera instanceof THREE5__namespace.OrthographicCamera && Number.isFinite(camera.bottom)) {
617
+ return camera.bottom;
618
+ }
619
+ return DEFAULT_ORTHO_BOTTOM;
620
+ }
621
+ __name(inferOrthoBottom, "inferOrthoBottom");
622
+ function inferZoom(camera) {
623
+ if (camera && "zoom" in camera && typeof camera.zoom === "number" && Number.isFinite(camera.zoom)) {
624
+ return camera.zoom;
625
+ }
626
+ return DEFAULT_ZOOM;
627
+ }
628
+ __name(inferZoom, "inferZoom");
629
+ var _CameraComponent = class _CameraComponent extends Component {
630
+ constructor(payload = {}) {
631
+ super();
632
+ this.camera = payload.camera ?? new THREE5__namespace.PerspectiveCamera();
633
+ this.type = payload.type ?? "3d";
634
+ this.isDefault = typeof payload.isDefault === "boolean" ? payload.isDefault : false;
635
+ this.projection = payload.projection ?? inferProjection(payload.camera);
636
+ this.fov = typeof payload.fov === "number" && Number.isFinite(payload.fov) ? payload.fov : inferFov(payload.camera);
637
+ this.near = typeof payload.near === "number" && Number.isFinite(payload.near) ? payload.near : inferNear(payload.camera);
638
+ this.far = typeof payload.far === "number" && Number.isFinite(payload.far) ? payload.far : inferFar(payload.camera);
639
+ this.left = typeof payload.left === "number" && Number.isFinite(payload.left) ? payload.left : inferOrthoLeft(payload.camera);
640
+ this.right = typeof payload.right === "number" && Number.isFinite(payload.right) ? payload.right : inferOrthoRight(payload.camera);
641
+ this.top = typeof payload.top === "number" && Number.isFinite(payload.top) ? payload.top : inferOrthoTop(payload.camera);
642
+ this.bottom = typeof payload.bottom === "number" && Number.isFinite(payload.bottom) ? payload.bottom : inferOrthoBottom(payload.camera);
643
+ this.zoom = typeof payload.zoom === "number" && Number.isFinite(payload.zoom) ? payload.zoom : inferZoom(payload.camera);
644
+ }
645
+ };
646
+ __name(_CameraComponent, "CameraComponent");
647
+ var CameraComponent = _CameraComponent;
648
+
649
+ // core/components/Audio.ts
650
+ var DEFAULT_AUDIO_OPTIONS = {
651
+ autoplay: false,
652
+ loop: false,
653
+ pitch: 1,
654
+ volume: 1,
655
+ positional: false,
656
+ refDistance: 1,
657
+ distanceModel: "inverse",
658
+ rolloffFactor: 1,
659
+ bus: "sfx"
660
+ };
661
+ var _AudioComponent = class _AudioComponent extends Component {
662
+ constructor(path, options = {}) {
663
+ super();
664
+ this.path = path;
665
+ this.options = {
666
+ ...DEFAULT_AUDIO_OPTIONS,
667
+ ...options
668
+ };
669
+ this.object = null;
670
+ this.audio = null;
671
+ Object.defineProperty(this, "isPlaying", {
672
+ value: false,
673
+ writable: true,
674
+ configurable: true,
675
+ enumerable: false
676
+ });
677
+ Object.defineProperty(this, "isPaused", {
678
+ value: false,
679
+ writable: true,
680
+ configurable: true,
681
+ enumerable: false
682
+ });
683
+ }
684
+ /**
685
+ * Signals `AudioSystem` to start (or resume) playback.
686
+ * Has no direct effect in the editor — `AudioSystem` drives the actual
687
+ * THREE.js call in preview.
688
+ */
689
+ play() {
690
+ this.isPlaying = true;
691
+ this.isPaused = false;
692
+ }
693
+ /**
694
+ * Signals `AudioSystem` to pause playback, preserving the current position.
695
+ * Calling {@link play} afterwards resumes from where it paused.
696
+ * No-op if not currently playing.
697
+ */
698
+ pause() {
699
+ if (!this.isPlaying) return;
700
+ this.isPlaying = false;
701
+ this.isPaused = true;
702
+ }
703
+ /**
704
+ * Signals `AudioSystem` to stop playback and reset the playback position.
705
+ */
706
+ stop() {
707
+ this.isPlaying = false;
708
+ this.isPaused = false;
709
+ }
710
+ };
711
+ __name(_AudioComponent, "AudioComponent");
712
+ var AudioComponent = _AudioComponent;
713
+
714
+ // core/components/Environment.ts
715
+ var DEFAULT_ENVIRONMENT_LIGHTING = {
716
+ envMapUrl: "",
717
+ envIntensity: 1,
718
+ envRotationY: 0,
719
+ useAsBackground: false,
720
+ backgroundBlurriness: 0,
721
+ backgroundIntensity: 1,
722
+ toneMapping: "none",
723
+ exposure: 1
724
+ };
725
+ var DEFAULT_ENVIRONMENT_STATE = {
726
+ skybox: {
727
+ type: "none",
728
+ color: "#1e1e1e",
729
+ imageUrl: "",
730
+ gradient: {
731
+ colors: ["#464766", "#657ea6", "#0f0e1a"],
732
+ effect: "linear"
733
+ }
734
+ },
735
+ fog: {
736
+ type: "none",
737
+ color: "#1e1e1e",
738
+ linear: {
739
+ near: 1,
740
+ far: 100
741
+ },
742
+ exponential: {
743
+ density: 2e-3
744
+ }
745
+ },
746
+ gravity: {
747
+ x: 0,
748
+ y: -9.81,
749
+ z: 0
750
+ },
751
+ fixedTimeStep: 0.02
752
+ };
753
+ function normalizeColors(colors) {
754
+ if (!Array.isArray(colors)) {
755
+ return [...DEFAULT_ENVIRONMENT_STATE.skybox.gradient.colors];
756
+ }
757
+ const normalized = colors.filter(
758
+ (entry) => typeof entry === "string" && entry.length > 0
759
+ );
760
+ if (normalized.length === 0) {
761
+ return [...DEFAULT_ENVIRONMENT_STATE.skybox.gradient.colors];
762
+ }
763
+ return normalized;
764
+ }
765
+ __name(normalizeColors, "normalizeColors");
766
+ function normalizeGradientEffect(value) {
767
+ if (value === "radial" || value === "linear" || value === "angular") {
768
+ return value;
769
+ }
770
+ return DEFAULT_ENVIRONMENT_STATE.skybox.gradient.effect;
771
+ }
772
+ __name(normalizeGradientEffect, "normalizeGradientEffect");
773
+ function normalizeSkyboxType(value) {
774
+ if (value === "gradient" || value === "color" || value === "none") {
775
+ return value;
776
+ }
777
+ if (value === "image" || value === "Image") {
778
+ return "image";
779
+ }
780
+ return DEFAULT_ENVIRONMENT_STATE.skybox.type;
781
+ }
782
+ __name(normalizeSkyboxType, "normalizeSkyboxType");
783
+ function normalizeFogType(value) {
784
+ if (value === "linear" || value === "exponential" || value === "none") {
785
+ return value;
786
+ }
787
+ return DEFAULT_ENVIRONMENT_STATE.fog.type;
788
+ }
789
+ __name(normalizeFogType, "normalizeFogType");
790
+ function toFiniteNumber(value, fallback) {
791
+ if (typeof value !== "number" || !Number.isFinite(value)) {
792
+ return fallback;
793
+ }
794
+ return value;
795
+ }
796
+ __name(toFiniteNumber, "toFiniteNumber");
797
+ function normalizeImageProjection(value) {
798
+ return value === "screen" || value === "equirect" ? value : void 0;
799
+ }
800
+ __name(normalizeImageProjection, "normalizeImageProjection");
801
+ function normalizeToneMapping(value) {
802
+ if (value === "none" || value === "aces" || value === "agx" || value === "neutral") {
803
+ return value;
804
+ }
805
+ return DEFAULT_ENVIRONMENT_LIGHTING.toneMapping;
806
+ }
807
+ __name(normalizeToneMapping, "normalizeToneMapping");
808
+ function normalizeEnvironmentLighting(value) {
809
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
810
+ return void 0;
811
+ }
812
+ const lighting = value;
813
+ const defaults = DEFAULT_ENVIRONMENT_LIGHTING;
814
+ return {
815
+ envMapUrl: typeof lighting.envMapUrl === "string" ? lighting.envMapUrl : defaults.envMapUrl,
816
+ envIntensity: Math.max(0, toFiniteNumber(lighting.envIntensity, defaults.envIntensity)),
817
+ envRotationY: toFiniteNumber(lighting.envRotationY, defaults.envRotationY),
818
+ useAsBackground: typeof lighting.useAsBackground === "boolean" ? lighting.useAsBackground : defaults.useAsBackground,
819
+ backgroundBlurriness: Math.min(
820
+ 1,
821
+ Math.max(0, toFiniteNumber(lighting.backgroundBlurriness, defaults.backgroundBlurriness))
822
+ ),
823
+ backgroundIntensity: Math.max(
824
+ 0,
825
+ toFiniteNumber(lighting.backgroundIntensity, defaults.backgroundIntensity)
826
+ ),
827
+ toneMapping: normalizeToneMapping(lighting.toneMapping),
828
+ exposure: Math.max(0, toFiniteNumber(lighting.exposure, defaults.exposure))
829
+ };
830
+ }
831
+ __name(normalizeEnvironmentLighting, "normalizeEnvironmentLighting");
832
+ var _Environment = class _Environment extends Component {
833
+ constructor(values) {
834
+ super();
835
+ const skybox = values?.skybox;
836
+ const fog = values?.fog;
837
+ const gravity = values?.gravity;
838
+ const skyboxState = {
839
+ type: normalizeSkyboxType(skybox?.type),
840
+ color: typeof skybox?.color === "string" ? skybox.color : DEFAULT_ENVIRONMENT_STATE.skybox.color,
841
+ imageUrl: typeof skybox?.imageUrl === "string" ? skybox.imageUrl : DEFAULT_ENVIRONMENT_STATE.skybox.imageUrl,
842
+ gradient: {
843
+ colors: normalizeColors(skybox?.gradient?.colors),
844
+ effect: normalizeGradientEffect(skybox?.gradient?.effect)
845
+ }
846
+ };
847
+ const imageProjection = normalizeImageProjection(skybox?.imageProjection);
848
+ if (imageProjection) {
849
+ skyboxState.imageProjection = imageProjection;
850
+ }
851
+ this.values = {
852
+ skybox: skyboxState,
853
+ fog: {
854
+ type: normalizeFogType(fog?.type),
855
+ color: typeof fog?.color === "string" ? fog.color : DEFAULT_ENVIRONMENT_STATE.fog.color,
856
+ linear: {
857
+ near: toFiniteNumber(
858
+ fog?.linear?.near,
859
+ DEFAULT_ENVIRONMENT_STATE.fog.linear.near
860
+ ),
861
+ far: toFiniteNumber(
862
+ fog?.linear?.far,
863
+ DEFAULT_ENVIRONMENT_STATE.fog.linear.far
864
+ )
865
+ },
866
+ exponential: {
867
+ density: toFiniteNumber(
868
+ fog?.exponential?.density,
869
+ DEFAULT_ENVIRONMENT_STATE.fog.exponential.density
870
+ )
871
+ }
872
+ },
873
+ gravity: {
874
+ x: toFiniteNumber(gravity?.x, DEFAULT_ENVIRONMENT_STATE.gravity.x),
875
+ y: toFiniteNumber(gravity?.y, DEFAULT_ENVIRONMENT_STATE.gravity.y),
876
+ z: toFiniteNumber(gravity?.z, DEFAULT_ENVIRONMENT_STATE.gravity.z)
877
+ },
878
+ fixedTimeStep: toFiniteNumber(
879
+ values?.fixedTimeStep,
880
+ DEFAULT_ENVIRONMENT_STATE.fixedTimeStep
881
+ )
882
+ };
883
+ const lighting = normalizeEnvironmentLighting(values?.lighting);
884
+ if (lighting) {
885
+ this.values.lighting = lighting;
886
+ }
887
+ }
888
+ };
889
+ __name(_Environment, "Environment");
890
+ var Environment = _Environment;
891
+
892
+ // core/components/Postprocessing.ts
893
+ var DEFAULT_POSTPROCESSING_STATE = {
894
+ postEnabled: false,
895
+ dof: {
896
+ enabled: false,
897
+ focusDistance: 0.015,
898
+ focalLength: 0.018,
899
+ bokehScale: 3
900
+ },
901
+ bloom: {
902
+ enabled: false,
903
+ intensity: 1.2,
904
+ threshold: 0.2,
905
+ radius: 0.7
906
+ },
907
+ vignette: {
908
+ enabled: false,
909
+ offset: 0.05,
910
+ darkness: 1.2
911
+ },
912
+ chromAberration: {
913
+ enabled: false,
914
+ offsetX: 3e-3,
915
+ offsetY: 3e-3
916
+ },
917
+ noise: {
918
+ enabled: false,
919
+ opacity: 0.12
920
+ },
921
+ pixelation: {
922
+ enabled: false,
923
+ granularity: 6
924
+ },
925
+ toneMapping: {
926
+ enabled: false,
927
+ exposure: 1.3
928
+ },
929
+ hueSaturation: {
930
+ enabled: false,
931
+ hue: 0.05,
932
+ saturation: 0.2
933
+ },
934
+ sepia: {
935
+ enabled: false,
936
+ intensity: 0.5
937
+ },
938
+ smaa: {
939
+ enabled: false
940
+ },
941
+ ssao: {
942
+ enabled: false,
943
+ intensity: 1.5,
944
+ radius: 0.25
945
+ },
946
+ dotScreen: {
947
+ enabled: false,
948
+ dotScreenScale: 1.2,
949
+ dotScreenAngle: 1.57,
950
+ blendFunction: void 0,
951
+ opacity: void 0
952
+ },
953
+ glitch: {
954
+ enabled: false,
955
+ blendFunction: void 0,
956
+ delay: void 0,
957
+ duration: void 0,
958
+ dtSize: void 0,
959
+ columns: void 0,
960
+ ratio: void 0,
961
+ mode: void 0}
962
+ };
963
+ function asRecord(value) {
964
+ if (!value || typeof value !== "object") {
965
+ return null;
966
+ }
967
+ return value;
968
+ }
969
+ __name(asRecord, "asRecord");
970
+ function toFiniteNumber2(value, fallback) {
971
+ if (typeof value !== "number" || !Number.isFinite(value)) {
972
+ return fallback;
973
+ }
974
+ return value;
975
+ }
976
+ __name(toFiniteNumber2, "toFiniteNumber");
977
+ function toBoolean(value, fallback) {
978
+ if (typeof value !== "boolean") {
979
+ return fallback;
980
+ }
981
+ return value;
982
+ }
983
+ __name(toBoolean, "toBoolean");
984
+ function normalizeNumberTuple(value) {
985
+ if (!Array.isArray(value) || value.length !== 2) {
986
+ return void 0;
987
+ }
988
+ if (typeof value[0] !== "number" || !Number.isFinite(value[0]) || typeof value[1] !== "number" || !Number.isFinite(value[1])) {
989
+ return void 0;
990
+ }
991
+ return [value[0], value[1]];
992
+ }
993
+ __name(normalizeNumberTuple, "normalizeNumberTuple");
994
+ function normalizePostprocessing(value) {
995
+ const postprocessing = asRecord(value);
996
+ const defaults = DEFAULT_POSTPROCESSING_STATE;
997
+ const dof = asRecord(postprocessing?.dof);
998
+ const bloom = asRecord(postprocessing?.bloom);
999
+ const vignette = asRecord(postprocessing?.vignette);
1000
+ const chromAberration = asRecord(postprocessing?.chromAberration);
1001
+ const noise = asRecord(postprocessing?.noise);
1002
+ const pixelation = asRecord(postprocessing?.pixelation);
1003
+ const toneMapping = asRecord(postprocessing?.toneMapping);
1004
+ const hueSaturation = asRecord(postprocessing?.hueSaturation);
1005
+ const sepia = asRecord(postprocessing?.sepia);
1006
+ const smaa = asRecord(postprocessing?.smaa);
1007
+ const ssao = asRecord(postprocessing?.ssao);
1008
+ const dotScreen = asRecord(postprocessing?.dotScreen);
1009
+ const glitch = asRecord(postprocessing?.glitch);
1010
+ const glitchChromaticAberrationOffset = asRecord(
1011
+ glitch?.chromaticAberrationOffset
1012
+ );
1013
+ const glitchStrength = asRecord(glitch?.strength);
1014
+ const dotScreenScale = toFiniteNumber2(
1015
+ dotScreen?.dotScreenScale,
1016
+ defaults.dotScreen.dotScreenScale
1017
+ );
1018
+ const dotScreenAngle = toFiniteNumber2(
1019
+ dotScreen?.dotScreenAngle,
1020
+ defaults.dotScreen.dotScreenAngle
1021
+ );
1022
+ const normalizedGlitchStrength = typeof glitch?.strength === "number" && Number.isFinite(glitch.strength) ? glitch.strength : glitchStrength && typeof glitchStrength.x === "number" && Number.isFinite(glitchStrength.x) && typeof glitchStrength.y === "number" && Number.isFinite(glitchStrength.y) ? { x: glitchStrength.x, y: glitchStrength.y } : void 0;
1023
+ const normalizedGlitchChromaticAberrationOffset = normalizeNumberTuple(glitch?.chromaticAberrationOffset) ?? (glitchChromaticAberrationOffset && typeof glitchChromaticAberrationOffset.x === "number" && Number.isFinite(glitchChromaticAberrationOffset.x) && typeof glitchChromaticAberrationOffset.y === "number" && Number.isFinite(glitchChromaticAberrationOffset.y) ? {
1024
+ x: glitchChromaticAberrationOffset.x,
1025
+ y: glitchChromaticAberrationOffset.y
1026
+ } : void 0);
1027
+ return {
1028
+ postEnabled: toBoolean(postprocessing?.postEnabled, defaults.postEnabled),
1029
+ dof: {
1030
+ enabled: toBoolean(dof?.enabled, defaults.dof.enabled),
1031
+ focusDistance: toFiniteNumber2(dof?.focusDistance, defaults.dof.focusDistance),
1032
+ focalLength: toFiniteNumber2(dof?.focalLength, defaults.dof.focalLength),
1033
+ bokehScale: toFiniteNumber2(dof?.bokehScale, defaults.dof.bokehScale)
1034
+ },
1035
+ bloom: {
1036
+ enabled: toBoolean(bloom?.enabled, defaults.bloom.enabled),
1037
+ intensity: toFiniteNumber2(bloom?.intensity, defaults.bloom.intensity),
1038
+ threshold: toFiniteNumber2(bloom?.threshold, defaults.bloom.threshold),
1039
+ radius: toFiniteNumber2(bloom?.radius, defaults.bloom.radius)
1040
+ },
1041
+ vignette: {
1042
+ enabled: toBoolean(vignette?.enabled, defaults.vignette.enabled),
1043
+ offset: toFiniteNumber2(vignette?.offset, defaults.vignette.offset),
1044
+ darkness: toFiniteNumber2(vignette?.darkness, defaults.vignette.darkness)
1045
+ },
1046
+ chromAberration: {
1047
+ enabled: toBoolean(chromAberration?.enabled, defaults.chromAberration.enabled),
1048
+ offsetX: toFiniteNumber2(chromAberration?.offsetX, defaults.chromAberration.offsetX),
1049
+ offsetY: toFiniteNumber2(chromAberration?.offsetY, defaults.chromAberration.offsetY)
1050
+ },
1051
+ noise: {
1052
+ enabled: toBoolean(noise?.enabled, defaults.noise.enabled),
1053
+ opacity: toFiniteNumber2(noise?.opacity, defaults.noise.opacity)
1054
+ },
1055
+ pixelation: {
1056
+ enabled: toBoolean(pixelation?.enabled, defaults.pixelation.enabled),
1057
+ granularity: toFiniteNumber2(pixelation?.granularity, defaults.pixelation.granularity)
1058
+ },
1059
+ toneMapping: {
1060
+ enabled: toBoolean(toneMapping?.enabled, defaults.toneMapping.enabled),
1061
+ exposure: toFiniteNumber2(toneMapping?.exposure, defaults.toneMapping.exposure)
1062
+ },
1063
+ hueSaturation: {
1064
+ enabled: toBoolean(hueSaturation?.enabled, defaults.hueSaturation.enabled),
1065
+ hue: toFiniteNumber2(hueSaturation?.hue, defaults.hueSaturation.hue),
1066
+ saturation: toFiniteNumber2(
1067
+ hueSaturation?.saturation,
1068
+ defaults.hueSaturation.saturation
1069
+ )
1070
+ },
1071
+ sepia: {
1072
+ enabled: toBoolean(sepia?.enabled, defaults.sepia.enabled),
1073
+ intensity: toFiniteNumber2(sepia?.intensity, defaults.sepia.intensity)
1074
+ },
1075
+ smaa: {
1076
+ enabled: toBoolean(smaa?.enabled, defaults.smaa.enabled)
1077
+ },
1078
+ ssao: {
1079
+ enabled: toBoolean(ssao?.enabled, defaults.ssao.enabled),
1080
+ intensity: toFiniteNumber2(ssao?.intensity, defaults.ssao.intensity),
1081
+ radius: toFiniteNumber2(ssao?.radius, defaults.ssao.radius)
1082
+ },
1083
+ dotScreen: {
1084
+ enabled: toBoolean(dotScreen?.enabled, defaults.dotScreen.enabled),
1085
+ dotScreenScale,
1086
+ dotScreenAngle,
1087
+ scale: toFiniteNumber2(dotScreen?.scale, dotScreenScale),
1088
+ angle: toFiniteNumber2(dotScreen?.angle, dotScreenAngle),
1089
+ blendFunction: typeof dotScreen?.blendFunction === "number" && Number.isFinite(dotScreen.blendFunction) ? dotScreen.blendFunction : defaults.dotScreen.blendFunction,
1090
+ opacity: typeof dotScreen?.opacity === "number" && Number.isFinite(dotScreen.opacity) ? dotScreen.opacity : defaults.dotScreen.opacity
1091
+ },
1092
+ glitch: {
1093
+ enabled: toBoolean(glitch?.enabled, defaults.glitch.enabled),
1094
+ blendFunction: typeof glitch?.blendFunction === "number" && Number.isFinite(glitch.blendFunction) ? glitch.blendFunction : defaults.glitch.blendFunction,
1095
+ chromaticAberrationOffset: normalizedGlitchChromaticAberrationOffset,
1096
+ delay: normalizeNumberTuple(glitch?.delay) ?? defaults.glitch.delay,
1097
+ duration: normalizeNumberTuple(glitch?.duration) ?? defaults.glitch.duration,
1098
+ strength: normalizedGlitchStrength,
1099
+ dtSize: typeof glitch?.dtSize === "number" && Number.isFinite(glitch.dtSize) ? glitch.dtSize : defaults.glitch.dtSize,
1100
+ columns: typeof glitch?.columns === "number" && Number.isFinite(glitch.columns) ? glitch.columns : defaults.glitch.columns,
1101
+ ratio: typeof glitch?.ratio === "number" && Number.isFinite(glitch.ratio) ? glitch.ratio : defaults.glitch.ratio,
1102
+ mode: typeof glitch?.mode === "string" ? glitch.mode : defaults.glitch.mode,
1103
+ active: toBoolean(glitch?.active, false)
1104
+ }
1105
+ };
1106
+ }
1107
+ __name(normalizePostprocessing, "normalizePostprocessing");
1108
+ var _Postprocessing = class _Postprocessing extends Component {
1109
+ constructor(values) {
1110
+ super();
1111
+ this.values = normalizePostprocessing(values);
1112
+ }
1113
+ };
1114
+ __name(_Postprocessing, "Postprocessing");
1115
+ var Postprocessing = _Postprocessing;
1116
+ var DEFAULT_MESH_GEOMETRY_PARAMETERS = {
1117
+ capsule: { radius: 0.5, height: 1 },
1118
+ cube: { width: 1, height: 1, depth: 1 },
1119
+ cylinder: { radius: 0.5, height: 1 },
1120
+ plane: { width: 100, height: 100 },
1121
+ sphere: { radius: 0.5 }
1122
+ };
1123
+ var GEOMETRY_TYPE_BY_KIND = {
1124
+ capsule: "CapsuleGeometry",
1125
+ cube: "BoxGeometry",
1126
+ cylinder: "CylinderGeometry",
1127
+ model: "Model",
1128
+ plane: "PlaneGeometry",
1129
+ sphere: "SphereGeometry"
1130
+ };
1131
+ var _MeshGeometryComponent = class _MeshGeometryComponent extends Component {
1132
+ constructor(kind, object, parameters, options) {
1133
+ super();
1134
+ this.kind = kind;
1135
+ this.geometryType = GEOMETRY_TYPE_BY_KIND[kind];
1136
+ this.object = object;
1137
+ this.modelName = options?.modelName ?? "";
1138
+ this.castShadow = options?.castShadow ?? false;
1139
+ this.receiveShadow = options?.receiveShadow ?? false;
1140
+ switch (kind) {
1141
+ case "cube":
1142
+ this.parameters = {
1143
+ ...DEFAULT_MESH_GEOMETRY_PARAMETERS.cube,
1144
+ ...parameters
1145
+ };
1146
+ break;
1147
+ case "plane":
1148
+ this.parameters = {
1149
+ ...DEFAULT_MESH_GEOMETRY_PARAMETERS.plane,
1150
+ ...parameters
1151
+ };
1152
+ break;
1153
+ case "sphere":
1154
+ this.parameters = {
1155
+ ...DEFAULT_MESH_GEOMETRY_PARAMETERS.sphere,
1156
+ ...parameters
1157
+ };
1158
+ break;
1159
+ case "cylinder":
1160
+ this.parameters = {
1161
+ ...DEFAULT_MESH_GEOMETRY_PARAMETERS.cylinder,
1162
+ ...parameters
1163
+ };
1164
+ break;
1165
+ case "capsule":
1166
+ this.parameters = {
1167
+ ...DEFAULT_MESH_GEOMETRY_PARAMETERS.capsule,
1168
+ ...parameters
1169
+ };
1170
+ break;
1171
+ case "model":
1172
+ this.parameters = {};
1173
+ break;
1174
+ }
1175
+ }
1176
+ };
1177
+ __name(_MeshGeometryComponent, "MeshGeometryComponent");
1178
+ var MeshGeometryComponent = _MeshGeometryComponent;
1179
+
1180
+ // core/components/InstancedMesh.ts
1181
+ var DEFAULT_INSTANCED_MESH_PARAMETERS = {
1182
+ capsule: DEFAULT_MESH_GEOMETRY_PARAMETERS.capsule,
1183
+ cube: DEFAULT_MESH_GEOMETRY_PARAMETERS.cube,
1184
+ cylinder: DEFAULT_MESH_GEOMETRY_PARAMETERS.cylinder,
1185
+ model: DEFAULT_MESH_GEOMETRY_PARAMETERS.cube,
1186
+ plane: DEFAULT_MESH_GEOMETRY_PARAMETERS.plane,
1187
+ sphere: DEFAULT_MESH_GEOMETRY_PARAMETERS.sphere
1188
+ };
1189
+ var _InstancedMeshComponent = class _InstancedMeshComponent extends Component {
1190
+ constructor(meshKind = "cube", meshParameters, options) {
1191
+ super();
1192
+ this.meshKind = meshKind;
1193
+ this.modelPath = options?.modelPath ?? "";
1194
+ this.meshParameters = {
1195
+ ...DEFAULT_INSTANCED_MESH_PARAMETERS[meshKind],
1196
+ ...meshParameters ?? {}
1197
+ };
1198
+ this.castShadow = options?.castShadow ?? false;
1199
+ this.receiveShadow = options?.receiveShadow ?? false;
1200
+ this.instanceEntityIds = options?.instanceEntityIds ?? [];
1201
+ this.instancedMesh = null;
1202
+ }
1203
+ /** Sanitize and return a copy of the current mesh parameters with valid values. */
1204
+ getSanitizedParameters() {
1205
+ const MIN_DIM = 0.01;
1206
+ const MIN_RAD = 1e-3;
1207
+ const sanitize = /* @__PURE__ */ __name((v, min) => Number.isFinite(v) ? Math.max(min, v) : min, "sanitize");
1208
+ switch (this.meshKind) {
1209
+ case "cube": {
1210
+ const p = this.meshParameters;
1211
+ return {
1212
+ width: sanitize(p.width, MIN_DIM),
1213
+ height: sanitize(p.height, MIN_DIM),
1214
+ depth: sanitize(p.depth, MIN_DIM)
1215
+ };
1216
+ }
1217
+ case "plane": {
1218
+ const p = this.meshParameters;
1219
+ return {
1220
+ width: sanitize(p.width, MIN_DIM),
1221
+ height: sanitize(p.height, MIN_DIM)
1222
+ };
1223
+ }
1224
+ case "sphere": {
1225
+ const p = this.meshParameters;
1226
+ return { radius: sanitize(p.radius, MIN_RAD) };
1227
+ }
1228
+ case "cylinder":
1229
+ case "capsule": {
1230
+ const p = this.meshParameters;
1231
+ return {
1232
+ radius: sanitize(p.radius, MIN_RAD),
1233
+ height: sanitize(p.height, MIN_DIM)
1234
+ };
1235
+ }
1236
+ case "model":
1237
+ return DEFAULT_MESH_GEOMETRY_PARAMETERS.cube;
1238
+ }
1239
+ }
1240
+ };
1241
+ __name(_InstancedMeshComponent, "InstancedMeshComponent");
1242
+ var InstancedMeshComponent = _InstancedMeshComponent;
1243
+
1244
+ // core/components/InstanceSlotComponent.ts
1245
+ var _InstanceSlotComponent = class _InstanceSlotComponent extends Component {
1246
+ constructor(groupEntityId, slotIndex) {
1247
+ super();
1248
+ this.groupEntityId = groupEntityId;
1249
+ this.slotIndex = slotIndex;
1250
+ }
1251
+ };
1252
+ __name(_InstanceSlotComponent, "InstanceSlotComponent");
1253
+ var InstanceSlotComponent = _InstanceSlotComponent;
1254
+
1255
+ // core/components/Physics.ts
1256
+ var DEFAULT_RIGIDBODY_STATE = {
1257
+ enabled: true,
1258
+ type: "dynamic",
1259
+ mass: 1,
1260
+ linearDamping: 0,
1261
+ angularDamping: 0,
1262
+ gravityScale: 1,
1263
+ canSleep: true,
1264
+ ccdEnabled: false,
1265
+ lockTranslations: false,
1266
+ lockRotations: false};
1267
+ var DEFAULT_COLLIDER_STATE = {
1268
+ enabled: true,
1269
+ shape: "cuboid",
1270
+ offsetPosition: {
1271
+ x: 0,
1272
+ y: 0,
1273
+ z: 0
1274
+ },
1275
+ offsetRotation: {
1276
+ x: 0,
1277
+ y: 0,
1278
+ z: 0
1279
+ },
1280
+ size: {
1281
+ x: 1,
1282
+ y: 1,
1283
+ z: 1
1284
+ },
1285
+ radius: 0.5,
1286
+ height: 1,
1287
+ restitution: 0,
1288
+ friction: 0.5,
1289
+ isSensor: false
1290
+ };
1291
+ function asRecord2(value) {
1292
+ if (!value || typeof value !== "object") {
1293
+ return null;
1294
+ }
1295
+ return value;
1296
+ }
1297
+ __name(asRecord2, "asRecord");
1298
+ function toFiniteNumber3(value, fallback) {
1299
+ if (typeof value !== "number" || !Number.isFinite(value)) {
1300
+ return fallback;
1301
+ }
1302
+ return value;
1303
+ }
1304
+ __name(toFiniteNumber3, "toFiniteNumber");
1305
+ function toBoolean2(value, fallback) {
1306
+ if (typeof value !== "boolean") {
1307
+ return fallback;
1308
+ }
1309
+ return value;
1310
+ }
1311
+ __name(toBoolean2, "toBoolean");
1312
+ function toRigidbodyType(value, fallback) {
1313
+ if (value === "dynamic" || value === "fixed" || value === "kinematicPosition" || value === "kinematicVelocity") {
1314
+ return value;
1315
+ }
1316
+ return fallback;
1317
+ }
1318
+ __name(toRigidbodyType, "toRigidbodyType");
1319
+ function toColliderShape(value, fallback) {
1320
+ if (value === "cuboid" || value === "ball" || value === "capsule" || value === "cylinder" || value === "trimesh") {
1321
+ return value;
1322
+ }
1323
+ return fallback;
1324
+ }
1325
+ __name(toColliderShape, "toColliderShape");
1326
+ function normalizeRigidbodyState(value) {
1327
+ const source = asRecord2(value);
1328
+ const defaults = DEFAULT_RIGIDBODY_STATE;
1329
+ const legacyLockTranslations = toBoolean2(
1330
+ source?.lockTranslations,
1331
+ defaults.lockTranslations
1332
+ );
1333
+ const legacyLockRotations = toBoolean2(
1334
+ source?.lockRotations,
1335
+ defaults.lockRotations
1336
+ );
1337
+ const lockTranslationX = toBoolean2(
1338
+ source?.lockTranslationX,
1339
+ legacyLockTranslations
1340
+ );
1341
+ const lockTranslationY = toBoolean2(
1342
+ source?.lockTranslationY,
1343
+ legacyLockTranslations
1344
+ );
1345
+ const lockTranslationZ = toBoolean2(
1346
+ source?.lockTranslationZ,
1347
+ legacyLockTranslations
1348
+ );
1349
+ const lockRotationX = toBoolean2(source?.lockRotationX, legacyLockRotations);
1350
+ const lockRotationY = toBoolean2(source?.lockRotationY, legacyLockRotations);
1351
+ const lockRotationZ = toBoolean2(source?.lockRotationZ, legacyLockRotations);
1352
+ return {
1353
+ enabled: toBoolean2(source?.enabled, defaults.enabled),
1354
+ type: toRigidbodyType(source?.type, defaults.type),
1355
+ mass: Math.max(1e-4, toFiniteNumber3(source?.mass, defaults.mass)),
1356
+ linearDamping: Math.max(
1357
+ 0,
1358
+ toFiniteNumber3(source?.linearDamping, defaults.linearDamping)
1359
+ ),
1360
+ angularDamping: Math.max(
1361
+ 0,
1362
+ toFiniteNumber3(source?.angularDamping, defaults.angularDamping)
1363
+ ),
1364
+ gravityScale: toFiniteNumber3(source?.gravityScale, defaults.gravityScale),
1365
+ canSleep: toBoolean2(source?.canSleep, defaults.canSleep),
1366
+ ccdEnabled: toBoolean2(source?.ccdEnabled, defaults.ccdEnabled),
1367
+ lockTranslations: legacyLockTranslations,
1368
+ lockTranslationX,
1369
+ lockTranslationY,
1370
+ lockTranslationZ,
1371
+ lockRotations: legacyLockRotations,
1372
+ lockRotationX,
1373
+ lockRotationY,
1374
+ lockRotationZ
1375
+ };
1376
+ }
1377
+ __name(normalizeRigidbodyState, "normalizeRigidbodyState");
1378
+ function normalizeColliderState(value) {
1379
+ const source = asRecord2(value);
1380
+ const defaults = DEFAULT_COLLIDER_STATE;
1381
+ const offsetPosition = asRecord2(source?.offsetPosition);
1382
+ const offsetRotation = asRecord2(source?.offsetRotation);
1383
+ const size = asRecord2(source?.size);
1384
+ return {
1385
+ enabled: toBoolean2(source?.enabled, defaults.enabled),
1386
+ shape: toColliderShape(source?.shape, defaults.shape),
1387
+ offsetPosition: {
1388
+ x: toFiniteNumber3(offsetPosition?.x, defaults.offsetPosition.x),
1389
+ y: toFiniteNumber3(offsetPosition?.y, defaults.offsetPosition.y),
1390
+ z: toFiniteNumber3(offsetPosition?.z, defaults.offsetPosition.z)
1391
+ },
1392
+ offsetRotation: {
1393
+ x: toFiniteNumber3(offsetRotation?.x, defaults.offsetRotation.x),
1394
+ y: toFiniteNumber3(offsetRotation?.y, defaults.offsetRotation.y),
1395
+ z: toFiniteNumber3(offsetRotation?.z, defaults.offsetRotation.z)
1396
+ },
1397
+ size: {
1398
+ x: Math.max(1e-4, toFiniteNumber3(size?.x, defaults.size.x)),
1399
+ y: Math.max(1e-4, toFiniteNumber3(size?.y, defaults.size.y)),
1400
+ z: Math.max(1e-4, toFiniteNumber3(size?.z, defaults.size.z))
1401
+ },
1402
+ radius: Math.max(1e-4, toFiniteNumber3(source?.radius, defaults.radius)),
1403
+ height: Math.max(1e-4, toFiniteNumber3(source?.height, defaults.height)),
1404
+ restitution: Math.max(0, toFiniteNumber3(source?.restitution, defaults.restitution)),
1405
+ friction: Math.max(0, toFiniteNumber3(source?.friction, defaults.friction)),
1406
+ isSensor: toBoolean2(source?.isSensor, defaults.isSensor)
1407
+ };
1408
+ }
1409
+ __name(normalizeColliderState, "normalizeColliderState");
1410
+ function normalizePhysicsState(value) {
1411
+ const source = asRecord2(value);
1412
+ return {
1413
+ rigidbody: normalizeRigidbodyState(
1414
+ source?.rigidbody ?? void 0
1415
+ ),
1416
+ collider: normalizeColliderState(
1417
+ source?.collider ?? void 0
1418
+ )
1419
+ };
1420
+ }
1421
+ __name(normalizePhysicsState, "normalizePhysicsState");
1422
+ function setPhysicsLiveRef(component, key, value) {
1423
+ Object.defineProperty(component, key, {
1424
+ value,
1425
+ writable: true,
1426
+ configurable: true,
1427
+ enumerable: false
1428
+ });
1429
+ }
1430
+ __name(setPhysicsLiveRef, "setPhysicsLiveRef");
1431
+ var _PhysicsComponent = class _PhysicsComponent extends Component {
1432
+ constructor(values) {
1433
+ super();
1434
+ this.values = normalizePhysicsState(values);
1435
+ setPhysicsLiveRef(this, "rigidBody", null);
1436
+ setPhysicsLiveRef(this, "collider", null);
1437
+ }
1438
+ /**
1439
+ * Patch rigidbody and/or collider state. Each sub-object is deep-merged
1440
+ * with the current values via the respective normalizer.
1441
+ */
1442
+ setValues(patch) {
1443
+ this.values = normalizePhysicsState({
1444
+ rigidbody: { ...this.values.rigidbody, ...patch.rigidbody ?? {} },
1445
+ collider: { ...this.values.collider, ...patch.collider ?? {} }
1446
+ });
1447
+ }
1448
+ };
1449
+ __name(_PhysicsComponent, "PhysicsComponent");
1450
+ var PhysicsComponent = _PhysicsComponent;
1451
+
1452
+ // core/components/Image.ts
1453
+ var _ImageComponent = class _ImageComponent extends Component {
1454
+ constructor(path, width = 1, height = 1) {
1455
+ super();
1456
+ this.path = path;
1457
+ this.width = width;
1458
+ this.height = height;
1459
+ this.texture = null;
1460
+ this.object = null;
1461
+ }
1462
+ };
1463
+ __name(_ImageComponent, "ImageComponent");
1464
+ var ImageComponent = _ImageComponent;
1465
+
1466
+ // core/components/ImageTarget.ts
1467
+ var _ImageTarget = class _ImageTarget extends Component {
1468
+ constructor(options, texture, object) {
1469
+ super();
1470
+ this.targets = options?.targets ?? [];
1471
+ this.compiledTargetUrl = options?.compiledTargetUrl;
1472
+ this.compiledTargetDir = options?.compiledTargetDir;
1473
+ this.texture = texture ?? null;
1474
+ this.object = object ?? null;
1475
+ }
1476
+ };
1477
+ __name(_ImageTarget, "ImageTarget");
1478
+ var ImageTarget = _ImageTarget;
1479
+ function toHexColor(value) {
1480
+ return `#${value.getHexString()}`;
1481
+ }
1482
+ __name(toHexColor, "toHexColor");
1483
+ function createValueState(light) {
1484
+ const base = {
1485
+ color: toHexColor(light.color),
1486
+ intensity: light.intensity,
1487
+ castShadow: light.castShadow ?? false,
1488
+ frustumCulling: light.frustumCulled
1489
+ };
1490
+ if (light instanceof THREE5__namespace.PointLight) {
1491
+ base.distance = light.distance;
1492
+ base.decay = light.decay;
1493
+ } else if (light instanceof THREE5__namespace.SpotLight) {
1494
+ base.distance = light.distance;
1495
+ base.decay = light.decay;
1496
+ base.angle = light.angle;
1497
+ base.penumbra = light.penumbra;
1498
+ } else if (light instanceof THREE5__namespace.RectAreaLight) {
1499
+ base.width = light.width;
1500
+ base.height = light.height;
1501
+ }
1502
+ return base;
1503
+ }
1504
+ __name(createValueState, "createValueState");
1505
+ var _LightComponent = class _LightComponent extends Component {
1506
+ constructor(light) {
1507
+ super();
1508
+ this.light = light;
1509
+ this.type = light.type;
1510
+ this.values = createValueState(light);
1511
+ }
1512
+ setValues(patch) {
1513
+ this.values = {
1514
+ ...this.values,
1515
+ ...patch
1516
+ };
1517
+ }
1518
+ };
1519
+ __name(_LightComponent, "LightComponent");
1520
+ var LightComponent = _LightComponent;
1521
+ function toHexColor2(value, fallback) {
1522
+ if (value && typeof value === "object" && typeof value.getHexString === "function") {
1523
+ try {
1524
+ return `#${value.getHexString()}`;
1525
+ } catch {
1526
+ return fallback;
1527
+ }
1528
+ }
1529
+ return fallback;
1530
+ }
1531
+ __name(toHexColor2, "toHexColor");
1532
+ function getMaterialType(material) {
1533
+ if (material instanceof THREE5__namespace.MeshPhysicalMaterial) {
1534
+ return "physical";
1535
+ }
1536
+ if (material instanceof THREE5__namespace.MeshPhongMaterial) {
1537
+ return "phong";
1538
+ }
1539
+ if (material instanceof THREE5__namespace.MeshBasicMaterial) {
1540
+ return "basic";
1541
+ }
1542
+ return "standard";
1543
+ }
1544
+ __name(getMaterialType, "getMaterialType");
1545
+ function textureImageSrc(texture) {
1546
+ const src = texture?.image?.src;
1547
+ return typeof src === "string" ? src : void 0;
1548
+ }
1549
+ __name(textureImageSrc, "textureImageSrc");
1550
+ function textureSourceUrl(texture) {
1551
+ if (!texture?.image) {
1552
+ return void 0;
1553
+ }
1554
+ const currentSrc = texture.source?.data?.currentSrc;
1555
+ if (typeof currentSrc === "string" && currentSrc) {
1556
+ return currentSrc;
1557
+ }
1558
+ return textureImageSrc(texture);
1559
+ }
1560
+ __name(textureSourceUrl, "textureSourceUrl");
1561
+ function createMaterialValue(material) {
1562
+ const materialRecord = material;
1563
+ const normalScale = materialRecord.normalScale;
1564
+ const map = materialRecord.map;
1565
+ return {
1566
+ type: getMaterialType(material),
1567
+ color: toHexColor2(materialRecord.color, "#ffffff"),
1568
+ roughness: typeof materialRecord.roughness === "number" ? materialRecord.roughness : 0.5,
1569
+ metalness: typeof materialRecord.metalness === "number" ? materialRecord.metalness : 0.5,
1570
+ normalScale: typeof normalScale?.x === "number" ? normalScale.x : 1,
1571
+ opacity: typeof materialRecord.opacity === "number" ? materialRecord.opacity : 1,
1572
+ emissive: toHexColor2(materialRecord.emissive, "#000000"),
1573
+ emissiveIntensity: typeof materialRecord.emissiveIntensity === "number" ? materialRecord.emissiveIntensity : 0,
1574
+ side: typeof materialRecord.side === "number" ? materialRecord.side : THREE5__namespace.FrontSide,
1575
+ blending: typeof materialRecord.blending === "number" ? materialRecord.blending : THREE5__namespace.NormalBlending,
1576
+ depthTest: materialRecord.depthTest !== false,
1577
+ depthWrite: materialRecord.depthWrite !== false,
1578
+ wireframe: Boolean(materialRecord.wireframe),
1579
+ transparent: Boolean(materialRecord.transparent),
1580
+ textureMap: textureSourceUrl(map),
1581
+ alphaTextureMap: textureImageSrc(
1582
+ materialRecord.alphaMap
1583
+ ),
1584
+ normalMap: textureImageSrc(
1585
+ materialRecord.normalMap
1586
+ ),
1587
+ roughnessMap: textureImageSrc(
1588
+ materialRecord.roughnessMap
1589
+ ),
1590
+ metalnessMap: textureImageSrc(
1591
+ materialRecord.metalnessMap
1592
+ ),
1593
+ aoMap: textureImageSrc(materialRecord.aoMap),
1594
+ emissiveMap: textureImageSrc(
1595
+ materialRecord.emissiveMap
1596
+ ),
1597
+ bumpMap: textureImageSrc(
1598
+ materialRecord.bumpMap
1599
+ ),
1600
+ displacementMap: textureImageSrc(
1601
+ materialRecord.displacementMap
1602
+ ),
1603
+ lightMap: textureImageSrc(
1604
+ materialRecord.lightMap
1605
+ ),
1606
+ envMap: textureImageSrc(materialRecord.envMap),
1607
+ textureFiltering: map?.magFilter === THREE5__namespace.NearestFilter ? "sharp" : "smooth",
1608
+ useMipmaps: map?.generateMipmaps !== false
1609
+ };
1610
+ }
1611
+ __name(createMaterialValue, "createMaterialValue");
1612
+ function defaultMaterialValue() {
1613
+ return {
1614
+ type: "standard",
1615
+ color: "#ffffff",
1616
+ roughness: 0.5,
1617
+ metalness: 0.5,
1618
+ normalScale: 1,
1619
+ opacity: 1,
1620
+ emissive: "#000000",
1621
+ emissiveIntensity: 0,
1622
+ side: THREE5__namespace.FrontSide,
1623
+ blending: THREE5__namespace.NormalBlending,
1624
+ depthTest: true,
1625
+ depthWrite: true,
1626
+ wireframe: false,
1627
+ transparent: false,
1628
+ textureFiltering: "smooth",
1629
+ useMipmaps: true
1630
+ };
1631
+ }
1632
+ __name(defaultMaterialValue, "defaultMaterialValue");
1633
+ var _MaterialComponent = class _MaterialComponent extends Component {
1634
+ constructor(materialOrMaterials = []) {
1635
+ super();
1636
+ this.materials = [];
1637
+ this.material = null;
1638
+ this.values = [];
1639
+ this.assetRefs = [];
1640
+ this.setMaterials(materialOrMaterials);
1641
+ }
1642
+ /** Link/unlink a slot to a material asset URL (editor bookkeeping only). */
1643
+ setAssetRef(index, url) {
1644
+ if (index < 0) {
1645
+ return;
1646
+ }
1647
+ while (this.assetRefs.length <= index) {
1648
+ this.assetRefs.push(null);
1649
+ }
1650
+ this.assetRefs[index] = url;
1651
+ }
1652
+ /** The material-asset URL a slot is linked to, or null when local. */
1653
+ getAssetRef(index) {
1654
+ return this.assetRefs[index] ?? null;
1655
+ }
1656
+ setMaterials(materialOrMaterials = []) {
1657
+ this.materials = Array.isArray(materialOrMaterials) ? materialOrMaterials.filter(Boolean) : materialOrMaterials ? [materialOrMaterials] : [];
1658
+ this.material = this.materials[0] ?? null;
1659
+ this.values = this.materials.length > 0 ? this.materials.map((material) => createMaterialValue(material)) : [defaultMaterialValue()];
1660
+ }
1661
+ updateValue(index, patch) {
1662
+ if (index < 0) {
1663
+ return;
1664
+ }
1665
+ while (this.values.length <= index) {
1666
+ this.values.push(defaultMaterialValue());
1667
+ }
1668
+ this.values[index] = {
1669
+ ...this.values[index],
1670
+ ...patch
1671
+ };
1672
+ }
1673
+ resetValue(index) {
1674
+ if (index < 0) {
1675
+ return;
1676
+ }
1677
+ while (this.values.length <= index) {
1678
+ this.values.push(defaultMaterialValue());
1679
+ }
1680
+ const type = this.values[index]?.type ?? "standard";
1681
+ this.values[index] = {
1682
+ ...defaultMaterialValue(),
1683
+ type
1684
+ };
1685
+ }
1686
+ setMaterialType(index, type) {
1687
+ this.updateValue(index, { type });
1688
+ }
1689
+ setTextureFiltering(index, filtering) {
1690
+ this.updateValue(index, { textureFiltering: filtering });
1691
+ }
1692
+ setUseMipmaps(index, enabled) {
1693
+ this.updateValue(index, { useMipmaps: enabled });
1694
+ }
1695
+ };
1696
+ __name(_MaterialComponent, "MaterialComponent");
1697
+ var MaterialComponent = _MaterialComponent;
1698
+
1699
+ // core/components/Model.ts
1700
+ var MODEL_NO_PATH_MESSAGE = "No model path set.";
1701
+ function setModelLoadState(component, state, error) {
1702
+ Object.defineProperty(component, "loadState", {
1703
+ value: state,
1704
+ writable: true,
1705
+ configurable: true,
1706
+ enumerable: false
1707
+ });
1708
+ Object.defineProperty(component, "loadError", {
1709
+ value: state === "error" ? error ?? "Failed to load model." : void 0,
1710
+ writable: true,
1711
+ configurable: true,
1712
+ enumerable: false
1713
+ });
1714
+ }
1715
+ __name(setModelLoadState, "setModelLoadState");
1716
+ var _ModelComponent = class _ModelComponent extends Component {
1717
+ constructor(path) {
1718
+ super();
1719
+ this.path = path;
1720
+ this.object = null;
1721
+ if (path) {
1722
+ setModelLoadState(this, "loading");
1723
+ } else {
1724
+ setModelLoadState(this, "error", MODEL_NO_PATH_MESSAGE);
1725
+ }
1726
+ }
1727
+ };
1728
+ __name(_ModelComponent, "ModelComponent");
1729
+ var ModelComponent = _ModelComponent;
1730
+
1731
+ // core/components/Name.ts
1732
+ var _Name = class _Name extends Component {
1733
+ constructor(value) {
1734
+ super();
1735
+ this.value = value;
1736
+ }
1737
+ };
1738
+ __name(_Name, "Name");
1739
+ var Name = _Name;
1740
+
1741
+ // core/components/Object3DRef.ts
1742
+ var _Object3DRef = class _Object3DRef extends Component {
1743
+ constructor(object, visibility) {
1744
+ super();
1745
+ this.object = object;
1746
+ this.visibility = typeof visibility === "boolean" ? visibility : Boolean(object.visible);
1747
+ }
1748
+ };
1749
+ __name(_Object3DRef, "Object3DRef");
1750
+ var Object3DRef = _Object3DRef;
1751
+
1752
+ // core/components/ParentId.ts
1753
+ var _ParentId = class _ParentId extends Component {
1754
+ constructor(value = null) {
1755
+ super();
1756
+ this.value = value;
1757
+ }
1758
+ };
1759
+ __name(_ParentId, "ParentId");
1760
+ var ParentId = _ParentId;
1761
+
1762
+ // core/components/PrefabInstance.ts
1763
+ var generateInstanceId = /* @__PURE__ */ __name(() => {
1764
+ try {
1765
+ return crypto.randomUUID();
1766
+ } catch {
1767
+ return `i-${Math.random().toString(36).slice(2, 10)}${Date.now().toString(36)}`;
1768
+ }
1769
+ }, "generateInstanceId");
1770
+ var _PrefabInstance = class _PrefabInstance extends Component {
1771
+ constructor(url, overrides = [], instanceId) {
1772
+ super();
1773
+ this.url = url;
1774
+ this.overrides = overrides;
1775
+ this.instanceId = typeof instanceId === "string" && instanceId.length > 0 ? instanceId : generateInstanceId();
1776
+ }
1777
+ };
1778
+ __name(_PrefabInstance, "PrefabInstance");
1779
+ var PrefabInstance = _PrefabInstance;
1780
+
1781
+ // core/components/PrefabNode.ts
1782
+ var _PrefabNode = class _PrefabNode extends Component {
1783
+ constructor(nodeId) {
1784
+ super();
1785
+ this.nodeId = nodeId;
1786
+ }
1787
+ };
1788
+ __name(_PrefabNode, "PrefabNode");
1789
+ var PrefabNode = _PrefabNode;
1790
+
1791
+ // core/components/ScriptComponent.ts
1792
+ var _ScriptComponent = class _ScriptComponent extends Component {
1793
+ constructor(entries = []) {
1794
+ super();
1795
+ this.entries = entries.map((entry) => ({
1796
+ entityId: typeof entry.entityId === "number" ? entry.entityId : 0,
1797
+ className: typeof entry.className === "string" ? entry.className : "",
1798
+ scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
1799
+ enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
1800
+ data: entry.data && typeof entry.data === "object" && !Array.isArray(entry.data) ? entry.data : {},
1801
+ runtimeState: entry.runtimeState,
1802
+ runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
1803
+ }));
1804
+ Object.defineProperty(this, "scriptInstance", {
1805
+ value: null,
1806
+ writable: true,
1807
+ configurable: true,
1808
+ enumerable: false
1809
+ });
1810
+ Object.defineProperty(this, "scriptInstances", {
1811
+ value: /* @__PURE__ */ new Map(),
1812
+ writable: true,
1813
+ configurable: true,
1814
+ enumerable: false
1815
+ });
1816
+ }
1817
+ };
1818
+ __name(_ScriptComponent, "ScriptComponent");
1819
+ var ScriptComponent = _ScriptComponent;
1820
+
1821
+ // core/components/ScriptObjectComponent.ts
1822
+ var _ScriptObjectComponent = class _ScriptObjectComponent extends Component {
1823
+ constructor(input = {}) {
1824
+ super();
1825
+ this.scriptUrl = typeof input.scriptUrl === "string" && input.scriptUrl.length > 0 ? input.scriptUrl : null;
1826
+ this.className = typeof input.className === "string" && input.className.length > 0 ? input.className : null;
1827
+ this.enabled = typeof input.enabled === "boolean" ? input.enabled : true;
1828
+ this.data = input.data && typeof input.data === "object" && !Array.isArray(input.data) ? input.data : {};
1829
+ this.runtimeState = input.runtimeState === "idle" || input.runtimeState === "loading" || input.runtimeState === "ready" || input.runtimeState === "error" ? input.runtimeState : "idle";
1830
+ this.runtimeMessage = typeof input.runtimeMessage === "string" ? input.runtimeMessage : void 0;
1831
+ Object.defineProperty(this, "instance", {
1832
+ value: null,
1833
+ writable: true,
1834
+ configurable: true,
1835
+ enumerable: false
1836
+ });
1837
+ }
1838
+ };
1839
+ __name(_ScriptObjectComponent, "ScriptObjectComponent");
1840
+ var ScriptObjectComponent = _ScriptObjectComponent;
1841
+
1842
+ // core/components/Selectable.ts
1843
+ var _Selectable = class _Selectable extends Component {
1844
+ constructor(enabled = true) {
1845
+ super();
1846
+ this.enabled = enabled;
1847
+ }
1848
+ };
1849
+ __name(_Selectable, "Selectable");
1850
+ var Selectable = _Selectable;
1851
+
1852
+ // core/components/Sprite.ts
1853
+ var _SpriteComponent = class _SpriteComponent extends Component {
1854
+ constructor(path, width = 1, height = 1) {
1855
+ super();
1856
+ this.path = path;
1857
+ this.width = width;
1858
+ this.height = height;
1859
+ this.texture = null;
1860
+ this.object = null;
1861
+ }
1862
+ };
1863
+ __name(_SpriteComponent, "SpriteComponent");
1864
+ var SpriteComponent = _SpriteComponent;
1865
+ function readXYZ(input) {
1866
+ return {
1867
+ x: input.x,
1868
+ y: input.y,
1869
+ z: input.z
1870
+ };
1871
+ }
1872
+ __name(readXYZ, "readXYZ");
1873
+ var _TransformComponent = class _TransformComponent extends Component {
1874
+ constructor(data = {}) {
1875
+ super();
1876
+ const position = data.position ?? {};
1877
+ const rotation = data.rotation ?? {};
1878
+ const scale = data.scale ?? {};
1879
+ this.position = {
1880
+ x: position.x ?? 0,
1881
+ y: position.y ?? 0,
1882
+ z: position.z ?? 0
1883
+ };
1884
+ this.rotation = {
1885
+ x: rotation.x ?? 0,
1886
+ y: rotation.y ?? 0,
1887
+ z: rotation.z ?? 0
1888
+ };
1889
+ this.scale = {
1890
+ x: scale.x ?? 1,
1891
+ y: scale.y ?? 1,
1892
+ z: scale.z ?? 1
1893
+ };
1894
+ }
1895
+ toPositionVector3(target = new THREE5.Vector3()) {
1896
+ return target.set(this.position.x, this.position.y, this.position.z);
1897
+ }
1898
+ toRotationEuler(target = new THREE5.Euler(), order = "XYZ") {
1899
+ return target.set(this.rotation.x, this.rotation.y, this.rotation.z, order);
1900
+ }
1901
+ toRotationQuaternion(target = new THREE5.Quaternion(), order = "XYZ") {
1902
+ const euler2 = new THREE5.Euler(
1903
+ this.rotation.x,
1904
+ this.rotation.y,
1905
+ this.rotation.z,
1906
+ order
1907
+ );
1908
+ return target.setFromEuler(euler2);
1909
+ }
1910
+ toScaleVector3(target = new THREE5.Vector3()) {
1911
+ return target.set(this.scale.x, this.scale.y, this.scale.z);
1912
+ }
1913
+ setPosition(input) {
1914
+ const next = readXYZ(input);
1915
+ this.position.x = next.x;
1916
+ this.position.y = next.y;
1917
+ this.position.z = next.z;
1918
+ return this;
1919
+ }
1920
+ setScale(input) {
1921
+ const next = readXYZ(input);
1922
+ this.scale.x = next.x;
1923
+ this.scale.y = next.y;
1924
+ this.scale.z = next.z;
1925
+ return this;
1926
+ }
1927
+ setRotation(input, order = "XYZ") {
1928
+ if (input instanceof THREE5.Quaternion) {
1929
+ const euler2 = new THREE5.Euler().setFromQuaternion(input, order);
1930
+ this.rotation.x = euler2.x;
1931
+ this.rotation.y = euler2.y;
1932
+ this.rotation.z = euler2.z;
1933
+ return this;
1934
+ }
1935
+ const next = readXYZ(input);
1936
+ this.rotation.x = next.x;
1937
+ this.rotation.y = next.y;
1938
+ this.rotation.z = next.z;
1939
+ return this;
1940
+ }
1941
+ };
1942
+ __name(_TransformComponent, "TransformComponent");
1943
+ var TransformComponent = _TransformComponent;
1944
+
1945
+ // core/components/Video.ts
1946
+ var DEFAULT_VIDEO_OPTIONS = {
1947
+ autoplay: false,
1948
+ loop: true,
1949
+ volume: 1,
1950
+ width: 1,
1951
+ height: 1,
1952
+ isGreenScreen: false,
1953
+ backgroundColor: "#00ff00",
1954
+ similarity: 0.4,
1955
+ smoothness: 0.08,
1956
+ spill: 0.12,
1957
+ /** When `true`, the video's audio stream is spatialized using the entity's transform. */
1958
+ positional: false,
1959
+ /** Distance at which volume is unattenuated (positional only). */
1960
+ refDistance: 1,
1961
+ /** WebAudio distance model (`linear`, `inverse`, `exponential`). Positional only. */
1962
+ distanceModel: "inverse",
1963
+ /** How quickly volume falls off past `refDistance`. Positional only. */
1964
+ rolloffFactor: 1
1965
+ };
1966
+ var _VideoComponent = class _VideoComponent extends Component {
1967
+ constructor(path, options = {}) {
1968
+ super();
1969
+ this.path = path;
1970
+ this.options = {
1971
+ ...DEFAULT_VIDEO_OPTIONS,
1972
+ ...options
1973
+ };
1974
+ this.object = null;
1975
+ this.videoElement = null;
1976
+ this.texture = null;
1977
+ this.material = null;
1978
+ this.audioNode = null;
1979
+ Object.defineProperty(this, "isPlaying", {
1980
+ value: false,
1981
+ writable: true,
1982
+ configurable: true,
1983
+ enumerable: false
1984
+ });
1985
+ Object.defineProperty(this, "isPaused", {
1986
+ value: false,
1987
+ writable: true,
1988
+ configurable: true,
1989
+ enumerable: false
1990
+ });
1991
+ }
1992
+ /**
1993
+ * Signals `VideoSystem` to start (or resume) playback.
1994
+ * Has no direct effect in the editor — `VideoSystem` drives the actual
1995
+ * HTML video element call in preview.
1996
+ */
1997
+ play() {
1998
+ this.isPlaying = true;
1999
+ this.isPaused = false;
2000
+ }
2001
+ /**
2002
+ * Signals `VideoSystem` to pause playback, preserving the current position.
2003
+ * Calling {@link play} afterwards resumes from where it paused.
2004
+ * No-op if not currently playing.
2005
+ */
2006
+ pause() {
2007
+ if (!this.isPlaying) return;
2008
+ this.isPlaying = false;
2009
+ this.isPaused = true;
2010
+ }
2011
+ /**
2012
+ * Signals `VideoSystem` to stop playback and reset the playback position.
2013
+ */
2014
+ stop() {
2015
+ this.isPlaying = false;
2016
+ this.isPaused = false;
2017
+ }
2018
+ };
2019
+ __name(_VideoComponent, "VideoComponent");
2020
+ var VideoComponent = _VideoComponent;
2021
+
2022
+ // core/components/VRTeleportArea.ts
2023
+ var _VRTeleportAreaComponent = class _VRTeleportAreaComponent extends Component {
2024
+ constructor(options) {
2025
+ super();
2026
+ this.enabled = options?.enabled ?? true;
2027
+ const shape = options?.shape;
2028
+ this.shape = shape === "cylinder" ? "circle" : options?.shape ?? "plane";
2029
+ this.width = options?.width ?? 10;
2030
+ this.depth = options?.depth ?? 10;
2031
+ }
2032
+ };
2033
+ __name(_VRTeleportAreaComponent, "VRTeleportAreaComponent");
2034
+ var VRTeleportAreaComponent = _VRTeleportAreaComponent;
2035
+
2036
+ // core/components/XRInteractable.ts
2037
+ var _XRInteractableComponent = class _XRInteractableComponent extends Component {
2038
+ constructor(options) {
2039
+ super();
2040
+ this.enabled = options?.enabled ?? true;
2041
+ this.grabbable = options?.grabbable ?? true;
2042
+ this.pointable = options?.pointable ?? true;
2043
+ this.grabReach = options?.grabReach ?? "both";
2044
+ this.distanceBehavior = options?.distanceBehavior ?? "snap";
2045
+ this.grabGesture = options?.grabGesture ?? "any";
2046
+ this.grabRadius = options?.grabRadius ?? 0.15;
2047
+ this.grabOffsetPosition = options?.grabOffsetPosition ?? {
2048
+ x: 0,
2049
+ y: 0,
2050
+ z: 0
2051
+ };
2052
+ this.grabOffsetRotation = options?.grabOffsetRotation ?? {
2053
+ x: 0,
2054
+ y: 0,
2055
+ z: 0
2056
+ };
2057
+ this.grabHands = options?.grabHands ?? "handOff";
2058
+ this.twoHandRotation = options?.twoHandRotation ?? "align";
2059
+ this.allowTwoHandScale = options?.allowTwoHandScale ?? false;
2060
+ this.minScale = options?.minScale ?? 0.25;
2061
+ this.maxScale = options?.maxScale ?? 4;
2062
+ this.attachPoints = (options?.attachPoints ?? []).map(
2063
+ (point) => createAttachPoint(point)
2064
+ );
2065
+ this.applyVelocityOnRelease = options?.applyVelocityOnRelease ?? true;
2066
+ this.velocityScale = options?.velocityScale ?? 1;
2067
+ this.hoverBehavior = options?.hoverBehavior ?? "color";
2068
+ this.hoverColor = options?.hoverColor ?? "#4da3ff";
2069
+ this.hoverScale = options?.hoverScale ?? 1.06;
2070
+ }
2071
+ };
2072
+ __name(_XRInteractableComponent, "XRInteractableComponent");
2073
+ var XRInteractableComponent = _XRInteractableComponent;
2074
+ function createAttachPoint(partial) {
2075
+ return {
2076
+ id: partial.id,
2077
+ name: partial.name ?? partial.id,
2078
+ position: { x: 0, y: 0, z: 0, ...partial.position },
2079
+ rotation: { x: 0, y: 0, z: 0, ...partial.rotation },
2080
+ hand: partial.hand ?? "any",
2081
+ role: partial.role ?? "any"
2082
+ };
2083
+ }
2084
+ __name(createAttachPoint, "createAttachPoint");
2085
+
2086
+ // core/components/XRRig.ts
2087
+ var _XRRigComponent = class _XRRigComponent extends Component {
2088
+ constructor(options) {
2089
+ super();
2090
+ this.trackingOrigin = options?.trackingOrigin ?? "floor";
2091
+ this.locomotion = options?.locomotion ?? "teleport";
2092
+ this.moveSpeed = options?.moveSpeed ?? 2;
2093
+ this.snapTurn = options?.snapTurn ?? true;
2094
+ this.snapTurnDegrees = options?.snapTurnDegrees ?? 30;
2095
+ this.fallbackEyeHeight = options?.fallbackEyeHeight ?? 1.6;
2096
+ this.teleportArcColor = options?.teleportArcColor ?? "#4da3ff";
2097
+ this.teleportArcInvalidColor = options?.teleportArcInvalidColor ?? "#ff5a5a";
2098
+ this.teleportArcThickness = options?.teleportArcThickness ?? 0.012;
2099
+ this.passthrough = options?.passthrough ?? false;
2100
+ this.depthOcclusion = options?.depthOcclusion ?? false;
2101
+ this.environmentPhysics = options?.environmentPhysics ?? "none";
2102
+ this.environmentDebug = options?.environmentDebug ?? false;
2103
+ this.hitTest = options?.hitTest ?? false;
2104
+ this.anchors = options?.anchors ?? false;
2105
+ }
2106
+ };
2107
+ __name(_XRRigComponent, "XRRigComponent");
2108
+ var XRRigComponent = _XRRigComponent;
2109
+
2110
+ // core/components/XRAnchor.ts
2111
+ var _XRAnchorComponent = class _XRAnchorComponent extends Component {
2112
+ constructor(options) {
2113
+ super();
2114
+ this.enabled = options?.enabled ?? true;
2115
+ }
2116
+ };
2117
+ __name(_XRAnchorComponent, "XRAnchorComponent");
2118
+ var XRAnchorComponent = _XRAnchorComponent;
2119
+
2120
+ // core/components/BoneAttachment.ts
2121
+ var _BoneAttachmentComponent = class _BoneAttachmentComponent extends Component {
2122
+ constructor(options) {
2123
+ super();
2124
+ this.bone = options?.bone ?? "";
2125
+ this.humanoid = options?.humanoid ?? null;
2126
+ this.compensateScale = options?.compensateScale ?? true;
2127
+ this.enabled = options?.enabled ?? true;
2128
+ }
2129
+ };
2130
+ __name(_BoneAttachmentComponent, "BoneAttachmentComponent");
2131
+ var BoneAttachmentComponent = _BoneAttachmentComponent;
2132
+
2133
+ // core/components/Network.ts
2134
+ var _NetworkIdentityComponent = class _NetworkIdentityComponent extends Component {
2135
+ constructor() {
2136
+ super();
2137
+ for (const key of ["networkId", "owner"]) {
2138
+ Object.defineProperty(this, key, {
2139
+ value: "",
2140
+ writable: true,
2141
+ configurable: true,
2142
+ enumerable: false
2143
+ });
2144
+ }
2145
+ }
2146
+ };
2147
+ __name(_NetworkIdentityComponent, "NetworkIdentityComponent");
2148
+ var NetworkIdentityComponent = _NetworkIdentityComponent;
2149
+ var _NetworkTransformComponent = class _NetworkTransformComponent extends Component {
2150
+ constructor(options = {}) {
2151
+ super();
2152
+ this.enabled = true;
2153
+ /** Updates per second the owner sends. */
2154
+ this.sendRate = 20;
2155
+ /** How far in the past others see it, in ms. More is smoother; less is more current. */
2156
+ this.interpolationMs = 100;
2157
+ this.syncRotation = true;
2158
+ /** A jump longer than this (m) snaps instead of sliding, for respawns and teleports. */
2159
+ this.teleportDistance = 5;
2160
+ Object.assign(this, options);
2161
+ }
2162
+ };
2163
+ __name(_NetworkTransformComponent, "NetworkTransformComponent");
2164
+ var NetworkTransformComponent = _NetworkTransformComponent;
2165
+ var _NetworkedPropsComponent = class _NetworkedPropsComponent extends Component {
2166
+ constructor(values = {}) {
2167
+ super();
2168
+ this.values = values;
2169
+ }
2170
+ };
2171
+ __name(_NetworkedPropsComponent, "NetworkedPropsComponent");
2172
+ var NetworkedPropsComponent = _NetworkedPropsComponent;
2173
+ var _NetworkSpawnerComponent = class _NetworkSpawnerComponent extends Component {
2174
+ constructor(playerPrefab = "", spawnRadius = 2) {
2175
+ super();
2176
+ this.playerPrefab = playerPrefab;
2177
+ this.spawnRadius = spawnRadius;
2178
+ }
2179
+ };
2180
+ __name(_NetworkSpawnerComponent, "NetworkSpawnerComponent");
2181
+ var NetworkSpawnerComponent = _NetworkSpawnerComponent;
2182
+
2183
+ // core/components/IK.ts
2184
+ function normalizeIKChain(chain) {
2185
+ const weight = typeof chain.weight === "number" && Number.isFinite(chain.weight) ? chain.weight : 1;
2186
+ return {
2187
+ limb: chain.limb,
2188
+ target: typeof chain.target === "number" ? chain.target : null,
2189
+ pole: typeof chain.pole === "number" ? chain.pole : null,
2190
+ weight: Math.min(1, Math.max(0, weight)),
2191
+ matchRotation: chain.matchRotation ?? false,
2192
+ enabled: chain.enabled ?? true
2193
+ };
2194
+ }
2195
+ __name(normalizeIKChain, "normalizeIKChain");
2196
+ var _IKComponent = class _IKComponent extends Component {
2197
+ constructor(options) {
2198
+ super();
2199
+ this.chains = (options?.chains ?? []).map(normalizeIKChain);
2200
+ this.enabled = options?.enabled ?? true;
2201
+ }
2202
+ };
2203
+ __name(_IKComponent, "IKComponent");
2204
+ var IKComponent = _IKComponent;
2205
+
2206
+ // core/components/UIPanel.ts
2207
+ var _UIPanelComponent = class _UIPanelComponent extends Component {
2208
+ constructor(options) {
2209
+ super();
2210
+ this.width = options?.width ?? 0.6;
2211
+ this.height = options?.height ?? 0.4;
2212
+ this.backgroundColor = options?.backgroundColor ?? "#1c1c1c";
2213
+ this.backgroundOpacity = options?.backgroundOpacity ?? 0.92;
2214
+ this.cornerRadius = options?.cornerRadius ?? 0.02;
2215
+ this.borderWidth = options?.borderWidth ?? 0;
2216
+ this.borderColor = options?.borderColor ?? "#333333";
2217
+ this.pixelDensity = options?.pixelDensity ?? 1024;
2218
+ this.follow = options?.follow ?? "world";
2219
+ }
2220
+ };
2221
+ __name(_UIPanelComponent, "UIPanelComponent");
2222
+ var UIPanelComponent = _UIPanelComponent;
2223
+
2224
+ // core/components/UIText.ts
2225
+ var _UITextComponent = class _UITextComponent extends Component {
2226
+ constructor(options) {
2227
+ super();
2228
+ this.text = options?.text ?? "Text";
2229
+ this.width = options?.width ?? 0.5;
2230
+ this.height = options?.height ?? 0.12;
2231
+ this.fontSize = options?.fontSize ?? 0.035;
2232
+ this.fontWeight = options?.fontWeight ?? 500;
2233
+ this.color = options?.color ?? "#ffffff";
2234
+ this.align = options?.align ?? "center";
2235
+ this.valign = options?.valign ?? "middle";
2236
+ this.lineHeight = options?.lineHeight ?? 1.25;
2237
+ this.padding = options?.padding ?? 0.01;
2238
+ }
2239
+ };
2240
+ __name(_UITextComponent, "UITextComponent");
2241
+ var UITextComponent = _UITextComponent;
2242
+
2243
+ // core/components/UIButton.ts
2244
+ var _UIButtonComponent = class _UIButtonComponent extends Component {
2245
+ constructor(options) {
2246
+ super();
2247
+ this.label = options?.label ?? "Button";
2248
+ this.actionId = options?.actionId ?? "";
2249
+ this.width = options?.width ?? 0.3;
2250
+ this.height = options?.height ?? 0.1;
2251
+ this.fontSize = options?.fontSize ?? 0.03;
2252
+ this.fontWeight = options?.fontWeight ?? 600;
2253
+ this.textColor = options?.textColor ?? "#ffffff";
2254
+ this.backgroundColor = options?.backgroundColor ?? "#2a2a2a";
2255
+ this.backgroundOpacity = options?.backgroundOpacity ?? 1;
2256
+ this.cornerRadius = options?.cornerRadius ?? 0.02;
2257
+ this.borderWidth = options?.borderWidth ?? 2e-3;
2258
+ this.borderColor = options?.borderColor ?? "#3a3a3a";
2259
+ }
2260
+ };
2261
+ __name(_UIButtonComponent, "UIButtonComponent");
2262
+ var UIButtonComponent = _UIButtonComponent;
2263
+
2264
+ // core/components/UIToggle.ts
2265
+ var _UIToggleComponent = class _UIToggleComponent extends Component {
2266
+ constructor(options) {
2267
+ super();
2268
+ this.value = options?.value ?? false;
2269
+ this.actionId = options?.actionId ?? "";
2270
+ this.width = options?.width ?? 0.14;
2271
+ this.height = options?.height ?? 0.07;
2272
+ this.trackColor = options?.trackColor ?? "#2a2a2a";
2273
+ this.accentColor = options?.accentColor ?? "#ff6b35";
2274
+ this.knobColor = options?.knobColor ?? "#ffffff";
2275
+ }
2276
+ };
2277
+ __name(_UIToggleComponent, "UIToggleComponent");
2278
+ var UIToggleComponent = _UIToggleComponent;
2279
+
2280
+ // core/components/UISlider.ts
2281
+ var _UISliderComponent = class _UISliderComponent extends Component {
2282
+ constructor(options) {
2283
+ super();
2284
+ this.min = options?.min ?? 0;
2285
+ this.max = options?.max ?? Math.max(1, this.min + 1);
2286
+ if (this.max <= this.min) this.max = this.min + 1;
2287
+ const v = options?.value ?? (this.min + this.max) / 2;
2288
+ this.value = Math.min(this.max, Math.max(this.min, v));
2289
+ this.actionId = options?.actionId ?? "";
2290
+ this.width = options?.width ?? 0.4;
2291
+ this.height = options?.height ?? 0.06;
2292
+ this.trackColor = options?.trackColor ?? "#2a2a2a";
2293
+ this.accentColor = options?.accentColor ?? "#ff6b35";
2294
+ this.knobColor = options?.knobColor ?? "#ffffff";
2295
+ }
2296
+ };
2297
+ __name(_UISliderComponent, "UISliderComponent");
2298
+ var UISliderComponent = _UISliderComponent;
2299
+
2300
+ // core/components/XRInteractor.ts
2301
+ var _XRInteractorComponent = class _XRInteractorComponent extends Component {
2302
+ constructor(options) {
2303
+ super();
2304
+ this.interactorType = options?.interactorType ?? "both";
2305
+ this.handPreset = options?.handPreset ?? "default";
2306
+ this.handColor = options?.handColor ?? "#e8b48a";
2307
+ this.handOpacity = options?.handOpacity ?? 1;
2308
+ this.handEmissiveIntensity = options?.handEmissiveIntensity ?? 0;
2309
+ this.rayVisibility = options?.rayVisibility ?? "interacting";
2310
+ this.rayColor = options?.rayColor ?? "#4da3ff";
2311
+ this.rayThickness = options?.rayThickness ?? 6e-3;
2312
+ }
2313
+ };
2314
+ __name(_XRInteractorComponent, "XRInteractorComponent");
2315
+ var XRInteractorComponent = _XRInteractorComponent;
2316
+ var _XRInteractorSideComponent = class _XRInteractorSideComponent extends Component {
2317
+ constructor(options) {
2318
+ super();
2319
+ this.side = options?.side ?? "left";
2320
+ }
2321
+ };
2322
+ __name(_XRInteractorSideComponent, "XRInteractorSideComponent");
2323
+ var XRInteractorSideComponent = _XRInteractorSideComponent;
2324
+
2325
+ // core/components/XRHandPose.ts
2326
+ var DEFAULT_POSE_CURLS = {
2327
+ thumb: 0,
2328
+ index: 0,
2329
+ middle: 0,
2330
+ ring: 0,
2331
+ pinky: 0
2332
+ };
2333
+ function createHandPoseEntry(partial) {
2334
+ return {
2335
+ id: partial.id,
2336
+ name: partial.name ?? partial.id,
2337
+ preset: partial.preset ?? null,
2338
+ curls: { ...DEFAULT_POSE_CURLS, ...partial.curls },
2339
+ tolerance: partial.tolerance ?? 0.25,
2340
+ directions: {
2341
+ thumb: [...partial.directions?.thumb ?? []],
2342
+ index: [...partial.directions?.index ?? []],
2343
+ middle: [...partial.directions?.middle ?? []],
2344
+ ring: [...partial.directions?.ring ?? []],
2345
+ pinky: [...partial.directions?.pinky ?? []]
2346
+ },
2347
+ directionTolerance: partial.directionTolerance ?? 45,
2348
+ hand: partial.hand ?? null,
2349
+ orientation: partial.orientation ?? null,
2350
+ minHoldSeconds: partial.minHoldSeconds ?? 0.15,
2351
+ enabled: partial.enabled ?? true
2352
+ };
2353
+ }
2354
+ __name(createHandPoseEntry, "createHandPoseEntry");
2355
+ var _XRHandPoseComponent = class _XRHandPoseComponent extends Component {
2356
+ constructor(options) {
2357
+ super();
2358
+ this.enabled = options?.enabled ?? true;
2359
+ this.poses = (options?.poses ?? []).map((pose) => createHandPoseEntry(pose));
2360
+ }
2361
+ };
2362
+ __name(_XRHandPoseComponent, "XRHandPoseComponent");
2363
+ var XRHandPoseComponent = _XRHandPoseComponent;
2364
+ new THREE5__namespace.Vector3();
2365
+ new THREE5__namespace.Vector3();
2366
+ function applyTransform(object, transform) {
2367
+ object.position.set(
2368
+ transform.position.x,
2369
+ transform.position.y,
2370
+ transform.position.z
2371
+ );
2372
+ object.rotation.set(
2373
+ transform.rotation.x,
2374
+ transform.rotation.y,
2375
+ transform.rotation.z
2376
+ );
2377
+ object.scale.set(transform.scale.x, transform.scale.y, transform.scale.z);
2378
+ }
2379
+ __name(applyTransform, "applyTransform");
2380
+
2381
+ // core/prefab/collectEntitySubtree.ts
2382
+ function collectEntitySubtree(world, rootIds) {
2383
+ const childrenByParent = /* @__PURE__ */ new Map();
2384
+ for (const entityId of world.query(ParentId)) {
2385
+ const parentId = world.getComponent(entityId, ParentId)?.value;
2386
+ if (parentId === null || parentId === void 0) {
2387
+ continue;
2388
+ }
2389
+ const siblings = childrenByParent.get(parentId);
2390
+ if (siblings) {
2391
+ siblings.push(entityId);
2392
+ } else {
2393
+ childrenByParent.set(parentId, [entityId]);
2394
+ }
2395
+ }
2396
+ const ordered = [];
2397
+ const seen = /* @__PURE__ */ new Set();
2398
+ const queue = [...rootIds];
2399
+ while (queue.length > 0) {
2400
+ const entityId = queue.shift();
2401
+ if (seen.has(entityId)) {
2402
+ continue;
2403
+ }
2404
+ seen.add(entityId);
2405
+ ordered.push(entityId);
2406
+ const children = childrenByParent.get(entityId);
2407
+ if (children) {
2408
+ queue.push(...children.sort((a, b) => a - b));
2409
+ }
2410
+ }
2411
+ return ordered;
2412
+ }
2413
+ __name(collectEntitySubtree, "collectEntitySubtree");
2414
+
2415
+ // core/hydration/readers.ts
2416
+ function asRecord3(value) {
2417
+ if (!value || typeof value !== "object") {
2418
+ return null;
2419
+ }
2420
+ return value;
2421
+ }
2422
+ __name(asRecord3, "asRecord");
2423
+ function readString(value) {
2424
+ if (typeof value === "string") {
2425
+ return value;
2426
+ }
2427
+ const record = asRecord3(value);
2428
+ if (!record) {
2429
+ return null;
2430
+ }
2431
+ return typeof record.value === "string" ? record.value : null;
2432
+ }
2433
+ __name(readString, "readString");
2434
+ function readTransform(value) {
2435
+ const record = asRecord3(value);
2436
+ if (!record) {
2437
+ return void 0;
2438
+ }
2439
+ const position = asRecord3(record.position);
2440
+ const rotation = asRecord3(record.rotation);
2441
+ const scale = asRecord3(record.scale);
2442
+ return {
2443
+ position: position ? {
2444
+ x: typeof position.x === "number" ? position.x : void 0,
2445
+ y: typeof position.y === "number" ? position.y : void 0,
2446
+ z: typeof position.z === "number" ? position.z : void 0
2447
+ } : void 0,
2448
+ rotation: rotation ? {
2449
+ x: typeof rotation.x === "number" ? rotation.x : void 0,
2450
+ y: typeof rotation.y === "number" ? rotation.y : void 0,
2451
+ z: typeof rotation.z === "number" ? rotation.z : void 0
2452
+ } : void 0,
2453
+ scale: scale ? {
2454
+ x: typeof scale.x === "number" ? scale.x : void 0,
2455
+ y: typeof scale.y === "number" ? scale.y : void 0,
2456
+ z: typeof scale.z === "number" ? scale.z : void 0
2457
+ } : void 0
2458
+ };
2459
+ }
2460
+ __name(readTransform, "readTransform");
2461
+ function readByComponent(components, componentName) {
2462
+ const component = components.find((entry) => entry.component === componentName);
2463
+ const map = /* @__PURE__ */ new Map();
2464
+ if (!component) {
2465
+ return map;
2466
+ }
2467
+ for (const entry of component.entries) {
2468
+ map.set(entry.entityId, entry.value);
2469
+ }
2470
+ return map;
2471
+ }
2472
+ __name(readByComponent, "readByComponent");
2473
+ function readBoolean(value) {
2474
+ return typeof value === "boolean" ? value : void 0;
2475
+ }
2476
+ __name(readBoolean, "readBoolean");
2477
+ function readNumber(value) {
2478
+ return typeof value === "number" ? value : void 0;
2479
+ }
2480
+ __name(readNumber, "readNumber");
2481
+
2482
+ // core/hydration/componentValues.ts
2483
+ function buildComponentValueMaps(snapshot) {
2484
+ return {
2485
+ object3DRefValues: readByComponent(snapshot.components, "Object3DRef"),
2486
+ nameValues: readByComponent(snapshot.components, "Name"),
2487
+ transformValues: readByComponent(snapshot.components, "TransformComponent"),
2488
+ modelValues: readByComponent(snapshot.components, "ModelComponent"),
2489
+ imageValues: readByComponent(snapshot.components, "ImageComponent"),
2490
+ spriteValues: readByComponent(snapshot.components, "SpriteComponent"),
2491
+ videoValues: readByComponent(snapshot.components, "VideoComponent"),
2492
+ cameraValues: readByComponent(snapshot.components, "CameraComponent"),
2493
+ environmentValues: readByComponent(snapshot.components, "Environment"),
2494
+ postprocessingValues: readByComponent(snapshot.components, "Postprocessing"),
2495
+ audioValues: readByComponent(snapshot.components, "AudioComponent"),
2496
+ imageTargetValues: readByComponent(snapshot.components, "ImageTarget"),
2497
+ lightValues: readByComponent(snapshot.components, "LightComponent"),
2498
+ materialValues: readByComponent(snapshot.components, "MaterialComponent"),
2499
+ meshGeometryValues: readByComponent(snapshot.components, "MeshGeometryComponent"),
2500
+ selectableValues: readByComponent(snapshot.components, "Selectable"),
2501
+ physicsValues: readByComponent(snapshot.components, "PhysicsComponent"),
2502
+ animationValues: readByComponent(snapshot.components, "AnimationComponent"),
2503
+ imageTargetAnchorValues: readByComponent(snapshot.components, "ImageTargetAnchor"),
2504
+ scriptValues: readByComponent(snapshot.components, "ScriptComponent"),
2505
+ scriptObjectValues: readByComponent(
2506
+ snapshot.components,
2507
+ "ScriptObjectComponent"
2508
+ ),
2509
+ xrRigValues: readByComponent(snapshot.components, "XRRigComponent"),
2510
+ vrTeleportAreaValues: readByComponent(
2511
+ snapshot.components,
2512
+ "VRTeleportAreaComponent"
2513
+ ),
2514
+ xrInteractableValues: readByComponent(
2515
+ snapshot.components,
2516
+ "XRInteractableComponent"
2517
+ ),
2518
+ xrInteractorValues: readByComponent(
2519
+ snapshot.components,
2520
+ "XRInteractorComponent"
2521
+ ),
2522
+ xrHandPoseValues: readByComponent(
2523
+ snapshot.components,
2524
+ "XRHandPoseComponent"
2525
+ ),
2526
+ xrAnchorValues: readByComponent(snapshot.components, "XRAnchorComponent"),
2527
+ boneAttachmentValues: readByComponent(snapshot.components, "BoneAttachmentComponent"),
2528
+ ikValues: readByComponent(snapshot.components, "IKComponent"),
2529
+ networkIdentityValues: readByComponent(snapshot.components, "NetworkIdentityComponent"),
2530
+ networkTransformValues: readByComponent(snapshot.components, "NetworkTransformComponent"),
2531
+ networkedPropsValues: readByComponent(snapshot.components, "NetworkedPropsComponent"),
2532
+ networkSpawnerValues: readByComponent(snapshot.components, "NetworkSpawnerComponent"),
2533
+ uiPanelValues: readByComponent(snapshot.components, "UIPanelComponent"),
2534
+ uiTextValues: readByComponent(snapshot.components, "UITextComponent"),
2535
+ uiButtonValues: readByComponent(snapshot.components, "UIButtonComponent"),
2536
+ uiToggleValues: readByComponent(snapshot.components, "UIToggleComponent"),
2537
+ uiSliderValues: readByComponent(snapshot.components, "UISliderComponent"),
2538
+ xrInteractorSideValues: readByComponent(
2539
+ snapshot.components,
2540
+ "XRInteractorSideComponent"
2541
+ ),
2542
+ instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
2543
+ instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent"),
2544
+ prefabNodeValues: readByComponent(snapshot.components, "PrefabNode"),
2545
+ prefabInstanceValues: readByComponent(snapshot.components, "PrefabInstance")
2546
+ };
2547
+ }
2548
+ __name(buildComponentValueMaps, "buildComponentValueMaps");
2549
+
2550
+ // core/hydration/parentLinks.ts
2551
+ function applyParentLinks(snapshot, idMap, objectManagementSystem, world) {
2552
+ const parentValues = readByComponent(snapshot.components, "ParentId");
2553
+ for (const [sourceEntityId, parentValue] of parentValues.entries()) {
2554
+ const targetEntityId = idMap.get(sourceEntityId);
2555
+ if (targetEntityId === void 0) {
2556
+ continue;
2557
+ }
2558
+ const parentRecord = asRecord3(parentValue);
2559
+ const sourceParentId = parentRecord && typeof parentRecord.value === "number" ? parentRecord.value : null;
2560
+ if (sourceParentId === null) {
2561
+ objectManagementSystem.setParent(world, targetEntityId, null, {
2562
+ preserveWorldTransform: false
2563
+ });
2564
+ continue;
2565
+ }
2566
+ const mappedParentId = idMap.get(sourceParentId);
2567
+ objectManagementSystem.setParent(world, targetEntityId, mappedParentId ?? null, {
2568
+ preserveWorldTransform: false
2569
+ });
2570
+ }
2571
+ }
2572
+ __name(applyParentLinks, "applyParentLinks");
2573
+
2574
+ // core/hydration/postCreateComponents.ts
2575
+ function remapEntityRefsInScriptData(data, idMap) {
2576
+ const result = {};
2577
+ for (const [key, value] of Object.entries(data)) {
2578
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
2579
+ const v = value;
2580
+ if (v.type === "entity" && typeof v.value === "number") {
2581
+ result[key] = { ...v, value: idMap.get(v.value) ?? v.value };
2582
+ } else if (v.type === "component" && v.value !== null && typeof v.value === "object" && !Array.isArray(v.value) && typeof v.value.entityId === "number") {
2583
+ const ref = v.value;
2584
+ result[key] = {
2585
+ ...v,
2586
+ value: { ...ref, entityId: idMap.get(ref.entityId) ?? ref.entityId }
2587
+ };
2588
+ } else {
2589
+ result[key] = value;
2590
+ }
2591
+ } else {
2592
+ result[key] = value;
2593
+ }
2594
+ }
2595
+ return result;
2596
+ }
2597
+ __name(remapEntityRefsInScriptData, "remapEntityRefsInScriptData");
2598
+ function restorePostCreateComponents(world, objectManagementSystem, targetEntityId, sourceEntityId, entityType, values, idMap) {
2599
+ const objectRef = world.getComponent(targetEntityId, Object3DRef)?.object ?? null;
2600
+ const sourceAudio = asRecord3(values.audioValues.get(sourceEntityId));
2601
+ if (sourceAudio && entityType !== "audio") {
2602
+ const sourceOptions = asRecord3(sourceAudio.options) ?? {};
2603
+ objectManagementSystem.createComponentNow(
2604
+ "audio",
2605
+ world,
2606
+ targetEntityId,
2607
+ typeof sourceAudio.path === "string" ? sourceAudio.path : "",
2608
+ sourceOptions,
2609
+ {
2610
+ object: objectRef,
2611
+ listener: objectManagementSystem.getOrCreateAudioListener(),
2612
+ isEditor: objectManagementSystem.isEditorMode()
2613
+ }
2614
+ );
2615
+ }
2616
+ const sourceImageTarget = asRecord3(values.imageTargetValues.get(sourceEntityId));
2617
+ if (sourceImageTarget && entityType !== "imageTarget") {
2618
+ objectManagementSystem.createComponentNow(
2619
+ "imageTarget",
2620
+ world,
2621
+ targetEntityId,
2622
+ {
2623
+ targets: Array.isArray(sourceImageTarget.targets) ? sourceImageTarget.targets : [],
2624
+ compiledTargetUrl: typeof sourceImageTarget.compiledTargetUrl === "string" ? sourceImageTarget.compiledTargetUrl : void 0,
2625
+ compiledTargetDir: typeof sourceImageTarget.compiledTargetDir === "string" ? sourceImageTarget.compiledTargetDir : void 0
2626
+ }
2627
+ );
2628
+ }
2629
+ const sourceImageTargetAnchor = asRecord3(values.imageTargetAnchorValues.get(sourceEntityId));
2630
+ if (sourceImageTargetAnchor) {
2631
+ const mappedTargetId = typeof sourceImageTargetAnchor.targetId === "number" && Number.isFinite(sourceImageTargetAnchor.targetId) ? sourceImageTargetAnchor.targetId : null;
2632
+ objectManagementSystem.createComponentNow("imageTargetAnchor", world, targetEntityId, {
2633
+ targetId: mappedTargetId,
2634
+ targetUrl: typeof sourceImageTargetAnchor.targetUrl === "string" ? sourceImageTargetAnchor.targetUrl : void 0
2635
+ });
2636
+ }
2637
+ const sourceScript = asRecord3(values.scriptValues.get(sourceEntityId));
2638
+ if (sourceScript) {
2639
+ const entries = Array.isArray(sourceScript.entries) ? sourceScript.entries.map((entry) => asRecord3(entry)).filter((entry) => Boolean(entry)).map((entry) => {
2640
+ const runtimeState = entry.runtimeState === "idle" || entry.runtimeState === "loading" || entry.runtimeState === "ready" || entry.runtimeState === "error" ? entry.runtimeState : void 0;
2641
+ return {
2642
+ entityId: targetEntityId,
2643
+ className: typeof entry.className === "string" ? entry.className : "",
2644
+ scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
2645
+ enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
2646
+ data: entry.data && typeof entry.data === "object" && !Array.isArray(entry.data) ? remapEntityRefsInScriptData(entry.data, idMap) : {},
2647
+ runtimeState,
2648
+ runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
2649
+ };
2650
+ }).filter((entry) => entry.className || entry.scriptUrl) : [];
2651
+ if (entries.length) {
2652
+ world.addComponent(targetEntityId, new ScriptComponent(entries));
2653
+ }
2654
+ }
2655
+ const sourceScriptObject = asRecord3(values.scriptObjectValues.get(sourceEntityId));
2656
+ if (sourceScriptObject) {
2657
+ const soc = world.getComponent(targetEntityId, ScriptObjectComponent);
2658
+ const data = asRecord3(sourceScriptObject.data);
2659
+ if (soc && data) {
2660
+ soc.data = remapEntityRefsInScriptData(data, idMap);
2661
+ }
2662
+ }
2663
+ {
2664
+ const sourceXrRig = asRecord3(values.xrRigValues.get(sourceEntityId));
2665
+ const rig = world.getComponent(targetEntityId, XRRigComponent);
2666
+ if (sourceXrRig && rig) {
2667
+ if (typeof sourceXrRig.locomotion === "string") {
2668
+ rig.locomotion = sourceXrRig.locomotion;
2669
+ }
2670
+ if (typeof sourceXrRig.moveSpeed === "number") {
2671
+ rig.moveSpeed = sourceXrRig.moveSpeed;
2672
+ }
2673
+ if (typeof sourceXrRig.snapTurn === "boolean") {
2674
+ rig.snapTurn = sourceXrRig.snapTurn;
2675
+ }
2676
+ if (typeof sourceXrRig.snapTurnDegrees === "number") {
2677
+ rig.snapTurnDegrees = sourceXrRig.snapTurnDegrees;
2678
+ }
2679
+ if (typeof sourceXrRig.teleportArcColor === "string") {
2680
+ rig.teleportArcColor = sourceXrRig.teleportArcColor;
2681
+ }
2682
+ if (typeof sourceXrRig.teleportArcInvalidColor === "string") {
2683
+ rig.teleportArcInvalidColor = sourceXrRig.teleportArcInvalidColor;
2684
+ }
2685
+ if (typeof sourceXrRig.teleportArcThickness === "number") {
2686
+ rig.teleportArcThickness = sourceXrRig.teleportArcThickness;
2687
+ }
2688
+ if (typeof sourceXrRig.fallbackEyeHeight === "number") {
2689
+ rig.fallbackEyeHeight = sourceXrRig.fallbackEyeHeight;
2690
+ }
2691
+ if (typeof sourceXrRig.passthrough === "boolean") {
2692
+ rig.passthrough = sourceXrRig.passthrough;
2693
+ }
2694
+ if (typeof sourceXrRig.depthOcclusion === "boolean") {
2695
+ rig.depthOcclusion = sourceXrRig.depthOcclusion;
2696
+ }
2697
+ if (typeof sourceXrRig.environmentPhysics === "string") {
2698
+ rig.environmentPhysics = sourceXrRig.environmentPhysics;
2699
+ }
2700
+ if (typeof sourceXrRig.environmentDebug === "boolean") {
2701
+ rig.environmentDebug = sourceXrRig.environmentDebug;
2702
+ }
2703
+ if (typeof sourceXrRig.hitTest === "boolean") {
2704
+ rig.hitTest = sourceXrRig.hitTest;
2705
+ }
2706
+ if (typeof sourceXrRig.anchors === "boolean") {
2707
+ rig.anchors = sourceXrRig.anchors;
2708
+ }
2709
+ }
2710
+ }
2711
+ {
2712
+ const sourceArea = asRecord3(values.vrTeleportAreaValues.get(sourceEntityId));
2713
+ const area = world.getComponent(targetEntityId, VRTeleportAreaComponent);
2714
+ if (sourceArea && area) {
2715
+ if (typeof sourceArea.enabled === "boolean") {
2716
+ area.enabled = sourceArea.enabled;
2717
+ }
2718
+ if (typeof sourceArea.shape === "string") {
2719
+ area.shape = sourceArea.shape === "cylinder" ? "circle" : sourceArea.shape;
2720
+ }
2721
+ if (typeof sourceArea.width === "number") area.width = sourceArea.width;
2722
+ if (typeof sourceArea.depth === "number") area.depth = sourceArea.depth;
2723
+ }
2724
+ }
2725
+ {
2726
+ const sourceInteractable = asRecord3(
2727
+ values.xrInteractableValues.get(sourceEntityId)
2728
+ );
2729
+ let interactable = world.getComponent(
2730
+ targetEntityId,
2731
+ XRInteractableComponent
2732
+ );
2733
+ if (sourceInteractable && !interactable) {
2734
+ interactable = new XRInteractableComponent();
2735
+ world.addComponent(targetEntityId, interactable);
2736
+ }
2737
+ if (sourceInteractable && interactable) {
2738
+ if (typeof sourceInteractable.enabled === "boolean") {
2739
+ interactable.enabled = sourceInteractable.enabled;
2740
+ }
2741
+ if (typeof sourceInteractable.grabbable === "boolean") {
2742
+ interactable.grabbable = sourceInteractable.grabbable;
2743
+ }
2744
+ if (typeof sourceInteractable.pointable === "boolean") {
2745
+ interactable.pointable = sourceInteractable.pointable;
2746
+ }
2747
+ if (typeof sourceInteractable.grabReach === "string") {
2748
+ interactable.grabReach = sourceInteractable.grabReach;
2749
+ }
2750
+ if (typeof sourceInteractable.distanceBehavior === "string") {
2751
+ interactable.distanceBehavior = sourceInteractable.distanceBehavior;
2752
+ }
2753
+ if (typeof sourceInteractable.grabGesture === "string") {
2754
+ interactable.grabGesture = sourceInteractable.grabGesture;
2755
+ }
2756
+ if (typeof sourceInteractable.grabRadius === "number") {
2757
+ interactable.grabRadius = sourceInteractable.grabRadius;
2758
+ }
2759
+ if (typeof sourceInteractable.grabHands === "string") {
2760
+ interactable.grabHands = sourceInteractable.grabHands;
2761
+ }
2762
+ if (typeof sourceInteractable.twoHandRotation === "string") {
2763
+ interactable.twoHandRotation = sourceInteractable.twoHandRotation;
2764
+ }
2765
+ if (typeof sourceInteractable.allowTwoHandScale === "boolean") {
2766
+ interactable.allowTwoHandScale = sourceInteractable.allowTwoHandScale;
2767
+ }
2768
+ if (typeof sourceInteractable.minScale === "number") {
2769
+ interactable.minScale = sourceInteractable.minScale;
2770
+ }
2771
+ if (typeof sourceInteractable.maxScale === "number") {
2772
+ interactable.maxScale = sourceInteractable.maxScale;
2773
+ }
2774
+ if (Array.isArray(sourceInteractable.attachPoints)) {
2775
+ interactable.attachPoints = sourceInteractable.attachPoints.map((point) => asRecord3(point)).filter(
2776
+ (point) => point !== null && typeof point.id === "string"
2777
+ ).map(
2778
+ (point) => createAttachPoint(
2779
+ point
2780
+ )
2781
+ );
2782
+ }
2783
+ if (typeof sourceInteractable.applyVelocityOnRelease === "boolean") {
2784
+ interactable.applyVelocityOnRelease = sourceInteractable.applyVelocityOnRelease;
2785
+ } else if (typeof sourceInteractable.throwOnRelease === "boolean") {
2786
+ interactable.applyVelocityOnRelease = sourceInteractable.throwOnRelease;
2787
+ }
2788
+ if (typeof sourceInteractable.velocityScale === "number") {
2789
+ interactable.velocityScale = sourceInteractable.velocityScale;
2790
+ } else if (typeof sourceInteractable.throwStrength === "number") {
2791
+ interactable.velocityScale = sourceInteractable.throwStrength;
2792
+ }
2793
+ const grabPos = asRecord3(sourceInteractable.grabOffsetPosition);
2794
+ if (grabPos) {
2795
+ interactable.grabOffsetPosition = {
2796
+ x: typeof grabPos.x === "number" ? grabPos.x : 0,
2797
+ y: typeof grabPos.y === "number" ? grabPos.y : 0,
2798
+ z: typeof grabPos.z === "number" ? grabPos.z : 0
2799
+ };
2800
+ }
2801
+ const grabRot = asRecord3(sourceInteractable.grabOffsetRotation);
2802
+ if (grabRot) {
2803
+ interactable.grabOffsetRotation = {
2804
+ x: typeof grabRot.x === "number" ? grabRot.x : 0,
2805
+ y: typeof grabRot.y === "number" ? grabRot.y : 0,
2806
+ z: typeof grabRot.z === "number" ? grabRot.z : 0
2807
+ };
2808
+ }
2809
+ if (typeof sourceInteractable.hoverBehavior === "string") {
2810
+ interactable.hoverBehavior = sourceInteractable.hoverBehavior;
2811
+ } else if (sourceInteractable.highlightOnHover === false) {
2812
+ interactable.hoverBehavior = "none";
2813
+ }
2814
+ if (typeof sourceInteractable.hoverColor === "string") {
2815
+ interactable.hoverColor = sourceInteractable.hoverColor;
2816
+ }
2817
+ if (typeof sourceInteractable.hoverScale === "number") {
2818
+ interactable.hoverScale = sourceInteractable.hoverScale;
2819
+ }
2820
+ }
2821
+ }
2822
+ {
2823
+ const sourceHandPose = asRecord3(
2824
+ values.xrHandPoseValues.get(sourceEntityId)
2825
+ );
2826
+ let handPose = world.getComponent(targetEntityId, XRHandPoseComponent);
2827
+ if (sourceHandPose && !handPose) {
2828
+ handPose = new XRHandPoseComponent();
2829
+ world.addComponent(targetEntityId, handPose);
2830
+ }
2831
+ if (sourceHandPose && handPose) {
2832
+ if (typeof sourceHandPose.enabled === "boolean") {
2833
+ handPose.enabled = sourceHandPose.enabled;
2834
+ }
2835
+ if (Array.isArray(sourceHandPose.poses)) {
2836
+ handPose.poses = sourceHandPose.poses.map((entry) => asRecord3(entry)).filter(
2837
+ (entry) => entry !== null && typeof entry.id === "string"
2838
+ ).map(
2839
+ (entry) => createHandPoseEntry(
2840
+ entry
2841
+ )
2842
+ );
2843
+ }
2844
+ }
2845
+ }
2846
+ {
2847
+ const sourceAnchor = asRecord3(values.xrAnchorValues.get(sourceEntityId));
2848
+ let anchor = world.getComponent(targetEntityId, XRAnchorComponent);
2849
+ if (sourceAnchor && !anchor) {
2850
+ anchor = new XRAnchorComponent();
2851
+ world.addComponent(targetEntityId, anchor);
2852
+ }
2853
+ if (sourceAnchor && anchor) {
2854
+ if (typeof sourceAnchor.enabled === "boolean") {
2855
+ anchor.enabled = sourceAnchor.enabled;
2856
+ }
2857
+ }
2858
+ }
2859
+ {
2860
+ const source = asRecord3(values.boneAttachmentValues.get(sourceEntityId));
2861
+ if (source) {
2862
+ let attachment = world.getComponent(targetEntityId, BoneAttachmentComponent);
2863
+ if (!attachment) {
2864
+ attachment = new BoneAttachmentComponent();
2865
+ world.addComponent(targetEntityId, attachment);
2866
+ }
2867
+ if (typeof source.bone === "string") attachment.bone = source.bone;
2868
+ if (typeof source.humanoid === "string" || source.humanoid === null) attachment.humanoid = source.humanoid;
2869
+ if (typeof source.compensateScale === "boolean") attachment.compensateScale = source.compensateScale;
2870
+ if (typeof source.enabled === "boolean") attachment.enabled = source.enabled;
2871
+ }
2872
+ }
2873
+ if (values.networkIdentityValues.has(sourceEntityId) && !world.getComponent(targetEntityId, NetworkIdentityComponent)) {
2874
+ world.addComponent(targetEntityId, new NetworkIdentityComponent());
2875
+ }
2876
+ {
2877
+ const source = asRecord3(values.networkTransformValues.get(sourceEntityId));
2878
+ if (source) {
2879
+ let net = world.getComponent(targetEntityId, NetworkTransformComponent);
2880
+ if (!net) {
2881
+ net = new NetworkTransformComponent();
2882
+ world.addComponent(targetEntityId, net);
2883
+ }
2884
+ if (typeof source.enabled === "boolean") net.enabled = source.enabled;
2885
+ if (typeof source.sendRate === "number") net.sendRate = source.sendRate;
2886
+ if (typeof source.interpolationMs === "number") {
2887
+ net.interpolationMs = source.interpolationMs;
2888
+ }
2889
+ if (typeof source.syncRotation === "boolean") {
2890
+ net.syncRotation = source.syncRotation;
2891
+ }
2892
+ if (typeof source.teleportDistance === "number") {
2893
+ net.teleportDistance = source.teleportDistance;
2894
+ }
2895
+ }
2896
+ }
2897
+ {
2898
+ const source = asRecord3(values.networkedPropsValues.get(sourceEntityId));
2899
+ if (source) {
2900
+ let props = world.getComponent(targetEntityId, NetworkedPropsComponent);
2901
+ if (!props) {
2902
+ props = new NetworkedPropsComponent();
2903
+ world.addComponent(targetEntityId, props);
2904
+ }
2905
+ props.values = asRecord3(source.values) ?? {};
2906
+ }
2907
+ }
2908
+ {
2909
+ const source = asRecord3(values.networkSpawnerValues.get(sourceEntityId));
2910
+ if (source) {
2911
+ let spawner = world.getComponent(targetEntityId, NetworkSpawnerComponent);
2912
+ if (!spawner) {
2913
+ spawner = new NetworkSpawnerComponent();
2914
+ world.addComponent(targetEntityId, spawner);
2915
+ }
2916
+ if (typeof source.playerPrefab === "string") {
2917
+ spawner.playerPrefab = source.playerPrefab;
2918
+ }
2919
+ if (typeof source.spawnRadius === "number") {
2920
+ spawner.spawnRadius = source.spawnRadius;
2921
+ }
2922
+ }
2923
+ }
2924
+ {
2925
+ const source = asRecord3(values.ikValues.get(sourceEntityId));
2926
+ if (source) {
2927
+ let ik = world.getComponent(targetEntityId, IKComponent);
2928
+ if (!ik) {
2929
+ ik = new IKComponent();
2930
+ world.addComponent(targetEntityId, ik);
2931
+ }
2932
+ if (typeof source.enabled === "boolean") ik.enabled = source.enabled;
2933
+ if (Array.isArray(source.chains)) {
2934
+ const mapId = /* @__PURE__ */ __name((v) => typeof v === "number" ? idMap.get(v) ?? v : null, "mapId");
2935
+ ik.chains = source.chains.map((raw) => asRecord3(raw)).filter((c) => !!c && typeof c.limb === "string").map(
2936
+ (c) => normalizeIKChain({
2937
+ ...c,
2938
+ limb: c.limb,
2939
+ target: mapId(c.target),
2940
+ pole: mapId(c.pole)
2941
+ })
2942
+ );
2943
+ }
2944
+ }
2945
+ }
2946
+ {
2947
+ const restoreUi = /* @__PURE__ */ __name((map, Ctor, existing) => {
2948
+ const source = asRecord3(map.get(sourceEntityId));
2949
+ if (!source) return;
2950
+ let component = existing;
2951
+ if (!component) {
2952
+ component = new Ctor();
2953
+ world.addComponent(targetEntityId, component);
2954
+ }
2955
+ const target = component;
2956
+ for (const [key, value] of Object.entries(source)) {
2957
+ const current = target[key];
2958
+ if ((typeof value === "string" || typeof value === "number" || typeof value === "boolean") && typeof current === typeof value) {
2959
+ target[key] = value;
2960
+ }
2961
+ }
2962
+ }, "restoreUi");
2963
+ restoreUi(
2964
+ values.uiPanelValues,
2965
+ UIPanelComponent,
2966
+ world.getComponent(targetEntityId, UIPanelComponent)
2967
+ );
2968
+ restoreUi(
2969
+ values.uiTextValues,
2970
+ UITextComponent,
2971
+ world.getComponent(targetEntityId, UITextComponent)
2972
+ );
2973
+ restoreUi(
2974
+ values.uiButtonValues,
2975
+ UIButtonComponent,
2976
+ world.getComponent(targetEntityId, UIButtonComponent)
2977
+ );
2978
+ restoreUi(
2979
+ values.uiToggleValues,
2980
+ UIToggleComponent,
2981
+ world.getComponent(targetEntityId, UIToggleComponent)
2982
+ );
2983
+ restoreUi(
2984
+ values.uiSliderValues,
2985
+ UISliderComponent,
2986
+ world.getComponent(targetEntityId, UISliderComponent)
2987
+ );
2988
+ }
2989
+ {
2990
+ const sourceInteractor = asRecord3(
2991
+ values.xrInteractorValues.get(sourceEntityId)
2992
+ );
2993
+ const interactor = world.getComponent(targetEntityId, XRInteractorComponent);
2994
+ if (sourceInteractor && interactor) {
2995
+ if (typeof sourceInteractor.interactorType === "string") {
2996
+ interactor.interactorType = sourceInteractor.interactorType;
2997
+ }
2998
+ if (typeof sourceInteractor.handPreset === "string") {
2999
+ interactor.handPreset = sourceInteractor.handPreset;
3000
+ }
3001
+ if (typeof sourceInteractor.handColor === "string") {
3002
+ interactor.handColor = sourceInteractor.handColor;
3003
+ }
3004
+ if (typeof sourceInteractor.handOpacity === "number") {
3005
+ interactor.handOpacity = sourceInteractor.handOpacity;
3006
+ }
3007
+ if (typeof sourceInteractor.handEmissiveIntensity === "number") {
3008
+ interactor.handEmissiveIntensity = sourceInteractor.handEmissiveIntensity;
3009
+ }
3010
+ if (typeof sourceInteractor.rayVisibility === "string") {
3011
+ interactor.rayVisibility = sourceInteractor.rayVisibility;
3012
+ } else if (typeof sourceInteractor.showRay === "boolean") {
3013
+ interactor.rayVisibility = sourceInteractor.showRay ? "interacting" : "never";
3014
+ }
3015
+ if (typeof sourceInteractor.rayColor === "string") {
3016
+ interactor.rayColor = sourceInteractor.rayColor;
3017
+ }
3018
+ if (typeof sourceInteractor.rayThickness === "number") {
3019
+ interactor.rayThickness = sourceInteractor.rayThickness;
3020
+ }
3021
+ }
3022
+ }
3023
+ {
3024
+ const sourceSide = asRecord3(
3025
+ values.xrInteractorSideValues.get(sourceEntityId)
3026
+ );
3027
+ if (sourceSide && typeof sourceSide.side === "string") {
3028
+ const existing = world.getComponent(
3029
+ targetEntityId,
3030
+ XRInteractorSideComponent
3031
+ );
3032
+ if (existing) {
3033
+ existing.side = sourceSide.side;
3034
+ } else {
3035
+ world.addComponent(
3036
+ targetEntityId,
3037
+ new XRInteractorSideComponent({
3038
+ side: sourceSide.side
3039
+ })
3040
+ );
3041
+ }
3042
+ }
3043
+ }
3044
+ {
3045
+ const sourceRigOrigin = asRecord3(values.xrRigValues.get(sourceEntityId));
3046
+ const rigForOrigin = world.getComponent(targetEntityId, XRRigComponent);
3047
+ if (sourceRigOrigin && rigForOrigin && typeof sourceRigOrigin.trackingOrigin === "string") {
3048
+ rigForOrigin.trackingOrigin = sourceRigOrigin.trackingOrigin;
3049
+ }
3050
+ }
3051
+ {
3052
+ const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
3053
+ if (imComponent && imComponent.instanceEntityIds.length > 0) {
3054
+ imComponent.instanceEntityIds = imComponent.instanceEntityIds.map(
3055
+ (oldId) => idMap.get(oldId) ?? oldId
3056
+ );
3057
+ }
3058
+ }
3059
+ {
3060
+ const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
3061
+ if (slotComponent && slotComponent.groupEntityId !== -1) {
3062
+ slotComponent.groupEntityId = idMap.get(slotComponent.groupEntityId) ?? slotComponent.groupEntityId;
3063
+ }
3064
+ }
3065
+ }
3066
+ __name(restorePostCreateComponents, "restorePostCreateComponents");
3067
+
3068
+ // core/hydration/animation.ts
3069
+ function readAnimationClipName(value) {
3070
+ if (typeof value === "string") {
3071
+ return value;
3072
+ }
3073
+ const record = asRecord3(value);
3074
+ if (!record) {
3075
+ return null;
3076
+ }
3077
+ if (typeof record.name === "string") {
3078
+ return record.name;
3079
+ }
3080
+ return null;
3081
+ }
3082
+ __name(readAnimationClipName, "readAnimationClipName");
3083
+ function readAnimationStates(value) {
3084
+ if (!Array.isArray(value)) {
3085
+ return [];
3086
+ }
3087
+ const states = [];
3088
+ for (const entry of value) {
3089
+ const state = asRecord3(entry);
3090
+ if (!state) {
3091
+ continue;
3092
+ }
3093
+ const name = typeof state.name === "string" ? state.name : null;
3094
+ const clip = readAnimationClipName(state.clip);
3095
+ if (!name || !clip) {
3096
+ continue;
3097
+ }
3098
+ states.push({
3099
+ name,
3100
+ clip,
3101
+ clipId: typeof state.clipId === "string" ? state.clipId : void 0,
3102
+ loop: typeof state.loop === "boolean" ? state.loop : false
3103
+ });
3104
+ }
3105
+ return states;
3106
+ }
3107
+ __name(readAnimationStates, "readAnimationStates");
3108
+ function readAnimationClipSources(value) {
3109
+ if (!Array.isArray(value)) {
3110
+ return [];
3111
+ }
3112
+ const seen = /* @__PURE__ */ new Set();
3113
+ const sources = [];
3114
+ for (const entry of value) {
3115
+ if (typeof entry !== "string") {
3116
+ continue;
3117
+ }
3118
+ const trimmed = entry.trim();
3119
+ if (!trimmed || seen.has(trimmed)) {
3120
+ continue;
3121
+ }
3122
+ seen.add(trimmed);
3123
+ sources.push(trimmed);
3124
+ }
3125
+ return sources;
3126
+ }
3127
+ __name(readAnimationClipSources, "readAnimationClipSources");
3128
+ function toAnimationOptions(sourceAnimation) {
3129
+ const paused = readBoolean(sourceAnimation.paused);
3130
+ const reverse = readBoolean(sourceAnimation.reverse);
3131
+ const timeScale = readNumber(sourceAnimation.timeScale);
3132
+ const crossFadeDuration = readNumber(sourceAnimation.crossFadeDuration);
3133
+ const states = readAnimationStates(sourceAnimation.states);
3134
+ const externalClipSources = readAnimationClipSources(
3135
+ sourceAnimation.externalClipSources
3136
+ );
3137
+ const activeStateName = typeof sourceAnimation.activeStateName === "string" ? sourceAnimation.activeStateName : typeof sourceAnimation.activeState === "string" ? sourceAnimation.activeState : typeof sourceAnimation.active?.name === "string" ? sourceAnimation.active.name ?? null : null;
3138
+ return {
3139
+ paused,
3140
+ reverse,
3141
+ timeScale,
3142
+ crossFadeDuration,
3143
+ states,
3144
+ externalClipSources,
3145
+ activeState: activeStateName
3146
+ };
3147
+ }
3148
+ __name(toAnimationOptions, "toAnimationOptions");
3149
+ function restoreAnimationComponent(world, objectManagementSystem, targetEntityId, sourceAnimation) {
3150
+ const options = toAnimationOptions(sourceAnimation);
3151
+ let animation = world.getComponent(targetEntityId, AnimationComponent);
3152
+ if (!animation) {
3153
+ objectManagementSystem.createComponentNow(
3154
+ "animation",
3155
+ world,
3156
+ targetEntityId,
3157
+ options
3158
+ );
3159
+ animation = world.getComponent(targetEntityId, AnimationComponent);
3160
+ }
3161
+ if (!animation) {
3162
+ return;
3163
+ }
3164
+ const availableClips = Array.isArray(sourceAnimation.availableClips) ? sourceAnimation.availableClips.filter(
3165
+ (clip) => typeof clip === "string" && clip.length > 0
3166
+ ) : [];
3167
+ if (availableClips.length > 0) {
3168
+ animation.availableClips = [...availableClips];
3169
+ }
3170
+ if (Array.isArray(options.externalClipSources)) {
3171
+ animation.setExternalClipSources(options.externalClipSources);
3172
+ }
3173
+ const states = options.states ?? [];
3174
+ const hasClips = Array.isArray(animation.clips) && animation.clips.length > 0;
3175
+ if (!hasClips) {
3176
+ animation.__pendingHydratedOptions = options;
3177
+ if (typeof options.reverse === "boolean") {
3178
+ animation.reverse = options.reverse;
3179
+ }
3180
+ if (typeof options.timeScale === "number") {
3181
+ animation.timeScale = options.timeScale;
3182
+ }
3183
+ if (typeof options.crossFadeDuration === "number") {
3184
+ animation.crossFadeDuration = options.crossFadeDuration;
3185
+ }
3186
+ if (typeof options.paused === "boolean") {
3187
+ animation.paused = options.paused;
3188
+ }
3189
+ return;
3190
+ }
3191
+ if (states.length > 0) {
3192
+ animation.setStates(states);
3193
+ }
3194
+ if (typeof options.reverse === "boolean") {
3195
+ animation.reverse = options.reverse;
3196
+ }
3197
+ if (typeof options.timeScale === "number") {
3198
+ animation.timeScale = options.timeScale;
3199
+ }
3200
+ if (typeof options.crossFadeDuration === "number") {
3201
+ animation.crossFadeDuration = options.crossFadeDuration;
3202
+ }
3203
+ if (typeof options.activeState === "string" && options.activeState.length > 0) {
3204
+ animation.setActiveState(options.activeState, !options.paused);
3205
+ }
3206
+ if (typeof options.paused === "boolean") {
3207
+ if (options.paused) {
3208
+ animation.pauseState();
3209
+ } else if (typeof options.activeState === "string" && options.activeState.length > 0) {
3210
+ animation.playState(options.activeState);
3211
+ }
3212
+ }
3213
+ }
3214
+ __name(restoreAnimationComponent, "restoreAnimationComponent");
3215
+
3216
+ // core/hydration/restoreComponentState.ts
3217
+ function readEnvironmentState(value) {
3218
+ const record = asRecord3(value);
3219
+ if (!record) {
3220
+ return null;
3221
+ }
3222
+ const nestedValues = asRecord3(record.values);
3223
+ if (nestedValues) {
3224
+ return nestedValues;
3225
+ }
3226
+ return record;
3227
+ }
3228
+ __name(readEnvironmentState, "readEnvironmentState");
3229
+ function readPostprocessingState(value) {
3230
+ const record = asRecord3(value);
3231
+ if (!record) {
3232
+ return null;
3233
+ }
3234
+ const nestedValues = asRecord3(record.values);
3235
+ if (nestedValues) {
3236
+ return nestedValues;
3237
+ }
3238
+ return record;
3239
+ }
3240
+ __name(readPostprocessingState, "readPostprocessingState");
3241
+ function restoreComponentState(world, objectManagementSystem, targetEntityId, sourceEntityId, entityType, values) {
3242
+ const sourceName = readString(values.nameValues.get(sourceEntityId));
3243
+ if (sourceName !== null) {
3244
+ const nameComponent = world.getComponent(targetEntityId, Name);
3245
+ if (nameComponent) {
3246
+ nameComponent.value = sourceName;
3247
+ }
3248
+ }
3249
+ const sourceObject3DRef = asRecord3(values.object3DRefValues.get(sourceEntityId));
3250
+ if (sourceObject3DRef) {
3251
+ const object3DRefComponent = world.getComponent(targetEntityId, Object3DRef);
3252
+ const visibility = readBoolean(sourceObject3DRef.visibility);
3253
+ if (object3DRefComponent && typeof visibility === "boolean") {
3254
+ object3DRefComponent.visibility = visibility;
3255
+ }
3256
+ }
3257
+ const sourceTransform = readTransform(values.transformValues.get(sourceEntityId));
3258
+ if (sourceTransform) {
3259
+ const transformComponent = world.getComponent(targetEntityId, TransformComponent);
3260
+ if (transformComponent) {
3261
+ if (typeof sourceTransform.position?.x === "number") {
3262
+ transformComponent.position.x = sourceTransform.position.x;
3263
+ }
3264
+ if (typeof sourceTransform.position?.y === "number") {
3265
+ transformComponent.position.y = sourceTransform.position.y;
3266
+ }
3267
+ if (typeof sourceTransform.position?.z === "number") {
3268
+ transformComponent.position.z = sourceTransform.position.z;
3269
+ }
3270
+ if (typeof sourceTransform.rotation?.x === "number") {
3271
+ transformComponent.rotation.x = sourceTransform.rotation.x;
3272
+ }
3273
+ if (typeof sourceTransform.rotation?.y === "number") {
3274
+ transformComponent.rotation.y = sourceTransform.rotation.y;
3275
+ }
3276
+ if (typeof sourceTransform.rotation?.z === "number") {
3277
+ transformComponent.rotation.z = sourceTransform.rotation.z;
3278
+ }
3279
+ if (typeof sourceTransform.scale?.x === "number") {
3280
+ transformComponent.scale.x = sourceTransform.scale.x;
3281
+ }
3282
+ if (typeof sourceTransform.scale?.y === "number") {
3283
+ transformComponent.scale.y = sourceTransform.scale.y;
3284
+ }
3285
+ if (typeof sourceTransform.scale?.z === "number") {
3286
+ transformComponent.scale.z = sourceTransform.scale.z;
3287
+ }
3288
+ }
3289
+ }
3290
+ const sourceModel = asRecord3(values.modelValues.get(sourceEntityId));
3291
+ if (sourceModel) {
3292
+ const modelComponent = world.getComponent(targetEntityId, ModelComponent);
3293
+ if (modelComponent && typeof sourceModel.path === "string") {
3294
+ modelComponent.path = sourceModel.path;
3295
+ }
3296
+ }
3297
+ const sourceImage = asRecord3(values.imageValues.get(sourceEntityId));
3298
+ if (sourceImage) {
3299
+ const imageComponent = world.getComponent(targetEntityId, ImageComponent);
3300
+ if (imageComponent) {
3301
+ if (typeof sourceImage.path === "string") {
3302
+ imageComponent.path = sourceImage.path;
3303
+ }
3304
+ const width = readNumber(sourceImage.width);
3305
+ if (typeof width === "number") {
3306
+ imageComponent.width = width;
3307
+ }
3308
+ const height = readNumber(sourceImage.height);
3309
+ if (typeof height === "number") {
3310
+ imageComponent.height = height;
3311
+ }
3312
+ }
3313
+ }
3314
+ const sourceSprite = asRecord3(values.spriteValues.get(sourceEntityId));
3315
+ if (sourceSprite) {
3316
+ const spriteComponent = world.getComponent(targetEntityId, SpriteComponent);
3317
+ if (spriteComponent) {
3318
+ if (typeof sourceSprite.path === "string") {
3319
+ spriteComponent.path = sourceSprite.path;
3320
+ }
3321
+ const width = readNumber(sourceSprite.width);
3322
+ if (typeof width === "number") {
3323
+ spriteComponent.width = width;
3324
+ }
3325
+ const height = readNumber(sourceSprite.height);
3326
+ if (typeof height === "number") {
3327
+ spriteComponent.height = height;
3328
+ }
3329
+ }
3330
+ }
3331
+ const sourceVideo = asRecord3(values.videoValues.get(sourceEntityId));
3332
+ if (sourceVideo) {
3333
+ const videoComponent = world.getComponent(targetEntityId, VideoComponent);
3334
+ if (videoComponent) {
3335
+ if (typeof sourceVideo.path === "string") {
3336
+ videoComponent.path = sourceVideo.path;
3337
+ }
3338
+ const videoOptions = asRecord3(sourceVideo.options);
3339
+ if (videoOptions) {
3340
+ videoComponent.options = {
3341
+ ...videoComponent.options,
3342
+ ...videoOptions
3343
+ };
3344
+ }
3345
+ }
3346
+ }
3347
+ const sourceAudio = asRecord3(values.audioValues.get(sourceEntityId));
3348
+ if (sourceAudio && entityType === "audio") {
3349
+ const audioComponent = world.getComponent(targetEntityId, AudioComponent);
3350
+ if (audioComponent) {
3351
+ if (typeof sourceAudio.path === "string") {
3352
+ audioComponent.path = sourceAudio.path;
3353
+ }
3354
+ const audioOptions = asRecord3(sourceAudio.options);
3355
+ if (audioOptions) {
3356
+ audioComponent.options = {
3357
+ ...audioComponent.options,
3358
+ ...audioOptions
3359
+ };
3360
+ }
3361
+ }
3362
+ }
3363
+ const sourceCamera = asRecord3(values.cameraValues.get(sourceEntityId));
3364
+ if (sourceCamera) {
3365
+ const cameraComponent = world.getComponent(targetEntityId, CameraComponent);
3366
+ if (cameraComponent) {
3367
+ if (sourceCamera.projection === "orthographic" || sourceCamera.projection === "perspective") {
3368
+ cameraComponent.projection = sourceCamera.projection;
3369
+ }
3370
+ if (sourceCamera.type === "3d" || sourceCamera.type === "ar") {
3371
+ cameraComponent.type = sourceCamera.type;
3372
+ }
3373
+ if (typeof sourceCamera.isDefault === "boolean") {
3374
+ cameraComponent.isDefault = sourceCamera.isDefault;
3375
+ }
3376
+ const fov = readNumber(sourceCamera.fov);
3377
+ if (typeof fov === "number") {
3378
+ cameraComponent.fov = fov;
3379
+ }
3380
+ const near = readNumber(sourceCamera.near);
3381
+ if (typeof near === "number") {
3382
+ cameraComponent.near = near;
3383
+ }
3384
+ const far = readNumber(sourceCamera.far);
3385
+ if (typeof far === "number") {
3386
+ cameraComponent.far = far;
3387
+ }
3388
+ const left = readNumber(sourceCamera.left);
3389
+ if (typeof left === "number") {
3390
+ cameraComponent.left = left;
3391
+ }
3392
+ const right = readNumber(sourceCamera.right);
3393
+ if (typeof right === "number") {
3394
+ cameraComponent.right = right;
3395
+ }
3396
+ const top = readNumber(sourceCamera.top);
3397
+ if (typeof top === "number") {
3398
+ cameraComponent.top = top;
3399
+ }
3400
+ const bottom = readNumber(sourceCamera.bottom);
3401
+ if (typeof bottom === "number") {
3402
+ cameraComponent.bottom = bottom;
3403
+ }
3404
+ const zoom = readNumber(sourceCamera.zoom);
3405
+ if (typeof zoom === "number") {
3406
+ cameraComponent.zoom = zoom;
3407
+ }
3408
+ }
3409
+ }
3410
+ const sourceEnvironment = readEnvironmentState(
3411
+ values.environmentValues.get(sourceEntityId)
3412
+ );
3413
+ if (sourceEnvironment) {
3414
+ let environmentComponent = world.getComponent(targetEntityId, Environment);
3415
+ if (!environmentComponent) {
3416
+ objectManagementSystem.createComponentNow(
3417
+ "environment",
3418
+ world,
3419
+ targetEntityId,
3420
+ sourceEnvironment
3421
+ );
3422
+ environmentComponent = world.getComponent(targetEntityId, Environment);
3423
+ }
3424
+ if (environmentComponent) {
3425
+ environmentComponent.values = new Environment({
3426
+ ...environmentComponent.values,
3427
+ ...sourceEnvironment
3428
+ }).values;
3429
+ }
3430
+ }
3431
+ const sourcePostprocessing = readPostprocessingState(
3432
+ values.postprocessingValues.get(sourceEntityId)
3433
+ );
3434
+ if (sourcePostprocessing) {
3435
+ let postprocessingComponent = world.getComponent(targetEntityId, Postprocessing);
3436
+ if (!postprocessingComponent) {
3437
+ objectManagementSystem.createComponentNow(
3438
+ "postprocessing",
3439
+ world,
3440
+ targetEntityId,
3441
+ sourcePostprocessing
3442
+ );
3443
+ postprocessingComponent = world.getComponent(targetEntityId, Postprocessing);
3444
+ }
3445
+ if (postprocessingComponent) {
3446
+ postprocessingComponent.values = new Postprocessing({
3447
+ ...postprocessingComponent.values,
3448
+ ...sourcePostprocessing
3449
+ }).values;
3450
+ }
3451
+ }
3452
+ const sourceImageTarget = asRecord3(values.imageTargetValues.get(sourceEntityId));
3453
+ if (sourceImageTarget && entityType === "imageTarget") {
3454
+ const imageTargetComponent = world.getComponent(targetEntityId, ImageTarget);
3455
+ if (imageTargetComponent) {
3456
+ imageTargetComponent.targets = Array.isArray(sourceImageTarget.targets) ? sourceImageTarget.targets : [];
3457
+ imageTargetComponent.compiledTargetUrl = typeof sourceImageTarget.compiledTargetUrl === "string" ? sourceImageTarget.compiledTargetUrl : void 0;
3458
+ imageTargetComponent.compiledTargetDir = typeof sourceImageTarget.compiledTargetDir === "string" ? sourceImageTarget.compiledTargetDir : void 0;
3459
+ }
3460
+ }
3461
+ const sourceLight = asRecord3(values.lightValues.get(sourceEntityId));
3462
+ if (sourceLight) {
3463
+ const lightComponent = world.getComponent(targetEntityId, LightComponent);
3464
+ const sourceValues = asRecord3(sourceLight.values);
3465
+ if (lightComponent && sourceValues) {
3466
+ lightComponent.values = {
3467
+ ...lightComponent.values,
3468
+ ...sourceValues
3469
+ };
3470
+ }
3471
+ }
3472
+ const sourceMaterial = asRecord3(values.materialValues.get(sourceEntityId));
3473
+ if (sourceMaterial) {
3474
+ const materialComponent = world.getComponent(targetEntityId, MaterialComponent);
3475
+ const sourceValues = sourceMaterial.values;
3476
+ if (materialComponent && Array.isArray(sourceValues)) {
3477
+ materialComponent.values = sourceValues;
3478
+ }
3479
+ const sourceAssetRefs = sourceMaterial.assetRefs;
3480
+ if (materialComponent && Array.isArray(sourceAssetRefs)) {
3481
+ materialComponent.assetRefs = sourceAssetRefs;
3482
+ }
3483
+ }
3484
+ const sourceMeshGeometry = asRecord3(values.meshGeometryValues.get(sourceEntityId));
3485
+ if (sourceMeshGeometry) {
3486
+ const meshGeometryComponent = world.getComponent(
3487
+ targetEntityId,
3488
+ MeshGeometryComponent
3489
+ );
3490
+ if (meshGeometryComponent) {
3491
+ const parameters = asRecord3(sourceMeshGeometry.parameters);
3492
+ if (parameters) {
3493
+ meshGeometryComponent.parameters = parameters;
3494
+ }
3495
+ if (typeof sourceMeshGeometry.modelName === "string") {
3496
+ meshGeometryComponent.modelName = sourceMeshGeometry.modelName;
3497
+ }
3498
+ if (typeof sourceMeshGeometry.castShadow === "boolean") {
3499
+ meshGeometryComponent.castShadow = sourceMeshGeometry.castShadow;
3500
+ }
3501
+ if (typeof sourceMeshGeometry.receiveShadow === "boolean") {
3502
+ meshGeometryComponent.receiveShadow = sourceMeshGeometry.receiveShadow;
3503
+ }
3504
+ }
3505
+ }
3506
+ const sourceSelectable = asRecord3(values.selectableValues.get(sourceEntityId));
3507
+ if (sourceSelectable) {
3508
+ const enabled = readBoolean(sourceSelectable.enabled);
3509
+ let selectable = world.getComponent(targetEntityId, Selectable);
3510
+ if (!selectable) {
3511
+ objectManagementSystem.createComponentNow(
3512
+ "selectable",
3513
+ world,
3514
+ targetEntityId,
3515
+ enabled ?? true
3516
+ );
3517
+ selectable = world.getComponent(targetEntityId, Selectable);
3518
+ }
3519
+ if (selectable && typeof enabled === "boolean") {
3520
+ selectable.enabled = enabled;
3521
+ }
3522
+ }
3523
+ const sourcePhysics = asRecord3(values.physicsValues.get(sourceEntityId));
3524
+ if (sourcePhysics) {
3525
+ const physicsValues = asRecord3(sourcePhysics.values) ?? sourcePhysics;
3526
+ let physics = world.getComponent(targetEntityId, PhysicsComponent);
3527
+ if (!physics) {
3528
+ objectManagementSystem.createComponentNow(
3529
+ "physics",
3530
+ world,
3531
+ targetEntityId,
3532
+ physicsValues
3533
+ );
3534
+ physics = world.getComponent(targetEntityId, PhysicsComponent);
3535
+ }
3536
+ if (physics) {
3537
+ physics.setValues({
3538
+ rigidbody: asRecord3(physicsValues.rigidbody) ?? {},
3539
+ collider: asRecord3(physicsValues.collider) ?? {}
3540
+ });
3541
+ }
3542
+ }
3543
+ const sourceAnimation = asRecord3(values.animationValues.get(sourceEntityId));
3544
+ if (sourceAnimation) {
3545
+ restoreAnimationComponent(
3546
+ world,
3547
+ objectManagementSystem,
3548
+ targetEntityId,
3549
+ sourceAnimation
3550
+ );
3551
+ }
3552
+ const sourceInstancedMesh = asRecord3(values.instancedMeshValues.get(sourceEntityId));
3553
+ if (sourceInstancedMesh) {
3554
+ const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
3555
+ if (imComponent) {
3556
+ if (typeof sourceInstancedMesh.meshKind === "string") {
3557
+ imComponent.meshKind = sourceInstancedMesh.meshKind;
3558
+ }
3559
+ if (typeof sourceInstancedMesh.modelPath === "string") {
3560
+ imComponent.modelPath = sourceInstancedMesh.modelPath;
3561
+ }
3562
+ const parameters = asRecord3(sourceInstancedMesh.meshParameters);
3563
+ if (parameters) {
3564
+ imComponent.meshParameters = parameters;
3565
+ }
3566
+ if (typeof sourceInstancedMesh.castShadow === "boolean") {
3567
+ imComponent.castShadow = sourceInstancedMesh.castShadow;
3568
+ }
3569
+ if (typeof sourceInstancedMesh.receiveShadow === "boolean") {
3570
+ imComponent.receiveShadow = sourceInstancedMesh.receiveShadow;
3571
+ }
3572
+ if (Array.isArray(sourceInstancedMesh.instanceEntityIds)) {
3573
+ imComponent.instanceEntityIds = sourceInstancedMesh.instanceEntityIds;
3574
+ }
3575
+ imComponent.instancedMesh = null;
3576
+ }
3577
+ }
3578
+ const sourceInstanceSlot = asRecord3(values.instanceSlotValues.get(sourceEntityId));
3579
+ if (sourceInstanceSlot) {
3580
+ const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
3581
+ if (slotComponent) {
3582
+ if (typeof sourceInstanceSlot.slotIndex === "number") {
3583
+ slotComponent.slotIndex = sourceInstanceSlot.slotIndex;
3584
+ }
3585
+ }
3586
+ }
3587
+ const sourcePrefabNode = asRecord3(values.prefabNodeValues.get(sourceEntityId));
3588
+ if (sourcePrefabNode && typeof sourcePrefabNode.nodeId === "string") {
3589
+ if (!world.getComponent(targetEntityId, PrefabNode)) {
3590
+ world.addComponent(targetEntityId, new PrefabNode(sourcePrefabNode.nodeId));
3591
+ }
3592
+ }
3593
+ const sourcePrefabInstance = asRecord3(
3594
+ values.prefabInstanceValues.get(sourceEntityId)
3595
+ );
3596
+ if (sourcePrefabInstance && typeof sourcePrefabInstance.url === "string") {
3597
+ if (!world.getComponent(targetEntityId, PrefabInstance)) {
3598
+ const overrides = Array.isArray(sourcePrefabInstance.overrides) ? sourcePrefabInstance.overrides.filter(
3599
+ (entry) => typeof entry === "string"
3600
+ ) : [];
3601
+ world.addComponent(
3602
+ targetEntityId,
3603
+ new PrefabInstance(
3604
+ sourcePrefabInstance.url,
3605
+ overrides,
3606
+ // Preserve the placement identity; the constructor generates a
3607
+ // fresh one for legacy snapshots that predate instanceId.
3608
+ typeof sourcePrefabInstance.instanceId === "string" && sourcePrefabInstance.instanceId.length > 0 ? sourcePrefabInstance.instanceId : void 0
3609
+ )
3610
+ );
3611
+ }
3612
+ }
3613
+ }
3614
+ __name(restoreComponentState, "restoreComponentState");
3615
+
3616
+ // core/hydration/types.ts
3617
+ var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
3618
+ "cube",
3619
+ "sphere",
3620
+ "plane",
3621
+ "capsule",
3622
+ "cylinder",
3623
+ "empty",
3624
+ "model",
3625
+ "image",
3626
+ "imageTarget",
3627
+ "sprite",
3628
+ "audio",
3629
+ "camera",
3630
+ "video",
3631
+ "ambientLight",
3632
+ "directionalLight",
3633
+ "pointLight",
3634
+ "spotLight",
3635
+ "areaLight",
3636
+ "instancedMesh",
3637
+ "instanceSlot",
3638
+ "scriptObject",
3639
+ "xrRig",
3640
+ "xrInteractor",
3641
+ "teleportArea",
3642
+ "uiPanel",
3643
+ "uiText",
3644
+ "uiButton",
3645
+ "uiToggle",
3646
+ "uiSlider"
3647
+ ]);
3648
+
3649
+ // core/hydration/hydrateWorld.ts
3650
+ function buildEntityCreationPayload(sourceEntityId, kind, componentValues) {
3651
+ const payload = {
3652
+ name: readString(componentValues.nameValues.get(sourceEntityId)) ?? void 0,
3653
+ transform: readTransform(componentValues.transformValues.get(sourceEntityId))
3654
+ };
3655
+ if (kind === "model") {
3656
+ const model = asRecord3(componentValues.modelValues.get(sourceEntityId));
3657
+ if (typeof model?.path === "string") {
3658
+ payload.path = model.path;
3659
+ }
3660
+ }
3661
+ if (kind === "image") {
3662
+ const image = asRecord3(componentValues.imageValues.get(sourceEntityId));
3663
+ if (typeof image?.path === "string") {
3664
+ payload.path = image.path;
3665
+ }
3666
+ }
3667
+ if (kind === "sprite") {
3668
+ const sprite = asRecord3(componentValues.spriteValues.get(sourceEntityId));
3669
+ if (typeof sprite?.path === "string") {
3670
+ payload.path = sprite.path;
3671
+ }
3672
+ }
3673
+ if (kind === "video") {
3674
+ const video = asRecord3(componentValues.videoValues.get(sourceEntityId));
3675
+ if (typeof video?.path === "string") {
3676
+ payload.path = video.path;
3677
+ }
3678
+ const videoOptions = asRecord3(video?.options);
3679
+ if (videoOptions) {
3680
+ payload.options = videoOptions;
3681
+ }
3682
+ }
3683
+ if (kind === "audio") {
3684
+ const audio = asRecord3(componentValues.audioValues.get(sourceEntityId));
3685
+ if (typeof audio?.path === "string") {
3686
+ payload.path = audio.path;
3687
+ }
3688
+ const audioOptions = asRecord3(audio?.options);
3689
+ if (audioOptions) {
3690
+ payload.options = audioOptions;
3691
+ }
3692
+ }
3693
+ if (kind === "camera") {
3694
+ const camera = asRecord3(componentValues.cameraValues.get(sourceEntityId));
3695
+ if (camera) {
3696
+ const projection = camera.projection === "orthographic" || camera.projection === "perspective" ? camera.projection : void 0;
3697
+ const type = camera.type === "3d" || camera.type === "ar" ? camera.type : void 0;
3698
+ payload.options = {
3699
+ isDefault: typeof camera.isDefault === "boolean" ? camera.isDefault : void 0,
3700
+ projection,
3701
+ type,
3702
+ fov: typeof camera.fov === "number" ? camera.fov : void 0,
3703
+ near: typeof camera.near === "number" ? camera.near : void 0,
3704
+ far: typeof camera.far === "number" ? camera.far : void 0,
3705
+ left: typeof camera.left === "number" ? camera.left : void 0,
3706
+ right: typeof camera.right === "number" ? camera.right : void 0,
3707
+ top: typeof camera.top === "number" ? camera.top : void 0,
3708
+ bottom: typeof camera.bottom === "number" ? camera.bottom : void 0,
3709
+ zoom: typeof camera.zoom === "number" ? camera.zoom : void 0
3710
+ };
3711
+ }
3712
+ }
3713
+ if (kind === "imageTarget") {
3714
+ const imageTarget = asRecord3(componentValues.imageTargetValues.get(sourceEntityId));
3715
+ if (imageTarget) {
3716
+ payload.options = {
3717
+ targets: Array.isArray(imageTarget.targets) ? imageTarget.targets : [],
3718
+ compiledTargetUrl: typeof imageTarget.compiledTargetUrl === "string" ? imageTarget.compiledTargetUrl : void 0,
3719
+ compiledTargetDir: typeof imageTarget.compiledTargetDir === "string" ? imageTarget.compiledTargetDir : void 0
3720
+ };
3721
+ }
3722
+ }
3723
+ if (kind === "instancedMesh") {
3724
+ const im = asRecord3(componentValues.instancedMeshValues.get(sourceEntityId));
3725
+ if (im) {
3726
+ payload.options = {
3727
+ meshKind: typeof im.meshKind === "string" ? im.meshKind : "cube",
3728
+ modelPath: typeof im.modelPath === "string" ? im.modelPath : void 0,
3729
+ meshParameters: asRecord3(im.meshParameters) ?? void 0,
3730
+ castShadow: typeof im.castShadow === "boolean" ? im.castShadow : false,
3731
+ receiveShadow: typeof im.receiveShadow === "boolean" ? im.receiveShadow : false,
3732
+ // New format: signal the factory to skip child entity creation.
3733
+ // Old format (instances[]): pass through for migration — factory will
3734
+ // create slot entities from the legacy InstanceTransform array.
3735
+ ...Array.isArray(im.instanceEntityIds) ? { instanceEntityIds: im.instanceEntityIds } : Array.isArray(im.instances) ? { instances: im.instances } : {}
3736
+ };
3737
+ }
3738
+ }
3739
+ if (kind === "instanceSlot") {
3740
+ const slot = asRecord3(componentValues.instanceSlotValues.get(sourceEntityId));
3741
+ if (slot) {
3742
+ payload.options = {
3743
+ groupEntityId: typeof slot.groupEntityId === "number" ? slot.groupEntityId : -1,
3744
+ slotIndex: typeof slot.slotIndex === "number" ? slot.slotIndex : 0
3745
+ };
3746
+ }
3747
+ }
3748
+ if (kind === "scriptObject") {
3749
+ const so = asRecord3(componentValues.scriptObjectValues.get(sourceEntityId));
3750
+ if (so) {
3751
+ payload.options = {
3752
+ scriptUrl: typeof so.scriptUrl === "string" ? so.scriptUrl : null,
3753
+ className: typeof so.className === "string" ? so.className : null,
3754
+ enabled: typeof so.enabled === "boolean" ? so.enabled : true
3755
+ };
3756
+ }
3757
+ }
3758
+ return payload;
3759
+ }
3760
+ __name(buildEntityCreationPayload, "buildEntityCreationPayload");
3761
+ function resolvePrimaryCameraSourceEntityId(snapshot, componentValues, entityTypeValues) {
3762
+ let firstCameraSourceEntityId = null;
3763
+ for (const sourceEntityId of snapshot.entities) {
3764
+ const entityType = readString(entityTypeValues.get(sourceEntityId));
3765
+ if (entityType !== "camera") {
3766
+ continue;
3767
+ }
3768
+ if (firstCameraSourceEntityId === null) {
3769
+ firstCameraSourceEntityId = sourceEntityId;
3770
+ }
3771
+ const cameraValue = asRecord3(componentValues.cameraValues.get(sourceEntityId));
3772
+ if (cameraValue?.isDefault === true) {
3773
+ return sourceEntityId;
3774
+ }
3775
+ }
3776
+ return firstCameraSourceEntityId;
3777
+ }
3778
+ __name(resolvePrimaryCameraSourceEntityId, "resolvePrimaryCameraSourceEntityId");
3779
+ function applyLocalTransformsAfterHierarchyRestore(world, scopeEntityIds) {
3780
+ const transformEntities = scopeEntityIds ? Array.from(scopeEntityIds) : world.query(TransformComponent, Object3DRef);
3781
+ for (const entityId of transformEntities) {
3782
+ const transform = world.getComponent(entityId, TransformComponent);
3783
+ const object = world.getComponent(entityId, Object3DRef)?.object;
3784
+ if (!transform || !object) {
3785
+ continue;
3786
+ }
3787
+ applyTransform(object, transform);
3788
+ object.updateMatrixWorld(true);
3789
+ }
3790
+ }
3791
+ __name(applyLocalTransformsAfterHierarchyRestore, "applyLocalTransformsAfterHierarchyRestore");
3792
+ function hydrateWorldFromSnapshotDetailed(snapshot, world, objectManagementSystem, options) {
3793
+ if (!snapshot || !snapshot.entities.length) {
3794
+ return {
3795
+ restoredCount: 0,
3796
+ selectedEntityId: null,
3797
+ idMap: /* @__PURE__ */ new Map()
3798
+ };
3799
+ }
3800
+ const assignPrimaryCamera = options?.assignPrimaryCamera !== false;
3801
+ const entityTypeValues = readByComponent(snapshot.components, "EntityType");
3802
+ const componentValues = buildComponentValueMaps(snapshot);
3803
+ const primaryCameraSourceEntityId = assignPrimaryCamera ? resolvePrimaryCameraSourceEntityId(
3804
+ snapshot,
3805
+ componentValues,
3806
+ entityTypeValues
3807
+ ) : null;
3808
+ const idMap = /* @__PURE__ */ new Map();
3809
+ for (const sourceEntityId of snapshot.entities) {
3810
+ const entityTypeValue = entityTypeValues.get(sourceEntityId);
3811
+ const entityType = readString(entityTypeValue);
3812
+ if (!entityType || !HYDRATABLE_ENTITY_KINDS.has(entityType)) {
3813
+ continue;
3814
+ }
3815
+ const kind = entityType;
3816
+ const payload = buildEntityCreationPayload(sourceEntityId, kind, componentValues);
3817
+ if (kind === "camera" && sourceEntityId === primaryCameraSourceEntityId) {
3818
+ payload.useWorldCamera = true;
3819
+ const options2 = asRecord3(payload.options);
3820
+ payload.options = {
3821
+ ...options2 ?? {},
3822
+ isDefault: true
3823
+ };
3824
+ }
3825
+ payload.skipDefaultChildren = true;
3826
+ const createdEntityId = objectManagementSystem.createNow(kind, world, payload);
3827
+ idMap.set(sourceEntityId, createdEntityId);
3828
+ }
3829
+ for (const sourceEntityId of snapshot.entities) {
3830
+ const targetEntityId = idMap.get(sourceEntityId);
3831
+ if (targetEntityId === void 0) {
3832
+ continue;
3833
+ }
3834
+ const entityType = readString(entityTypeValues.get(sourceEntityId));
3835
+ restoreComponentState(
3836
+ world,
3837
+ objectManagementSystem,
3838
+ targetEntityId,
3839
+ sourceEntityId,
3840
+ entityType,
3841
+ componentValues
3842
+ );
3843
+ restorePostCreateComponents(
3844
+ world,
3845
+ objectManagementSystem,
3846
+ targetEntityId,
3847
+ sourceEntityId,
3848
+ entityType,
3849
+ componentValues,
3850
+ idMap
3851
+ );
3852
+ }
3853
+ applyParentLinks(snapshot, idMap, objectManagementSystem, world);
3854
+ objectManagementSystem.reconcileSceneFromWorld(world);
3855
+ applyLocalTransformsAfterHierarchyRestore(
3856
+ world,
3857
+ options?.applyTransformsScope === "created" ? idMap.values() : void 0
3858
+ );
3859
+ const selectedEntityId = typeof snapshot.selectedEntityId === "number" ? idMap.get(snapshot.selectedEntityId) ?? null : null;
3860
+ return {
3861
+ restoredCount: idMap.size,
3862
+ selectedEntityId,
3863
+ idMap
3864
+ };
3865
+ }
3866
+ __name(hydrateWorldFromSnapshotDetailed, "hydrateWorldFromSnapshotDetailed");
3867
+
3868
+ // core/prefab/overrides.ts
3869
+ var asRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
3870
+ function findSnapshotRootEntityIds(snapshot) {
3871
+ const parentBlock = snapshot.components.find(
3872
+ (block) => block.component === "ParentId"
3873
+ );
3874
+ const parentByEntity = /* @__PURE__ */ new Map();
3875
+ for (const entry of parentBlock?.entries ?? []) {
3876
+ parentByEntity.set(entry.entityId, asRecord4(entry.value)?.value ?? null);
3877
+ }
3878
+ return snapshot.entities.filter(
3879
+ (entityId) => typeof parentByEntity.get(entityId) !== "number"
3880
+ );
3881
+ }
3882
+ __name(findSnapshotRootEntityIds, "findSnapshotRootEntityIds");
3883
+
3884
+ // core/prefab/instantiateSubtree.ts
3885
+ var INSTANTIATE_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
3886
+ "Environment",
3887
+ "Postprocessing",
3888
+ "SelectionTransformState"
3889
+ ]);
3890
+ function instantiateSubtree(world, objectManagementSystem, snapshot) {
3891
+ const snapshotRootIds = new Set(findSnapshotRootEntityIds(snapshot));
3892
+ const safeSnapshot = {
3893
+ entities: snapshot.entities,
3894
+ components: snapshot.components.filter((block) => !INSTANTIATE_EXCLUDED_COMPONENTS.has(block.component)).map(
3895
+ (block) => block.component === "PrefabInstance" ? {
3896
+ component: block.component,
3897
+ entries: block.entries.filter(
3898
+ (entry) => !snapshotRootIds.has(entry.entityId)
3899
+ )
3900
+ } : block
3901
+ ).filter((block) => block.entries.length > 0)
3902
+ };
3903
+ const result = hydrateWorldFromSnapshotDetailed(
3904
+ safeSnapshot,
3905
+ world,
3906
+ objectManagementSystem,
3907
+ { assignPrimaryCamera: false, applyTransformsScope: "created" }
3908
+ );
3909
+ const rootSourceId = findSnapshotRootEntityIds(safeSnapshot).find(
3910
+ (sourceId) => result.idMap.has(sourceId)
3911
+ );
3912
+ return {
3913
+ rootId: rootSourceId !== void 0 ? result.idMap.get(rootSourceId) ?? null : null,
3914
+ idMap: result.idMap
3915
+ };
3916
+ }
3917
+ __name(instantiateSubtree, "instantiateSubtree");
3918
+
3919
+ // core/prefab/types.ts
3920
+ var isRecord = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
3921
+ function parsePrefabAsset(json) {
3922
+ if (!isRecord(json)) {
3923
+ return null;
3924
+ }
3925
+ if (typeof json.version !== "number" || json.version < 1) {
3926
+ return null;
3927
+ }
3928
+ const snapshot = json.snapshot;
3929
+ if (!isRecord(snapshot)) {
3930
+ return null;
3931
+ }
3932
+ const entities = snapshot.entities;
3933
+ const components = snapshot.components;
3934
+ if (!Array.isArray(entities) || !Array.isArray(components)) {
3935
+ return null;
3936
+ }
3937
+ if (!entities.every((id) => typeof id === "number")) {
3938
+ return null;
3939
+ }
3940
+ if (!components.every(
3941
+ (block) => isRecord(block) && typeof block.component === "string" && Array.isArray(block.entries)
3942
+ )) {
3943
+ return null;
3944
+ }
3945
+ return {
3946
+ version: json.version,
3947
+ type: json.type === "scene" ? "scene" : "prefab",
3948
+ name: typeof json.name === "string" ? json.name : void 0,
3949
+ snapshot
3950
+ };
3951
+ }
3952
+ __name(parsePrefabAsset, "parsePrefabAsset");
3953
+ var resolvePrefabAssetUrl = /* @__PURE__ */ __name((url) => url, "resolvePrefabAssetUrl");
3954
+ var resolveUrl = resolvePrefabAssetUrl;
3955
+ function transformStringsDeep(value, fn) {
3956
+ if (typeof value === "string") {
3957
+ return fn(value);
3958
+ }
3959
+ if (Array.isArray(value)) {
3960
+ return value.map((item) => transformStringsDeep(item, fn));
3961
+ }
3962
+ if (value !== null && typeof value === "object") {
3963
+ const result = {};
3964
+ for (const [key, item] of Object.entries(value)) {
3965
+ result[key] = transformStringsDeep(item, fn);
3966
+ }
3967
+ return result;
3968
+ }
3969
+ return value;
3970
+ }
3971
+ __name(transformStringsDeep, "transformStringsDeep");
3972
+ var prefabCache = /* @__PURE__ */ new Map();
3973
+ function loadPrefab(url) {
3974
+ const cached = prefabCache.get(url);
3975
+ if (cached) {
3976
+ return cached;
3977
+ }
3978
+ const pending = (async () => {
3979
+ const response = await fetch(resolveUrl(url));
3980
+ if (!response.ok) {
3981
+ throw new Error(`Failed to fetch prefab "${url}" (${response.status})`);
3982
+ }
3983
+ const json = await response.json();
3984
+ const parsed = parsePrefabAsset(json);
3985
+ if (!parsed) {
3986
+ throw new Error(`Invalid prefab file at "${url}"`);
3987
+ }
3988
+ return {
3989
+ ...parsed,
3990
+ snapshot: transformStringsDeep(
3991
+ parsed.snapshot,
3992
+ resolveUrl
3993
+ )
3994
+ };
3995
+ })();
3996
+ prefabCache.set(url, pending);
3997
+ pending.catch(() => {
3998
+ if (prefabCache.get(url) === pending) {
3999
+ prefabCache.delete(url);
4000
+ }
4001
+ });
4002
+ return pending;
4003
+ }
4004
+ __name(loadPrefab, "loadPrefab");
4005
+ function resolveSource(source) {
4006
+ if (typeof source === "string") {
4007
+ return { url: source, asset: loadPrefab(source) };
4008
+ }
4009
+ if ("path" in source && typeof source.path === "string") {
4010
+ return { url: source.path, asset: loadPrefab(source.path) };
4011
+ }
4012
+ const asset = source;
4013
+ return { url: asset.name ?? "", asset };
4014
+ }
4015
+ __name(resolveSource, "resolveSource");
4016
+ async function spawnPrefab(world, source, options) {
4017
+ const { url, asset } = resolveSource(source);
4018
+ const prefab = await asset;
4019
+ const objectManagementSystem = world.getObjectManagementSystem();
4020
+ const { rootId } = instantiateSubtree(
4021
+ world,
4022
+ objectManagementSystem,
4023
+ prefab.snapshot
4024
+ );
4025
+ if (rootId === null) {
4026
+ throw new Error(
4027
+ `Prefab "${url || prefab.name || "unknown"}" contained no spawnable entities`
4028
+ );
4029
+ }
4030
+ if (!world.getComponent(rootId, PrefabInstance)) {
4031
+ world.addComponent(rootId, new PrefabInstance(url, []));
4032
+ }
4033
+ if (options?.parentId !== void 0 && options.parentId !== null) {
4034
+ objectManagementSystem.setParent(world, rootId, options.parentId, {
4035
+ preserveWorldTransform: false
4036
+ });
4037
+ }
4038
+ const transform = world.getComponent(rootId, TransformComponent);
4039
+ if (transform && (options?.position || options?.rotation || options?.scale)) {
4040
+ const write = /* @__PURE__ */ __name((target, src) => {
4041
+ if (!src) return;
4042
+ if (typeof src.x === "number") target.x = src.x;
4043
+ if (typeof src.y === "number") target.y = src.y;
4044
+ if (typeof src.z === "number") target.z = src.z;
4045
+ }, "write");
4046
+ write(transform.position, options.position);
4047
+ write(transform.rotation, options.rotation);
4048
+ write(transform.scale, options.scale);
4049
+ const object = world.getComponent(rootId, Object3DRef)?.object;
4050
+ if (object) {
4051
+ applyTransform(object, transform);
4052
+ object.updateMatrixWorld(true);
4053
+ }
4054
+ }
4055
+ return rootId;
4056
+ }
4057
+ __name(spawnPrefab, "spawnPrefab");
4058
+ function despawnPrefab(world, rootId, dispose = true) {
4059
+ const objectManagementSystem = world.getObjectManagementSystem();
4060
+ const subtree = collectEntitySubtree(world, [rootId]).reverse();
4061
+ let removed = 0;
4062
+ for (const entityId of subtree) {
4063
+ if (objectManagementSystem.deleteEntity(world, entityId, dispose)) {
4064
+ removed += 1;
4065
+ }
4066
+ }
4067
+ return removed;
4068
+ }
4069
+ __name(despawnPrefab, "despawnPrefab");
4070
+ var _Behaviour = class _Behaviour {
4071
+ /**
4072
+ * Engine-managed constructor. Hosts (`ScriptBehaviourSystem`) instantiate
4073
+ * subclasses with the owning world, the entity id, and the script's `data`
4074
+ * payload. User code should not call this directly.
4075
+ *
4076
+ * @param world - The owning ECS world.
4077
+ * @param entityId - The entity this script is bound to.
4078
+ * @param component - The `ScriptComponent.data` payload, or any object that
4079
+ * should be exposed to the script as `this.data`.
4080
+ */
4081
+ constructor(world, entityId, component) {
4082
+ /**
4083
+ * Inspector-bound payload from the entity's `ScriptComponent`. Override the
4084
+ * type on subclasses with `declare data: MyDataShape` to get type safety
4085
+ * inside hooks. Saved with the project so values persist across reloads.
4086
+ */
4087
+ this.data = {};
4088
+ /**
4089
+ * Seconds elapsed since the last frame. Set by the engine before each
4090
+ * {@link Behaviour.onUpdate}.
4091
+ */
4092
+ this.deltaTime = 0;
4093
+ this.world = world;
4094
+ this.entityId = entityId;
4095
+ if (component) this.data = component;
4096
+ this.entity = this.getEntity();
4097
+ this.threeRef = this.getComponent(Object3DRef);
4098
+ this.transform = this.getComponent(TransformComponent);
4099
+ }
4100
+ /**
4101
+ * Engine-managed per-frame entry point. Refreshes {@link Behaviour.deltaTime}
4102
+ * and delegates to {@link Behaviour.onUpdate}.
4103
+ *
4104
+ * @remarks Do **not** override this method — override
4105
+ * {@link Behaviour.onUpdate} instead.
4106
+ *
4107
+ * @param world - The owning world (may differ from the constructor world
4108
+ * after hot reload).
4109
+ * @param deltaTime - Seconds since the last frame.
4110
+ */
4111
+ update(world, deltaTime) {
4112
+ this.deltaTime = deltaTime;
4113
+ this.world = world;
4114
+ this.onUpdate();
4115
+ }
4116
+ /**
4117
+ * Optional cleanup hook invoked when the script is detached or the entity
4118
+ * is destroyed. Override to release timers, listeners, or other resources.
4119
+ *
4120
+ * @param world - The owning world at disposal time.
4121
+ */
4122
+ dispose(world) {
4123
+ }
4124
+ /**
4125
+ * Instantiate a prefab asset into the world at runtime.
4126
+ *
4127
+ * `source` is typically an `AssetInput` field from this script's `data`
4128
+ * (drag a `.prefab` from the asset browser onto the field in the editor),
4129
+ * a URL string, or a pre-loaded `PrefabAsset`. Resolves with the new root
4130
+ * entity id.
4131
+ *
4132
+ * ```ts
4133
+ * data = { enemyPrefab: { path: "", type: "prefab" } };
4134
+ * async onUpdate() {
4135
+ * if (shouldSpawn) {
4136
+ * const id = await this.spawnPrefab(this.data.enemyPrefab, {
4137
+ * position: { x: 0, y: 0, z: -5 },
4138
+ * });
4139
+ * }
4140
+ * }
4141
+ * ```
4142
+ */
4143
+ spawnPrefab(source, options) {
4144
+ return spawnPrefab(this.world, source, options);
4145
+ }
4146
+ /**
4147
+ * The shared world, or `null` in a single-player run, so a script can work
4148
+ * both ways:
4149
+ *
4150
+ * ```ts
4151
+ * if (this.network && !this.network.isOwner) return; // someone else moves this
4152
+ * ```
4153
+ */
4154
+ get network() {
4155
+ return this.world.getNetwork()?.handleFor(this.entityId) ?? null;
4156
+ }
4157
+ /** Someone joined the room. `playerId` is their session id. */
4158
+ onPlayerJoin(_playerId) {
4159
+ }
4160
+ /** Someone left the room. */
4161
+ onPlayerLeave(_playerId) {
4162
+ }
4163
+ /** A shared value on this entity changed. */
4164
+ onNetworkProp(_key, _value) {
4165
+ }
4166
+ /**
4167
+ * Load a `.soundbank.json` asset so {@link Behaviour.playSlot} can play it.
4168
+ * `source` is an asset path or an `AssetInput` field.
4169
+ */
4170
+ loadSoundBank(source) {
4171
+ return this.world.getAudioSystem()?.loadSoundBank(source) ?? Promise.resolve();
4172
+ }
4173
+ /**
4174
+ * Play a named sound from a loaded bank, as a random take. Returns whether it
4175
+ * sounded: its chance, cooldown or priority may keep it quiet.
4176
+ *
4177
+ * ```ts
4178
+ * this.playSlot("hit", { position: this.transform.position });
4179
+ * ```
4180
+ */
4181
+ playSlot(id, options) {
4182
+ return this.world.getAudioSystem()?.playSlot(id, options) ?? false;
4183
+ }
4184
+ /**
4185
+ * Remove a spawned prefab instance (the root entity and all descendants).
4186
+ * Returns the number of entities removed.
4187
+ */
4188
+ despawn(rootEntityId) {
4189
+ return despawnPrefab(this.world, rootEntityId);
4190
+ }
4191
+ /**
4192
+ * Returns the entity's world-space position as a new `THREE.Vector3`, or
4193
+ * `null` if the entity has no scene presence.
4194
+ */
4195
+ getWorldPosition() {
4196
+ if (!this.threeRef) {
4197
+ return null;
4198
+ }
4199
+ const position = new THREE5__namespace.Vector3();
4200
+ this.threeRef.object.getWorldPosition(position);
4201
+ return position;
4202
+ }
4203
+ /**
4204
+ * Returns the entity's forward direction in world space (the +Z axis of its
4205
+ * world matrix), or `null` if the entity has no scene presence.
4206
+ */
4207
+ getWorldDirection() {
4208
+ if (!this.threeRef) {
4209
+ return null;
4210
+ }
4211
+ const target = new THREE5__namespace.Vector3();
4212
+ this.threeRef.object.getWorldDirection(target);
4213
+ return target;
4214
+ }
4215
+ /**
4216
+ * Returns a unit vector pointing from this entity toward the given world
4217
+ * position, or `null` if the entity has no scene presence.
4218
+ *
4219
+ * @param targetPosition - Destination point in world space.
4220
+ */
4221
+ directionTo(targetPosition) {
4222
+ const currentPosition = this.getWorldPosition();
4223
+ if (!currentPosition) {
4224
+ return null;
4225
+ }
4226
+ return targetPosition.clone().sub(currentPosition).normalize();
4227
+ }
4228
+ /**
4229
+ * Returns the world-space distance from this entity to the given position,
4230
+ * or `null` if the entity has no scene presence.
4231
+ *
4232
+ * @param targetPosition - Destination point in world space.
4233
+ */
4234
+ distanceTo(targetPosition) {
4235
+ const currentPosition = this.getWorldPosition();
4236
+ if (!currentPosition) {
4237
+ return null;
4238
+ }
4239
+ return currentPosition.distanceTo(targetPosition);
4240
+ }
4241
+ /**
4242
+ * Linearly interpolates the entity's position toward `targetPosition` and
4243
+ * writes the result back through {@link TransformComponent}. No-op if the
4244
+ * entity has no scene presence.
4245
+ *
4246
+ * @param targetPosition - Destination point in world space.
4247
+ * @param alpha - Interpolation factor in [0, 1]. Multiply by `deltaTime`
4248
+ * for frame-rate-independent smoothing.
4249
+ */
4250
+ lerpTo(targetPosition, alpha) {
4251
+ if (!this.threeRef) {
4252
+ return;
4253
+ }
4254
+ const currentPosition = this.getWorldPosition();
4255
+ if (!currentPosition) {
4256
+ return;
4257
+ }
4258
+ const newPosition = currentPosition.lerp(targetPosition, alpha);
4259
+ this.transform.setPosition(newPosition);
4260
+ }
4261
+ /**
4262
+ * Spherically interpolates the entity's rotation toward `targetRotation`
4263
+ * and writes the result back through {@link TransformComponent}. No-op if
4264
+ * the entity has no scene presence.
4265
+ *
4266
+ * @param targetRotation - Destination orientation as a quaternion.
4267
+ * @param alpha - Interpolation factor in [0, 1].
4268
+ */
4269
+ slerpTo(targetRotation, alpha) {
4270
+ if (!this.threeRef) {
4271
+ return;
4272
+ }
4273
+ const rotation = new THREE5__namespace.Quaternion();
4274
+ this.threeRef.object.getWorldQuaternion(rotation);
4275
+ rotation.slerp(targetRotation, alpha);
4276
+ this.transform.setRotation(rotation);
4277
+ }
4278
+ /**
4279
+ * Rotates the entity to face `targetPosition` in world space and writes the
4280
+ * resulting orientation back through {@link TransformComponent}. No-op if
4281
+ * the entity has no scene presence.
4282
+ *
4283
+ * @param targetPosition - Point in world space to face.
4284
+ */
4285
+ lookAt(targetPosition) {
4286
+ if (!this.threeRef) {
4287
+ return;
4288
+ }
4289
+ const clone = this.threeRef.object.clone();
4290
+ const rotation = new THREE5__namespace.Quaternion();
4291
+ clone.lookAt(targetPosition);
4292
+ clone.getWorldQuaternion(rotation);
4293
+ this.transform.setRotation(rotation);
4294
+ }
4295
+ /** Returns every component currently attached to this entity. */
4296
+ getComponents() {
4297
+ return this.world.getEntityById(this.entityId)?.components ?? [];
4298
+ }
4299
+ /**
4300
+ * Returns the entity's component of the given class, or `null` if it has
4301
+ * no such component.
4302
+ *
4303
+ * @typeParam T - Concrete component type.
4304
+ * @param componentClass - Component class constructor to look up.
4305
+ *
4306
+ * @example
4307
+ * ```ts
4308
+ * const mesh = this.getComponent(MeshComponent);
4309
+ * if (mesh) console.log(mesh.geometryRef);
4310
+ * ```
4311
+ */
4312
+ getComponent(componentClass) {
4313
+ return this.world.getComponent(this.entityId, componentClass) ?? null;
4314
+ }
4315
+ /**
4316
+ * Returns the latest {@link WorldEntityView} snapshot for this entity, or
4317
+ * `null` if it was destroyed.
4318
+ */
4319
+ getEntity() {
4320
+ return this.world.getEntityById(this.entityId);
4321
+ }
4322
+ /**
4323
+ * Resolves the entity's parent from the {@link ParentId} component, if any.
4324
+ *
4325
+ * @returns A {@link ParentLookup} with the parent component reference and
4326
+ * the parent entity view (or `null` if the entity is at the root).
4327
+ */
4328
+ getParent() {
4329
+ const parentIdComponent = this.getComponent(ParentId);
4330
+ const parentEntityId = parentIdComponent?.value ?? null;
4331
+ if (parentEntityId === null) {
4332
+ return {
4333
+ parentIdComponent,
4334
+ parent: null
4335
+ };
4336
+ }
4337
+ return {
4338
+ parentIdComponent,
4339
+ parent: this.world.getEntityById(parentEntityId)
4340
+ };
4341
+ }
4342
+ /**
4343
+ * Returns every direct child entity of this one (entities whose
4344
+ * {@link ParentId} matches `entityId`).
4345
+ */
4346
+ getChildren() {
4347
+ return this.world.getAllEntities().filter((entity) => {
4348
+ const parentIdComponent = entity.components.find(
4349
+ (component) => component instanceof ParentId
4350
+ );
4351
+ return parentIdComponent?.value === this.entityId;
4352
+ });
4353
+ }
4354
+ /**
4355
+ * Called once before the first {@link Behaviour.onUpdate}. Override to
4356
+ * default and validate {@link Behaviour.data}, cache references, or set
4357
+ * initial state. Runs at preview/runtime only — never in the editor.
4358
+ */
4359
+ init() {
4360
+ }
4361
+ /**
4362
+ * Called every frame while the script is enabled. Override with the
4363
+ * script's main per-frame logic. Runs at preview/runtime only — never in the
4364
+ * editor (use {@link ScriptObject} for editor-visible visuals).
4365
+ */
4366
+ onUpdate() {
4367
+ }
4368
+ /** Called when the editor selects this entity. Optional UX hook. */
4369
+ onSelect() {
4370
+ }
4371
+ /** Called when the editor deselects this entity. Optional UX hook. */
4372
+ onDeselect() {
4373
+ }
4374
+ /**
4375
+ * Called when an image-tracking target this entity depends on becomes
4376
+ * visible. Optional AR hook.
4377
+ *
4378
+ * @param target - The newly-visible target entity view.
4379
+ */
4380
+ onTargetFound(target) {
4381
+ }
4382
+ /**
4383
+ * Called when an image-tracking target this entity depends on is lost.
4384
+ * Optional AR hook.
4385
+ *
4386
+ * @param target - The target entity view that became invisible.
4387
+ */
4388
+ onTargetLost(target) {
4389
+ }
4390
+ // ─── WebXR (VR / MR) hooks ────────────────────────────────────────────────
4391
+ // Dispatched by XRSessionSystem / XRInteractionSystem, following the same
4392
+ // pattern as the AR hooks above: public no-op methods that subclasses opt
4393
+ // into by overriding. They never fire outside an immersive session.
4394
+ /**
4395
+ * Called once when an immersive session starts. Optional XR hook.
4396
+ *
4397
+ * Use it to set up XR-only state. Inspect `capabilities` rather than guessing
4398
+ * by device: feature support differs sharply per headset (for example Vision
4399
+ * Pro grants no passthrough on the web today).
4400
+ *
4401
+ * @param capabilities - What the session actually granted, read from
4402
+ * `XRSession.enabledFeatures`.
4403
+ */
4404
+ onXRSessionStart(capabilities) {
4405
+ }
4406
+ /** Called once when the immersive session ends. Optional XR hook. */
4407
+ onXRSessionEnd() {
4408
+ }
4409
+ /**
4410
+ * Called when a primary action begins — controller trigger, hand pinch, or
4411
+ * Vision Pro gaze-pinch. Optional XR hook.
4412
+ *
4413
+ * @param input - Normalized state for the source that acted.
4414
+ */
4415
+ onSelectStart(input) {
4416
+ }
4417
+ /** Called when the primary action ends. Optional XR hook. */
4418
+ onSelectEnd(input) {
4419
+ }
4420
+ /**
4421
+ * Called when this entity is grabbed. Optional XR hook.
4422
+ *
4423
+ * Only fires for entities carrying an enabled, grabbable
4424
+ * `XRInteractableComponent`.
4425
+ *
4426
+ * @param input - The source doing the grabbing.
4427
+ */
4428
+ /**
4429
+ * A SECOND hand joined a two-hand grab on this entity.
4430
+ *
4431
+ * The first hand anchors the object and keeps holding it; this fires for the
4432
+ * hand that came second — the foregrip on a rifle, say.
4433
+ */
4434
+ onSecondaryGrab(_input) {
4435
+ }
4436
+ /** The second hand let go, leaving the object in the first hand alone. */
4437
+ onSecondaryRelease(_input) {
4438
+ }
4439
+ /**
4440
+ * A hand pose declared on this entity started being held.
4441
+ *
4442
+ * Fires once the pose has been sustained for its hold time, not the instant
4443
+ * the fingers pass through it.
4444
+ */
4445
+ onHandPoseStart(_event) {
4446
+ }
4447
+ /** A held hand pose ended, or its hand stopped being tracked. */
4448
+ onHandPoseEnd(_event) {
4449
+ }
4450
+ onGrab(input) {
4451
+ }
4452
+ /** Called when this entity is released. Optional XR hook. */
4453
+ onRelease(input) {
4454
+ }
4455
+ /** A UI button on this entity (or a descendant) was clicked. Clicks fire on
4456
+ * RELEASE while still pointing at the widget — sliding off cancels. */
4457
+ onUiPress(_event) {
4458
+ }
4459
+ /** A pointer began hovering a UI widget on this entity (or a descendant). */
4460
+ onUiHoverStart(_event) {
4461
+ }
4462
+ /** The pointer left the widget. */
4463
+ onUiHoverEnd(_event) {
4464
+ }
4465
+ /** A UI toggle flipped; `event.value` is the new boolean. */
4466
+ onUiToggle(_event) {
4467
+ }
4468
+ /** A UI slider moved; `event.value` is the new number. Fires on real value
4469
+ * changes during the drag and once more on release. */
4470
+ onUiChange(_event) {
4471
+ }
4472
+ };
4473
+ __name(_Behaviour, "Behaviour");
4474
+ /**
4475
+ * Static marker used by `ScriptBehaviourSystem` to detect `Behaviour`
4476
+ * subclasses across bundle-identity splits (esbuild may produce a second
4477
+ * copy of the package when scripts are bundled, breaking `instanceof`).
4478
+ * Inherited by every subclass via the prototype chain.
4479
+ *
4480
+ * @internal
4481
+ */
4482
+ _Behaviour.__reluBehaviourClass = true;
4483
+ var Behaviour = _Behaviour;
4484
+
4485
+ // core/systems/scriptShared.ts
4486
+ function reportScriptError(world, report, error) {
4487
+ const reporter = world.reportScriptError;
4488
+ if (typeof reporter === "function") {
4489
+ reporter.call(world, report, error);
4490
+ return;
4491
+ }
4492
+ console.error(
4493
+ `[spatial-ecs] ${report.className || "Script"} failed in ${report.phase} (entity ${report.entityId}):`,
4494
+ error
4495
+ );
4496
+ }
4497
+ __name(reportScriptError, "reportScriptError");
4498
+ function reportBehaviourHookError(world, entityId, instance, hook, error) {
4499
+ let scriptUrl = "";
4500
+ let className = instance?.constructor?.name ?? "";
4501
+ const script = typeof world.getComponent === "function" ? world.getComponent(entityId, ScriptComponent) : void 0;
4502
+ if (script?.scriptInstances && Array.isArray(script.entries)) {
4503
+ const entries = script.entries.filter(
4504
+ (entry) => entry && (entry.className || entry.scriptUrl)
4505
+ );
4506
+ for (const [index, live] of script.scriptInstances) {
4507
+ if (live !== instance) continue;
4508
+ const entry = entries[index];
4509
+ if (entry) {
4510
+ scriptUrl = typeof entry.scriptUrl === "string" ? entry.scriptUrl : "";
4511
+ className = typeof entry.className === "string" && entry.className ? entry.className : className;
4512
+ }
4513
+ break;
4514
+ }
4515
+ }
4516
+ reportScriptError(
4517
+ world,
4518
+ { entityId, scriptUrl, className, phase: hook, source: "behaviour" },
4519
+ error
4520
+ );
4521
+ }
4522
+ __name(reportBehaviourHookError, "reportBehaviourHookError");
4523
+
4524
+ // core/network/snapshotBuffer.ts
4525
+ var MAX_SNAPSHOTS = 32;
4526
+ function lerpPose(a, b, t) {
4527
+ const dot = a.qx * b.qx + a.qy * b.qy + a.qz * b.qz + a.qw * b.qw;
4528
+ const s = dot < 0 ? -1 : 1;
4529
+ const qx = a.qx + (s * b.qx - a.qx) * t;
4530
+ const qy = a.qy + (s * b.qy - a.qy) * t;
4531
+ const qz = a.qz + (s * b.qz - a.qz) * t;
4532
+ const qw = a.qw + (s * b.qw - a.qw) * t;
4533
+ const len = Math.hypot(qx, qy, qz, qw) || 1;
4534
+ return {
4535
+ x: a.x + (b.x - a.x) * t,
4536
+ y: a.y + (b.y - a.y) * t,
4537
+ z: a.z + (b.z - a.z) * t,
4538
+ qx: qx / len,
4539
+ qy: qy / len,
4540
+ qz: qz / len,
4541
+ qw: qw / len
4542
+ };
4543
+ }
4544
+ __name(lerpPose, "lerpPose");
4545
+ var _SnapshotBuffer = class _SnapshotBuffer {
4546
+ constructor(teleportDistance = Number.POSITIVE_INFINITY) {
4547
+ this.teleportDistance = teleportDistance;
4548
+ this.snapshots = [];
4549
+ }
4550
+ push(at, pose) {
4551
+ this.snapshots.push({ at, pose });
4552
+ if (this.snapshots.length > MAX_SNAPSHOTS) this.snapshots.shift();
4553
+ }
4554
+ /** The pose at time `at`: holds the first and last, and never extrapolates. */
4555
+ sample(at) {
4556
+ const list = this.snapshots;
4557
+ if (list.length === 0) return null;
4558
+ if (at <= list[0].at) return list[0].pose;
4559
+ for (let i = list.length - 1; i > 0; i--) {
4560
+ const a = list[i - 1];
4561
+ const b = list[i];
4562
+ if (at < a.at) continue;
4563
+ if (i > 1) this.snapshots = list.slice(i - 1);
4564
+ if (at >= b.at) return b.pose;
4565
+ const jump = Math.hypot(b.pose.x - a.pose.x, b.pose.y - a.pose.y, b.pose.z - a.pose.z);
4566
+ if (jump > this.teleportDistance) return b.pose;
4567
+ return lerpPose(a.pose, b.pose, (at - a.at) / (b.at - a.at));
4568
+ }
4569
+ return list[list.length - 1].pose;
4570
+ }
4571
+ };
4572
+ __name(_SnapshotBuffer, "SnapshotBuffer");
4573
+ var SnapshotBuffer = _SnapshotBuffer;
4574
+
4575
+ // core/network/NetworkSystem.ts
4576
+ var POSITION_EPSILON = 1e-3;
4577
+ var ROTATION_EPSILON = 5e-4;
4578
+ var euler = new THREE5__namespace.Euler();
4579
+ var quat = new THREE5__namespace.Quaternion();
4580
+ function poseOf(transform) {
4581
+ const { position: p, rotation: r } = transform;
4582
+ quat.setFromEuler(euler.set(r.x, r.y, r.z));
4583
+ return { x: p.x, y: p.y, z: p.z, qx: quat.x, qy: quat.y, qz: quat.z, qw: quat.w };
4584
+ }
4585
+ __name(poseOf, "poseOf");
4586
+ function applyPose(transform, pose, rotation) {
4587
+ transform.position.x = pose.x;
4588
+ transform.position.y = pose.y;
4589
+ transform.position.z = pose.z;
4590
+ if (!rotation) return;
4591
+ euler.setFromQuaternion(quat.set(pose.qx, pose.qy, pose.qz, pose.qw));
4592
+ transform.rotation.x = euler.x;
4593
+ transform.rotation.y = euler.y;
4594
+ transform.rotation.z = euler.z;
4595
+ }
4596
+ __name(applyPose, "applyPose");
4597
+ var moved = /* @__PURE__ */ __name((a, b) => Math.abs(a.x - b.x) > POSITION_EPSILON || Math.abs(a.y - b.y) > POSITION_EPSILON || Math.abs(a.z - b.z) > POSITION_EPSILON || Math.abs(a.qx - b.qx) > ROTATION_EPSILON || Math.abs(a.qy - b.qy) > ROTATION_EPSILON || Math.abs(a.qz - b.qz) > ROTATION_EPSILON || Math.abs(a.qw - b.qw) > ROTATION_EPSILON, "moved");
4598
+ function encodeProps(props) {
4599
+ return Object.fromEntries(
4600
+ Object.entries(props ?? {}).map(([k, v]) => [k, JSON.stringify(v)])
4601
+ );
4602
+ }
4603
+ __name(encodeProps, "encodeProps");
4604
+ var _NetworkSystem = class _NetworkSystem {
4605
+ constructor(now = () => performance.now()) {
4606
+ this.now = now;
4607
+ this.world = null;
4608
+ this.transport = null;
4609
+ this.tracked = /* @__PURE__ */ new Map();
4610
+ this.byEntity = /* @__PURE__ */ new Map();
4611
+ this.listeners = /* @__PURE__ */ new Map();
4612
+ this.handles = /* @__PURE__ */ new Map();
4613
+ this.spawnedAvatar = false;
4614
+ }
4615
+ /** Join the shared world. Call after hydrating, so scene objects exist. */
4616
+ connect(world, transport) {
4617
+ this.world = world;
4618
+ this.transport = transport;
4619
+ world.setNetwork(this);
4620
+ transport.onEntityAdd((e) => this.entityAdded(e));
4621
+ transport.onEntityChange((e) => this.entityChanged(e));
4622
+ transport.onEntityRemove((id) => this.entityRemoved(id));
4623
+ transport.onPlayerJoin((id) => this.dispatch("onPlayerJoin", id));
4624
+ transport.onPlayerLeave((id) => this.dispatch("onPlayerLeave", id));
4625
+ transport.onMessage((name, payload, from) => {
4626
+ for (const fn of this.listeners.get(name) ?? []) fn(payload, from);
4627
+ });
4628
+ transport.onCorrect((id, pose) => this.corrected(id, pose));
4629
+ transport.onClose(() => this.disconnected());
4630
+ this.registerScene();
4631
+ this.spawnAvatar();
4632
+ }
4633
+ /** Scene objects: every client hydrates the same scene, so their ids already match. */
4634
+ registerScene() {
4635
+ const world = this.world;
4636
+ const transport = this.transport;
4637
+ if (!world || !transport) return;
4638
+ const entities = [];
4639
+ for (const entityId of world.query(NetworkIdentityComponent)) {
4640
+ const identity = world.getComponent(entityId, NetworkIdentityComponent);
4641
+ if (!identity || identity.networkId) continue;
4642
+ identity.networkId = `scene-${entityId}`;
4643
+ const transform = world.getComponent(entityId, TransformComponent);
4644
+ const props = world.getComponent(entityId, NetworkedPropsComponent);
4645
+ const tracked = this.track(identity.networkId, entityId, "", null);
4646
+ tracked.props = encodeProps(props?.values);
4647
+ entities.push({
4648
+ id: identity.networkId,
4649
+ props: tracked.props,
4650
+ ...transform ? poseOf(transform) : { x: 0, y: 0, z: 0, qx: 0, qy: 0, qz: 0, qw: 1 }
4651
+ });
4652
+ }
4653
+ if (entities.length) transport.registerScene(entities);
4654
+ }
4655
+ spawnAvatar() {
4656
+ const world = this.world;
4657
+ if (!world || this.spawnedAvatar) return;
4658
+ const [entityId] = world.query(NetworkSpawnerComponent);
4659
+ if (entityId === void 0) return;
4660
+ const spawner = world.getComponent(entityId, NetworkSpawnerComponent);
4661
+ if (!spawner?.playerPrefab) return;
4662
+ this.spawnedAvatar = true;
4663
+ const at = world.getComponent(entityId, TransformComponent)?.position;
4664
+ const angle = Math.random() * Math.PI * 2;
4665
+ this.spawn(spawner.playerPrefab, {
4666
+ position: {
4667
+ x: (at?.x ?? 0) + Math.cos(angle) * spawner.spawnRadius,
4668
+ y: at?.y ?? 0,
4669
+ z: (at?.z ?? 0) + Math.sin(angle) * spawner.spawnRadius
4670
+ }
4671
+ });
4672
+ }
4673
+ track(id, entityId, owner, view2) {
4674
+ const entry = {
4675
+ id,
4676
+ entityId,
4677
+ owner,
4678
+ buffer: new SnapshotBuffer(),
4679
+ sentAt: 0,
4680
+ sent: null,
4681
+ props: {}
4682
+ };
4683
+ if (view2) entry.buffer.push(this.now(), view2);
4684
+ this.tracked.set(id, entry);
4685
+ if (entityId !== null) this.byEntity.set(entityId, entry);
4686
+ return entry;
4687
+ }
4688
+ /** The buffer needs the entity's own teleport setting, known once the entity exists. */
4689
+ bindEntity(entry, entityId) {
4690
+ const world = this.world;
4691
+ if (!world) return;
4692
+ entry.entityId = entityId;
4693
+ this.byEntity.set(entityId, entry);
4694
+ let identity = world.getComponent(entityId, NetworkIdentityComponent);
4695
+ if (!identity) {
4696
+ identity = new NetworkIdentityComponent();
4697
+ world.addComponent(entityId, identity);
4698
+ }
4699
+ identity.networkId = entry.id;
4700
+ identity.owner = entry.owner;
4701
+ const settings = world.getComponent(entityId, NetworkTransformComponent);
4702
+ entry.buffer = new SnapshotBuffer(settings?.teleportDistance);
4703
+ }
4704
+ entityAdded(view2) {
4705
+ const existing = this.tracked.get(view2.id);
4706
+ if (existing) {
4707
+ this.entityChanged(view2);
4708
+ return;
4709
+ }
4710
+ const entry = this.track(view2.id, null, view2.owner, view2);
4711
+ if (!view2.prefab || !this.world) return;
4712
+ euler.setFromQuaternion(quat.set(view2.qx, view2.qy, view2.qz, view2.qw));
4713
+ void spawnPrefab(this.world, view2.prefab, {
4714
+ position: { x: view2.x, y: view2.y, z: view2.z },
4715
+ rotation: { x: euler.x, y: euler.y, z: euler.z }
4716
+ }).then((entityId) => {
4717
+ if (this.tracked.get(view2.id) !== entry) {
4718
+ if (this.world) despawnPrefab(this.world, entityId);
4719
+ return;
4720
+ }
4721
+ this.bindEntity(entry, entityId);
4722
+ entry.buffer.push(this.now(), view2);
4723
+ this.applyProps(entry, view2.props);
4724
+ });
4725
+ }
4726
+ entityChanged(view2) {
4727
+ const entry = this.tracked.get(view2.id);
4728
+ if (!entry) return;
4729
+ entry.owner = view2.owner;
4730
+ if (entry.entityId !== null && this.world) {
4731
+ const identity = this.world.getComponent(entry.entityId, NetworkIdentityComponent);
4732
+ if (identity) identity.owner = view2.owner;
4733
+ }
4734
+ if (view2.owner !== this.transport?.sessionId) entry.buffer.push(this.now(), view2);
4735
+ this.applyProps(entry, view2.props);
4736
+ }
4737
+ entityRemoved(id) {
4738
+ const entry = this.tracked.get(id);
4739
+ if (!entry) return;
4740
+ this.tracked.delete(id);
4741
+ if (entry.entityId === null) return;
4742
+ this.byEntity.delete(entry.entityId);
4743
+ if (this.world) despawnPrefab(this.world, entry.entityId);
4744
+ }
4745
+ applyProps(entry, props) {
4746
+ if (entry.entityId === null || !this.world) return;
4747
+ for (const [key, json] of Object.entries(props)) {
4748
+ if (entry.props[key] === json) continue;
4749
+ entry.props[key] = json;
4750
+ const value = JSON.parse(json);
4751
+ let component = this.world.getComponent(entry.entityId, NetworkedPropsComponent);
4752
+ if (!component) {
4753
+ component = new NetworkedPropsComponent();
4754
+ this.world.addComponent(entry.entityId, component);
4755
+ }
4756
+ component.values[key] = value;
4757
+ this.dispatch("onNetworkProp", key, value, entry.entityId);
4758
+ }
4759
+ }
4760
+ corrected(id, pose) {
4761
+ const entry = this.tracked.get(id);
4762
+ if (entry?.entityId == null || !this.world) return;
4763
+ const transform = this.world.getComponent(entry.entityId, TransformComponent);
4764
+ if (transform) applyPose(transform, pose, true);
4765
+ entry.sent = pose;
4766
+ }
4767
+ disconnected() {
4768
+ this.transport = null;
4769
+ this.world?.setNetwork(null);
4770
+ }
4771
+ dispatch(hook, a, b, on) {
4772
+ const world = this.world;
4773
+ if (!world) return;
4774
+ const ids = on !== void 0 ? [on] : world.query(ScriptComponent);
4775
+ for (const entityId of ids) {
4776
+ const instances = world.getComponent(entityId, ScriptComponent)?.scriptInstances;
4777
+ for (const instance of instances?.values() ?? []) {
4778
+ if (!(instance instanceof Behaviour)) continue;
4779
+ try {
4780
+ instance[hook]?.(a, b);
4781
+ } catch (error) {
4782
+ reportBehaviourHookError(world, entityId, instance, hook, error);
4783
+ }
4784
+ }
4785
+ }
4786
+ }
4787
+ update(world) {
4788
+ const transport = this.transport;
4789
+ if (!transport) return;
4790
+ const now = this.now();
4791
+ for (const entry of this.tracked.values()) {
4792
+ if (entry.entityId === null) continue;
4793
+ const settings = world.getComponent(entry.entityId, NetworkTransformComponent);
4794
+ if (!settings?.enabled) continue;
4795
+ const transform = world.getComponent(entry.entityId, TransformComponent);
4796
+ if (!transform) continue;
4797
+ if (entry.owner === transport.sessionId) {
4798
+ if (now - entry.sentAt < 1e3 / settings.sendRate) continue;
4799
+ const pose = poseOf(transform);
4800
+ if (entry.sent && !moved(entry.sent, pose)) continue;
4801
+ entry.sentAt = now;
4802
+ entry.sent = pose;
4803
+ transport.sendPose(entry.id, pose);
4804
+ } else {
4805
+ const pose = entry.buffer.sample(now - settings.interpolationMs);
4806
+ if (pose) applyPose(transform, pose, settings.syncRotation);
4807
+ }
4808
+ }
4809
+ }
4810
+ dispose() {
4811
+ this.transport?.leave();
4812
+ this.transport = null;
4813
+ this.world?.setNetwork(null);
4814
+ this.tracked.clear();
4815
+ this.byEntity.clear();
4816
+ this.handles.clear();
4817
+ this.listeners.clear();
4818
+ }
4819
+ spawn(prefab, options = {}) {
4820
+ const p = options.position;
4821
+ const r = options.rotation;
4822
+ quat.setFromEuler(euler.set(r?.x ?? 0, r?.y ?? 0, r?.z ?? 0));
4823
+ this.transport?.spawn({
4824
+ prefab: typeof prefab === "string" ? prefab : prefab.path,
4825
+ props: encodeProps(options.props),
4826
+ x: p?.x ?? 0,
4827
+ y: p?.y ?? 0,
4828
+ z: p?.z ?? 0,
4829
+ qx: quat.x,
4830
+ qy: quat.y,
4831
+ qz: quat.z,
4832
+ qw: quat.w
4833
+ });
4834
+ }
4835
+ handleFor(entityId) {
4836
+ const known = this.handles.get(entityId);
4837
+ if (known) return known;
4838
+ const self = this;
4839
+ const entry = /* @__PURE__ */ __name(() => self.byEntity.get(entityId), "entry");
4840
+ const handle = {
4841
+ get connected() {
4842
+ return self.transport !== null;
4843
+ },
4844
+ get sessionId() {
4845
+ return self.transport?.sessionId ?? "";
4846
+ },
4847
+ get isHost() {
4848
+ const t = self.transport;
4849
+ return Boolean(t) && t?.host === t?.sessionId;
4850
+ },
4851
+ get isOwner() {
4852
+ return entry()?.owner === self.transport?.sessionId;
4853
+ },
4854
+ get players() {
4855
+ return self.transport?.players ?? [];
4856
+ },
4857
+ send: /* @__PURE__ */ __name((name, payload) => self.transport?.send(name, payload ?? null), "send"),
4858
+ onMessage: /* @__PURE__ */ __name((name, fn) => {
4859
+ const set = self.listeners.get(name) ?? /* @__PURE__ */ new Set();
4860
+ self.listeners.set(name, set);
4861
+ set.add(fn);
4862
+ return () => set.delete(fn);
4863
+ }, "onMessage"),
4864
+ spawn: /* @__PURE__ */ __name((prefab, options) => self.spawn(prefab, options), "spawn"),
4865
+ despawn: /* @__PURE__ */ __name((id = entityId) => {
4866
+ const target = self.byEntity.get(id);
4867
+ if (target) self.transport?.despawn(target.id);
4868
+ }, "despawn"),
4869
+ setProp: /* @__PURE__ */ __name((key, value) => {
4870
+ const target = entry();
4871
+ if (!target || target.entityId === null || !self.world) return;
4872
+ const json = JSON.stringify(value);
4873
+ target.props[key] = json;
4874
+ let component = self.world.getComponent(target.entityId, NetworkedPropsComponent);
4875
+ if (!component) {
4876
+ component = new NetworkedPropsComponent();
4877
+ self.world.addComponent(target.entityId, component);
4878
+ }
4879
+ component.values[key] = value;
4880
+ self.transport?.setProp(target.id, key, json);
4881
+ }, "setProp"),
4882
+ getProp: /* @__PURE__ */ __name((key) => self.world?.getComponent(entityId, NetworkedPropsComponent)?.values[key], "getProp")
4883
+ };
4884
+ this.handles.set(entityId, handle);
4885
+ return handle;
4886
+ }
4887
+ };
4888
+ __name(_NetworkSystem, "NetworkSystem");
4889
+ var NetworkSystem = _NetworkSystem;
4890
+
4891
+ exports.ColyseusTransport = ColyseusTransport;
4892
+ exports.NetworkSystem = NetworkSystem;
4893
+ exports.SnapshotBuffer = SnapshotBuffer;
4894
+ exports.withLatency = withLatency;
4895
+ //# sourceMappingURL=index.cjs.map
4896
+ //# sourceMappingURL=index.cjs.map