@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.
- package/dist/{System-V_mv07le.d.cts → System-8D-XBDKZ.d.cts} +734 -8
- package/dist/{System-V_mv07le.d.ts → System-DPMAW30g.d.ts} +734 -8
- package/dist/{XRHandPose-CU3vNFuS.d.ts → XRHandPose-G0Dl-F0w.d.ts} +93 -3
- package/dist/{XRHandPose-CQTLGxFC.d.cts → XRHandPose-VQMT1WXj.d.cts} +93 -3
- package/dist/animation/index.cjs +252 -0
- package/dist/animation/index.cjs.map +1 -0
- package/dist/animation/index.d.cts +100 -0
- package/dist/animation/index.d.ts +100 -0
- package/dist/animation/index.js +4 -0
- package/dist/animation/index.js.map +1 -0
- package/dist/chunk-CKTHDXPS.js +11 -0
- package/dist/chunk-CKTHDXPS.js.map +1 -0
- package/dist/chunk-G4XJ53LS.js +1237 -0
- package/dist/chunk-G4XJ53LS.js.map +1 -0
- package/dist/chunk-GSWC6LLD.js +241 -0
- package/dist/chunk-GSWC6LLD.js.map +1 -0
- package/dist/{chunk-DF5SSRN6.js → chunk-JIJQFW6P.js} +1216 -2920
- package/dist/chunk-JIJQFW6P.js.map +1 -0
- package/dist/{chunk-BUEKOSR5.js → chunk-NNDUOQ7O.js} +188 -14
- package/dist/chunk-NNDUOQ7O.js.map +1 -0
- package/dist/chunk-OHCNPPMX.js +334 -0
- package/dist/chunk-OHCNPPMX.js.map +1 -0
- package/dist/{chunk-RXBLOO5B.js → chunk-SGF73YTF.js} +105 -715
- package/dist/chunk-SGF73YTF.js.map +1 -0
- package/dist/chunk-U727NTWQ.js +2856 -0
- package/dist/chunk-U727NTWQ.js.map +1 -0
- package/dist/{chunk-OY7ZODZP.js → chunk-XE4OXN2W.js} +3 -9
- package/dist/chunk-XE4OXN2W.js.map +1 -0
- package/dist/{chunk-OWQSESTO.js → chunk-XU2DVWCP.js} +4 -3
- package/dist/chunk-XU2DVWCP.js.map +1 -0
- package/dist/components/index.cjs +183 -10
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +5 -3
- package/dist/components/index.d.ts +5 -3
- package/dist/components/index.js +3 -2
- package/dist/docs/api/Behaviour/classes/Behaviour.md +366 -79
- package/dist/docs/api/Behaviour/index.md +7 -3
- package/dist/docs/api/Behaviour/type-aliases/UiInteractionEvent.md +35 -0
- package/dist/docs/api/Component/classes/Component.md +14 -1
- package/dist/docs/api/components/classes/AnimationComponent.md +26 -26
- package/dist/docs/api/components/classes/AudioComponent.md +19 -19
- package/dist/docs/api/components/classes/CameraComponent.md +14 -14
- package/dist/docs/api/components/classes/EntityType.md +4 -4
- package/dist/docs/api/components/classes/Environment.md +5 -4
- package/dist/docs/api/components/classes/ImageComponent.md +7 -7
- package/dist/docs/api/components/classes/ImageTarget.md +8 -8
- package/dist/docs/api/components/classes/ImageTargetAnchor.md +4 -4
- package/dist/docs/api/components/classes/InstanceSlotComponent.md +4 -4
- package/dist/docs/api/components/classes/InstancedMeshComponent.md +10 -10
- package/dist/docs/api/components/classes/LightComponent.md +6 -6
- package/dist/docs/api/components/classes/MaterialComponent.md +16 -16
- package/dist/docs/api/components/classes/MeshComponent.md +3 -3
- package/dist/docs/api/components/classes/MeshGeometryComponent.md +9 -9
- package/dist/docs/api/components/classes/ModelComponent.md +8 -5
- package/dist/docs/api/components/classes/Name.md +3 -3
- package/dist/docs/api/components/classes/Object3DRef.md +4 -4
- package/dist/docs/api/components/classes/ParentId.md +3 -3
- package/dist/docs/api/components/classes/PhysicsComponent.md +7 -6
- package/dist/docs/api/components/classes/Postprocessing.md +3 -3
- package/dist/docs/api/components/classes/PrefabInstance.md +5 -5
- package/dist/docs/api/components/classes/PrefabNode.md +3 -3
- package/dist/docs/api/components/classes/ScriptComponent.md +5 -5
- package/dist/docs/api/components/classes/ScriptObjectComponent.md +9 -9
- package/dist/docs/api/components/classes/Selectable.md +3 -3
- package/dist/docs/api/components/classes/SelectionTransformState.md +5 -5
- package/dist/docs/api/components/classes/SpriteComponent.md +7 -7
- package/dist/docs/api/components/classes/TransformComponent.md +12 -12
- package/dist/docs/api/components/classes/UIButtonComponent.md +63 -0
- package/dist/docs/api/components/classes/UIPanelComponent.md +62 -0
- package/dist/docs/api/components/classes/UISliderComponent.md +59 -0
- package/dist/docs/api/components/classes/UITextComponent.md +59 -0
- package/dist/docs/api/components/classes/UIToggleComponent.md +56 -0
- package/dist/docs/api/components/classes/VRTeleportAreaComponent.md +53 -0
- package/dist/docs/api/components/classes/VideoComponent.md +28 -28
- package/dist/docs/api/components/classes/XRAnchorComponent.md +64 -0
- package/dist/docs/api/components/classes/XREnvironmentComponent.md +64 -0
- package/dist/docs/api/components/classes/XRHandPoseComponent.md +50 -0
- package/dist/docs/api/components/classes/XRInteractableComponent.md +74 -0
- package/dist/docs/api/components/classes/XRInteractorComponent.md +57 -0
- package/dist/docs/api/components/classes/XRInteractorSideComponent.md +50 -0
- package/dist/docs/api/components/classes/XRRigComponent.md +68 -0
- package/dist/docs/api/components/functions/createAttachPoint.md +25 -0
- package/dist/docs/api/components/functions/createHandPoseEntry.md +25 -0
- package/dist/docs/api/components/functions/defaultMaterialValue.md +1 -1
- package/dist/docs/api/components/functions/handPoseDefinitionFor.md +33 -0
- package/dist/docs/api/components/functions/normalizeEnvironmentLighting.md +30 -0
- package/dist/docs/api/components/functions/normalizePhysicsState.md +1 -1
- package/dist/docs/api/components/functions/setModelLoadState.md +33 -0
- package/dist/docs/api/components/functions/setPhysicsLiveRef.md +3 -9
- package/dist/docs/api/components/index.md +61 -4
- package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +9 -9
- package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +13 -13
- package/dist/docs/api/components/type-aliases/CameraProjection.md +1 -1
- package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +5 -3
- package/dist/docs/api/components/type-aliases/ColliderShape.md +1 -1
- package/dist/docs/api/components/type-aliases/ColliderState.md +20 -20
- package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +4 -4
- package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +8 -8
- package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentLightingState.md +40 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxImageProjection.md +22 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +9 -7
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +1 -1
- package/dist/docs/api/components/type-aliases/EnvironmentState.md +7 -5
- package/dist/docs/api/components/type-aliases/EnvironmentToneMapping.md +16 -0
- package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +3 -3
- package/dist/docs/api/components/type-aliases/ImageTargetReference.md +7 -7
- package/dist/docs/api/components/type-aliases/InstanceTransform.md +13 -13
- package/dist/docs/api/components/type-aliases/InstancedMeshKind.md +1 -1
- package/dist/docs/api/components/type-aliases/LightShadowState.md +37 -0
- package/dist/docs/api/components/type-aliases/LightValueState.md +13 -11
- package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +1 -1
- package/dist/docs/api/components/type-aliases/MaterialValueState.md +28 -28
- package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +1 -1
- package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +7 -7
- package/dist/docs/api/components/type-aliases/ModelLoadState.md +15 -0
- package/dist/docs/api/components/type-aliases/PhysicsState.md +3 -3
- package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +3 -3
- package/dist/docs/api/components/type-aliases/PostprocessingState.md +62 -62
- package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +3 -3
- package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +2 -2
- package/dist/docs/api/components/type-aliases/RigidbodyState.md +17 -17
- package/dist/docs/api/components/type-aliases/RigidbodyType.md +1 -1
- package/dist/docs/api/components/type-aliases/ScriptEntry.md +8 -8
- package/dist/docs/api/components/type-aliases/ScriptObjectComponentInput.md +1 -1
- package/dist/docs/api/components/type-aliases/ScriptObjectRuntimeState.md +1 -1
- package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +1 -1
- package/dist/docs/api/components/type-aliases/TransformData.md +4 -4
- package/dist/docs/api/components/type-aliases/TransformModeValue.md +1 -1
- package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +1 -1
- package/dist/docs/api/components/type-aliases/UIButtonOptions.md +45 -0
- package/dist/docs/api/components/type-aliases/UIPanelOptions.md +39 -0
- package/dist/docs/api/components/type-aliases/UISliderOptions.md +39 -0
- package/dist/docs/api/components/type-aliases/UITextOptions.md +41 -0
- package/dist/docs/api/components/type-aliases/UIToggleOptions.md +35 -0
- package/dist/docs/api/components/type-aliases/UiFollowMode.md +15 -0
- package/dist/docs/api/components/type-aliases/UiTextAlign.md +13 -0
- package/dist/docs/api/components/type-aliases/UiTextVAlign.md +13 -0
- package/dist/docs/api/components/type-aliases/VRTeleportAreaOptions.md +29 -0
- package/dist/docs/api/components/type-aliases/Vec3.md +4 -4
- package/dist/docs/api/components/type-aliases/VrTeleportShape.md +15 -0
- package/dist/docs/api/components/type-aliases/XRAnchorOptions.md +23 -0
- package/dist/docs/api/components/type-aliases/XRHandPoseOptions.md +23 -0
- package/dist/docs/api/components/type-aliases/XRInteractableOptions.md +75 -0
- package/dist/docs/api/components/type-aliases/XRInteractorOptions.md +37 -0
- package/dist/docs/api/components/type-aliases/XRRigOptions.md +51 -0
- package/dist/docs/api/components/type-aliases/XrAttachPoint.md +53 -0
- package/dist/docs/api/components/type-aliases/XrDistanceGrabBehavior.md +19 -0
- package/dist/docs/api/components/type-aliases/XrEnvironmentKind.md +15 -0
- package/dist/docs/api/components/type-aliases/XrEnvironmentOrientation.md +15 -0
- package/dist/docs/api/components/type-aliases/XrEnvironmentPhysics.md +25 -0
- package/dist/docs/api/components/type-aliases/XrGrabGesture.md +19 -0
- package/dist/docs/api/components/type-aliases/XrGrabHands.md +20 -0
- package/dist/docs/api/components/type-aliases/XrGrabReach.md +20 -0
- package/dist/docs/api/components/type-aliases/XrHandPoseEntry.md +49 -0
- package/dist/docs/api/components/type-aliases/XrHandPreset.md +19 -0
- package/dist/docs/api/components/type-aliases/XrInteractorSide.md +15 -0
- package/dist/docs/api/components/type-aliases/XrInteractorType.md +13 -0
- package/dist/docs/api/components/type-aliases/XrLocomotionMode.md +15 -0
- package/dist/docs/api/components/type-aliases/XrTrackingOrigin.md +24 -0
- package/dist/docs/api/components/type-aliases/XrTwoHandRotation.md +15 -0
- package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_LIGHTING.md +15 -0
- package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_INSTANCED_MESH_PARAMETERS.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_INSTANCE_TRANSFORM.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_POSE_CURLS.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_POSE_DIRECTIONS.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +1 -1
- package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +1 -1
- package/dist/docs/api/components/variables/MODEL_NO_PATH_MESSAGE.md +15 -0
- package/dist/docs/api/index/classes/AnimationStateMachine.md +16 -16
- package/dist/docs/api/index/classes/AnimationStateManager.md +13 -13
- package/dist/docs/api/index/classes/AnimationSystem.md +3 -3
- package/dist/docs/api/index/classes/AudioSystem.md +4 -4
- package/dist/docs/api/index/classes/CameraSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +19 -4
- package/dist/docs/api/index/classes/HandPoseTracker.md +114 -0
- package/dist/docs/api/index/classes/InputSystem.md +33 -33
- package/dist/docs/api/index/classes/InstancedMeshSystem.md +2 -2
- package/dist/docs/api/index/classes/LightSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/MaterialSyncSystem.md +3 -3
- package/dist/docs/api/index/classes/MeshGeometrySystem.md +2 -2
- package/dist/docs/api/index/classes/ObjectManagementSystem.md +14 -14
- package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +2 -2
- package/dist/docs/api/index/classes/PhysicsSyncSystem.md +4 -4
- package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +34 -10
- package/dist/docs/api/index/classes/RenderSystem.md +13 -4
- package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +9 -5
- package/dist/docs/api/index/classes/ScriptObject.md +10 -10
- package/dist/docs/api/index/classes/ScriptObjectSystem.md +6 -6
- package/dist/docs/api/index/classes/TeleportAimGate.md +114 -0
- package/dist/docs/api/index/classes/ThrowVelocityTracker.md +89 -0
- package/dist/docs/api/index/classes/TransformSyncSystem.md +2 -2
- package/dist/docs/api/index/classes/UIInteractionSystem.md +60 -0
- package/dist/docs/api/index/classes/UIPanelSystem.md +79 -0
- package/dist/docs/api/index/classes/VRTeleportAreaSystem.md +49 -0
- package/dist/docs/api/index/classes/VideoSystem.md +8 -6
- package/dist/docs/api/index/classes/World.md +282 -100
- package/dist/docs/api/index/classes/XRAnchorSystem.md +90 -0
- package/dist/docs/api/index/classes/XRControllerVisualSystem.md +77 -0
- package/dist/docs/api/index/classes/XREnvironmentSystem.md +137 -0
- package/dist/docs/api/index/classes/XRHandPoseSystem.md +107 -0
- package/dist/docs/api/index/classes/XRHitTestSystem.md +93 -0
- package/dist/docs/api/index/classes/XRHoverVisualSystem.md +76 -0
- package/dist/docs/api/index/classes/XRInputSystem.md +189 -0
- package/dist/docs/api/index/classes/XRInteractionSystem.md +323 -0
- package/dist/docs/api/index/classes/XRLocomotionSystem.md +128 -0
- package/dist/docs/api/index/classes/XRSessionSystem.md +116 -0
- package/dist/docs/api/index/classes/XRTeleportVisualSystem.md +75 -0
- package/dist/docs/api/index/functions/angularVelocityFrom.md +33 -0
- package/dist/docs/api/index/functions/applyHandMaterial.md +26 -0
- package/dist/docs/api/index/functions/applyPrefabToSnapshotInstances.md +1 -1
- package/dist/docs/api/index/functions/arcGroundCrossing.md +30 -0
- package/dist/docs/api/index/functions/buildComponentValueMaps.md +1 -1
- package/dist/docs/api/index/functions/buildNodeKeyMapsFromSnapshot.md +1 -1
- package/dist/docs/api/index/functions/buildNodeMapsFromSnapshot.md +1 -1
- package/dist/docs/api/index/functions/canonicalizeComponentValue.md +1 -1
- package/dist/docs/api/index/functions/clearModelCache.md +1 -1
- package/dist/docs/api/index/functions/clearPrefabCache.md +1 -1
- package/dist/docs/api/index/functions/cloneHandPose.md +23 -0
- package/dist/docs/api/index/functions/collectDiffPaths.md +1 -1
- package/dist/docs/api/index/functions/collectDirectPrefabDependencies.md +1 -1
- package/dist/docs/api/index/functions/collectEntitySubtree.md +1 -1
- package/dist/docs/api/index/functions/collectSnapshotSubtreeIds.md +1 -1
- package/dist/docs/api/index/functions/computeFingerCurl.md +29 -0
- package/dist/docs/api/index/functions/computeHandShape.md +29 -0
- package/dist/docs/api/index/functions/computeInstanceOverrides.md +1 -1
- package/dist/docs/api/index/functions/computePalmPose.md +30 -0
- package/dist/docs/api/index/functions/computePalmWidth.md +25 -0
- package/dist/docs/api/index/functions/computePinch.md +29 -0
- package/dist/docs/api/index/functions/computeSpread.md +33 -0
- package/dist/docs/api/index/functions/createAnimationComponent.md +1 -1
- package/dist/docs/api/index/functions/createAudioComponent.md +1 -1
- package/dist/docs/api/index/functions/createCameraComponent.md +1 -1
- package/dist/docs/api/index/functions/createEntityTypeComponent.md +2 -2
- package/dist/docs/api/index/functions/createEnvironmentComponent.md +1 -1
- package/dist/docs/api/index/functions/createHandMaterial.md +30 -0
- package/dist/docs/api/index/functions/createImageComponent.md +1 -1
- package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +1 -1
- package/dist/docs/api/index/functions/createImageTargetComponent.md +2 -2
- package/dist/docs/api/index/functions/createInstanceSlotComponent.md +1 -1
- package/dist/docs/api/index/functions/createInstancedMeshComponent.md +1 -1
- package/dist/docs/api/index/functions/createLightComponent.md +2 -2
- package/dist/docs/api/index/functions/createMaterialComponent.md +2 -2
- package/dist/docs/api/index/functions/createMeshComponent.md +1 -1
- package/dist/docs/api/index/functions/createMeshGeometryComponent.md +1 -1
- package/dist/docs/api/index/functions/createModelComponent.md +1 -1
- package/dist/docs/api/index/functions/createNameComponent.md +1 -1
- package/dist/docs/api/index/functions/createObject3DRefComponent.md +1 -1
- package/dist/docs/api/index/functions/createParentIdComponent.md +1 -1
- package/dist/docs/api/index/functions/createPhysicsComponent.md +1 -1
- package/dist/docs/api/index/functions/createPostprocessingComponent.md +1 -1
- package/dist/docs/api/index/functions/createScriptComponent.md +1 -1
- package/dist/docs/api/index/functions/createScriptObjectComponent.md +1 -1
- package/dist/docs/api/index/functions/createSelectableComponent.md +1 -1
- package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +1 -1
- package/dist/docs/api/index/functions/createSpriteComponent.md +1 -1
- package/dist/docs/api/index/functions/createTransformComponent.md +1 -1
- package/dist/docs/api/index/functions/createUIButtonComponent.md +28 -0
- package/dist/docs/api/index/functions/createUIPanelComponent.md +28 -0
- package/dist/docs/api/index/functions/createUISliderComponent.md +28 -0
- package/dist/docs/api/index/functions/createUITextComponent.md +28 -0
- package/dist/docs/api/index/functions/createUIToggleComponent.md +28 -0
- package/dist/docs/api/index/functions/createVRTeleportAreaComponent.md +28 -0
- package/dist/docs/api/index/functions/createVideoComponent.md +1 -1
- package/dist/docs/api/index/functions/createXRAnchorComponent.md +28 -0
- package/dist/docs/api/index/functions/createXRHandPoseComponent.md +28 -0
- package/dist/docs/api/index/functions/createXRInteractableComponent.md +28 -0
- package/dist/docs/api/index/functions/createXRInteractorComponent.md +28 -0
- package/dist/docs/api/index/functions/createXRInteractorSideComponent.md +28 -0
- package/dist/docs/api/index/functions/createXRRigComponent.md +28 -0
- package/dist/docs/api/index/functions/decanonicalizeComponentValue.md +1 -1
- package/dist/docs/api/index/functions/despawnPrefab.md +1 -1
- package/dist/docs/api/index/functions/encodeOverride.md +1 -1
- package/dist/docs/api/index/functions/estimateHandScale.md +28 -0
- package/dist/docs/api/index/functions/findSnapshotRootEntityIds.md +1 -1
- package/dist/docs/api/index/functions/findTopLevelNestedRegions.md +1 -1
- package/dist/docs/api/index/functions/getHandPosePreset.md +31 -0
- package/dist/docs/api/index/functions/groupOverridePaths.md +1 -1
- package/dist/docs/api/index/functions/handPoseFromCurls.md +42 -0
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +1 -1
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +1 -1
- package/dist/docs/api/index/functions/indexSnapshotByEntity.md +1 -1
- package/dist/docs/api/index/functions/instantiateSubtree.md +1 -1
- package/dist/docs/api/index/functions/loadPrefab.md +1 -1
- package/dist/docs/api/index/functions/loadSharedGltf.md +1 -1
- package/dist/docs/api/index/functions/matchHandPose.md +34 -0
- package/dist/docs/api/index/functions/mergeComponentValue.md +1 -1
- package/dist/docs/api/index/functions/parseOverride.md +1 -1
- package/dist/docs/api/index/functions/parsePrefabAsset.md +1 -1
- package/dist/docs/api/index/functions/prefabFileVersionFor.md +1 -1
- package/dist/docs/api/index/functions/readXrCapabilities.md +30 -0
- package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +1 -1
- package/dist/docs/api/index/functions/registerDefaultFactories.md +1 -1
- package/dist/docs/api/index/functions/remapSnapshotEntityIds.md +3 -3
- package/dist/docs/api/index/functions/resolveDracoDecoderPath.md +1 -1
- package/dist/docs/api/index/functions/restoreComponentState.md +1 -1
- package/dist/docs/api/index/functions/restorePostCreateComponents.md +1 -1
- package/dist/docs/api/index/functions/sampleTeleportArc.md +40 -0
- package/dist/docs/api/index/functions/serializeEntitySubtree.md +1 -1
- package/dist/docs/api/index/functions/setDracoDecoderPath.md +1 -1
- package/dist/docs/api/index/functions/setPrefabAssetUrlResolver.md +1 -1
- package/dist/docs/api/index/functions/spawnPrefab.md +1 -1
- package/dist/docs/api/index/index.md +116 -4
- package/dist/docs/api/index/interfaces/ChromaKeyOptions.md +20 -0
- package/dist/docs/api/index/interfaces/EcsSystem.md +3 -3
- package/dist/docs/api/index/interfaces/PostprocessingBuildContext.md +21 -0
- package/dist/docs/api/index/interfaces/PostprocessingPipeline.md +84 -0
- package/dist/docs/api/index/interfaces/RenderBackend.md +168 -0
- package/dist/docs/api/index/interfaces/StateMachine.md +13 -13
- package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +4 -4
- package/dist/docs/api/index/type-aliases/ApplyPrefabToSnapshotResult.md +3 -3
- package/dist/docs/api/index/type-aliases/ComponentFactory.md +1 -1
- package/dist/docs/api/index/type-aliases/ComponentValueMaps.md +50 -26
- package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +14 -2
- package/dist/docs/api/index/type-aliases/EcsRenderer.md +17 -0
- package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +3 -3
- package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +4 -4
- package/dist/docs/api/index/type-aliases/ExternalRefWarning.md +5 -5
- package/dist/docs/api/index/type-aliases/HandMaterialOptions.md +32 -0
- package/dist/docs/api/index/type-aliases/HandPoseTrackerOptions.md +27 -0
- package/dist/docs/api/index/type-aliases/HydrateOptions.md +3 -3
- package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +4 -4
- package/dist/docs/api/index/type-aliases/InstantiateSubtreeResult.md +3 -3
- package/dist/docs/api/index/type-aliases/KeyboardKey.md +1 -1
- package/dist/docs/api/index/type-aliases/ModuleLoader.md +1 -1
- package/dist/docs/api/index/type-aliases/MouseButton.md +1 -1
- package/dist/docs/api/index/type-aliases/NestedRegion.md +5 -5
- package/dist/docs/api/index/type-aliases/NodeKeyMaps.md +5 -5
- package/dist/docs/api/index/type-aliases/NodeMaps.md +4 -4
- package/dist/docs/api/index/type-aliases/PrefabAsset.md +5 -5
- package/dist/docs/api/index/type-aliases/RemapSnapshotOptions.md +2 -2
- package/dist/docs/api/index/type-aliases/RendererKind.md +15 -0
- package/dist/docs/api/index/type-aliases/ScriptBehaviourSystemOptions.md +23 -0
- package/dist/docs/api/index/type-aliases/ScriptErrorEvent.md +39 -0
- package/dist/docs/api/index/type-aliases/ScriptErrorListener.md +25 -0
- package/dist/docs/api/index/type-aliases/ScriptErrorPhase.md +28 -0
- package/dist/docs/api/index/type-aliases/ScriptErrorReport.md +31 -0
- package/dist/docs/api/index/type-aliases/ScriptErrorSource.md +15 -0
- package/dist/docs/api/index/type-aliases/SelectionContext.md +4 -4
- package/dist/docs/api/index/type-aliases/SerializeEntitySubtreeResult.md +4 -4
- package/dist/docs/api/index/type-aliases/SpawnPrefabOptions.md +5 -5
- package/dist/docs/api/index/type-aliases/SpawnPrefabSource.md +1 -1
- package/dist/docs/api/index/type-aliases/SubtreeSnapshot.md +3 -3
- package/dist/docs/api/index/type-aliases/UiCanvasLike.md +46 -0
- package/dist/docs/api/index/type-aliases/VelocitySample.md +23 -0
- package/dist/docs/api/index/type-aliases/XrCapabilities.md +41 -0
- package/dist/docs/api/index/type-aliases/XrFinger.md +13 -0
- package/dist/docs/api/index/type-aliases/XrFingerCurl.md +27 -0
- package/dist/docs/api/index/type-aliases/XrFingerTarget.md +31 -0
- package/dist/docs/api/index/type-aliases/XrHandJointName.md +40 -0
- package/dist/docs/api/index/type-aliases/XrHandJoints.md +18 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseAxis.md +15 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseContext.md +23 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseDefinition.md +47 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseDirection.md +21 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseEvent.md +13 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseEventDetail.md +27 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseMatch.md +25 -0
- package/dist/docs/api/index/type-aliases/XrHandPoseOrientation.md +25 -0
- package/dist/docs/api/index/type-aliases/XrHandShape.md +46 -0
- package/dist/docs/api/index/type-aliases/XrHandedness.md +15 -0
- package/dist/docs/api/index/type-aliases/XrHitResult.md +25 -0
- package/dist/docs/api/index/type-aliases/XrInputKind.md +19 -0
- package/dist/docs/api/index/type-aliases/XrInputState.md +60 -0
- package/dist/docs/api/index/type-aliases/XrPalmPose.md +31 -0
- package/dist/docs/api/index/variables/ADDED_NODE_MARKER_COMPONENT.md +2 -2
- package/dist/docs/api/index/variables/ARC_GRAVITY.md +15 -0
- package/dist/docs/api/index/variables/ARC_MAX_TIME.md +15 -0
- package/dist/docs/api/index/variables/ARC_SPEED.md +15 -0
- package/dist/docs/api/index/variables/ARC_STEPS.md +15 -0
- package/dist/docs/api/index/variables/CURLED_COS.md +13 -0
- package/dist/docs/api/index/variables/DEFAULT_DIRECTION_TOLERANCE.md +15 -0
- package/dist/docs/api/index/variables/DEFAULT_ENTER_CONFIDENCE.md +13 -0
- package/dist/docs/api/index/variables/DEFAULT_EXIT_CONFIDENCE.md +13 -0
- package/dist/docs/api/index/variables/DEFAULT_LOST_GRACE_SECONDS.md +13 -0
- package/dist/docs/api/index/variables/DEFAULT_MIN_HOLD_SECONDS.md +13 -0
- package/dist/docs/api/index/variables/DEFAULT_SCRIPT_ERROR_RETRY_DELAY.md +17 -0
- package/dist/docs/api/index/variables/FALLBACK_HAND_SCALE.md +15 -0
- package/dist/docs/api/index/variables/HAND_POSE_PRESETS.md +19 -0
- package/dist/docs/api/index/variables/HAND_POSE_PRESET_IDS.md +15 -0
- package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +1 -1
- package/dist/docs/api/index/variables/KeyboardKeys.md +89 -89
- package/dist/docs/api/index/variables/MATCH_FALLOFF.md +15 -0
- package/dist/docs/api/index/variables/MAX_PLAUSIBLE_SPEED.md +25 -0
- package/dist/docs/api/index/variables/MAX_SAMPLE_AGE_SECONDS.md +18 -0
- package/dist/docs/api/index/variables/NODE_KEY_SEPARATOR.md +1 -1
- package/dist/docs/api/index/variables/NO_XR_CAPABILITIES.md +15 -0
- package/dist/docs/api/index/variables/OVERRIDE_DIFF_EXCLUDED_COMPONENTS.md +1 -1
- package/dist/docs/api/index/variables/OVERRIDE_ROOT_EXCLUDED_COMPONENTS.md +1 -1
- package/dist/docs/api/index/variables/PINCH_FINGERS.md +15 -0
- package/dist/docs/api/index/variables/PREFAB_FILE_VERSION.md +1 -1
- package/dist/docs/api/index/variables/PREFAB_FILE_VERSION_NESTED.md +1 -1
- package/dist/docs/api/index/variables/SCRIPT_OBJECT_ROOT_FLAG.md +1 -1
- package/dist/docs/api/index/variables/SHARED_MODEL_RESOURCE_FLAG.md +1 -1
- package/dist/docs/api/index/variables/STRAIGHT_COS.md +19 -0
- package/dist/docs/api/index/variables/VELOCITY_SAMPLES.md +15 -0
- package/dist/docs/api/index/variables/XR_FINGERS.md +13 -0
- package/dist/docs/api/index/variables/XR_HOVER_SHELL_FLAG.md +15 -0
- package/dist/docs/api/index/variables/webglBackend.md +16 -0
- package/dist/docs/api/typedoc-sidebar.json +1 -1
- package/dist/docs/api/types/type-aliases/AssetInput.md +3 -3
- package/dist/docs/api/types/type-aliases/CheckboxInput.md +3 -3
- package/dist/docs/api/types/type-aliases/ColorInput.md +1 -1
- package/dist/docs/api/types/type-aliases/ComponentInput.md +4 -4
- package/dist/docs/api/types/type-aliases/ComponentKind.md +1 -1
- package/dist/docs/api/types/type-aliases/DropdownInput.md +3 -3
- package/dist/docs/api/types/type-aliases/DropdownOption.md +3 -3
- package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +1 -1
- package/dist/docs/api/types/type-aliases/EcsEntityKind.md +10 -2
- package/dist/docs/api/types/type-aliases/EntityId.md +1 -1
- package/dist/docs/api/types/type-aliases/EntityInput.md +3 -3
- package/dist/docs/api/types/type-aliases/FloatInput.md +1 -1
- package/dist/docs/api/types/type-aliases/IntersectionResult.md +3 -3
- package/dist/docs/api/types/type-aliases/ParentLookup.md +3 -3
- package/dist/docs/api/types/type-aliases/SelectionListener.md +1 -1
- package/dist/docs/api/types/type-aliases/SliderInput.md +5 -5
- package/dist/docs/api/types/type-aliases/TextInput.md +1 -1
- package/dist/docs/api/types/type-aliases/ToggleInput.md +1 -1
- package/dist/docs/api/types/type-aliases/Vec3.md +1 -1
- package/dist/docs/api/types/type-aliases/Vector2Input.md +3 -3
- package/dist/docs/api/types/type-aliases/Vector3Input.md +4 -4
- package/dist/docs/api/types/type-aliases/WorldEntityView.md +1 -1
- package/dist/docs/guide/audio-mixing-and-sound-banks.md +71 -0
- package/dist/docs/guide/authoring-a-behaviour.md +3 -3
- package/dist/docs/guide/authoring-a-script-object.md +12 -9
- package/dist/docs/guide/behaviour-data-binding/index.md +11 -11
- package/dist/docs/guide/behaviour-lifecycle.md +9 -0
- package/dist/docs/guide/bone-attachments-and-ik.md +128 -0
- package/dist/docs/guide/component-catalog.md +10 -2
- package/dist/docs/guide/components/light.md +42 -0
- package/dist/docs/guide/components/model.md +32 -3
- package/dist/docs/guide/concepts.md +2 -2
- package/dist/docs/guide/getting-started/creating-objects.md +2 -2
- package/dist/docs/guide/getting-started/editing-objects.md +2 -2
- package/dist/docs/guide/getting-started/editor/ai-agent.md +227 -0
- package/dist/docs/guide/getting-started/editor/hierarchy.md +2 -2
- package/dist/docs/guide/getting-started/editor/index.md +3 -2
- package/dist/docs/guide/getting-started/editor/inspector.md +2 -2
- package/dist/docs/guide/getting-started/editor/scene-inspector.md +3 -3
- package/dist/docs/guide/getting-started/editor/toolbar.md +11 -11
- package/dist/docs/guide/getting-started/editor/viewport.md +17 -9
- package/dist/docs/guide/getting-started/index.md +1 -1
- package/dist/docs/guide/getting-started/installation.md +1 -1
- package/dist/docs/guide/getting-started/preview-and-test.md +7 -7
- package/dist/docs/guide/getting-started/project-types/image-tracking.md +23 -11
- package/dist/docs/guide/getting-started/project-types/index.md +4 -4
- package/dist/docs/guide/getting-started/project-types/vr.md +270 -2
- package/dist/docs/guide/getting-started/projects.md +4 -5
- package/dist/docs/guide/getting-started/shortcuts.md +5 -4
- package/dist/docs/guide/multiplayer.md +92 -0
- package/dist/docs/guide/scene/environment.md +101 -4
- package/dist/docs/guide/scene/index.md +4 -4
- package/dist/docs/guide/scene/postprocessing.md +67 -5
- package/dist/docs/guide/spawning/area-light.md +2 -0
- package/dist/docs/guide/systems/environment-sync-system.md +11 -6
- package/dist/docs/guide/systems/light-sync-system.md +5 -3
- package/dist/docs/guide/systems/postprocessing-sync-system.md +16 -6
- package/dist/docs/guide/systems/render-system.md +7 -6
- package/dist/docs/guide/systems/script-behaviour-system.md +7 -5
- package/dist/docs/guide/systems/script-object-system.md +3 -1
- package/dist/docs/guide/systems/video-system.md +1 -1
- package/dist/docs/guide/webgpu-and-tsl.md +415 -0
- package/dist/docs/guide/world-api.md +52 -2
- package/dist/factories/index.cjs +770 -283
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +14 -3
- package/dist/factories/index.d.ts +14 -3
- package/dist/factories/index.js +7 -4
- package/dist/{index-D2Jt_JzH.d.ts → index-C61n65PE.d.ts} +135 -42
- package/dist/{index-DaG03vyN.d.cts → index-C70N4BYG.d.cts} +135 -42
- package/dist/{index-C3ik3sA1.d.ts → index-D9DjrUn3.d.cts} +25 -3
- package/dist/{index-Dlr-7-4m.d.cts → index-DppafVu4.d.ts} +25 -3
- package/dist/index.cjs +3642 -1263
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +113 -11
- package/dist/index.d.ts +113 -11
- package/dist/index.js +187 -12
- package/dist/index.js.map +1 -1
- package/dist/network/index.cjs +4896 -0
- package/dist/network/index.cjs.map +1 -0
- package/dist/network/index.d.cts +98 -0
- package/dist/network/index.d.ts +98 -0
- package/dist/network/index.js +493 -0
- package/dist/network/index.js.map +1 -0
- package/dist/systems/index.cjs +3958 -1762
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +4 -2
- package/dist/systems/index.d.ts +4 -2
- package/dist/systems/index.js +8 -4
- package/dist/types.d.cts +3 -1
- package/dist/types.d.ts +3 -1
- package/dist/webgpu/index.d.ts +113 -0
- package/dist/webgpu/index.js +302 -0
- package/dist/webgpu/index.js.map +1 -0
- package/dist/worldSnapshotUtils.d.cts +3 -1
- package/dist/worldSnapshotUtils.d.ts +3 -1
- package/dist/worldSnapshotUtils.js +3 -2
- package/package.json +19 -3
- package/dist/chunk-BUEKOSR5.js.map +0 -1
- package/dist/chunk-DF5SSRN6.js.map +0 -1
- package/dist/chunk-OWQSESTO.js.map +0 -1
- package/dist/chunk-OY7ZODZP.js.map +0 -1
- package/dist/chunk-RXBLOO5B.js.map +0 -1
- package/dist/chunk-WJD2VKEH.js +0 -315
- package/dist/chunk-WJD2VKEH.js.map +0 -1
|
@@ -1,36 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { getRendererKindOf, readWorldRenderBackend, readWorldRendererKind } from './chunk-OHCNPPMX.js';
|
|
2
|
+
import { resolveScriptCtor, Behaviour, normalizeScriptData, defaultModuleLoader, reportScriptError, serializeDataForStorage, toErrorMessage, readScriptPhase, withScriptPhase, mergeDataByCurrentDefaults, resolveInputData, resolvePrefabAssetUrl, reportBehaviourHookError } from './chunk-U727NTWQ.js';
|
|
3
|
+
import { createGLTFLoader, SHARED_MODEL_RESOURCE_FLAG, applyTransform, findModelBone } from './chunk-G4XJ53LS.js';
|
|
4
|
+
import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, normalizeEnvironmentLighting, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ScriptComponent, ScriptObjectComponent, AudioComponent, VideoComponent, XRInteractableComponent, XRRigComponent, VRTeleportAreaComponent, ParentId, XREnvironmentComponent, UIButtonComponent, UIToggleComponent, UISliderComponent, Name, UIPanelComponent, UITextComponent, XRAnchorComponent, IKComponent, XRInteractorComponent, XRInteractorSideComponent, handPoseDefinitionFor, getHandPosePreset, XRHandPoseComponent } from './chunk-NNDUOQ7O.js';
|
|
5
|
+
import { __name } from './chunk-XE4OXN2W.js';
|
|
4
6
|
import * as THREE19 from 'three';
|
|
5
|
-
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
6
7
|
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
|
|
7
|
-
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
8
|
-
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
9
|
-
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
10
|
-
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
|
|
11
|
-
import { DotScreenPass } from 'three/examples/jsm/postprocessing/DotScreenPass.js';
|
|
12
|
-
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';
|
|
13
|
-
import { FilmPass } from 'three/examples/jsm/postprocessing/FilmPass.js';
|
|
14
|
-
import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js';
|
|
15
|
-
import { SSAOPass } from 'three/examples/jsm/postprocessing/SSAOPass.js';
|
|
16
|
-
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
|
|
17
|
-
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js';
|
|
18
|
-
import { HueSaturationShader } from 'three/examples/jsm/shaders/HueSaturationShader.js';
|
|
19
|
-
import { SepiaShader } from 'three/examples/jsm/shaders/SepiaShader.js';
|
|
20
|
-
import { VignetteShader } from 'three/examples/jsm/shaders/VignetteShader.js';
|
|
21
8
|
import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';
|
|
22
9
|
import { XRHandModelFactory } from 'three/examples/jsm/webxr/XRHandModelFactory.js';
|
|
23
10
|
|
|
24
11
|
function createClipSourceLoader() {
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
const dracoLoader = new DRACOLoader();
|
|
28
|
-
dracoLoader.setDecoderPath(resolveDracoDecoderPath());
|
|
29
|
-
loader.setDRACOLoader(dracoLoader);
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.warn("DRACOLoader could not be configured for clip source loading.", error);
|
|
32
|
-
}
|
|
33
|
-
return loader;
|
|
12
|
+
return createGLTFLoader();
|
|
34
13
|
}
|
|
35
14
|
__name(createClipSourceLoader, "createClipSourceLoader");
|
|
36
15
|
function normalizeDeltaTime(deltaTime) {
|
|
@@ -579,6 +558,88 @@ var _ObjectVisibilitySystem = class _ObjectVisibilitySystem {
|
|
|
579
558
|
};
|
|
580
559
|
__name(_ObjectVisibilitySystem, "ObjectVisibilitySystem");
|
|
581
560
|
var ObjectVisibilitySystem = _ObjectVisibilitySystem;
|
|
561
|
+
function getUrlExtension(url) {
|
|
562
|
+
const path = url.split(/[?#]/)[0] ?? "";
|
|
563
|
+
const lastSegment = path.split("/").pop() ?? "";
|
|
564
|
+
const dot = lastSegment.lastIndexOf(".");
|
|
565
|
+
return dot >= 0 ? lastSegment.slice(dot + 1).toLowerCase() : "";
|
|
566
|
+
}
|
|
567
|
+
__name(getUrlExtension, "getUrlExtension");
|
|
568
|
+
async function loadEquirectTexture(url) {
|
|
569
|
+
const extension = getUrlExtension(url);
|
|
570
|
+
let texture;
|
|
571
|
+
if (extension === "hdr") {
|
|
572
|
+
const { HDRLoader } = await import('three/examples/jsm/loaders/HDRLoader.js');
|
|
573
|
+
texture = await new HDRLoader().loadAsync(url);
|
|
574
|
+
} else if (extension === "exr") {
|
|
575
|
+
const { EXRLoader } = await import('three/examples/jsm/loaders/EXRLoader.js');
|
|
576
|
+
texture = await new EXRLoader().loadAsync(url);
|
|
577
|
+
} else {
|
|
578
|
+
texture = await new THREE19.TextureLoader().loadAsync(url);
|
|
579
|
+
texture.colorSpace = THREE19.SRGBColorSpace;
|
|
580
|
+
}
|
|
581
|
+
texture.mapping = THREE19.EquirectangularReflectionMapping;
|
|
582
|
+
texture.needsUpdate = true;
|
|
583
|
+
return texture;
|
|
584
|
+
}
|
|
585
|
+
__name(loadEquirectTexture, "loadEquirectTexture");
|
|
586
|
+
var rendererStates = /* @__PURE__ */ new WeakMap();
|
|
587
|
+
function toThreeToneMapping(mode) {
|
|
588
|
+
switch (mode) {
|
|
589
|
+
case "aces":
|
|
590
|
+
return THREE19.ACESFilmicToneMapping;
|
|
591
|
+
case "agx":
|
|
592
|
+
return THREE19.AgXToneMapping;
|
|
593
|
+
case "neutral":
|
|
594
|
+
return THREE19.NeutralToneMapping;
|
|
595
|
+
default:
|
|
596
|
+
return THREE19.NoToneMapping;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
__name(toThreeToneMapping, "toThreeToneMapping");
|
|
600
|
+
function resolveToneMapping(environment, postprocessing) {
|
|
601
|
+
const environmentMode = environment && environment.mode !== "none" ? environment.mode : null;
|
|
602
|
+
const mode = environmentMode ?? (postprocessing ? "aces" : "none");
|
|
603
|
+
const exposure = postprocessing ? postprocessing.exposure : environment?.exposure ?? 1;
|
|
604
|
+
return { mode, exposure };
|
|
605
|
+
}
|
|
606
|
+
__name(resolveToneMapping, "resolveToneMapping");
|
|
607
|
+
function setRendererToneMappingSource(renderer, source, request) {
|
|
608
|
+
if (!renderer || typeof renderer !== "object") {
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
const target = renderer;
|
|
612
|
+
let state = rendererStates.get(renderer);
|
|
613
|
+
if (!state) {
|
|
614
|
+
if (request === null) return;
|
|
615
|
+
state = {
|
|
616
|
+
baseline: {
|
|
617
|
+
toneMapping: target.toneMapping ?? THREE19.NoToneMapping,
|
|
618
|
+
exposure: typeof target.toneMappingExposure === "number" ? target.toneMappingExposure : 1
|
|
619
|
+
},
|
|
620
|
+
environment: null,
|
|
621
|
+
postprocessing: null
|
|
622
|
+
};
|
|
623
|
+
rendererStates.set(renderer, state);
|
|
624
|
+
}
|
|
625
|
+
if (source === "environment") {
|
|
626
|
+
state.environment = request;
|
|
627
|
+
} else {
|
|
628
|
+
state.postprocessing = request;
|
|
629
|
+
}
|
|
630
|
+
if (!state.environment && !state.postprocessing) {
|
|
631
|
+
target.toneMapping = state.baseline.toneMapping;
|
|
632
|
+
target.toneMappingExposure = state.baseline.exposure;
|
|
633
|
+
rendererStates.delete(renderer);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
const resolved = resolveToneMapping(state.environment, state.postprocessing);
|
|
637
|
+
target.toneMapping = toThreeToneMapping(resolved.mode);
|
|
638
|
+
target.toneMappingExposure = resolved.exposure;
|
|
639
|
+
}
|
|
640
|
+
__name(setRendererToneMappingSource, "setRendererToneMappingSource");
|
|
641
|
+
|
|
642
|
+
// core/systems/EnvironmentSyncSystem.ts
|
|
582
643
|
var MIN_FOG_DELTA = 1e-3;
|
|
583
644
|
var MIN_DENSITY = 0;
|
|
584
645
|
function createGradientTexture(effect, colors) {
|
|
@@ -627,14 +688,48 @@ function createGradientTexture(effect, colors) {
|
|
|
627
688
|
return texture;
|
|
628
689
|
}
|
|
629
690
|
__name(createGradientTexture, "createGradientTexture");
|
|
691
|
+
function readRenderer(world) {
|
|
692
|
+
const getRenderer = world.getRenderer;
|
|
693
|
+
if (typeof getRenderer !== "function") return null;
|
|
694
|
+
try {
|
|
695
|
+
return getRenderer.call(world) ?? null;
|
|
696
|
+
} catch {
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
__name(readRenderer, "readRenderer");
|
|
630
701
|
var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
631
702
|
constructor(scene) {
|
|
632
703
|
this.textureLoader = new THREE19.TextureLoader();
|
|
633
|
-
|
|
704
|
+
/** `true` once an Environment entity has been seen (drives the reset path). */
|
|
705
|
+
this.hasEnvironment = false;
|
|
706
|
+
this.skyboxSignature = null;
|
|
707
|
+
this.fogSignature = null;
|
|
708
|
+
this.lightingSignature = null;
|
|
634
709
|
this.activeTexture = null;
|
|
710
|
+
/** Load key (`url`, or `equirect|url`) of the current/pending image skybox. */
|
|
635
711
|
this.pendingImageUrl = null;
|
|
712
|
+
/** What the skybox wants as the background, before passthrough/env overrides. */
|
|
713
|
+
this.skyboxBackground = null;
|
|
636
714
|
/** Whether the skybox is currently withheld because passthrough is on. */
|
|
637
715
|
this.passthroughSuppressed = false;
|
|
716
|
+
// ── Image-based lighting ────────────────────────────────────────────────
|
|
717
|
+
this.renderer = null;
|
|
718
|
+
this.lighting = null;
|
|
719
|
+
/** URL of the environment map currently loaded or loading. */
|
|
720
|
+
this.envUrl = null;
|
|
721
|
+
/** Incremented per env-map load; a load whose token is stale is discarded. */
|
|
722
|
+
this.envLoadToken = 0;
|
|
723
|
+
/** Equirect source texture of the current environment map. */
|
|
724
|
+
this.envSource = null;
|
|
725
|
+
/**
|
|
726
|
+
* PMREM render target built from {@link envSource} (WebGL only; on WebGPU
|
|
727
|
+
* the renderer prefilters `scene.environment` itself and this stays null).
|
|
728
|
+
*/
|
|
729
|
+
this.envTarget = null;
|
|
730
|
+
this.sceneLightingBaseline = null;
|
|
731
|
+
this.sceneBackgroundBaseline = null;
|
|
732
|
+
this.disposed = false;
|
|
638
733
|
this.scene = scene;
|
|
639
734
|
}
|
|
640
735
|
disposeActiveTexture() {
|
|
@@ -643,18 +738,53 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
643
738
|
this.activeTexture = null;
|
|
644
739
|
}
|
|
645
740
|
}
|
|
646
|
-
|
|
647
|
-
|
|
741
|
+
/** Write the background the current state calls for. */
|
|
742
|
+
commitBackground() {
|
|
743
|
+
if (this.passthroughSuppressed) {
|
|
744
|
+
this.scene.background = null;
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
const lighting = this.lighting;
|
|
748
|
+
if (lighting?.useAsBackground && this.envSource) {
|
|
749
|
+
if (!this.sceneBackgroundBaseline) {
|
|
750
|
+
this.sceneBackgroundBaseline = {
|
|
751
|
+
backgroundBlurriness: this.scene.backgroundBlurriness,
|
|
752
|
+
backgroundIntensity: this.scene.backgroundIntensity,
|
|
753
|
+
backgroundRotationY: this.scene.backgroundRotation.y
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
this.scene.background = this.envSource;
|
|
757
|
+
this.scene.backgroundBlurriness = lighting.backgroundBlurriness;
|
|
758
|
+
this.scene.backgroundIntensity = lighting.backgroundIntensity;
|
|
759
|
+
this.scene.backgroundRotation.y = lighting.envRotationY;
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
this.restoreBackgroundBaseline();
|
|
763
|
+
this.scene.background = this.skyboxBackground;
|
|
764
|
+
}
|
|
765
|
+
restoreBackgroundBaseline() {
|
|
766
|
+
const baseline = this.sceneBackgroundBaseline;
|
|
767
|
+
if (!baseline) return;
|
|
768
|
+
this.scene.backgroundBlurriness = baseline.backgroundBlurriness;
|
|
769
|
+
this.scene.backgroundIntensity = baseline.backgroundIntensity;
|
|
770
|
+
this.scene.backgroundRotation.y = baseline.backgroundRotationY;
|
|
771
|
+
this.sceneBackgroundBaseline = null;
|
|
772
|
+
}
|
|
773
|
+
setSkyboxBackground(value) {
|
|
774
|
+
this.skyboxBackground = value;
|
|
775
|
+
this.commitBackground();
|
|
776
|
+
}
|
|
777
|
+
applySkybox(skybox) {
|
|
648
778
|
if (skybox.type === "none") {
|
|
649
779
|
this.disposeActiveTexture();
|
|
650
780
|
this.pendingImageUrl = null;
|
|
651
|
-
this.
|
|
781
|
+
this.setSkyboxBackground(null);
|
|
652
782
|
return;
|
|
653
783
|
}
|
|
654
784
|
if (skybox.type === "color") {
|
|
655
785
|
this.disposeActiveTexture();
|
|
656
786
|
this.pendingImageUrl = null;
|
|
657
|
-
this.
|
|
787
|
+
this.setSkyboxBackground(new THREE19.Color(skybox.color || "#1e1e1e"));
|
|
658
788
|
return;
|
|
659
789
|
}
|
|
660
790
|
if (skybox.type === "gradient") {
|
|
@@ -665,44 +795,54 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
665
795
|
skybox.gradient.colors
|
|
666
796
|
);
|
|
667
797
|
this.activeTexture = texture;
|
|
668
|
-
this.
|
|
798
|
+
this.setSkyboxBackground(texture);
|
|
669
799
|
return;
|
|
670
800
|
}
|
|
671
801
|
const imageUrl = skybox.imageUrl?.trim() ?? "";
|
|
672
802
|
if (!imageUrl) {
|
|
673
803
|
this.disposeActiveTexture();
|
|
674
804
|
this.pendingImageUrl = null;
|
|
675
|
-
this.
|
|
805
|
+
this.setSkyboxBackground(null);
|
|
676
806
|
return;
|
|
677
807
|
}
|
|
678
|
-
|
|
679
|
-
|
|
808
|
+
const equirect = skybox.imageProjection === "equirect";
|
|
809
|
+
const loadKey = equirect ? `equirect|${imageUrl}` : imageUrl;
|
|
810
|
+
if (this.pendingImageUrl === loadKey && this.activeTexture) {
|
|
811
|
+
this.setSkyboxBackground(this.activeTexture);
|
|
680
812
|
return;
|
|
681
813
|
}
|
|
682
814
|
this.disposeActiveTexture();
|
|
683
|
-
this.pendingImageUrl =
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}
|
|
815
|
+
this.pendingImageUrl = loadKey;
|
|
816
|
+
const onLoaded = /* @__PURE__ */ __name((texture) => {
|
|
817
|
+
if (this.pendingImageUrl !== loadKey) {
|
|
818
|
+
texture.dispose();
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
if (!equirect) {
|
|
691
822
|
texture.colorSpace = THREE19.SRGBColorSpace;
|
|
692
|
-
this.activeTexture = texture;
|
|
693
|
-
this.scene.background = texture;
|
|
694
|
-
},
|
|
695
|
-
void 0,
|
|
696
|
-
() => {
|
|
697
|
-
if (this.pendingImageUrl === imageUrl) {
|
|
698
|
-
this.pendingImageUrl = null;
|
|
699
|
-
this.scene.background = null;
|
|
700
|
-
}
|
|
701
823
|
}
|
|
702
|
-
|
|
824
|
+
this.activeTexture = texture;
|
|
825
|
+
this.setSkyboxBackground(texture);
|
|
826
|
+
}, "onLoaded");
|
|
827
|
+
const onFailed = /* @__PURE__ */ __name(() => {
|
|
828
|
+
if (this.pendingImageUrl === loadKey) {
|
|
829
|
+
this.pendingImageUrl = null;
|
|
830
|
+
this.setSkyboxBackground(null);
|
|
831
|
+
}
|
|
832
|
+
}, "onFailed");
|
|
833
|
+
if (equirect) {
|
|
834
|
+
loadEquirectTexture(imageUrl).then(onLoaded, (error) => {
|
|
835
|
+
console.error(
|
|
836
|
+
`[EnvironmentSyncSystem] Failed to load skybox image ${imageUrl}`,
|
|
837
|
+
error
|
|
838
|
+
);
|
|
839
|
+
onFailed();
|
|
840
|
+
});
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
this.textureLoader.load(imageUrl, onLoaded, void 0, onFailed);
|
|
703
844
|
}
|
|
704
|
-
applyFog(
|
|
705
|
-
const fog = component.values.fog;
|
|
845
|
+
applyFog(fog) {
|
|
706
846
|
if (fog.type === "none") {
|
|
707
847
|
this.scene.fog = null;
|
|
708
848
|
return;
|
|
@@ -718,27 +858,167 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
718
858
|
const density = Number.isFinite(fog.exponential.density) ? Math.max(MIN_DENSITY, fog.exponential.density) : 2e-3;
|
|
719
859
|
this.scene.fog = new THREE19.FogExp2(fogColor, density);
|
|
720
860
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (
|
|
724
|
-
this.
|
|
725
|
-
|
|
861
|
+
// ── Image-based lighting ────────────────────────────────────────────────
|
|
862
|
+
disposeEnvResources() {
|
|
863
|
+
if (this.envTarget) {
|
|
864
|
+
this.envTarget.dispose();
|
|
865
|
+
this.envTarget = null;
|
|
866
|
+
}
|
|
867
|
+
if (this.envSource) {
|
|
868
|
+
this.envSource.dispose();
|
|
869
|
+
this.envSource = null;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
/** Drop the environment map (any in-flight load is abandoned). */
|
|
873
|
+
clearEnvMap() {
|
|
874
|
+
this.envLoadToken += 1;
|
|
875
|
+
this.envUrl = null;
|
|
876
|
+
const owned = this.envTarget?.texture ?? this.envSource;
|
|
877
|
+
if (owned && this.scene.environment === owned) {
|
|
878
|
+
this.scene.environment = this.sceneLightingBaseline?.environment ?? null;
|
|
879
|
+
}
|
|
880
|
+
this.disposeEnvResources();
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Undo everything the lighting block wrote to the scene and renderer.
|
|
884
|
+
* `commit` re-applies the background afterwards (off during teardown, which
|
|
885
|
+
* must not touch the background).
|
|
886
|
+
*/
|
|
887
|
+
clearLighting(commit = true) {
|
|
888
|
+
this.clearEnvMap();
|
|
889
|
+
const baseline = this.sceneLightingBaseline;
|
|
890
|
+
if (baseline) {
|
|
891
|
+
this.scene.environment = baseline.environment;
|
|
892
|
+
this.scene.environmentIntensity = baseline.environmentIntensity;
|
|
893
|
+
this.scene.environmentRotation.y = baseline.environmentRotationY;
|
|
894
|
+
this.sceneLightingBaseline = null;
|
|
895
|
+
}
|
|
896
|
+
if (this.lighting) {
|
|
897
|
+
setRendererToneMappingSource(this.renderer, "environment", null);
|
|
898
|
+
}
|
|
899
|
+
const hadEnvBackground = this.sceneBackgroundBaseline !== null;
|
|
900
|
+
this.lighting = null;
|
|
901
|
+
if (commit) {
|
|
902
|
+
this.commitBackground();
|
|
903
|
+
} else if (hadEnvBackground) {
|
|
904
|
+
this.restoreBackgroundBaseline();
|
|
905
|
+
if (!this.passthroughSuppressed) {
|
|
726
906
|
this.scene.background = null;
|
|
727
|
-
} else {
|
|
728
|
-
this.signature = null;
|
|
729
907
|
}
|
|
730
908
|
}
|
|
731
|
-
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* PMREM-filter an equirect texture. `null` when no usable renderer exists,
|
|
912
|
+
* or on WebGPU: there the WebGL `PMREMGenerator` would silently produce a
|
|
913
|
+
* black map, while `WebGPURenderer` prefilters an equirect
|
|
914
|
+
* `scene.environment` (and a blurred background) by itself.
|
|
915
|
+
*/
|
|
916
|
+
buildPmrem(texture) {
|
|
917
|
+
const renderer = this.renderer;
|
|
918
|
+
if (!renderer || getRendererKindOf(renderer) === "webgpu") return null;
|
|
919
|
+
let generator = null;
|
|
920
|
+
try {
|
|
921
|
+
generator = new THREE19.PMREMGenerator(renderer);
|
|
922
|
+
return generator.fromEquirectangular(texture);
|
|
923
|
+
} catch (error) {
|
|
924
|
+
console.warn(
|
|
925
|
+
"[EnvironmentSyncSystem] PMREM prefilter failed; using the equirect texture directly.",
|
|
926
|
+
error
|
|
927
|
+
);
|
|
928
|
+
return null;
|
|
929
|
+
} finally {
|
|
930
|
+
generator?.dispose();
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
loadEnvMap(url) {
|
|
934
|
+
this.envLoadToken += 1;
|
|
935
|
+
const token = this.envLoadToken;
|
|
936
|
+
this.envUrl = url;
|
|
937
|
+
loadEquirectTexture(url).then(
|
|
938
|
+
(texture) => {
|
|
939
|
+
if (this.disposed || token !== this.envLoadToken) {
|
|
940
|
+
texture.dispose();
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
const target = this.buildPmrem(texture);
|
|
944
|
+
this.disposeEnvResources();
|
|
945
|
+
this.envSource = texture;
|
|
946
|
+
this.envTarget = target;
|
|
947
|
+
this.scene.environment = target ? target.texture : texture;
|
|
948
|
+
this.applyEnvironmentParams();
|
|
949
|
+
this.commitBackground();
|
|
950
|
+
},
|
|
951
|
+
(error) => {
|
|
952
|
+
if (this.disposed || token !== this.envLoadToken) return;
|
|
953
|
+
console.error(
|
|
954
|
+
`[EnvironmentSyncSystem] Failed to load environment map ${url}`,
|
|
955
|
+
error
|
|
956
|
+
);
|
|
957
|
+
this.clearEnvMap();
|
|
958
|
+
this.commitBackground();
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
applyEnvironmentParams() {
|
|
963
|
+
const lighting = this.lighting;
|
|
964
|
+
if (!lighting) return;
|
|
965
|
+
this.scene.environmentIntensity = lighting.envIntensity;
|
|
966
|
+
this.scene.environmentRotation.y = lighting.envRotationY;
|
|
967
|
+
}
|
|
968
|
+
applyLighting(value) {
|
|
969
|
+
const lighting = normalizeEnvironmentLighting(value);
|
|
970
|
+
if (!lighting) {
|
|
971
|
+
if (this.lighting || this.sceneLightingBaseline) {
|
|
972
|
+
this.clearLighting();
|
|
973
|
+
}
|
|
732
974
|
return;
|
|
733
975
|
}
|
|
976
|
+
if (!this.sceneLightingBaseline) {
|
|
977
|
+
this.sceneLightingBaseline = {
|
|
978
|
+
environment: this.scene.environment,
|
|
979
|
+
environmentIntensity: this.scene.environmentIntensity,
|
|
980
|
+
environmentRotationY: this.scene.environmentRotation.y
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
this.lighting = lighting;
|
|
984
|
+
setRendererToneMappingSource(this.renderer, "environment", {
|
|
985
|
+
mode: lighting.toneMapping,
|
|
986
|
+
exposure: lighting.exposure
|
|
987
|
+
});
|
|
988
|
+
const url = lighting.envMapUrl.trim();
|
|
989
|
+
if (!url) {
|
|
990
|
+
if (this.envUrl !== null || this.envSource) {
|
|
991
|
+
this.clearEnvMap();
|
|
992
|
+
}
|
|
993
|
+
} else if (url !== this.envUrl) {
|
|
994
|
+
this.loadEnvMap(url);
|
|
995
|
+
}
|
|
996
|
+
this.applyEnvironmentParams();
|
|
997
|
+
this.commitBackground();
|
|
998
|
+
}
|
|
999
|
+
resetAll() {
|
|
1000
|
+
this.hasEnvironment = false;
|
|
1001
|
+
this.skyboxSignature = null;
|
|
1002
|
+
this.fogSignature = null;
|
|
1003
|
+
this.lightingSignature = null;
|
|
1004
|
+
this.pendingImageUrl = null;
|
|
1005
|
+
this.disposeActiveTexture();
|
|
1006
|
+
this.skyboxBackground = null;
|
|
1007
|
+
this.clearLighting();
|
|
1008
|
+
this.scene.background = null;
|
|
1009
|
+
this.scene.fog = null;
|
|
1010
|
+
}
|
|
1011
|
+
update(world) {
|
|
1012
|
+
this.renderer = readRenderer(world);
|
|
1013
|
+
const passthrough = world.isXrPassthrough();
|
|
1014
|
+
if (passthrough !== this.passthroughSuppressed) {
|
|
1015
|
+
this.passthroughSuppressed = passthrough;
|
|
1016
|
+
this.commitBackground();
|
|
1017
|
+
}
|
|
734
1018
|
const entityIds = world.query(Environment);
|
|
735
1019
|
if (entityIds.length === 0) {
|
|
736
|
-
if (this.
|
|
737
|
-
this.
|
|
738
|
-
this.pendingImageUrl = null;
|
|
739
|
-
this.disposeActiveTexture();
|
|
740
|
-
this.scene.background = null;
|
|
741
|
-
this.scene.fog = null;
|
|
1020
|
+
if (this.hasEnvironment) {
|
|
1021
|
+
this.resetAll();
|
|
742
1022
|
}
|
|
743
1023
|
return;
|
|
744
1024
|
}
|
|
@@ -747,29 +1027,50 @@ var _EnvironmentSyncSystem = class _EnvironmentSyncSystem {
|
|
|
747
1027
|
if (!environment) {
|
|
748
1028
|
return;
|
|
749
1029
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
1030
|
+
this.hasEnvironment = true;
|
|
1031
|
+
const values = environment.values;
|
|
1032
|
+
const skyboxSignature = JSON.stringify(values.skybox);
|
|
1033
|
+
if (skyboxSignature !== this.skyboxSignature) {
|
|
1034
|
+
this.skyboxSignature = skyboxSignature;
|
|
1035
|
+
this.applySkybox(values.skybox);
|
|
1036
|
+
}
|
|
1037
|
+
const fogSignature = JSON.stringify(values.fog);
|
|
1038
|
+
if (fogSignature !== this.fogSignature) {
|
|
1039
|
+
this.fogSignature = fogSignature;
|
|
1040
|
+
this.applyFog(values.fog);
|
|
1041
|
+
}
|
|
1042
|
+
const lightingSignature = JSON.stringify(values.lighting ?? null);
|
|
1043
|
+
if (lightingSignature !== this.lightingSignature) {
|
|
1044
|
+
this.lightingSignature = lightingSignature;
|
|
1045
|
+
this.applyLighting(values.lighting);
|
|
753
1046
|
}
|
|
754
|
-
this.signature = nextSignature;
|
|
755
|
-
this.applySkybox(environment);
|
|
756
|
-
this.applyFog(environment);
|
|
757
1047
|
}
|
|
758
1048
|
dispose() {
|
|
759
1049
|
this.pendingImageUrl = null;
|
|
760
1050
|
this.disposeActiveTexture();
|
|
1051
|
+
this.clearLighting(false);
|
|
1052
|
+
this.disposed = true;
|
|
761
1053
|
}
|
|
762
1054
|
};
|
|
763
1055
|
__name(_EnvironmentSyncSystem, "EnvironmentSyncSystem");
|
|
764
1056
|
var EnvironmentSyncSystem = _EnvironmentSyncSystem;
|
|
1057
|
+
|
|
1058
|
+
// core/systems/PostprocessingSyncSystem.ts
|
|
765
1059
|
var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
766
|
-
|
|
1060
|
+
/**
|
|
1061
|
+
* @param backend - Builds the chain. When omitted, the world's backend
|
|
1062
|
+
* (`world.getRenderBackend()`) is used.
|
|
1063
|
+
*/
|
|
1064
|
+
constructor(renderer, scene, camera, backend) {
|
|
767
1065
|
this.signature = null;
|
|
1066
|
+
/** Deep copy of the values the current chain reflects. */
|
|
1067
|
+
this.appliedValues = null;
|
|
768
1068
|
this.composer = null;
|
|
769
1069
|
this.composerEnabled = false;
|
|
770
1070
|
this.renderer = renderer;
|
|
771
1071
|
this.scene = scene;
|
|
772
1072
|
this.camera = camera;
|
|
1073
|
+
this.backend = backend ?? null;
|
|
773
1074
|
}
|
|
774
1075
|
setComposerEnabled(enabled) {
|
|
775
1076
|
this.composerEnabled = enabled;
|
|
@@ -779,6 +1080,7 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
779
1080
|
}
|
|
780
1081
|
}
|
|
781
1082
|
disposeComposer() {
|
|
1083
|
+
this.appliedValues = null;
|
|
782
1084
|
if (!this.composer) {
|
|
783
1085
|
this.setComposerEnabled(false);
|
|
784
1086
|
return;
|
|
@@ -793,101 +1095,59 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
793
1095
|
this.composer = null;
|
|
794
1096
|
this.setComposerEnabled(false);
|
|
795
1097
|
}
|
|
796
|
-
|
|
1098
|
+
/** Ask the renderer for tone mapping while the effect is active. */
|
|
1099
|
+
applyToneMapping(values) {
|
|
1100
|
+
const active = Boolean(values?.postEnabled && values.toneMapping.enabled);
|
|
1101
|
+
setRendererToneMappingSource(
|
|
1102
|
+
this.renderer,
|
|
1103
|
+
"postprocessing",
|
|
1104
|
+
active && values ? { exposure: Math.max(0, values.toneMapping.exposure) } : null
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
resolveBackend(world) {
|
|
1108
|
+
return this.backend ?? readWorldRenderBackend(world);
|
|
1109
|
+
}
|
|
1110
|
+
buildComposer(world, values) {
|
|
797
1111
|
this.disposeComposer();
|
|
1112
|
+
this.applyToneMapping(values);
|
|
798
1113
|
if (!values.postEnabled) {
|
|
799
1114
|
return;
|
|
800
1115
|
}
|
|
801
|
-
const composer =
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
);
|
|
811
|
-
}
|
|
812
|
-
if (values.bloom.enabled) {
|
|
813
|
-
const size = this.renderer.getSize(new THREE19.Vector2());
|
|
814
|
-
composer.addPass(
|
|
815
|
-
new UnrealBloomPass(
|
|
816
|
-
new THREE19.Vector2(size.width, size.height),
|
|
817
|
-
values.bloom.intensity,
|
|
818
|
-
values.bloom.radius,
|
|
819
|
-
values.bloom.threshold
|
|
820
|
-
)
|
|
821
|
-
);
|
|
822
|
-
}
|
|
823
|
-
if (values.vignette.enabled) {
|
|
824
|
-
const pass = new ShaderPass(VignetteShader);
|
|
825
|
-
const offset = pass.uniforms.offset;
|
|
826
|
-
const darkness = pass.uniforms.darkness;
|
|
827
|
-
if (offset) {
|
|
828
|
-
offset.value = values.vignette.offset;
|
|
829
|
-
}
|
|
830
|
-
if (darkness) {
|
|
831
|
-
darkness.value = values.vignette.darkness;
|
|
832
|
-
}
|
|
833
|
-
composer.addPass(pass);
|
|
834
|
-
}
|
|
835
|
-
if (values.hueSaturation.enabled) {
|
|
836
|
-
const pass = new ShaderPass(HueSaturationShader);
|
|
837
|
-
const hue = pass.uniforms.hue;
|
|
838
|
-
const saturation = pass.uniforms.saturation;
|
|
839
|
-
if (hue) {
|
|
840
|
-
hue.value = values.hueSaturation.hue;
|
|
841
|
-
}
|
|
842
|
-
if (saturation) {
|
|
843
|
-
saturation.value = values.hueSaturation.saturation;
|
|
844
|
-
}
|
|
845
|
-
composer.addPass(pass);
|
|
846
|
-
}
|
|
847
|
-
if (values.sepia.enabled) {
|
|
848
|
-
const pass = new ShaderPass(SepiaShader);
|
|
849
|
-
const amount = pass.uniforms.amount;
|
|
850
|
-
if (amount) {
|
|
851
|
-
amount.value = values.sepia.intensity;
|
|
852
|
-
}
|
|
853
|
-
composer.addPass(pass);
|
|
854
|
-
}
|
|
855
|
-
if (values.noise.enabled) {
|
|
856
|
-
composer.addPass(new FilmPass(values.noise.opacity));
|
|
857
|
-
}
|
|
858
|
-
if (values.dotScreen.enabled) {
|
|
859
|
-
composer.addPass(
|
|
860
|
-
new DotScreenPass(
|
|
861
|
-
new THREE19.Vector2(0, 0),
|
|
862
|
-
values.dotScreen.angle ?? values.dotScreen.dotScreenAngle,
|
|
863
|
-
values.dotScreen.scale ?? values.dotScreen.dotScreenScale
|
|
864
|
-
)
|
|
865
|
-
);
|
|
866
|
-
}
|
|
867
|
-
if (values.ssao.enabled) {
|
|
868
|
-
const pass = new SSAOPass(this.scene, this.camera);
|
|
869
|
-
pass.kernelRadius = values.ssao.radius;
|
|
870
|
-
pass.minDistance = 1e-3;
|
|
871
|
-
pass.maxDistance = Math.max(0.01, values.ssao.intensity);
|
|
872
|
-
composer.addPass(pass);
|
|
873
|
-
}
|
|
874
|
-
if (values.glitch.enabled) {
|
|
875
|
-
const pass = new GlitchPass();
|
|
876
|
-
pass.enabled = true;
|
|
877
|
-
pass.goWild = Boolean(values.glitch.active);
|
|
878
|
-
composer.addPass(pass);
|
|
1116
|
+
const composer = this.resolveBackend(world).createPostprocessing({
|
|
1117
|
+
renderer: this.renderer,
|
|
1118
|
+
scene: this.scene,
|
|
1119
|
+
camera: this.camera,
|
|
1120
|
+
values,
|
|
1121
|
+
world
|
|
1122
|
+
});
|
|
1123
|
+
if (!composer) {
|
|
1124
|
+
return;
|
|
879
1125
|
}
|
|
880
|
-
composer.addPass(new OutputPass());
|
|
881
1126
|
this.composer = composer;
|
|
1127
|
+
this.appliedValues = structuredCloneValues(values);
|
|
882
1128
|
this.scene.userData.ecsPostprocessingComposer = composer;
|
|
883
1129
|
this.setComposerEnabled(true);
|
|
884
1130
|
}
|
|
1131
|
+
/** Update the existing chain in place; `false` when it must be rebuilt. */
|
|
1132
|
+
tryUpdateInPlace(world, values) {
|
|
1133
|
+
const composer = this.composer;
|
|
1134
|
+
const previous = this.appliedValues;
|
|
1135
|
+
if (!composer || !previous || !values.postEnabled) return false;
|
|
1136
|
+
if (this.scene.userData.ecsPostprocessingComposer !== composer) return false;
|
|
1137
|
+
const backend = this.resolveBackend(world);
|
|
1138
|
+
if (typeof backend.updatePostprocessing !== "function") return false;
|
|
1139
|
+
if (!backend.updatePostprocessing(composer, previous, values)) return false;
|
|
1140
|
+
this.appliedValues = structuredCloneValues(values);
|
|
1141
|
+
this.applyToneMapping(values);
|
|
1142
|
+
return true;
|
|
1143
|
+
}
|
|
885
1144
|
update(world) {
|
|
886
1145
|
const entityIds = world.query(Postprocessing);
|
|
887
1146
|
if (entityIds.length === 0) {
|
|
888
1147
|
if (this.signature !== null) {
|
|
889
1148
|
this.signature = null;
|
|
890
1149
|
this.disposeComposer();
|
|
1150
|
+
this.applyToneMapping(null);
|
|
891
1151
|
delete this.scene.userData.ecsPostprocessing;
|
|
892
1152
|
}
|
|
893
1153
|
return;
|
|
@@ -901,12 +1161,15 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
901
1161
|
return;
|
|
902
1162
|
}
|
|
903
1163
|
this.signature = nextSignature;
|
|
904
|
-
this.
|
|
1164
|
+
if (!this.tryUpdateInPlace(world, postprocessing.values)) {
|
|
1165
|
+
this.buildComposer(world, postprocessing.values);
|
|
1166
|
+
}
|
|
905
1167
|
this.scene.userData.ecsPostprocessing = postprocessing.values;
|
|
906
1168
|
}
|
|
907
1169
|
dispose() {
|
|
908
1170
|
this.signature = null;
|
|
909
1171
|
this.disposeComposer();
|
|
1172
|
+
this.applyToneMapping(null);
|
|
910
1173
|
delete this.scene.userData.ecsPostprocessing;
|
|
911
1174
|
delete this.scene.userData.ecsPostprocessingComposerActive;
|
|
912
1175
|
delete this.scene.userData.ecsPostprocessingComposer;
|
|
@@ -914,6 +1177,10 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
914
1177
|
};
|
|
915
1178
|
__name(_PostprocessingSyncSystem, "PostprocessingSyncSystem");
|
|
916
1179
|
var PostprocessingSyncSystem = _PostprocessingSyncSystem;
|
|
1180
|
+
function structuredCloneValues(values) {
|
|
1181
|
+
return JSON.parse(JSON.stringify(values));
|
|
1182
|
+
}
|
|
1183
|
+
__name(structuredCloneValues, "structuredCloneValues");
|
|
917
1184
|
var MIN_SIZE = 1e-4;
|
|
918
1185
|
function toBodyType(RAPIER, bodyType) {
|
|
919
1186
|
switch (bodyType) {
|
|
@@ -1840,7 +2107,140 @@ var InputSystem = _InputSystem;
|
|
|
1840
2107
|
var MIN_LIGHT_DISTANCE = 0;
|
|
1841
2108
|
var MIN_LIGHT_INTENSITY = 0;
|
|
1842
2109
|
var MIN_AREA_SIZE = 0.01;
|
|
1843
|
-
|
|
2110
|
+
var MIN_SHADOW_MAP_SIZE = 16;
|
|
2111
|
+
var MAX_SHADOW_MAP_SIZE = 8192;
|
|
2112
|
+
var MIN_SHADOW_NEAR = 1e-3;
|
|
2113
|
+
var MIN_SHADOW_CAMERA_SIZE = 0.01;
|
|
2114
|
+
var shadowRecords = /* @__PURE__ */ new WeakMap();
|
|
2115
|
+
function finiteOrUndefined(value) {
|
|
2116
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2117
|
+
}
|
|
2118
|
+
__name(finiteOrUndefined, "finiteOrUndefined");
|
|
2119
|
+
function readShadowRecord(shadow) {
|
|
2120
|
+
let record = shadowRecords.get(shadow);
|
|
2121
|
+
if (!record) {
|
|
2122
|
+
const camera = shadow.camera;
|
|
2123
|
+
record = {
|
|
2124
|
+
baseline: {
|
|
2125
|
+
mapSize: shadow.mapSize.x,
|
|
2126
|
+
bias: shadow.bias,
|
|
2127
|
+
normalBias: shadow.normalBias,
|
|
2128
|
+
radius: shadow.radius,
|
|
2129
|
+
cameraSize: camera.isOrthographicCamera === true && typeof camera.right === "number" ? camera.right : null,
|
|
2130
|
+
near: typeof camera.near === "number" ? camera.near : 0.5,
|
|
2131
|
+
far: typeof camera.far === "number" ? camera.far : 500
|
|
2132
|
+
},
|
|
2133
|
+
applied: /* @__PURE__ */ new Set()
|
|
2134
|
+
};
|
|
2135
|
+
shadowRecords.set(shadow, record);
|
|
2136
|
+
}
|
|
2137
|
+
return record;
|
|
2138
|
+
}
|
|
2139
|
+
__name(readShadowRecord, "readShadowRecord");
|
|
2140
|
+
function resolveShadowField(record, key, provided, fallback) {
|
|
2141
|
+
if (provided !== void 0) {
|
|
2142
|
+
record.applied.add(key);
|
|
2143
|
+
return provided;
|
|
2144
|
+
}
|
|
2145
|
+
if (record.applied.has(key)) {
|
|
2146
|
+
record.applied.delete(key);
|
|
2147
|
+
return fallback;
|
|
2148
|
+
}
|
|
2149
|
+
return void 0;
|
|
2150
|
+
}
|
|
2151
|
+
__name(resolveShadowField, "resolveShadowField");
|
|
2152
|
+
function setShadowMapSize(shadow, size, rendererKind) {
|
|
2153
|
+
if (shadow.mapSize.x === size && shadow.mapSize.y === size) {
|
|
2154
|
+
return;
|
|
2155
|
+
}
|
|
2156
|
+
shadow.mapSize.set(size, size);
|
|
2157
|
+
if (rendererKind === "webgpu") {
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
const map = shadow.map;
|
|
2161
|
+
if (map) {
|
|
2162
|
+
map.depthTexture?.dispose();
|
|
2163
|
+
map.dispose();
|
|
2164
|
+
shadow.map = null;
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
__name(setShadowMapSize, "setShadowMapSize");
|
|
2168
|
+
function applyShadowValues(light, shadowValues, rendererKind) {
|
|
2169
|
+
const shadow = light.shadow;
|
|
2170
|
+
if (!shadow) {
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
const values = shadowValues && typeof shadowValues === "object" ? shadowValues : null;
|
|
2174
|
+
if (!values && !shadowRecords.has(shadow)) {
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
const record = readShadowRecord(shadow);
|
|
2178
|
+
const { baseline } = record;
|
|
2179
|
+
const input = values ?? {};
|
|
2180
|
+
const requestedMapSize = finiteOrUndefined(input.mapSize);
|
|
2181
|
+
const mapSize = resolveShadowField(
|
|
2182
|
+
record,
|
|
2183
|
+
"mapSize",
|
|
2184
|
+
requestedMapSize === void 0 ? void 0 : Math.round(
|
|
2185
|
+
Math.min(MAX_SHADOW_MAP_SIZE, Math.max(MIN_SHADOW_MAP_SIZE, requestedMapSize))
|
|
2186
|
+
),
|
|
2187
|
+
baseline.mapSize
|
|
2188
|
+
);
|
|
2189
|
+
if (mapSize !== void 0) {
|
|
2190
|
+
setShadowMapSize(shadow, mapSize, rendererKind);
|
|
2191
|
+
}
|
|
2192
|
+
const bias = resolveShadowField(record, "bias", finiteOrUndefined(input.bias), baseline.bias);
|
|
2193
|
+
if (bias !== void 0) shadow.bias = bias;
|
|
2194
|
+
const normalBias = resolveShadowField(
|
|
2195
|
+
record,
|
|
2196
|
+
"normalBias",
|
|
2197
|
+
finiteOrUndefined(input.normalBias),
|
|
2198
|
+
baseline.normalBias
|
|
2199
|
+
);
|
|
2200
|
+
if (normalBias !== void 0) shadow.normalBias = normalBias;
|
|
2201
|
+
const radius = resolveShadowField(
|
|
2202
|
+
record,
|
|
2203
|
+
"radius",
|
|
2204
|
+
finiteOrUndefined(input.radius),
|
|
2205
|
+
baseline.radius
|
|
2206
|
+
);
|
|
2207
|
+
if (radius !== void 0) shadow.radius = Math.max(0, radius);
|
|
2208
|
+
const camera = shadow.camera;
|
|
2209
|
+
let cameraChanged = false;
|
|
2210
|
+
if (camera.isOrthographicCamera === true && baseline.cameraSize !== null) {
|
|
2211
|
+
const cameraSize = resolveShadowField(
|
|
2212
|
+
record,
|
|
2213
|
+
"cameraSize",
|
|
2214
|
+
finiteOrUndefined(input.cameraSize),
|
|
2215
|
+
baseline.cameraSize
|
|
2216
|
+
);
|
|
2217
|
+
if (cameraSize !== void 0) {
|
|
2218
|
+
const size = Math.max(MIN_SHADOW_CAMERA_SIZE, cameraSize);
|
|
2219
|
+
camera.left = -size;
|
|
2220
|
+
camera.right = size;
|
|
2221
|
+
camera.top = size;
|
|
2222
|
+
camera.bottom = -size;
|
|
2223
|
+
cameraChanged = true;
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
const near = resolveShadowField(record, "near", finiteOrUndefined(input.near), baseline.near);
|
|
2227
|
+
if (near !== void 0) {
|
|
2228
|
+
camera.near = Math.max(MIN_SHADOW_NEAR, near);
|
|
2229
|
+
cameraChanged = true;
|
|
2230
|
+
}
|
|
2231
|
+
const far = resolveShadowField(record, "far", finiteOrUndefined(input.far), baseline.far);
|
|
2232
|
+
if (far !== void 0) {
|
|
2233
|
+
const currentNear = typeof camera.near === "number" ? camera.near : MIN_SHADOW_NEAR;
|
|
2234
|
+
camera.far = Math.max(currentNear + MIN_SHADOW_NEAR, far);
|
|
2235
|
+
cameraChanged = true;
|
|
2236
|
+
}
|
|
2237
|
+
if (cameraChanged) {
|
|
2238
|
+
camera.updateProjectionMatrix?.();
|
|
2239
|
+
}
|
|
2240
|
+
shadow.needsUpdate = true;
|
|
2241
|
+
}
|
|
2242
|
+
__name(applyShadowValues, "applyShadowValues");
|
|
2243
|
+
function applyLightValues(lightComponent, rendererKind) {
|
|
1844
2244
|
const { light, values } = lightComponent;
|
|
1845
2245
|
if (typeof values.color === "string") {
|
|
1846
2246
|
light.color.set(values.color);
|
|
@@ -1884,6 +2284,7 @@ function applyLightValues(lightComponent) {
|
|
|
1884
2284
|
light.height = Math.max(MIN_AREA_SIZE, values.height);
|
|
1885
2285
|
}
|
|
1886
2286
|
}
|
|
2287
|
+
applyShadowValues(light, values.shadow, rendererKind);
|
|
1887
2288
|
}
|
|
1888
2289
|
__name(applyLightValues, "applyLightValues");
|
|
1889
2290
|
var _LightSyncSystem = class _LightSyncSystem {
|
|
@@ -1892,6 +2293,7 @@ var _LightSyncSystem = class _LightSyncSystem {
|
|
|
1892
2293
|
}
|
|
1893
2294
|
update(world) {
|
|
1894
2295
|
const entityIds = world.query(LightComponent);
|
|
2296
|
+
let rendererKind = null;
|
|
1895
2297
|
const alive = new Set(entityIds);
|
|
1896
2298
|
for (const trackedId of this.signatures.keys()) {
|
|
1897
2299
|
if (!alive.has(trackedId)) {
|
|
@@ -1907,7 +2309,8 @@ var _LightSyncSystem = class _LightSyncSystem {
|
|
|
1907
2309
|
if (this.signatures.get(entityId) === signature) {
|
|
1908
2310
|
continue;
|
|
1909
2311
|
}
|
|
1910
|
-
|
|
2312
|
+
rendererKind ?? (rendererKind = readWorldRendererKind(world));
|
|
2313
|
+
applyLightValues(lightComponent, rendererKind);
|
|
1911
2314
|
this.signatures.set(entityId, signature);
|
|
1912
2315
|
}
|
|
1913
2316
|
}
|
|
@@ -2356,14 +2759,7 @@ __name(_MeshGeometrySystem, "MeshGeometrySystem");
|
|
|
2356
2759
|
var MeshGeometrySystem = _MeshGeometrySystem;
|
|
2357
2760
|
var loadGLTF = /* @__PURE__ */ __name((path) => {
|
|
2358
2761
|
return new Promise((resolve, reject) => {
|
|
2359
|
-
const loader =
|
|
2360
|
-
try {
|
|
2361
|
-
const dracoLoader = new DRACOLoader();
|
|
2362
|
-
dracoLoader.setDecoderPath(resolveDracoDecoderPath());
|
|
2363
|
-
loader.setDRACOLoader(dracoLoader);
|
|
2364
|
-
} catch (error) {
|
|
2365
|
-
console.debug("DRACOLoader setup failed or unavailable", error);
|
|
2366
|
-
}
|
|
2762
|
+
const loader = createGLTFLoader();
|
|
2367
2763
|
loader.load(
|
|
2368
2764
|
path,
|
|
2369
2765
|
(gltf) => {
|
|
@@ -2663,2688 +3059,94 @@ var _InstancedMeshSystem = class _InstancedMeshSystem {
|
|
|
2663
3059
|
im.setMatrixAt(i, _matrix);
|
|
2664
3060
|
}
|
|
2665
3061
|
im.instanceMatrix.needsUpdate = true;
|
|
2666
|
-
im.castShadow = comp.castShadow;
|
|
2667
|
-
im.receiveShadow = comp.receiveShadow;
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
}
|
|
2672
|
-
};
|
|
2673
|
-
__name(_InstancedMeshSystem, "InstancedMeshSystem");
|
|
2674
|
-
var InstancedMeshSystem = _InstancedMeshSystem;
|
|
2675
|
-
|
|
2676
|
-
// core/systems/RenderSystem.ts
|
|
2677
|
-
var _RenderSystem = class _RenderSystem {
|
|
2678
|
-
constructor(renderer, scene, camera, afterRender) {
|
|
2679
|
-
this.renderer = renderer;
|
|
2680
|
-
this.scene = scene;
|
|
2681
|
-
this.camera = camera;
|
|
2682
|
-
this.afterRender = afterRender;
|
|
2683
|
-
}
|
|
2684
|
-
update(_world) {
|
|
2685
|
-
if (this.scene.userData.ecsPostprocessingComposerActive === true) {
|
|
2686
|
-
const composer = this.scene.userData.ecsPostprocessingComposer;
|
|
2687
|
-
if (composer) {
|
|
2688
|
-
const width = Math.max(1, this.renderer.domElement.clientWidth);
|
|
2689
|
-
const height = Math.max(1, this.renderer.domElement.clientHeight);
|
|
2690
|
-
composer.setSize(width, height);
|
|
2691
|
-
composer.render();
|
|
2692
|
-
} else {
|
|
2693
|
-
this.renderer.render(this.scene, this.camera);
|
|
2694
|
-
}
|
|
2695
|
-
this.afterRender?.();
|
|
2696
|
-
return;
|
|
2697
|
-
}
|
|
2698
|
-
this.renderer.render(this.scene, this.camera);
|
|
2699
|
-
this.afterRender?.();
|
|
2700
|
-
}
|
|
2701
|
-
};
|
|
2702
|
-
__name(_RenderSystem, "RenderSystem");
|
|
2703
|
-
var RenderSystem = _RenderSystem;
|
|
2704
|
-
|
|
2705
|
-
// core/prefab/collectEntitySubtree.ts
|
|
2706
|
-
function collectEntitySubtree(world, rootIds) {
|
|
2707
|
-
const childrenByParent = /* @__PURE__ */ new Map();
|
|
2708
|
-
for (const entityId of world.query(ParentId)) {
|
|
2709
|
-
const parentId = world.getComponent(entityId, ParentId)?.value;
|
|
2710
|
-
if (parentId === null || parentId === void 0) {
|
|
2711
|
-
continue;
|
|
2712
|
-
}
|
|
2713
|
-
const siblings = childrenByParent.get(parentId);
|
|
2714
|
-
if (siblings) {
|
|
2715
|
-
siblings.push(entityId);
|
|
2716
|
-
} else {
|
|
2717
|
-
childrenByParent.set(parentId, [entityId]);
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
const ordered = [];
|
|
2721
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2722
|
-
const queue = [...rootIds];
|
|
2723
|
-
while (queue.length > 0) {
|
|
2724
|
-
const entityId = queue.shift();
|
|
2725
|
-
if (seen.has(entityId)) {
|
|
2726
|
-
continue;
|
|
2727
|
-
}
|
|
2728
|
-
seen.add(entityId);
|
|
2729
|
-
ordered.push(entityId);
|
|
2730
|
-
const children = childrenByParent.get(entityId);
|
|
2731
|
-
if (children) {
|
|
2732
|
-
queue.push(...children.sort((a, b) => a - b));
|
|
2733
|
-
}
|
|
2734
|
-
}
|
|
2735
|
-
return ordered;
|
|
2736
|
-
}
|
|
2737
|
-
__name(collectEntitySubtree, "collectEntitySubtree");
|
|
2738
|
-
|
|
2739
|
-
// core/hydration/readers.ts
|
|
2740
|
-
function asRecord(value) {
|
|
2741
|
-
if (!value || typeof value !== "object") {
|
|
2742
|
-
return null;
|
|
2743
|
-
}
|
|
2744
|
-
return value;
|
|
2745
|
-
}
|
|
2746
|
-
__name(asRecord, "asRecord");
|
|
2747
|
-
function readString(value) {
|
|
2748
|
-
if (typeof value === "string") {
|
|
2749
|
-
return value;
|
|
2750
|
-
}
|
|
2751
|
-
const record = asRecord(value);
|
|
2752
|
-
if (!record) {
|
|
2753
|
-
return null;
|
|
2754
|
-
}
|
|
2755
|
-
return typeof record.value === "string" ? record.value : null;
|
|
2756
|
-
}
|
|
2757
|
-
__name(readString, "readString");
|
|
2758
|
-
function readTransform(value) {
|
|
2759
|
-
const record = asRecord(value);
|
|
2760
|
-
if (!record) {
|
|
2761
|
-
return void 0;
|
|
2762
|
-
}
|
|
2763
|
-
const position = asRecord(record.position);
|
|
2764
|
-
const rotation = asRecord(record.rotation);
|
|
2765
|
-
const scale = asRecord(record.scale);
|
|
2766
|
-
return {
|
|
2767
|
-
position: position ? {
|
|
2768
|
-
x: typeof position.x === "number" ? position.x : void 0,
|
|
2769
|
-
y: typeof position.y === "number" ? position.y : void 0,
|
|
2770
|
-
z: typeof position.z === "number" ? position.z : void 0
|
|
2771
|
-
} : void 0,
|
|
2772
|
-
rotation: rotation ? {
|
|
2773
|
-
x: typeof rotation.x === "number" ? rotation.x : void 0,
|
|
2774
|
-
y: typeof rotation.y === "number" ? rotation.y : void 0,
|
|
2775
|
-
z: typeof rotation.z === "number" ? rotation.z : void 0
|
|
2776
|
-
} : void 0,
|
|
2777
|
-
scale: scale ? {
|
|
2778
|
-
x: typeof scale.x === "number" ? scale.x : void 0,
|
|
2779
|
-
y: typeof scale.y === "number" ? scale.y : void 0,
|
|
2780
|
-
z: typeof scale.z === "number" ? scale.z : void 0
|
|
2781
|
-
} : void 0
|
|
2782
|
-
};
|
|
2783
|
-
}
|
|
2784
|
-
__name(readTransform, "readTransform");
|
|
2785
|
-
function readByComponent(components, componentName) {
|
|
2786
|
-
const component = components.find((entry) => entry.component === componentName);
|
|
2787
|
-
const map = /* @__PURE__ */ new Map();
|
|
2788
|
-
if (!component) {
|
|
2789
|
-
return map;
|
|
2790
|
-
}
|
|
2791
|
-
for (const entry of component.entries) {
|
|
2792
|
-
map.set(entry.entityId, entry.value);
|
|
2793
|
-
}
|
|
2794
|
-
return map;
|
|
2795
|
-
}
|
|
2796
|
-
__name(readByComponent, "readByComponent");
|
|
2797
|
-
function readBoolean(value) {
|
|
2798
|
-
return typeof value === "boolean" ? value : void 0;
|
|
2799
|
-
}
|
|
2800
|
-
__name(readBoolean, "readBoolean");
|
|
2801
|
-
function readNumber(value) {
|
|
2802
|
-
return typeof value === "number" ? value : void 0;
|
|
2803
|
-
}
|
|
2804
|
-
__name(readNumber, "readNumber");
|
|
2805
|
-
|
|
2806
|
-
// core/hydration/componentValues.ts
|
|
2807
|
-
function buildComponentValueMaps(snapshot) {
|
|
2808
|
-
return {
|
|
2809
|
-
object3DRefValues: readByComponent(snapshot.components, "Object3DRef"),
|
|
2810
|
-
nameValues: readByComponent(snapshot.components, "Name"),
|
|
2811
|
-
transformValues: readByComponent(snapshot.components, "TransformComponent"),
|
|
2812
|
-
modelValues: readByComponent(snapshot.components, "ModelComponent"),
|
|
2813
|
-
imageValues: readByComponent(snapshot.components, "ImageComponent"),
|
|
2814
|
-
spriteValues: readByComponent(snapshot.components, "SpriteComponent"),
|
|
2815
|
-
videoValues: readByComponent(snapshot.components, "VideoComponent"),
|
|
2816
|
-
cameraValues: readByComponent(snapshot.components, "CameraComponent"),
|
|
2817
|
-
environmentValues: readByComponent(snapshot.components, "Environment"),
|
|
2818
|
-
postprocessingValues: readByComponent(snapshot.components, "Postprocessing"),
|
|
2819
|
-
audioValues: readByComponent(snapshot.components, "AudioComponent"),
|
|
2820
|
-
imageTargetValues: readByComponent(snapshot.components, "ImageTarget"),
|
|
2821
|
-
lightValues: readByComponent(snapshot.components, "LightComponent"),
|
|
2822
|
-
materialValues: readByComponent(snapshot.components, "MaterialComponent"),
|
|
2823
|
-
meshGeometryValues: readByComponent(snapshot.components, "MeshGeometryComponent"),
|
|
2824
|
-
selectableValues: readByComponent(snapshot.components, "Selectable"),
|
|
2825
|
-
physicsValues: readByComponent(snapshot.components, "PhysicsComponent"),
|
|
2826
|
-
animationValues: readByComponent(snapshot.components, "AnimationComponent"),
|
|
2827
|
-
imageTargetAnchorValues: readByComponent(snapshot.components, "ImageTargetAnchor"),
|
|
2828
|
-
scriptValues: readByComponent(snapshot.components, "ScriptComponent"),
|
|
2829
|
-
scriptObjectValues: readByComponent(
|
|
2830
|
-
snapshot.components,
|
|
2831
|
-
"ScriptObjectComponent"
|
|
2832
|
-
),
|
|
2833
|
-
xrRigValues: readByComponent(snapshot.components, "XRRigComponent"),
|
|
2834
|
-
vrTeleportAreaValues: readByComponent(
|
|
2835
|
-
snapshot.components,
|
|
2836
|
-
"VRTeleportAreaComponent"
|
|
2837
|
-
),
|
|
2838
|
-
xrInteractableValues: readByComponent(
|
|
2839
|
-
snapshot.components,
|
|
2840
|
-
"XRInteractableComponent"
|
|
2841
|
-
),
|
|
2842
|
-
xrInteractorValues: readByComponent(
|
|
2843
|
-
snapshot.components,
|
|
2844
|
-
"XRInteractorComponent"
|
|
2845
|
-
),
|
|
2846
|
-
xrHandPoseValues: readByComponent(
|
|
2847
|
-
snapshot.components,
|
|
2848
|
-
"XRHandPoseComponent"
|
|
2849
|
-
),
|
|
2850
|
-
xrAnchorValues: readByComponent(snapshot.components, "XRAnchorComponent"),
|
|
2851
|
-
uiPanelValues: readByComponent(snapshot.components, "UIPanelComponent"),
|
|
2852
|
-
uiTextValues: readByComponent(snapshot.components, "UITextComponent"),
|
|
2853
|
-
uiButtonValues: readByComponent(snapshot.components, "UIButtonComponent"),
|
|
2854
|
-
uiToggleValues: readByComponent(snapshot.components, "UIToggleComponent"),
|
|
2855
|
-
uiSliderValues: readByComponent(snapshot.components, "UISliderComponent"),
|
|
2856
|
-
xrInteractorSideValues: readByComponent(
|
|
2857
|
-
snapshot.components,
|
|
2858
|
-
"XRInteractorSideComponent"
|
|
2859
|
-
),
|
|
2860
|
-
instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
|
|
2861
|
-
instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent"),
|
|
2862
|
-
prefabNodeValues: readByComponent(snapshot.components, "PrefabNode"),
|
|
2863
|
-
prefabInstanceValues: readByComponent(snapshot.components, "PrefabInstance")
|
|
2864
|
-
};
|
|
2865
|
-
}
|
|
2866
|
-
__name(buildComponentValueMaps, "buildComponentValueMaps");
|
|
2867
|
-
|
|
2868
|
-
// core/hydration/parentLinks.ts
|
|
2869
|
-
function applyParentLinks(snapshot, idMap, objectManagementSystem, world) {
|
|
2870
|
-
const parentValues = readByComponent(snapshot.components, "ParentId");
|
|
2871
|
-
for (const [sourceEntityId, parentValue] of parentValues.entries()) {
|
|
2872
|
-
const targetEntityId = idMap.get(sourceEntityId);
|
|
2873
|
-
if (targetEntityId === void 0) {
|
|
2874
|
-
continue;
|
|
2875
|
-
}
|
|
2876
|
-
const parentRecord = asRecord(parentValue);
|
|
2877
|
-
const sourceParentId = parentRecord && typeof parentRecord.value === "number" ? parentRecord.value : null;
|
|
2878
|
-
if (sourceParentId === null) {
|
|
2879
|
-
objectManagementSystem.setParent(world, targetEntityId, null, {
|
|
2880
|
-
preserveWorldTransform: false
|
|
2881
|
-
});
|
|
2882
|
-
continue;
|
|
2883
|
-
}
|
|
2884
|
-
const mappedParentId = idMap.get(sourceParentId);
|
|
2885
|
-
objectManagementSystem.setParent(world, targetEntityId, mappedParentId ?? null, {
|
|
2886
|
-
preserveWorldTransform: false
|
|
2887
|
-
});
|
|
2888
|
-
}
|
|
2889
|
-
}
|
|
2890
|
-
__name(applyParentLinks, "applyParentLinks");
|
|
2891
|
-
|
|
2892
|
-
// core/hydration/postCreateComponents.ts
|
|
2893
|
-
function remapEntityRefsInScriptData(data, idMap) {
|
|
2894
|
-
const result = {};
|
|
2895
|
-
for (const [key, value] of Object.entries(data)) {
|
|
2896
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
2897
|
-
const v = value;
|
|
2898
|
-
if (v.type === "entity" && typeof v.value === "number") {
|
|
2899
|
-
result[key] = { ...v, value: idMap.get(v.value) ?? v.value };
|
|
2900
|
-
} else if (v.type === "component" && v.value !== null && typeof v.value === "object" && !Array.isArray(v.value) && typeof v.value.entityId === "number") {
|
|
2901
|
-
const ref = v.value;
|
|
2902
|
-
result[key] = {
|
|
2903
|
-
...v,
|
|
2904
|
-
value: { ...ref, entityId: idMap.get(ref.entityId) ?? ref.entityId }
|
|
2905
|
-
};
|
|
2906
|
-
} else {
|
|
2907
|
-
result[key] = value;
|
|
2908
|
-
}
|
|
2909
|
-
} else {
|
|
2910
|
-
result[key] = value;
|
|
2911
|
-
}
|
|
2912
|
-
}
|
|
2913
|
-
return result;
|
|
2914
|
-
}
|
|
2915
|
-
__name(remapEntityRefsInScriptData, "remapEntityRefsInScriptData");
|
|
2916
|
-
function restorePostCreateComponents(world, objectManagementSystem, targetEntityId, sourceEntityId, entityType, values, idMap) {
|
|
2917
|
-
const objectRef = world.getComponent(targetEntityId, Object3DRef)?.object ?? null;
|
|
2918
|
-
const sourceAudio = asRecord(values.audioValues.get(sourceEntityId));
|
|
2919
|
-
if (sourceAudio && entityType !== "audio") {
|
|
2920
|
-
const sourceOptions = asRecord(sourceAudio.options) ?? {};
|
|
2921
|
-
objectManagementSystem.createComponentNow(
|
|
2922
|
-
"audio",
|
|
2923
|
-
world,
|
|
2924
|
-
targetEntityId,
|
|
2925
|
-
typeof sourceAudio.path === "string" ? sourceAudio.path : "",
|
|
2926
|
-
sourceOptions,
|
|
2927
|
-
{
|
|
2928
|
-
object: objectRef,
|
|
2929
|
-
listener: objectManagementSystem.getOrCreateAudioListener(),
|
|
2930
|
-
isEditor: objectManagementSystem.isEditorMode()
|
|
2931
|
-
}
|
|
2932
|
-
);
|
|
2933
|
-
}
|
|
2934
|
-
const sourceImageTarget = asRecord(values.imageTargetValues.get(sourceEntityId));
|
|
2935
|
-
if (sourceImageTarget && entityType !== "imageTarget") {
|
|
2936
|
-
objectManagementSystem.createComponentNow(
|
|
2937
|
-
"imageTarget",
|
|
2938
|
-
world,
|
|
2939
|
-
targetEntityId,
|
|
2940
|
-
{
|
|
2941
|
-
targets: Array.isArray(sourceImageTarget.targets) ? sourceImageTarget.targets : [],
|
|
2942
|
-
compiledTargetUrl: typeof sourceImageTarget.compiledTargetUrl === "string" ? sourceImageTarget.compiledTargetUrl : void 0,
|
|
2943
|
-
compiledTargetDir: typeof sourceImageTarget.compiledTargetDir === "string" ? sourceImageTarget.compiledTargetDir : void 0
|
|
2944
|
-
}
|
|
2945
|
-
);
|
|
2946
|
-
}
|
|
2947
|
-
const sourceImageTargetAnchor = asRecord(values.imageTargetAnchorValues.get(sourceEntityId));
|
|
2948
|
-
if (sourceImageTargetAnchor) {
|
|
2949
|
-
const mappedTargetId = typeof sourceImageTargetAnchor.targetId === "number" && Number.isFinite(sourceImageTargetAnchor.targetId) ? sourceImageTargetAnchor.targetId : null;
|
|
2950
|
-
objectManagementSystem.createComponentNow("imageTargetAnchor", world, targetEntityId, {
|
|
2951
|
-
targetId: mappedTargetId,
|
|
2952
|
-
targetUrl: typeof sourceImageTargetAnchor.targetUrl === "string" ? sourceImageTargetAnchor.targetUrl : void 0
|
|
2953
|
-
});
|
|
2954
|
-
}
|
|
2955
|
-
const sourceScript = asRecord(values.scriptValues.get(sourceEntityId));
|
|
2956
|
-
if (sourceScript) {
|
|
2957
|
-
const entries = Array.isArray(sourceScript.entries) ? sourceScript.entries.map((entry) => asRecord(entry)).filter((entry) => Boolean(entry)).map((entry) => {
|
|
2958
|
-
const runtimeState = entry.runtimeState === "idle" || entry.runtimeState === "loading" || entry.runtimeState === "ready" || entry.runtimeState === "error" ? entry.runtimeState : void 0;
|
|
2959
|
-
return {
|
|
2960
|
-
entityId: targetEntityId,
|
|
2961
|
-
className: typeof entry.className === "string" ? entry.className : "",
|
|
2962
|
-
scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
|
|
2963
|
-
enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
|
|
2964
|
-
data: entry.data && typeof entry.data === "object" && !Array.isArray(entry.data) ? remapEntityRefsInScriptData(entry.data, idMap) : {},
|
|
2965
|
-
runtimeState,
|
|
2966
|
-
runtimeMessage: typeof entry.runtimeMessage === "string" ? entry.runtimeMessage : void 0
|
|
2967
|
-
};
|
|
2968
|
-
}).filter((entry) => entry.className || entry.scriptUrl) : [];
|
|
2969
|
-
if (entries.length) {
|
|
2970
|
-
world.addComponent(targetEntityId, new ScriptComponent(entries));
|
|
2971
|
-
}
|
|
2972
|
-
}
|
|
2973
|
-
const sourceScriptObject = asRecord(values.scriptObjectValues.get(sourceEntityId));
|
|
2974
|
-
if (sourceScriptObject) {
|
|
2975
|
-
const soc = world.getComponent(targetEntityId, ScriptObjectComponent);
|
|
2976
|
-
const data = asRecord(sourceScriptObject.data);
|
|
2977
|
-
if (soc && data) {
|
|
2978
|
-
soc.data = remapEntityRefsInScriptData(data, idMap);
|
|
2979
|
-
}
|
|
2980
|
-
}
|
|
2981
|
-
{
|
|
2982
|
-
const sourceXrRig = asRecord(values.xrRigValues.get(sourceEntityId));
|
|
2983
|
-
const rig = world.getComponent(targetEntityId, XRRigComponent);
|
|
2984
|
-
if (sourceXrRig && rig) {
|
|
2985
|
-
if (typeof sourceXrRig.locomotion === "string") {
|
|
2986
|
-
rig.locomotion = sourceXrRig.locomotion;
|
|
2987
|
-
}
|
|
2988
|
-
if (typeof sourceXrRig.moveSpeed === "number") {
|
|
2989
|
-
rig.moveSpeed = sourceXrRig.moveSpeed;
|
|
2990
|
-
}
|
|
2991
|
-
if (typeof sourceXrRig.snapTurn === "boolean") {
|
|
2992
|
-
rig.snapTurn = sourceXrRig.snapTurn;
|
|
2993
|
-
}
|
|
2994
|
-
if (typeof sourceXrRig.snapTurnDegrees === "number") {
|
|
2995
|
-
rig.snapTurnDegrees = sourceXrRig.snapTurnDegrees;
|
|
2996
|
-
}
|
|
2997
|
-
if (typeof sourceXrRig.teleportArcColor === "string") {
|
|
2998
|
-
rig.teleportArcColor = sourceXrRig.teleportArcColor;
|
|
2999
|
-
}
|
|
3000
|
-
if (typeof sourceXrRig.teleportArcInvalidColor === "string") {
|
|
3001
|
-
rig.teleportArcInvalidColor = sourceXrRig.teleportArcInvalidColor;
|
|
3002
|
-
}
|
|
3003
|
-
if (typeof sourceXrRig.teleportArcThickness === "number") {
|
|
3004
|
-
rig.teleportArcThickness = sourceXrRig.teleportArcThickness;
|
|
3005
|
-
}
|
|
3006
|
-
if (typeof sourceXrRig.fallbackEyeHeight === "number") {
|
|
3007
|
-
rig.fallbackEyeHeight = sourceXrRig.fallbackEyeHeight;
|
|
3008
|
-
}
|
|
3009
|
-
if (typeof sourceXrRig.passthrough === "boolean") {
|
|
3010
|
-
rig.passthrough = sourceXrRig.passthrough;
|
|
3011
|
-
}
|
|
3012
|
-
if (typeof sourceXrRig.depthOcclusion === "boolean") {
|
|
3013
|
-
rig.depthOcclusion = sourceXrRig.depthOcclusion;
|
|
3014
|
-
}
|
|
3015
|
-
if (typeof sourceXrRig.environmentPhysics === "string") {
|
|
3016
|
-
rig.environmentPhysics = sourceXrRig.environmentPhysics;
|
|
3017
|
-
}
|
|
3018
|
-
if (typeof sourceXrRig.environmentDebug === "boolean") {
|
|
3019
|
-
rig.environmentDebug = sourceXrRig.environmentDebug;
|
|
3020
|
-
}
|
|
3021
|
-
if (typeof sourceXrRig.hitTest === "boolean") {
|
|
3022
|
-
rig.hitTest = sourceXrRig.hitTest;
|
|
3023
|
-
}
|
|
3024
|
-
if (typeof sourceXrRig.anchors === "boolean") {
|
|
3025
|
-
rig.anchors = sourceXrRig.anchors;
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
}
|
|
3029
|
-
{
|
|
3030
|
-
const sourceArea = asRecord(values.vrTeleportAreaValues.get(sourceEntityId));
|
|
3031
|
-
const area = world.getComponent(targetEntityId, VRTeleportAreaComponent);
|
|
3032
|
-
if (sourceArea && area) {
|
|
3033
|
-
if (typeof sourceArea.enabled === "boolean") {
|
|
3034
|
-
area.enabled = sourceArea.enabled;
|
|
3035
|
-
}
|
|
3036
|
-
if (typeof sourceArea.shape === "string") {
|
|
3037
|
-
area.shape = sourceArea.shape === "cylinder" ? "circle" : sourceArea.shape;
|
|
3038
|
-
}
|
|
3039
|
-
if (typeof sourceArea.width === "number") area.width = sourceArea.width;
|
|
3040
|
-
if (typeof sourceArea.depth === "number") area.depth = sourceArea.depth;
|
|
3041
|
-
}
|
|
3042
|
-
}
|
|
3043
|
-
{
|
|
3044
|
-
const sourceInteractable = asRecord(
|
|
3045
|
-
values.xrInteractableValues.get(sourceEntityId)
|
|
3046
|
-
);
|
|
3047
|
-
let interactable = world.getComponent(
|
|
3048
|
-
targetEntityId,
|
|
3049
|
-
XRInteractableComponent
|
|
3050
|
-
);
|
|
3051
|
-
if (sourceInteractable && !interactable) {
|
|
3052
|
-
interactable = new XRInteractableComponent();
|
|
3053
|
-
world.addComponent(targetEntityId, interactable);
|
|
3054
|
-
}
|
|
3055
|
-
if (sourceInteractable && interactable) {
|
|
3056
|
-
if (typeof sourceInteractable.enabled === "boolean") {
|
|
3057
|
-
interactable.enabled = sourceInteractable.enabled;
|
|
3058
|
-
}
|
|
3059
|
-
if (typeof sourceInteractable.grabbable === "boolean") {
|
|
3060
|
-
interactable.grabbable = sourceInteractable.grabbable;
|
|
3061
|
-
}
|
|
3062
|
-
if (typeof sourceInteractable.pointable === "boolean") {
|
|
3063
|
-
interactable.pointable = sourceInteractable.pointable;
|
|
3064
|
-
}
|
|
3065
|
-
if (typeof sourceInteractable.grabReach === "string") {
|
|
3066
|
-
interactable.grabReach = sourceInteractable.grabReach;
|
|
3067
|
-
}
|
|
3068
|
-
if (typeof sourceInteractable.distanceBehavior === "string") {
|
|
3069
|
-
interactable.distanceBehavior = sourceInteractable.distanceBehavior;
|
|
3070
|
-
}
|
|
3071
|
-
if (typeof sourceInteractable.grabGesture === "string") {
|
|
3072
|
-
interactable.grabGesture = sourceInteractable.grabGesture;
|
|
3073
|
-
}
|
|
3074
|
-
if (typeof sourceInteractable.grabRadius === "number") {
|
|
3075
|
-
interactable.grabRadius = sourceInteractable.grabRadius;
|
|
3076
|
-
}
|
|
3077
|
-
if (typeof sourceInteractable.grabHands === "string") {
|
|
3078
|
-
interactable.grabHands = sourceInteractable.grabHands;
|
|
3079
|
-
}
|
|
3080
|
-
if (typeof sourceInteractable.twoHandRotation === "string") {
|
|
3081
|
-
interactable.twoHandRotation = sourceInteractable.twoHandRotation;
|
|
3082
|
-
}
|
|
3083
|
-
if (typeof sourceInteractable.allowTwoHandScale === "boolean") {
|
|
3084
|
-
interactable.allowTwoHandScale = sourceInteractable.allowTwoHandScale;
|
|
3085
|
-
}
|
|
3086
|
-
if (typeof sourceInteractable.minScale === "number") {
|
|
3087
|
-
interactable.minScale = sourceInteractable.minScale;
|
|
3088
|
-
}
|
|
3089
|
-
if (typeof sourceInteractable.maxScale === "number") {
|
|
3090
|
-
interactable.maxScale = sourceInteractable.maxScale;
|
|
3091
|
-
}
|
|
3092
|
-
if (Array.isArray(sourceInteractable.attachPoints)) {
|
|
3093
|
-
interactable.attachPoints = sourceInteractable.attachPoints.map((point) => asRecord(point)).filter(
|
|
3094
|
-
(point) => point !== null && typeof point.id === "string"
|
|
3095
|
-
).map(
|
|
3096
|
-
(point) => createAttachPoint(
|
|
3097
|
-
point
|
|
3098
|
-
)
|
|
3099
|
-
);
|
|
3100
|
-
}
|
|
3101
|
-
if (typeof sourceInteractable.applyVelocityOnRelease === "boolean") {
|
|
3102
|
-
interactable.applyVelocityOnRelease = sourceInteractable.applyVelocityOnRelease;
|
|
3103
|
-
} else if (typeof sourceInteractable.throwOnRelease === "boolean") {
|
|
3104
|
-
interactable.applyVelocityOnRelease = sourceInteractable.throwOnRelease;
|
|
3105
|
-
}
|
|
3106
|
-
if (typeof sourceInteractable.velocityScale === "number") {
|
|
3107
|
-
interactable.velocityScale = sourceInteractable.velocityScale;
|
|
3108
|
-
} else if (typeof sourceInteractable.throwStrength === "number") {
|
|
3109
|
-
interactable.velocityScale = sourceInteractable.throwStrength;
|
|
3110
|
-
}
|
|
3111
|
-
const grabPos = asRecord(sourceInteractable.grabOffsetPosition);
|
|
3112
|
-
if (grabPos) {
|
|
3113
|
-
interactable.grabOffsetPosition = {
|
|
3114
|
-
x: typeof grabPos.x === "number" ? grabPos.x : 0,
|
|
3115
|
-
y: typeof grabPos.y === "number" ? grabPos.y : 0,
|
|
3116
|
-
z: typeof grabPos.z === "number" ? grabPos.z : 0
|
|
3117
|
-
};
|
|
3118
|
-
}
|
|
3119
|
-
const grabRot = asRecord(sourceInteractable.grabOffsetRotation);
|
|
3120
|
-
if (grabRot) {
|
|
3121
|
-
interactable.grabOffsetRotation = {
|
|
3122
|
-
x: typeof grabRot.x === "number" ? grabRot.x : 0,
|
|
3123
|
-
y: typeof grabRot.y === "number" ? grabRot.y : 0,
|
|
3124
|
-
z: typeof grabRot.z === "number" ? grabRot.z : 0
|
|
3125
|
-
};
|
|
3126
|
-
}
|
|
3127
|
-
if (typeof sourceInteractable.hoverBehavior === "string") {
|
|
3128
|
-
interactable.hoverBehavior = sourceInteractable.hoverBehavior;
|
|
3129
|
-
} else if (sourceInteractable.highlightOnHover === false) {
|
|
3130
|
-
interactable.hoverBehavior = "none";
|
|
3131
|
-
}
|
|
3132
|
-
if (typeof sourceInteractable.hoverColor === "string") {
|
|
3133
|
-
interactable.hoverColor = sourceInteractable.hoverColor;
|
|
3134
|
-
}
|
|
3135
|
-
if (typeof sourceInteractable.hoverScale === "number") {
|
|
3136
|
-
interactable.hoverScale = sourceInteractable.hoverScale;
|
|
3137
|
-
}
|
|
3138
|
-
}
|
|
3139
|
-
}
|
|
3140
|
-
{
|
|
3141
|
-
const sourceHandPose = asRecord(
|
|
3142
|
-
values.xrHandPoseValues.get(sourceEntityId)
|
|
3143
|
-
);
|
|
3144
|
-
let handPose = world.getComponent(targetEntityId, XRHandPoseComponent);
|
|
3145
|
-
if (sourceHandPose && !handPose) {
|
|
3146
|
-
handPose = new XRHandPoseComponent();
|
|
3147
|
-
world.addComponent(targetEntityId, handPose);
|
|
3148
|
-
}
|
|
3149
|
-
if (sourceHandPose && handPose) {
|
|
3150
|
-
if (typeof sourceHandPose.enabled === "boolean") {
|
|
3151
|
-
handPose.enabled = sourceHandPose.enabled;
|
|
3152
|
-
}
|
|
3153
|
-
if (Array.isArray(sourceHandPose.poses)) {
|
|
3154
|
-
handPose.poses = sourceHandPose.poses.map((entry) => asRecord(entry)).filter(
|
|
3155
|
-
(entry) => entry !== null && typeof entry.id === "string"
|
|
3156
|
-
).map(
|
|
3157
|
-
(entry) => createHandPoseEntry(
|
|
3158
|
-
entry
|
|
3159
|
-
)
|
|
3160
|
-
);
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
}
|
|
3164
|
-
{
|
|
3165
|
-
const sourceAnchor = asRecord(values.xrAnchorValues.get(sourceEntityId));
|
|
3166
|
-
let anchor = world.getComponent(targetEntityId, XRAnchorComponent);
|
|
3167
|
-
if (sourceAnchor && !anchor) {
|
|
3168
|
-
anchor = new XRAnchorComponent();
|
|
3169
|
-
world.addComponent(targetEntityId, anchor);
|
|
3170
|
-
}
|
|
3171
|
-
if (sourceAnchor && anchor) {
|
|
3172
|
-
if (typeof sourceAnchor.enabled === "boolean") {
|
|
3173
|
-
anchor.enabled = sourceAnchor.enabled;
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
{
|
|
3178
|
-
const restoreUi = /* @__PURE__ */ __name((map, Ctor, existing) => {
|
|
3179
|
-
const source = asRecord(map.get(sourceEntityId));
|
|
3180
|
-
if (!source) return;
|
|
3181
|
-
let component = existing;
|
|
3182
|
-
if (!component) {
|
|
3183
|
-
component = new Ctor();
|
|
3184
|
-
world.addComponent(targetEntityId, component);
|
|
3185
|
-
}
|
|
3186
|
-
const target = component;
|
|
3187
|
-
for (const [key, value] of Object.entries(source)) {
|
|
3188
|
-
const current = target[key];
|
|
3189
|
-
if ((typeof value === "string" || typeof value === "number" || typeof value === "boolean") && typeof current === typeof value) {
|
|
3190
|
-
target[key] = value;
|
|
3191
|
-
}
|
|
3192
|
-
}
|
|
3193
|
-
}, "restoreUi");
|
|
3194
|
-
restoreUi(
|
|
3195
|
-
values.uiPanelValues,
|
|
3196
|
-
UIPanelComponent,
|
|
3197
|
-
world.getComponent(targetEntityId, UIPanelComponent)
|
|
3198
|
-
);
|
|
3199
|
-
restoreUi(
|
|
3200
|
-
values.uiTextValues,
|
|
3201
|
-
UITextComponent,
|
|
3202
|
-
world.getComponent(targetEntityId, UITextComponent)
|
|
3203
|
-
);
|
|
3204
|
-
restoreUi(
|
|
3205
|
-
values.uiButtonValues,
|
|
3206
|
-
UIButtonComponent,
|
|
3207
|
-
world.getComponent(targetEntityId, UIButtonComponent)
|
|
3208
|
-
);
|
|
3209
|
-
restoreUi(
|
|
3210
|
-
values.uiToggleValues,
|
|
3211
|
-
UIToggleComponent,
|
|
3212
|
-
world.getComponent(targetEntityId, UIToggleComponent)
|
|
3213
|
-
);
|
|
3214
|
-
restoreUi(
|
|
3215
|
-
values.uiSliderValues,
|
|
3216
|
-
UISliderComponent,
|
|
3217
|
-
world.getComponent(targetEntityId, UISliderComponent)
|
|
3218
|
-
);
|
|
3219
|
-
}
|
|
3220
|
-
{
|
|
3221
|
-
const sourceInteractor = asRecord(
|
|
3222
|
-
values.xrInteractorValues.get(sourceEntityId)
|
|
3223
|
-
);
|
|
3224
|
-
const interactor = world.getComponent(targetEntityId, XRInteractorComponent);
|
|
3225
|
-
if (sourceInteractor && interactor) {
|
|
3226
|
-
if (typeof sourceInteractor.interactorType === "string") {
|
|
3227
|
-
interactor.interactorType = sourceInteractor.interactorType;
|
|
3228
|
-
}
|
|
3229
|
-
if (typeof sourceInteractor.handPreset === "string") {
|
|
3230
|
-
interactor.handPreset = sourceInteractor.handPreset;
|
|
3231
|
-
}
|
|
3232
|
-
if (typeof sourceInteractor.handColor === "string") {
|
|
3233
|
-
interactor.handColor = sourceInteractor.handColor;
|
|
3234
|
-
}
|
|
3235
|
-
if (typeof sourceInteractor.handOpacity === "number") {
|
|
3236
|
-
interactor.handOpacity = sourceInteractor.handOpacity;
|
|
3237
|
-
}
|
|
3238
|
-
if (typeof sourceInteractor.handEmissiveIntensity === "number") {
|
|
3239
|
-
interactor.handEmissiveIntensity = sourceInteractor.handEmissiveIntensity;
|
|
3240
|
-
}
|
|
3241
|
-
if (typeof sourceInteractor.rayVisibility === "string") {
|
|
3242
|
-
interactor.rayVisibility = sourceInteractor.rayVisibility;
|
|
3243
|
-
} else if (typeof sourceInteractor.showRay === "boolean") {
|
|
3244
|
-
interactor.rayVisibility = sourceInteractor.showRay ? "interacting" : "never";
|
|
3245
|
-
}
|
|
3246
|
-
if (typeof sourceInteractor.rayColor === "string") {
|
|
3247
|
-
interactor.rayColor = sourceInteractor.rayColor;
|
|
3248
|
-
}
|
|
3249
|
-
if (typeof sourceInteractor.rayThickness === "number") {
|
|
3250
|
-
interactor.rayThickness = sourceInteractor.rayThickness;
|
|
3251
|
-
}
|
|
3252
|
-
}
|
|
3253
|
-
}
|
|
3254
|
-
{
|
|
3255
|
-
const sourceSide = asRecord(
|
|
3256
|
-
values.xrInteractorSideValues.get(sourceEntityId)
|
|
3257
|
-
);
|
|
3258
|
-
if (sourceSide && typeof sourceSide.side === "string") {
|
|
3259
|
-
const existing = world.getComponent(
|
|
3260
|
-
targetEntityId,
|
|
3261
|
-
XRInteractorSideComponent
|
|
3262
|
-
);
|
|
3263
|
-
if (existing) {
|
|
3264
|
-
existing.side = sourceSide.side;
|
|
3265
|
-
} else {
|
|
3266
|
-
world.addComponent(
|
|
3267
|
-
targetEntityId,
|
|
3268
|
-
new XRInteractorSideComponent({
|
|
3269
|
-
side: sourceSide.side
|
|
3270
|
-
})
|
|
3271
|
-
);
|
|
3272
|
-
}
|
|
3273
|
-
}
|
|
3274
|
-
}
|
|
3275
|
-
{
|
|
3276
|
-
const sourceRigOrigin = asRecord(values.xrRigValues.get(sourceEntityId));
|
|
3277
|
-
const rigForOrigin = world.getComponent(targetEntityId, XRRigComponent);
|
|
3278
|
-
if (sourceRigOrigin && rigForOrigin && typeof sourceRigOrigin.trackingOrigin === "string") {
|
|
3279
|
-
rigForOrigin.trackingOrigin = sourceRigOrigin.trackingOrigin;
|
|
3280
|
-
}
|
|
3281
|
-
}
|
|
3282
|
-
{
|
|
3283
|
-
const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
|
|
3284
|
-
if (imComponent && imComponent.instanceEntityIds.length > 0) {
|
|
3285
|
-
imComponent.instanceEntityIds = imComponent.instanceEntityIds.map(
|
|
3286
|
-
(oldId) => idMap.get(oldId) ?? oldId
|
|
3287
|
-
);
|
|
3288
|
-
}
|
|
3289
|
-
}
|
|
3290
|
-
{
|
|
3291
|
-
const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
|
|
3292
|
-
if (slotComponent && slotComponent.groupEntityId !== -1) {
|
|
3293
|
-
slotComponent.groupEntityId = idMap.get(slotComponent.groupEntityId) ?? slotComponent.groupEntityId;
|
|
3294
|
-
}
|
|
3295
|
-
}
|
|
3296
|
-
}
|
|
3297
|
-
__name(restorePostCreateComponents, "restorePostCreateComponents");
|
|
3298
|
-
|
|
3299
|
-
// core/hydration/animation.ts
|
|
3300
|
-
function readAnimationClipName(value) {
|
|
3301
|
-
if (typeof value === "string") {
|
|
3302
|
-
return value;
|
|
3303
|
-
}
|
|
3304
|
-
const record = asRecord(value);
|
|
3305
|
-
if (!record) {
|
|
3306
|
-
return null;
|
|
3307
|
-
}
|
|
3308
|
-
if (typeof record.name === "string") {
|
|
3309
|
-
return record.name;
|
|
3310
|
-
}
|
|
3311
|
-
return null;
|
|
3312
|
-
}
|
|
3313
|
-
__name(readAnimationClipName, "readAnimationClipName");
|
|
3314
|
-
function readAnimationStates(value) {
|
|
3315
|
-
if (!Array.isArray(value)) {
|
|
3316
|
-
return [];
|
|
3317
|
-
}
|
|
3318
|
-
const states = [];
|
|
3319
|
-
for (const entry of value) {
|
|
3320
|
-
const state = asRecord(entry);
|
|
3321
|
-
if (!state) {
|
|
3322
|
-
continue;
|
|
3323
|
-
}
|
|
3324
|
-
const name = typeof state.name === "string" ? state.name : null;
|
|
3325
|
-
const clip = readAnimationClipName(state.clip);
|
|
3326
|
-
if (!name || !clip) {
|
|
3327
|
-
continue;
|
|
3328
|
-
}
|
|
3329
|
-
states.push({
|
|
3330
|
-
name,
|
|
3331
|
-
clip,
|
|
3332
|
-
clipId: typeof state.clipId === "string" ? state.clipId : void 0,
|
|
3333
|
-
loop: typeof state.loop === "boolean" ? state.loop : false
|
|
3334
|
-
});
|
|
3335
|
-
}
|
|
3336
|
-
return states;
|
|
3337
|
-
}
|
|
3338
|
-
__name(readAnimationStates, "readAnimationStates");
|
|
3339
|
-
function readAnimationClipSources(value) {
|
|
3340
|
-
if (!Array.isArray(value)) {
|
|
3341
|
-
return [];
|
|
3342
|
-
}
|
|
3343
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3344
|
-
const sources = [];
|
|
3345
|
-
for (const entry of value) {
|
|
3346
|
-
if (typeof entry !== "string") {
|
|
3347
|
-
continue;
|
|
3348
|
-
}
|
|
3349
|
-
const trimmed = entry.trim();
|
|
3350
|
-
if (!trimmed || seen.has(trimmed)) {
|
|
3351
|
-
continue;
|
|
3352
|
-
}
|
|
3353
|
-
seen.add(trimmed);
|
|
3354
|
-
sources.push(trimmed);
|
|
3355
|
-
}
|
|
3356
|
-
return sources;
|
|
3357
|
-
}
|
|
3358
|
-
__name(readAnimationClipSources, "readAnimationClipSources");
|
|
3359
|
-
function toAnimationOptions(sourceAnimation) {
|
|
3360
|
-
const paused = readBoolean(sourceAnimation.paused);
|
|
3361
|
-
const reverse = readBoolean(sourceAnimation.reverse);
|
|
3362
|
-
const timeScale = readNumber(sourceAnimation.timeScale);
|
|
3363
|
-
const crossFadeDuration = readNumber(sourceAnimation.crossFadeDuration);
|
|
3364
|
-
const states = readAnimationStates(sourceAnimation.states);
|
|
3365
|
-
const externalClipSources = readAnimationClipSources(
|
|
3366
|
-
sourceAnimation.externalClipSources
|
|
3367
|
-
);
|
|
3368
|
-
const activeStateName = typeof sourceAnimation.activeStateName === "string" ? sourceAnimation.activeStateName : typeof sourceAnimation.activeState === "string" ? sourceAnimation.activeState : typeof sourceAnimation.active?.name === "string" ? sourceAnimation.active.name ?? null : null;
|
|
3369
|
-
return {
|
|
3370
|
-
paused,
|
|
3371
|
-
reverse,
|
|
3372
|
-
timeScale,
|
|
3373
|
-
crossFadeDuration,
|
|
3374
|
-
states,
|
|
3375
|
-
externalClipSources,
|
|
3376
|
-
activeState: activeStateName
|
|
3377
|
-
};
|
|
3378
|
-
}
|
|
3379
|
-
__name(toAnimationOptions, "toAnimationOptions");
|
|
3380
|
-
function restoreAnimationComponent(world, objectManagementSystem, targetEntityId, sourceAnimation) {
|
|
3381
|
-
const options = toAnimationOptions(sourceAnimation);
|
|
3382
|
-
let animation = world.getComponent(targetEntityId, AnimationComponent);
|
|
3383
|
-
if (!animation) {
|
|
3384
|
-
objectManagementSystem.createComponentNow(
|
|
3385
|
-
"animation",
|
|
3386
|
-
world,
|
|
3387
|
-
targetEntityId,
|
|
3388
|
-
options
|
|
3389
|
-
);
|
|
3390
|
-
animation = world.getComponent(targetEntityId, AnimationComponent);
|
|
3391
|
-
}
|
|
3392
|
-
if (!animation) {
|
|
3393
|
-
return;
|
|
3394
|
-
}
|
|
3395
|
-
const availableClips = Array.isArray(sourceAnimation.availableClips) ? sourceAnimation.availableClips.filter(
|
|
3396
|
-
(clip) => typeof clip === "string" && clip.length > 0
|
|
3397
|
-
) : [];
|
|
3398
|
-
if (availableClips.length > 0) {
|
|
3399
|
-
animation.availableClips = [...availableClips];
|
|
3400
|
-
}
|
|
3401
|
-
if (Array.isArray(options.externalClipSources)) {
|
|
3402
|
-
animation.setExternalClipSources(options.externalClipSources);
|
|
3403
|
-
}
|
|
3404
|
-
const states = options.states ?? [];
|
|
3405
|
-
const hasClips = Array.isArray(animation.clips) && animation.clips.length > 0;
|
|
3406
|
-
if (!hasClips) {
|
|
3407
|
-
animation.__pendingHydratedOptions = options;
|
|
3408
|
-
if (typeof options.reverse === "boolean") {
|
|
3409
|
-
animation.reverse = options.reverse;
|
|
3410
|
-
}
|
|
3411
|
-
if (typeof options.timeScale === "number") {
|
|
3412
|
-
animation.timeScale = options.timeScale;
|
|
3413
|
-
}
|
|
3414
|
-
if (typeof options.crossFadeDuration === "number") {
|
|
3415
|
-
animation.crossFadeDuration = options.crossFadeDuration;
|
|
3416
|
-
}
|
|
3417
|
-
if (typeof options.paused === "boolean") {
|
|
3418
|
-
animation.paused = options.paused;
|
|
3419
|
-
}
|
|
3420
|
-
return;
|
|
3421
|
-
}
|
|
3422
|
-
if (states.length > 0) {
|
|
3423
|
-
animation.setStates(states);
|
|
3424
|
-
}
|
|
3425
|
-
if (typeof options.reverse === "boolean") {
|
|
3426
|
-
animation.reverse = options.reverse;
|
|
3427
|
-
}
|
|
3428
|
-
if (typeof options.timeScale === "number") {
|
|
3429
|
-
animation.timeScale = options.timeScale;
|
|
3430
|
-
}
|
|
3431
|
-
if (typeof options.crossFadeDuration === "number") {
|
|
3432
|
-
animation.crossFadeDuration = options.crossFadeDuration;
|
|
3433
|
-
}
|
|
3434
|
-
if (typeof options.activeState === "string" && options.activeState.length > 0) {
|
|
3435
|
-
animation.setActiveState(options.activeState, !options.paused);
|
|
3436
|
-
}
|
|
3437
|
-
if (typeof options.paused === "boolean") {
|
|
3438
|
-
if (options.paused) {
|
|
3439
|
-
animation.pauseState();
|
|
3440
|
-
} else if (typeof options.activeState === "string" && options.activeState.length > 0) {
|
|
3441
|
-
animation.playState(options.activeState);
|
|
3442
|
-
}
|
|
3443
|
-
}
|
|
3444
|
-
}
|
|
3445
|
-
__name(restoreAnimationComponent, "restoreAnimationComponent");
|
|
3446
|
-
|
|
3447
|
-
// core/hydration/restoreComponentState.ts
|
|
3448
|
-
function readEnvironmentState(value) {
|
|
3449
|
-
const record = asRecord(value);
|
|
3450
|
-
if (!record) {
|
|
3451
|
-
return null;
|
|
3452
|
-
}
|
|
3453
|
-
const nestedValues = asRecord(record.values);
|
|
3454
|
-
if (nestedValues) {
|
|
3455
|
-
return nestedValues;
|
|
3456
|
-
}
|
|
3457
|
-
return record;
|
|
3458
|
-
}
|
|
3459
|
-
__name(readEnvironmentState, "readEnvironmentState");
|
|
3460
|
-
function readPostprocessingState(value) {
|
|
3461
|
-
const record = asRecord(value);
|
|
3462
|
-
if (!record) {
|
|
3463
|
-
return null;
|
|
3464
|
-
}
|
|
3465
|
-
const nestedValues = asRecord(record.values);
|
|
3466
|
-
if (nestedValues) {
|
|
3467
|
-
return nestedValues;
|
|
3468
|
-
}
|
|
3469
|
-
return record;
|
|
3470
|
-
}
|
|
3471
|
-
__name(readPostprocessingState, "readPostprocessingState");
|
|
3472
|
-
function restoreComponentState(world, objectManagementSystem, targetEntityId, sourceEntityId, entityType, values) {
|
|
3473
|
-
const sourceName = readString(values.nameValues.get(sourceEntityId));
|
|
3474
|
-
if (sourceName !== null) {
|
|
3475
|
-
const nameComponent = world.getComponent(targetEntityId, Name);
|
|
3476
|
-
if (nameComponent) {
|
|
3477
|
-
nameComponent.value = sourceName;
|
|
3478
|
-
}
|
|
3479
|
-
}
|
|
3480
|
-
const sourceObject3DRef = asRecord(values.object3DRefValues.get(sourceEntityId));
|
|
3481
|
-
if (sourceObject3DRef) {
|
|
3482
|
-
const object3DRefComponent = world.getComponent(targetEntityId, Object3DRef);
|
|
3483
|
-
const visibility = readBoolean(sourceObject3DRef.visibility);
|
|
3484
|
-
if (object3DRefComponent && typeof visibility === "boolean") {
|
|
3485
|
-
object3DRefComponent.visibility = visibility;
|
|
3486
|
-
}
|
|
3487
|
-
}
|
|
3488
|
-
const sourceTransform = readTransform(values.transformValues.get(sourceEntityId));
|
|
3489
|
-
if (sourceTransform) {
|
|
3490
|
-
const transformComponent = world.getComponent(targetEntityId, TransformComponent);
|
|
3491
|
-
if (transformComponent) {
|
|
3492
|
-
if (typeof sourceTransform.position?.x === "number") {
|
|
3493
|
-
transformComponent.position.x = sourceTransform.position.x;
|
|
3494
|
-
}
|
|
3495
|
-
if (typeof sourceTransform.position?.y === "number") {
|
|
3496
|
-
transformComponent.position.y = sourceTransform.position.y;
|
|
3497
|
-
}
|
|
3498
|
-
if (typeof sourceTransform.position?.z === "number") {
|
|
3499
|
-
transformComponent.position.z = sourceTransform.position.z;
|
|
3500
|
-
}
|
|
3501
|
-
if (typeof sourceTransform.rotation?.x === "number") {
|
|
3502
|
-
transformComponent.rotation.x = sourceTransform.rotation.x;
|
|
3503
|
-
}
|
|
3504
|
-
if (typeof sourceTransform.rotation?.y === "number") {
|
|
3505
|
-
transformComponent.rotation.y = sourceTransform.rotation.y;
|
|
3506
|
-
}
|
|
3507
|
-
if (typeof sourceTransform.rotation?.z === "number") {
|
|
3508
|
-
transformComponent.rotation.z = sourceTransform.rotation.z;
|
|
3509
|
-
}
|
|
3510
|
-
if (typeof sourceTransform.scale?.x === "number") {
|
|
3511
|
-
transformComponent.scale.x = sourceTransform.scale.x;
|
|
3512
|
-
}
|
|
3513
|
-
if (typeof sourceTransform.scale?.y === "number") {
|
|
3514
|
-
transformComponent.scale.y = sourceTransform.scale.y;
|
|
3515
|
-
}
|
|
3516
|
-
if (typeof sourceTransform.scale?.z === "number") {
|
|
3517
|
-
transformComponent.scale.z = sourceTransform.scale.z;
|
|
3518
|
-
}
|
|
3519
|
-
}
|
|
3520
|
-
}
|
|
3521
|
-
const sourceModel = asRecord(values.modelValues.get(sourceEntityId));
|
|
3522
|
-
if (sourceModel) {
|
|
3523
|
-
const modelComponent = world.getComponent(targetEntityId, ModelComponent);
|
|
3524
|
-
if (modelComponent && typeof sourceModel.path === "string") {
|
|
3525
|
-
modelComponent.path = sourceModel.path;
|
|
3526
|
-
}
|
|
3527
|
-
}
|
|
3528
|
-
const sourceImage = asRecord(values.imageValues.get(sourceEntityId));
|
|
3529
|
-
if (sourceImage) {
|
|
3530
|
-
const imageComponent = world.getComponent(targetEntityId, ImageComponent);
|
|
3531
|
-
if (imageComponent) {
|
|
3532
|
-
if (typeof sourceImage.path === "string") {
|
|
3533
|
-
imageComponent.path = sourceImage.path;
|
|
3534
|
-
}
|
|
3535
|
-
const width = readNumber(sourceImage.width);
|
|
3536
|
-
if (typeof width === "number") {
|
|
3537
|
-
imageComponent.width = width;
|
|
3538
|
-
}
|
|
3539
|
-
const height = readNumber(sourceImage.height);
|
|
3540
|
-
if (typeof height === "number") {
|
|
3541
|
-
imageComponent.height = height;
|
|
3542
|
-
}
|
|
3543
|
-
}
|
|
3544
|
-
}
|
|
3545
|
-
const sourceSprite = asRecord(values.spriteValues.get(sourceEntityId));
|
|
3546
|
-
if (sourceSprite) {
|
|
3547
|
-
const spriteComponent = world.getComponent(targetEntityId, SpriteComponent);
|
|
3548
|
-
if (spriteComponent) {
|
|
3549
|
-
if (typeof sourceSprite.path === "string") {
|
|
3550
|
-
spriteComponent.path = sourceSprite.path;
|
|
3551
|
-
}
|
|
3552
|
-
const width = readNumber(sourceSprite.width);
|
|
3553
|
-
if (typeof width === "number") {
|
|
3554
|
-
spriteComponent.width = width;
|
|
3555
|
-
}
|
|
3556
|
-
const height = readNumber(sourceSprite.height);
|
|
3557
|
-
if (typeof height === "number") {
|
|
3558
|
-
spriteComponent.height = height;
|
|
3559
|
-
}
|
|
3560
|
-
}
|
|
3561
|
-
}
|
|
3562
|
-
const sourceVideo = asRecord(values.videoValues.get(sourceEntityId));
|
|
3563
|
-
if (sourceVideo) {
|
|
3564
|
-
const videoComponent = world.getComponent(targetEntityId, VideoComponent);
|
|
3565
|
-
if (videoComponent) {
|
|
3566
|
-
if (typeof sourceVideo.path === "string") {
|
|
3567
|
-
videoComponent.path = sourceVideo.path;
|
|
3568
|
-
}
|
|
3569
|
-
const videoOptions = asRecord(sourceVideo.options);
|
|
3570
|
-
if (videoOptions) {
|
|
3571
|
-
videoComponent.options = {
|
|
3572
|
-
...videoComponent.options,
|
|
3573
|
-
...videoOptions
|
|
3574
|
-
};
|
|
3575
|
-
}
|
|
3576
|
-
}
|
|
3577
|
-
}
|
|
3578
|
-
const sourceAudio = asRecord(values.audioValues.get(sourceEntityId));
|
|
3579
|
-
if (sourceAudio && entityType === "audio") {
|
|
3580
|
-
const audioComponent = world.getComponent(targetEntityId, AudioComponent);
|
|
3581
|
-
if (audioComponent) {
|
|
3582
|
-
if (typeof sourceAudio.path === "string") {
|
|
3583
|
-
audioComponent.path = sourceAudio.path;
|
|
3584
|
-
}
|
|
3585
|
-
const audioOptions = asRecord(sourceAudio.options);
|
|
3586
|
-
if (audioOptions) {
|
|
3587
|
-
audioComponent.options = {
|
|
3588
|
-
...audioComponent.options,
|
|
3589
|
-
...audioOptions
|
|
3590
|
-
};
|
|
3591
|
-
}
|
|
3592
|
-
}
|
|
3593
|
-
}
|
|
3594
|
-
const sourceCamera = asRecord(values.cameraValues.get(sourceEntityId));
|
|
3595
|
-
if (sourceCamera) {
|
|
3596
|
-
const cameraComponent = world.getComponent(targetEntityId, CameraComponent);
|
|
3597
|
-
if (cameraComponent) {
|
|
3598
|
-
if (sourceCamera.projection === "orthographic" || sourceCamera.projection === "perspective") {
|
|
3599
|
-
cameraComponent.projection = sourceCamera.projection;
|
|
3600
|
-
}
|
|
3601
|
-
if (sourceCamera.type === "3d" || sourceCamera.type === "ar") {
|
|
3602
|
-
cameraComponent.type = sourceCamera.type;
|
|
3603
|
-
}
|
|
3604
|
-
if (typeof sourceCamera.isDefault === "boolean") {
|
|
3605
|
-
cameraComponent.isDefault = sourceCamera.isDefault;
|
|
3606
|
-
}
|
|
3607
|
-
const fov = readNumber(sourceCamera.fov);
|
|
3608
|
-
if (typeof fov === "number") {
|
|
3609
|
-
cameraComponent.fov = fov;
|
|
3610
|
-
}
|
|
3611
|
-
const near = readNumber(sourceCamera.near);
|
|
3612
|
-
if (typeof near === "number") {
|
|
3613
|
-
cameraComponent.near = near;
|
|
3614
|
-
}
|
|
3615
|
-
const far = readNumber(sourceCamera.far);
|
|
3616
|
-
if (typeof far === "number") {
|
|
3617
|
-
cameraComponent.far = far;
|
|
3618
|
-
}
|
|
3619
|
-
const left = readNumber(sourceCamera.left);
|
|
3620
|
-
if (typeof left === "number") {
|
|
3621
|
-
cameraComponent.left = left;
|
|
3622
|
-
}
|
|
3623
|
-
const right = readNumber(sourceCamera.right);
|
|
3624
|
-
if (typeof right === "number") {
|
|
3625
|
-
cameraComponent.right = right;
|
|
3626
|
-
}
|
|
3627
|
-
const top = readNumber(sourceCamera.top);
|
|
3628
|
-
if (typeof top === "number") {
|
|
3629
|
-
cameraComponent.top = top;
|
|
3630
|
-
}
|
|
3631
|
-
const bottom = readNumber(sourceCamera.bottom);
|
|
3632
|
-
if (typeof bottom === "number") {
|
|
3633
|
-
cameraComponent.bottom = bottom;
|
|
3634
|
-
}
|
|
3635
|
-
const zoom = readNumber(sourceCamera.zoom);
|
|
3636
|
-
if (typeof zoom === "number") {
|
|
3637
|
-
cameraComponent.zoom = zoom;
|
|
3638
|
-
}
|
|
3639
|
-
}
|
|
3640
|
-
}
|
|
3641
|
-
const sourceEnvironment = readEnvironmentState(
|
|
3642
|
-
values.environmentValues.get(sourceEntityId)
|
|
3643
|
-
);
|
|
3644
|
-
if (sourceEnvironment) {
|
|
3645
|
-
let environmentComponent = world.getComponent(targetEntityId, Environment);
|
|
3646
|
-
if (!environmentComponent) {
|
|
3647
|
-
objectManagementSystem.createComponentNow(
|
|
3648
|
-
"environment",
|
|
3649
|
-
world,
|
|
3650
|
-
targetEntityId,
|
|
3651
|
-
sourceEnvironment
|
|
3652
|
-
);
|
|
3653
|
-
environmentComponent = world.getComponent(targetEntityId, Environment);
|
|
3654
|
-
}
|
|
3655
|
-
if (environmentComponent) {
|
|
3656
|
-
environmentComponent.values = new Environment({
|
|
3657
|
-
...environmentComponent.values,
|
|
3658
|
-
...sourceEnvironment
|
|
3659
|
-
}).values;
|
|
3660
|
-
}
|
|
3661
|
-
}
|
|
3662
|
-
const sourcePostprocessing = readPostprocessingState(
|
|
3663
|
-
values.postprocessingValues.get(sourceEntityId)
|
|
3664
|
-
);
|
|
3665
|
-
if (sourcePostprocessing) {
|
|
3666
|
-
let postprocessingComponent = world.getComponent(targetEntityId, Postprocessing);
|
|
3667
|
-
if (!postprocessingComponent) {
|
|
3668
|
-
objectManagementSystem.createComponentNow(
|
|
3669
|
-
"postprocessing",
|
|
3670
|
-
world,
|
|
3671
|
-
targetEntityId,
|
|
3672
|
-
sourcePostprocessing
|
|
3673
|
-
);
|
|
3674
|
-
postprocessingComponent = world.getComponent(targetEntityId, Postprocessing);
|
|
3675
|
-
}
|
|
3676
|
-
if (postprocessingComponent) {
|
|
3677
|
-
postprocessingComponent.values = new Postprocessing({
|
|
3678
|
-
...postprocessingComponent.values,
|
|
3679
|
-
...sourcePostprocessing
|
|
3680
|
-
}).values;
|
|
3681
|
-
}
|
|
3682
|
-
}
|
|
3683
|
-
const sourceImageTarget = asRecord(values.imageTargetValues.get(sourceEntityId));
|
|
3684
|
-
if (sourceImageTarget && entityType === "imageTarget") {
|
|
3685
|
-
const imageTargetComponent = world.getComponent(targetEntityId, ImageTarget);
|
|
3686
|
-
if (imageTargetComponent) {
|
|
3687
|
-
imageTargetComponent.targets = Array.isArray(sourceImageTarget.targets) ? sourceImageTarget.targets : [];
|
|
3688
|
-
imageTargetComponent.compiledTargetUrl = typeof sourceImageTarget.compiledTargetUrl === "string" ? sourceImageTarget.compiledTargetUrl : void 0;
|
|
3689
|
-
imageTargetComponent.compiledTargetDir = typeof sourceImageTarget.compiledTargetDir === "string" ? sourceImageTarget.compiledTargetDir : void 0;
|
|
3690
|
-
}
|
|
3691
|
-
}
|
|
3692
|
-
const sourceLight = asRecord(values.lightValues.get(sourceEntityId));
|
|
3693
|
-
if (sourceLight) {
|
|
3694
|
-
const lightComponent = world.getComponent(targetEntityId, LightComponent);
|
|
3695
|
-
const sourceValues = asRecord(sourceLight.values);
|
|
3696
|
-
if (lightComponent && sourceValues) {
|
|
3697
|
-
lightComponent.values = {
|
|
3698
|
-
...lightComponent.values,
|
|
3699
|
-
...sourceValues
|
|
3700
|
-
};
|
|
3701
|
-
}
|
|
3702
|
-
}
|
|
3703
|
-
const sourceMaterial = asRecord(values.materialValues.get(sourceEntityId));
|
|
3704
|
-
if (sourceMaterial) {
|
|
3705
|
-
const materialComponent = world.getComponent(targetEntityId, MaterialComponent);
|
|
3706
|
-
const sourceValues = sourceMaterial.values;
|
|
3707
|
-
if (materialComponent && Array.isArray(sourceValues)) {
|
|
3708
|
-
materialComponent.values = sourceValues;
|
|
3709
|
-
}
|
|
3710
|
-
const sourceAssetRefs = sourceMaterial.assetRefs;
|
|
3711
|
-
if (materialComponent && Array.isArray(sourceAssetRefs)) {
|
|
3712
|
-
materialComponent.assetRefs = sourceAssetRefs;
|
|
3713
|
-
}
|
|
3714
|
-
}
|
|
3715
|
-
const sourceMeshGeometry = asRecord(values.meshGeometryValues.get(sourceEntityId));
|
|
3716
|
-
if (sourceMeshGeometry) {
|
|
3717
|
-
const meshGeometryComponent = world.getComponent(
|
|
3718
|
-
targetEntityId,
|
|
3719
|
-
MeshGeometryComponent
|
|
3720
|
-
);
|
|
3721
|
-
if (meshGeometryComponent) {
|
|
3722
|
-
const parameters = asRecord(sourceMeshGeometry.parameters);
|
|
3723
|
-
if (parameters) {
|
|
3724
|
-
meshGeometryComponent.parameters = parameters;
|
|
3725
|
-
}
|
|
3726
|
-
if (typeof sourceMeshGeometry.modelName === "string") {
|
|
3727
|
-
meshGeometryComponent.modelName = sourceMeshGeometry.modelName;
|
|
3728
|
-
}
|
|
3729
|
-
if (typeof sourceMeshGeometry.castShadow === "boolean") {
|
|
3730
|
-
meshGeometryComponent.castShadow = sourceMeshGeometry.castShadow;
|
|
3731
|
-
}
|
|
3732
|
-
if (typeof sourceMeshGeometry.receiveShadow === "boolean") {
|
|
3733
|
-
meshGeometryComponent.receiveShadow = sourceMeshGeometry.receiveShadow;
|
|
3734
|
-
}
|
|
3735
|
-
}
|
|
3736
|
-
}
|
|
3737
|
-
const sourceSelectable = asRecord(values.selectableValues.get(sourceEntityId));
|
|
3738
|
-
if (sourceSelectable) {
|
|
3739
|
-
const enabled = readBoolean(sourceSelectable.enabled);
|
|
3740
|
-
let selectable = world.getComponent(targetEntityId, Selectable);
|
|
3741
|
-
if (!selectable) {
|
|
3742
|
-
objectManagementSystem.createComponentNow(
|
|
3743
|
-
"selectable",
|
|
3744
|
-
world,
|
|
3745
|
-
targetEntityId,
|
|
3746
|
-
enabled ?? true
|
|
3747
|
-
);
|
|
3748
|
-
selectable = world.getComponent(targetEntityId, Selectable);
|
|
3749
|
-
}
|
|
3750
|
-
if (selectable && typeof enabled === "boolean") {
|
|
3751
|
-
selectable.enabled = enabled;
|
|
3752
|
-
}
|
|
3753
|
-
}
|
|
3754
|
-
const sourcePhysics = asRecord(values.physicsValues.get(sourceEntityId));
|
|
3755
|
-
if (sourcePhysics) {
|
|
3756
|
-
const physicsValues = asRecord(sourcePhysics.values) ?? sourcePhysics;
|
|
3757
|
-
let physics = world.getComponent(targetEntityId, PhysicsComponent);
|
|
3758
|
-
if (!physics) {
|
|
3759
|
-
objectManagementSystem.createComponentNow(
|
|
3760
|
-
"physics",
|
|
3761
|
-
world,
|
|
3762
|
-
targetEntityId,
|
|
3763
|
-
physicsValues
|
|
3764
|
-
);
|
|
3765
|
-
physics = world.getComponent(targetEntityId, PhysicsComponent);
|
|
3766
|
-
}
|
|
3767
|
-
if (physics) {
|
|
3768
|
-
physics.setValues({
|
|
3769
|
-
rigidbody: asRecord(physicsValues.rigidbody) ?? {},
|
|
3770
|
-
collider: asRecord(physicsValues.collider) ?? {}
|
|
3771
|
-
});
|
|
3772
|
-
}
|
|
3773
|
-
}
|
|
3774
|
-
const sourceAnimation = asRecord(values.animationValues.get(sourceEntityId));
|
|
3775
|
-
if (sourceAnimation) {
|
|
3776
|
-
restoreAnimationComponent(
|
|
3777
|
-
world,
|
|
3778
|
-
objectManagementSystem,
|
|
3779
|
-
targetEntityId,
|
|
3780
|
-
sourceAnimation
|
|
3781
|
-
);
|
|
3782
|
-
}
|
|
3783
|
-
const sourceInstancedMesh = asRecord(values.instancedMeshValues.get(sourceEntityId));
|
|
3784
|
-
if (sourceInstancedMesh) {
|
|
3785
|
-
const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
|
|
3786
|
-
if (imComponent) {
|
|
3787
|
-
if (typeof sourceInstancedMesh.meshKind === "string") {
|
|
3788
|
-
imComponent.meshKind = sourceInstancedMesh.meshKind;
|
|
3789
|
-
}
|
|
3790
|
-
if (typeof sourceInstancedMesh.modelPath === "string") {
|
|
3791
|
-
imComponent.modelPath = sourceInstancedMesh.modelPath;
|
|
3792
|
-
}
|
|
3793
|
-
const parameters = asRecord(sourceInstancedMesh.meshParameters);
|
|
3794
|
-
if (parameters) {
|
|
3795
|
-
imComponent.meshParameters = parameters;
|
|
3796
|
-
}
|
|
3797
|
-
if (typeof sourceInstancedMesh.castShadow === "boolean") {
|
|
3798
|
-
imComponent.castShadow = sourceInstancedMesh.castShadow;
|
|
3799
|
-
}
|
|
3800
|
-
if (typeof sourceInstancedMesh.receiveShadow === "boolean") {
|
|
3801
|
-
imComponent.receiveShadow = sourceInstancedMesh.receiveShadow;
|
|
3802
|
-
}
|
|
3803
|
-
if (Array.isArray(sourceInstancedMesh.instanceEntityIds)) {
|
|
3804
|
-
imComponent.instanceEntityIds = sourceInstancedMesh.instanceEntityIds;
|
|
3805
|
-
}
|
|
3806
|
-
imComponent.instancedMesh = null;
|
|
3807
|
-
}
|
|
3808
|
-
}
|
|
3809
|
-
const sourceInstanceSlot = asRecord(values.instanceSlotValues.get(sourceEntityId));
|
|
3810
|
-
if (sourceInstanceSlot) {
|
|
3811
|
-
const slotComponent = world.getComponent(targetEntityId, InstanceSlotComponent);
|
|
3812
|
-
if (slotComponent) {
|
|
3813
|
-
if (typeof sourceInstanceSlot.slotIndex === "number") {
|
|
3814
|
-
slotComponent.slotIndex = sourceInstanceSlot.slotIndex;
|
|
3815
|
-
}
|
|
3816
|
-
}
|
|
3817
|
-
}
|
|
3818
|
-
const sourcePrefabNode = asRecord(values.prefabNodeValues.get(sourceEntityId));
|
|
3819
|
-
if (sourcePrefabNode && typeof sourcePrefabNode.nodeId === "string") {
|
|
3820
|
-
if (!world.getComponent(targetEntityId, PrefabNode)) {
|
|
3821
|
-
world.addComponent(targetEntityId, new PrefabNode(sourcePrefabNode.nodeId));
|
|
3822
|
-
}
|
|
3823
|
-
}
|
|
3824
|
-
const sourcePrefabInstance = asRecord(
|
|
3825
|
-
values.prefabInstanceValues.get(sourceEntityId)
|
|
3826
|
-
);
|
|
3827
|
-
if (sourcePrefabInstance && typeof sourcePrefabInstance.url === "string") {
|
|
3828
|
-
if (!world.getComponent(targetEntityId, PrefabInstance)) {
|
|
3829
|
-
const overrides = Array.isArray(sourcePrefabInstance.overrides) ? sourcePrefabInstance.overrides.filter(
|
|
3830
|
-
(entry) => typeof entry === "string"
|
|
3831
|
-
) : [];
|
|
3832
|
-
world.addComponent(
|
|
3833
|
-
targetEntityId,
|
|
3834
|
-
new PrefabInstance(
|
|
3835
|
-
sourcePrefabInstance.url,
|
|
3836
|
-
overrides,
|
|
3837
|
-
// Preserve the placement identity; the constructor generates a
|
|
3838
|
-
// fresh one for legacy snapshots that predate instanceId.
|
|
3839
|
-
typeof sourcePrefabInstance.instanceId === "string" && sourcePrefabInstance.instanceId.length > 0 ? sourcePrefabInstance.instanceId : void 0
|
|
3840
|
-
)
|
|
3841
|
-
);
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
3844
|
-
}
|
|
3845
|
-
__name(restoreComponentState, "restoreComponentState");
|
|
3846
|
-
|
|
3847
|
-
// core/hydration/types.ts
|
|
3848
|
-
var HYDRATABLE_ENTITY_KINDS = /* @__PURE__ */ new Set([
|
|
3849
|
-
"cube",
|
|
3850
|
-
"sphere",
|
|
3851
|
-
"plane",
|
|
3852
|
-
"capsule",
|
|
3853
|
-
"cylinder",
|
|
3854
|
-
"empty",
|
|
3855
|
-
"model",
|
|
3856
|
-
"image",
|
|
3857
|
-
"imageTarget",
|
|
3858
|
-
"sprite",
|
|
3859
|
-
"audio",
|
|
3860
|
-
"camera",
|
|
3861
|
-
"video",
|
|
3862
|
-
"ambientLight",
|
|
3863
|
-
"directionalLight",
|
|
3864
|
-
"pointLight",
|
|
3865
|
-
"spotLight",
|
|
3866
|
-
"areaLight",
|
|
3867
|
-
"instancedMesh",
|
|
3868
|
-
"instanceSlot",
|
|
3869
|
-
"scriptObject",
|
|
3870
|
-
"xrRig",
|
|
3871
|
-
"xrInteractor",
|
|
3872
|
-
"teleportArea",
|
|
3873
|
-
"uiPanel",
|
|
3874
|
-
"uiText",
|
|
3875
|
-
"uiButton",
|
|
3876
|
-
"uiToggle",
|
|
3877
|
-
"uiSlider"
|
|
3878
|
-
]);
|
|
3879
|
-
|
|
3880
|
-
// core/hydration/hydrateWorld.ts
|
|
3881
|
-
function buildEntityCreationPayload(sourceEntityId, kind, componentValues) {
|
|
3882
|
-
const payload = {
|
|
3883
|
-
name: readString(componentValues.nameValues.get(sourceEntityId)) ?? void 0,
|
|
3884
|
-
transform: readTransform(componentValues.transformValues.get(sourceEntityId))
|
|
3885
|
-
};
|
|
3886
|
-
if (kind === "model") {
|
|
3887
|
-
const model = asRecord(componentValues.modelValues.get(sourceEntityId));
|
|
3888
|
-
if (typeof model?.path === "string") {
|
|
3889
|
-
payload.path = model.path;
|
|
3890
|
-
}
|
|
3891
|
-
}
|
|
3892
|
-
if (kind === "image") {
|
|
3893
|
-
const image = asRecord(componentValues.imageValues.get(sourceEntityId));
|
|
3894
|
-
if (typeof image?.path === "string") {
|
|
3895
|
-
payload.path = image.path;
|
|
3896
|
-
}
|
|
3897
|
-
}
|
|
3898
|
-
if (kind === "sprite") {
|
|
3899
|
-
const sprite = asRecord(componentValues.spriteValues.get(sourceEntityId));
|
|
3900
|
-
if (typeof sprite?.path === "string") {
|
|
3901
|
-
payload.path = sprite.path;
|
|
3902
|
-
}
|
|
3903
|
-
}
|
|
3904
|
-
if (kind === "video") {
|
|
3905
|
-
const video = asRecord(componentValues.videoValues.get(sourceEntityId));
|
|
3906
|
-
if (typeof video?.path === "string") {
|
|
3907
|
-
payload.path = video.path;
|
|
3908
|
-
}
|
|
3909
|
-
const videoOptions = asRecord(video?.options);
|
|
3910
|
-
if (videoOptions) {
|
|
3911
|
-
payload.options = videoOptions;
|
|
3912
|
-
}
|
|
3913
|
-
}
|
|
3914
|
-
if (kind === "audio") {
|
|
3915
|
-
const audio = asRecord(componentValues.audioValues.get(sourceEntityId));
|
|
3916
|
-
if (typeof audio?.path === "string") {
|
|
3917
|
-
payload.path = audio.path;
|
|
3918
|
-
}
|
|
3919
|
-
const audioOptions = asRecord(audio?.options);
|
|
3920
|
-
if (audioOptions) {
|
|
3921
|
-
payload.options = audioOptions;
|
|
3922
|
-
}
|
|
3923
|
-
}
|
|
3924
|
-
if (kind === "camera") {
|
|
3925
|
-
const camera = asRecord(componentValues.cameraValues.get(sourceEntityId));
|
|
3926
|
-
if (camera) {
|
|
3927
|
-
const projection = camera.projection === "orthographic" || camera.projection === "perspective" ? camera.projection : void 0;
|
|
3928
|
-
const type = camera.type === "3d" || camera.type === "ar" ? camera.type : void 0;
|
|
3929
|
-
payload.options = {
|
|
3930
|
-
isDefault: typeof camera.isDefault === "boolean" ? camera.isDefault : void 0,
|
|
3931
|
-
projection,
|
|
3932
|
-
type,
|
|
3933
|
-
fov: typeof camera.fov === "number" ? camera.fov : void 0,
|
|
3934
|
-
near: typeof camera.near === "number" ? camera.near : void 0,
|
|
3935
|
-
far: typeof camera.far === "number" ? camera.far : void 0,
|
|
3936
|
-
left: typeof camera.left === "number" ? camera.left : void 0,
|
|
3937
|
-
right: typeof camera.right === "number" ? camera.right : void 0,
|
|
3938
|
-
top: typeof camera.top === "number" ? camera.top : void 0,
|
|
3939
|
-
bottom: typeof camera.bottom === "number" ? camera.bottom : void 0,
|
|
3940
|
-
zoom: typeof camera.zoom === "number" ? camera.zoom : void 0
|
|
3941
|
-
};
|
|
3942
|
-
}
|
|
3943
|
-
}
|
|
3944
|
-
if (kind === "imageTarget") {
|
|
3945
|
-
const imageTarget = asRecord(componentValues.imageTargetValues.get(sourceEntityId));
|
|
3946
|
-
if (imageTarget) {
|
|
3947
|
-
payload.options = {
|
|
3948
|
-
targets: Array.isArray(imageTarget.targets) ? imageTarget.targets : [],
|
|
3949
|
-
compiledTargetUrl: typeof imageTarget.compiledTargetUrl === "string" ? imageTarget.compiledTargetUrl : void 0,
|
|
3950
|
-
compiledTargetDir: typeof imageTarget.compiledTargetDir === "string" ? imageTarget.compiledTargetDir : void 0
|
|
3951
|
-
};
|
|
3952
|
-
}
|
|
3953
|
-
}
|
|
3954
|
-
if (kind === "instancedMesh") {
|
|
3955
|
-
const im = asRecord(componentValues.instancedMeshValues.get(sourceEntityId));
|
|
3956
|
-
if (im) {
|
|
3957
|
-
payload.options = {
|
|
3958
|
-
meshKind: typeof im.meshKind === "string" ? im.meshKind : "cube",
|
|
3959
|
-
modelPath: typeof im.modelPath === "string" ? im.modelPath : void 0,
|
|
3960
|
-
meshParameters: asRecord(im.meshParameters) ?? void 0,
|
|
3961
|
-
castShadow: typeof im.castShadow === "boolean" ? im.castShadow : false,
|
|
3962
|
-
receiveShadow: typeof im.receiveShadow === "boolean" ? im.receiveShadow : false,
|
|
3963
|
-
// New format: signal the factory to skip child entity creation.
|
|
3964
|
-
// Old format (instances[]): pass through for migration — factory will
|
|
3965
|
-
// create slot entities from the legacy InstanceTransform array.
|
|
3966
|
-
...Array.isArray(im.instanceEntityIds) ? { instanceEntityIds: im.instanceEntityIds } : Array.isArray(im.instances) ? { instances: im.instances } : {}
|
|
3967
|
-
};
|
|
3968
|
-
}
|
|
3969
|
-
}
|
|
3970
|
-
if (kind === "instanceSlot") {
|
|
3971
|
-
const slot = asRecord(componentValues.instanceSlotValues.get(sourceEntityId));
|
|
3972
|
-
if (slot) {
|
|
3973
|
-
payload.options = {
|
|
3974
|
-
groupEntityId: typeof slot.groupEntityId === "number" ? slot.groupEntityId : -1,
|
|
3975
|
-
slotIndex: typeof slot.slotIndex === "number" ? slot.slotIndex : 0
|
|
3976
|
-
};
|
|
3977
|
-
}
|
|
3978
|
-
}
|
|
3979
|
-
if (kind === "scriptObject") {
|
|
3980
|
-
const so = asRecord(componentValues.scriptObjectValues.get(sourceEntityId));
|
|
3981
|
-
if (so) {
|
|
3982
|
-
payload.options = {
|
|
3983
|
-
scriptUrl: typeof so.scriptUrl === "string" ? so.scriptUrl : null,
|
|
3984
|
-
className: typeof so.className === "string" ? so.className : null,
|
|
3985
|
-
enabled: typeof so.enabled === "boolean" ? so.enabled : true
|
|
3986
|
-
};
|
|
3987
|
-
}
|
|
3988
|
-
}
|
|
3989
|
-
return payload;
|
|
3990
|
-
}
|
|
3991
|
-
__name(buildEntityCreationPayload, "buildEntityCreationPayload");
|
|
3992
|
-
function resolvePrimaryCameraSourceEntityId(snapshot, componentValues, entityTypeValues) {
|
|
3993
|
-
let firstCameraSourceEntityId = null;
|
|
3994
|
-
for (const sourceEntityId of snapshot.entities) {
|
|
3995
|
-
const entityType = readString(entityTypeValues.get(sourceEntityId));
|
|
3996
|
-
if (entityType !== "camera") {
|
|
3997
|
-
continue;
|
|
3998
|
-
}
|
|
3999
|
-
if (firstCameraSourceEntityId === null) {
|
|
4000
|
-
firstCameraSourceEntityId = sourceEntityId;
|
|
4001
|
-
}
|
|
4002
|
-
const cameraValue = asRecord(componentValues.cameraValues.get(sourceEntityId));
|
|
4003
|
-
if (cameraValue?.isDefault === true) {
|
|
4004
|
-
return sourceEntityId;
|
|
4005
|
-
}
|
|
4006
|
-
}
|
|
4007
|
-
return firstCameraSourceEntityId;
|
|
4008
|
-
}
|
|
4009
|
-
__name(resolvePrimaryCameraSourceEntityId, "resolvePrimaryCameraSourceEntityId");
|
|
4010
|
-
function applyLocalTransformsAfterHierarchyRestore(world, scopeEntityIds) {
|
|
4011
|
-
const transformEntities = scopeEntityIds ? Array.from(scopeEntityIds) : world.query(TransformComponent, Object3DRef);
|
|
4012
|
-
for (const entityId of transformEntities) {
|
|
4013
|
-
const transform = world.getComponent(entityId, TransformComponent);
|
|
4014
|
-
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
4015
|
-
if (!transform || !object) {
|
|
4016
|
-
continue;
|
|
4017
|
-
}
|
|
4018
|
-
applyTransform(object, transform);
|
|
4019
|
-
object.updateMatrixWorld(true);
|
|
4020
|
-
}
|
|
4021
|
-
}
|
|
4022
|
-
__name(applyLocalTransformsAfterHierarchyRestore, "applyLocalTransformsAfterHierarchyRestore");
|
|
4023
|
-
function hydrateWorldFromSnapshotDetailed(snapshot, world, objectManagementSystem, options) {
|
|
4024
|
-
if (!snapshot || !snapshot.entities.length) {
|
|
4025
|
-
return {
|
|
4026
|
-
restoredCount: 0,
|
|
4027
|
-
selectedEntityId: null,
|
|
4028
|
-
idMap: /* @__PURE__ */ new Map()
|
|
4029
|
-
};
|
|
4030
|
-
}
|
|
4031
|
-
const assignPrimaryCamera = options?.assignPrimaryCamera !== false;
|
|
4032
|
-
const entityTypeValues = readByComponent(snapshot.components, "EntityType");
|
|
4033
|
-
const componentValues = buildComponentValueMaps(snapshot);
|
|
4034
|
-
const primaryCameraSourceEntityId = assignPrimaryCamera ? resolvePrimaryCameraSourceEntityId(
|
|
4035
|
-
snapshot,
|
|
4036
|
-
componentValues,
|
|
4037
|
-
entityTypeValues
|
|
4038
|
-
) : null;
|
|
4039
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
4040
|
-
for (const sourceEntityId of snapshot.entities) {
|
|
4041
|
-
const entityTypeValue = entityTypeValues.get(sourceEntityId);
|
|
4042
|
-
const entityType = readString(entityTypeValue);
|
|
4043
|
-
if (!entityType || !HYDRATABLE_ENTITY_KINDS.has(entityType)) {
|
|
4044
|
-
continue;
|
|
4045
|
-
}
|
|
4046
|
-
const kind = entityType;
|
|
4047
|
-
const payload = buildEntityCreationPayload(sourceEntityId, kind, componentValues);
|
|
4048
|
-
if (kind === "camera" && sourceEntityId === primaryCameraSourceEntityId) {
|
|
4049
|
-
payload.useWorldCamera = true;
|
|
4050
|
-
const options2 = asRecord(payload.options);
|
|
4051
|
-
payload.options = {
|
|
4052
|
-
...options2 ?? {},
|
|
4053
|
-
isDefault: true
|
|
4054
|
-
};
|
|
4055
|
-
}
|
|
4056
|
-
payload.skipDefaultChildren = true;
|
|
4057
|
-
const createdEntityId = objectManagementSystem.createNow(kind, world, payload);
|
|
4058
|
-
idMap.set(sourceEntityId, createdEntityId);
|
|
4059
|
-
}
|
|
4060
|
-
for (const sourceEntityId of snapshot.entities) {
|
|
4061
|
-
const targetEntityId = idMap.get(sourceEntityId);
|
|
4062
|
-
if (targetEntityId === void 0) {
|
|
4063
|
-
continue;
|
|
4064
|
-
}
|
|
4065
|
-
const entityType = readString(entityTypeValues.get(sourceEntityId));
|
|
4066
|
-
restoreComponentState(
|
|
4067
|
-
world,
|
|
4068
|
-
objectManagementSystem,
|
|
4069
|
-
targetEntityId,
|
|
4070
|
-
sourceEntityId,
|
|
4071
|
-
entityType,
|
|
4072
|
-
componentValues
|
|
4073
|
-
);
|
|
4074
|
-
restorePostCreateComponents(
|
|
4075
|
-
world,
|
|
4076
|
-
objectManagementSystem,
|
|
4077
|
-
targetEntityId,
|
|
4078
|
-
sourceEntityId,
|
|
4079
|
-
entityType,
|
|
4080
|
-
componentValues,
|
|
4081
|
-
idMap
|
|
4082
|
-
);
|
|
4083
|
-
}
|
|
4084
|
-
applyParentLinks(snapshot, idMap, objectManagementSystem, world);
|
|
4085
|
-
objectManagementSystem.reconcileSceneFromWorld(world);
|
|
4086
|
-
applyLocalTransformsAfterHierarchyRestore(
|
|
4087
|
-
world,
|
|
4088
|
-
options?.applyTransformsScope === "created" ? idMap.values() : void 0
|
|
4089
|
-
);
|
|
4090
|
-
const selectedEntityId = typeof snapshot.selectedEntityId === "number" ? idMap.get(snapshot.selectedEntityId) ?? null : null;
|
|
4091
|
-
return {
|
|
4092
|
-
restoredCount: idMap.size,
|
|
4093
|
-
selectedEntityId,
|
|
4094
|
-
idMap
|
|
4095
|
-
};
|
|
4096
|
-
}
|
|
4097
|
-
__name(hydrateWorldFromSnapshotDetailed, "hydrateWorldFromSnapshotDetailed");
|
|
4098
|
-
function hydrateWorldFromSnapshot(snapshot, world, objectManagementSystem) {
|
|
4099
|
-
return hydrateWorldFromSnapshotDetailed(
|
|
4100
|
-
snapshot,
|
|
4101
|
-
world,
|
|
4102
|
-
objectManagementSystem
|
|
4103
|
-
).restoredCount;
|
|
4104
|
-
}
|
|
4105
|
-
__name(hydrateWorldFromSnapshot, "hydrateWorldFromSnapshot");
|
|
4106
|
-
|
|
4107
|
-
// core/prefab/nodeKeys.ts
|
|
4108
|
-
var NODE_KEY_SEPARATOR = "/";
|
|
4109
|
-
var ADDED_NODE_MARKER_COMPONENT = "+node";
|
|
4110
|
-
var asRecord2 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
|
|
4111
|
-
var readBlock = /* @__PURE__ */ __name((snapshot, component) => {
|
|
4112
|
-
const map = /* @__PURE__ */ new Map();
|
|
4113
|
-
const block = snapshot.components.find((b) => b.component === component);
|
|
4114
|
-
for (const entry of block?.entries ?? []) {
|
|
4115
|
-
const record = asRecord2(entry.value);
|
|
4116
|
-
if (record) {
|
|
4117
|
-
map.set(entry.entityId, record);
|
|
4118
|
-
}
|
|
4119
|
-
}
|
|
4120
|
-
return map;
|
|
4121
|
-
}, "readBlock");
|
|
4122
|
-
var fallbackInstanceId = /* @__PURE__ */ __name((entityId) => `e${entityId}`, "fallbackInstanceId");
|
|
4123
|
-
function buildNodeKeyMapsFromSnapshot(snapshot, options) {
|
|
4124
|
-
const parentValues = readBlock(snapshot, "ParentId");
|
|
4125
|
-
const nodeValues = readBlock(snapshot, "PrefabNode");
|
|
4126
|
-
const instanceValues = readBlock(snapshot, "PrefabInstance");
|
|
4127
|
-
const inDocument = new Set(snapshot.entities);
|
|
4128
|
-
const childrenByParent = /* @__PURE__ */ new Map();
|
|
4129
|
-
const rootIds = [];
|
|
4130
|
-
for (const entityId of snapshot.entities) {
|
|
4131
|
-
const parent = parentValues.get(entityId)?.value;
|
|
4132
|
-
if (typeof parent === "number" && inDocument.has(parent)) {
|
|
4133
|
-
const siblings = childrenByParent.get(parent);
|
|
4134
|
-
if (siblings) siblings.push(entityId);
|
|
4135
|
-
else childrenByParent.set(parent, [entityId]);
|
|
4136
|
-
} else {
|
|
4137
|
-
rootIds.push(entityId);
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
const scopeRoots = options?.scopeRootEntityId !== void 0 ? [options.scopeRootEntityId] : rootIds;
|
|
4141
|
-
const idToKey = /* @__PURE__ */ new Map();
|
|
4142
|
-
const keyToId = /* @__PURE__ */ new Map();
|
|
4143
|
-
const boundaryIds = /* @__PURE__ */ new Map();
|
|
4144
|
-
const scopeRootSet = new Set(scopeRoots);
|
|
4145
|
-
const queue = scopeRoots.map(
|
|
4146
|
-
(entityId) => ({ entityId, prefix: "" })
|
|
4147
|
-
);
|
|
4148
|
-
while (queue.length > 0) {
|
|
4149
|
-
const { entityId, prefix } = queue.shift();
|
|
4150
|
-
const instance = instanceValues.get(entityId);
|
|
4151
|
-
const isBoundary = Boolean(
|
|
4152
|
-
instance && typeof instance.url === "string" && !scopeRootSet.has(entityId)
|
|
4153
|
-
);
|
|
4154
|
-
let ownPrefix = prefix;
|
|
4155
|
-
let childPrefix = prefix;
|
|
4156
|
-
if (isBoundary && instance) {
|
|
4157
|
-
const instanceId = typeof instance.instanceId === "string" && instance.instanceId.length > 0 ? instance.instanceId : fallbackInstanceId(entityId);
|
|
4158
|
-
childPrefix = `${prefix}${instanceId}${NODE_KEY_SEPARATOR}`;
|
|
4159
|
-
ownPrefix = childPrefix;
|
|
4160
|
-
boundaryIds.set(entityId, {
|
|
4161
|
-
url: instance.url,
|
|
4162
|
-
instanceId
|
|
4163
|
-
});
|
|
4164
|
-
}
|
|
4165
|
-
const nodeId = nodeValues.get(entityId)?.nodeId;
|
|
4166
|
-
if (typeof nodeId === "string" && nodeId.length > 0) {
|
|
4167
|
-
const key = `${ownPrefix}${nodeId}`;
|
|
4168
|
-
idToKey.set(entityId, key);
|
|
4169
|
-
keyToId.set(key, entityId);
|
|
4170
|
-
}
|
|
4171
|
-
for (const child of childrenByParent.get(entityId) ?? []) {
|
|
4172
|
-
queue.push({ entityId: child, prefix: childPrefix });
|
|
4173
|
-
}
|
|
4174
|
-
}
|
|
4175
|
-
const rootEntityId = scopeRoots[0];
|
|
4176
|
-
const rootNodeId = rootEntityId !== void 0 ? nodeValues.get(rootEntityId)?.nodeId : void 0;
|
|
4177
|
-
return {
|
|
4178
|
-
idToKey,
|
|
4179
|
-
keyToId,
|
|
4180
|
-
rootKey: typeof rootNodeId === "string" && rootNodeId.length > 0 ? rootNodeId : null,
|
|
4181
|
-
boundaryIds
|
|
4182
|
-
};
|
|
4183
|
-
}
|
|
4184
|
-
__name(buildNodeKeyMapsFromSnapshot, "buildNodeKeyMapsFromSnapshot");
|
|
4185
|
-
function collectSnapshotSubtreeIds(snapshot, rootEntityId) {
|
|
4186
|
-
const parentValues = readBlock(snapshot, "ParentId");
|
|
4187
|
-
const childrenByParent = /* @__PURE__ */ new Map();
|
|
4188
|
-
for (const entityId of snapshot.entities) {
|
|
4189
|
-
const parent = parentValues.get(entityId)?.value;
|
|
4190
|
-
if (typeof parent === "number") {
|
|
4191
|
-
const siblings = childrenByParent.get(parent);
|
|
4192
|
-
if (siblings) siblings.push(entityId);
|
|
4193
|
-
else childrenByParent.set(parent, [entityId]);
|
|
4194
|
-
}
|
|
4195
|
-
}
|
|
4196
|
-
const ordered = [];
|
|
4197
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4198
|
-
const queue = [rootEntityId];
|
|
4199
|
-
while (queue.length > 0) {
|
|
4200
|
-
const entityId = queue.shift();
|
|
4201
|
-
if (seen.has(entityId)) continue;
|
|
4202
|
-
seen.add(entityId);
|
|
4203
|
-
ordered.push(entityId);
|
|
4204
|
-
queue.push(...childrenByParent.get(entityId) ?? []);
|
|
4205
|
-
}
|
|
4206
|
-
return ordered;
|
|
4207
|
-
}
|
|
4208
|
-
__name(collectSnapshotSubtreeIds, "collectSnapshotSubtreeIds");
|
|
4209
|
-
function findTopLevelNestedRegions(snapshot) {
|
|
4210
|
-
const parentValues = readBlock(snapshot, "ParentId");
|
|
4211
|
-
const instanceValues = readBlock(snapshot, "PrefabInstance");
|
|
4212
|
-
const inDocument = new Set(snapshot.entities);
|
|
4213
|
-
const roots = new Set(
|
|
4214
|
-
snapshot.entities.filter((entityId) => {
|
|
4215
|
-
const parent = parentValues.get(entityId)?.value;
|
|
4216
|
-
return typeof parent !== "number" || !inDocument.has(parent);
|
|
4217
|
-
})
|
|
4218
|
-
);
|
|
4219
|
-
const regions = [];
|
|
4220
|
-
for (const [entityId, instance] of instanceValues) {
|
|
4221
|
-
if (roots.has(entityId)) continue;
|
|
4222
|
-
if (typeof instance.url !== "string" || instance.url.length === 0) continue;
|
|
4223
|
-
let ancestor = parentValues.get(entityId)?.value;
|
|
4224
|
-
let nestedDeeper = false;
|
|
4225
|
-
let hops = 0;
|
|
4226
|
-
while (typeof ancestor === "number" && hops < 512) {
|
|
4227
|
-
if (instanceValues.has(ancestor) && !roots.has(ancestor)) {
|
|
4228
|
-
nestedDeeper = true;
|
|
4229
|
-
break;
|
|
4230
|
-
}
|
|
4231
|
-
ancestor = parentValues.get(ancestor)?.value;
|
|
4232
|
-
hops += 1;
|
|
4233
|
-
}
|
|
4234
|
-
if (nestedDeeper) continue;
|
|
4235
|
-
regions.push({
|
|
4236
|
-
rootEntityId: entityId,
|
|
4237
|
-
url: instance.url,
|
|
4238
|
-
instanceId: typeof instance.instanceId === "string" && instance.instanceId.length > 0 ? instance.instanceId : fallbackInstanceId(entityId),
|
|
4239
|
-
overrides: Array.isArray(instance.overrides) ? instance.overrides.filter(
|
|
4240
|
-
(entry) => typeof entry === "string"
|
|
4241
|
-
) : []
|
|
4242
|
-
});
|
|
4243
|
-
}
|
|
4244
|
-
regions.sort((a, b) => a.rootEntityId - b.rootEntityId);
|
|
4245
|
-
return regions;
|
|
4246
|
-
}
|
|
4247
|
-
__name(findTopLevelNestedRegions, "findTopLevelNestedRegions");
|
|
4248
|
-
|
|
4249
|
-
// core/prefab/overrides.ts
|
|
4250
|
-
var OVERRIDE_DIFF_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4251
|
-
"PrefabNode",
|
|
4252
|
-
"PrefabInstance",
|
|
4253
|
-
"EntityType",
|
|
4254
|
-
"Selectable",
|
|
4255
|
-
"SelectionTransformState"
|
|
4256
|
-
]);
|
|
4257
|
-
var OVERRIDE_ROOT_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4258
|
-
"TransformComponent",
|
|
4259
|
-
"Name",
|
|
4260
|
-
"ParentId"
|
|
4261
|
-
]);
|
|
4262
|
-
var asRecord3 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null, "asRecord");
|
|
4263
|
-
var clone = /* @__PURE__ */ __name((value) => value === void 0 ? value : structuredClone(value), "clone");
|
|
4264
|
-
var isNodeRef = /* @__PURE__ */ __name((value) => {
|
|
4265
|
-
const record = asRecord3(value);
|
|
4266
|
-
return Boolean(
|
|
4267
|
-
record && typeof record.$node === "string" && Object.keys(record).length === 1
|
|
4268
|
-
);
|
|
4269
|
-
}, "isNodeRef");
|
|
4270
|
-
var makeNodeRef = /* @__PURE__ */ __name((nodeId) => ({ $node: nodeId }), "makeNodeRef");
|
|
4271
|
-
function findSnapshotRootEntityIds(snapshot) {
|
|
4272
|
-
const parentBlock = snapshot.components.find(
|
|
4273
|
-
(block) => block.component === "ParentId"
|
|
4274
|
-
);
|
|
4275
|
-
const parentByEntity = /* @__PURE__ */ new Map();
|
|
4276
|
-
for (const entry of parentBlock?.entries ?? []) {
|
|
4277
|
-
parentByEntity.set(entry.entityId, asRecord3(entry.value)?.value ?? null);
|
|
4278
|
-
}
|
|
4279
|
-
return snapshot.entities.filter(
|
|
4280
|
-
(entityId) => typeof parentByEntity.get(entityId) !== "number"
|
|
4281
|
-
);
|
|
4282
|
-
}
|
|
4283
|
-
__name(findSnapshotRootEntityIds, "findSnapshotRootEntityIds");
|
|
4284
|
-
function buildNodeMapsFromSnapshot(snapshot) {
|
|
4285
|
-
const idToNode = /* @__PURE__ */ new Map();
|
|
4286
|
-
const nodeToId = /* @__PURE__ */ new Map();
|
|
4287
|
-
const nodeBlock = snapshot.components.find(
|
|
4288
|
-
(block) => block.component === "PrefabNode"
|
|
4289
|
-
);
|
|
4290
|
-
for (const entry of nodeBlock?.entries ?? []) {
|
|
4291
|
-
const nodeId = asRecord3(entry.value)?.nodeId;
|
|
4292
|
-
if (typeof nodeId === "string" && nodeId.length > 0) {
|
|
4293
|
-
idToNode.set(entry.entityId, nodeId);
|
|
4294
|
-
nodeToId.set(nodeId, entry.entityId);
|
|
4295
|
-
}
|
|
4296
|
-
}
|
|
4297
|
-
const rootEntityId = findSnapshotRootEntityIds(snapshot)[0];
|
|
4298
|
-
const rootNodeId = rootEntityId !== void 0 ? idToNode.get(rootEntityId) ?? null : null;
|
|
4299
|
-
return { idToNode, nodeToId, rootNodeId };
|
|
4300
|
-
}
|
|
4301
|
-
__name(buildNodeMapsFromSnapshot, "buildNodeMapsFromSnapshot");
|
|
4302
|
-
function indexSnapshotByEntity(snapshot) {
|
|
4303
|
-
const byEntity = /* @__PURE__ */ new Map();
|
|
4304
|
-
for (const block of snapshot.components) {
|
|
4305
|
-
for (const entry of block.entries) {
|
|
4306
|
-
let componentMap = byEntity.get(entry.entityId);
|
|
4307
|
-
if (!componentMap) {
|
|
4308
|
-
componentMap = /* @__PURE__ */ new Map();
|
|
4309
|
-
byEntity.set(entry.entityId, componentMap);
|
|
4310
|
-
}
|
|
4311
|
-
componentMap.set(block.component, entry.value);
|
|
4312
|
-
}
|
|
4313
|
-
}
|
|
4314
|
-
return byEntity;
|
|
4315
|
-
}
|
|
4316
|
-
__name(indexSnapshotByEntity, "indexSnapshotByEntity");
|
|
4317
|
-
var toRefOrRaw = /* @__PURE__ */ __name((id, idToNode) => {
|
|
4318
|
-
const nodeId = idToNode.get(id);
|
|
4319
|
-
return nodeId !== void 0 ? makeNodeRef(nodeId) : id;
|
|
4320
|
-
}, "toRefOrRaw");
|
|
4321
|
-
function canonicalizeScriptDataFields(data, idToNode) {
|
|
4322
|
-
const canonicalData = {};
|
|
4323
|
-
for (const [key, fieldValue] of Object.entries(data)) {
|
|
4324
|
-
const field = asRecord3(fieldValue);
|
|
4325
|
-
if (field?.type === "entity" && typeof field.value === "number") {
|
|
4326
|
-
canonicalData[key] = {
|
|
4327
|
-
...field,
|
|
4328
|
-
value: toRefOrRaw(field.value, idToNode)
|
|
4329
|
-
};
|
|
4330
|
-
continue;
|
|
4331
|
-
}
|
|
4332
|
-
const componentRef = asRecord3(field?.value);
|
|
4333
|
-
if (field?.type === "component" && componentRef && typeof componentRef.entityId === "number") {
|
|
4334
|
-
canonicalData[key] = {
|
|
4335
|
-
...field,
|
|
4336
|
-
value: {
|
|
4337
|
-
...componentRef,
|
|
4338
|
-
entityId: toRefOrRaw(componentRef.entityId, idToNode)
|
|
4339
|
-
}
|
|
4340
|
-
};
|
|
4341
|
-
continue;
|
|
4342
|
-
}
|
|
4343
|
-
canonicalData[key] = fieldValue;
|
|
4344
|
-
}
|
|
4345
|
-
return canonicalData;
|
|
4346
|
-
}
|
|
4347
|
-
__name(canonicalizeScriptDataFields, "canonicalizeScriptDataFields");
|
|
4348
|
-
function canonicalizeComponentValue(componentName, value, idToNode) {
|
|
4349
|
-
const cloned = clone(value);
|
|
4350
|
-
const record = asRecord3(cloned);
|
|
4351
|
-
if (!record) {
|
|
4352
|
-
return cloned;
|
|
4353
|
-
}
|
|
4354
|
-
if (componentName === "ParentId") {
|
|
4355
|
-
if (typeof record.value === "number") {
|
|
4356
|
-
record.value = toRefOrRaw(record.value, idToNode);
|
|
4357
|
-
}
|
|
4358
|
-
return record;
|
|
4359
|
-
}
|
|
4360
|
-
if (componentName === "Object3DRef") {
|
|
4361
|
-
return {
|
|
4362
|
-
visibility: typeof record.visibility === "boolean" ? record.visibility : true
|
|
4363
|
-
};
|
|
4364
|
-
}
|
|
4365
|
-
if (componentName === "ScriptComponent") {
|
|
4366
|
-
const entries = Array.isArray(record.entries) ? record.entries : [];
|
|
4367
|
-
return {
|
|
4368
|
-
entries: entries.map((rawEntry) => {
|
|
4369
|
-
const entry = asRecord3(rawEntry);
|
|
4370
|
-
if (!entry) {
|
|
4371
|
-
return rawEntry;
|
|
4372
|
-
}
|
|
4373
|
-
return {
|
|
4374
|
-
className: typeof entry.className === "string" ? entry.className : "",
|
|
4375
|
-
scriptUrl: typeof entry.scriptUrl === "string" ? entry.scriptUrl : "",
|
|
4376
|
-
enabled: typeof entry.enabled === "boolean" ? entry.enabled : true,
|
|
4377
|
-
data: canonicalizeScriptDataFields(asRecord3(entry.data) ?? {}, idToNode)
|
|
4378
|
-
};
|
|
4379
|
-
})
|
|
4380
|
-
};
|
|
4381
|
-
}
|
|
4382
|
-
if (componentName === "ScriptObjectComponent") {
|
|
4383
|
-
return {
|
|
4384
|
-
scriptUrl: typeof record.scriptUrl === "string" ? record.scriptUrl : null,
|
|
4385
|
-
className: typeof record.className === "string" ? record.className : null,
|
|
4386
|
-
enabled: typeof record.enabled === "boolean" ? record.enabled : true,
|
|
4387
|
-
data: canonicalizeScriptDataFields(asRecord3(record.data) ?? {}, idToNode)
|
|
4388
|
-
};
|
|
4389
|
-
}
|
|
4390
|
-
if (componentName === "InstancedMeshComponent") {
|
|
4391
|
-
if (Array.isArray(record.instanceEntityIds)) {
|
|
4392
|
-
record.instanceEntityIds = record.instanceEntityIds.map(
|
|
4393
|
-
(id) => typeof id === "number" ? toRefOrRaw(id, idToNode) : id
|
|
4394
|
-
);
|
|
4395
|
-
}
|
|
4396
|
-
return record;
|
|
4397
|
-
}
|
|
4398
|
-
if (componentName === "InstanceSlotComponent") {
|
|
4399
|
-
if (typeof record.groupEntityId === "number" && record.groupEntityId !== -1) {
|
|
4400
|
-
record.groupEntityId = toRefOrRaw(record.groupEntityId, idToNode);
|
|
4401
|
-
}
|
|
4402
|
-
return record;
|
|
4403
|
-
}
|
|
4404
|
-
return record;
|
|
4405
|
-
}
|
|
4406
|
-
__name(canonicalizeComponentValue, "canonicalizeComponentValue");
|
|
4407
|
-
function decanonicalizeComponentValue(value, nodeToId) {
|
|
4408
|
-
if (isNodeRef(value)) {
|
|
4409
|
-
return nodeToId.get(value.$node) ?? null;
|
|
4410
|
-
}
|
|
4411
|
-
if (Array.isArray(value)) {
|
|
4412
|
-
return value.map((item) => decanonicalizeComponentValue(item, nodeToId));
|
|
4413
|
-
}
|
|
4414
|
-
const record = asRecord3(value);
|
|
4415
|
-
if (record) {
|
|
4416
|
-
const result = {};
|
|
4417
|
-
for (const [key, item] of Object.entries(record)) {
|
|
4418
|
-
result[key] = decanonicalizeComponentValue(item, nodeToId);
|
|
4419
|
-
}
|
|
4420
|
-
return result;
|
|
4421
|
-
}
|
|
4422
|
-
return value;
|
|
4423
|
-
}
|
|
4424
|
-
__name(decanonicalizeComponentValue, "decanonicalizeComponentValue");
|
|
4425
|
-
var encodeOverride = /* @__PURE__ */ __name((nodeId, componentName, path) => `${nodeId}|${componentName}|${path}`, "encodeOverride");
|
|
4426
|
-
function parseOverride(encoded) {
|
|
4427
|
-
const firstSep = encoded.indexOf("|");
|
|
4428
|
-
if (firstSep <= 0) {
|
|
4429
|
-
return null;
|
|
4430
|
-
}
|
|
4431
|
-
const secondSep = encoded.indexOf("|", firstSep + 1);
|
|
4432
|
-
if (secondSep <= firstSep + 1) {
|
|
4433
|
-
return null;
|
|
4434
|
-
}
|
|
4435
|
-
return {
|
|
4436
|
-
nodeId: encoded.slice(0, firstSep),
|
|
4437
|
-
componentName: encoded.slice(firstSep + 1, secondSep),
|
|
4438
|
-
path: encoded.slice(secondSep + 1)
|
|
4439
|
-
};
|
|
4440
|
-
}
|
|
4441
|
-
__name(parseOverride, "parseOverride");
|
|
4442
|
-
function groupOverridePaths(overrides) {
|
|
4443
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
4444
|
-
for (const encoded of overrides) {
|
|
4445
|
-
const parsed = parseOverride(encoded);
|
|
4446
|
-
if (!parsed) {
|
|
4447
|
-
continue;
|
|
4448
|
-
}
|
|
4449
|
-
let byComponent = grouped.get(parsed.nodeId);
|
|
4450
|
-
if (!byComponent) {
|
|
4451
|
-
byComponent = /* @__PURE__ */ new Map();
|
|
4452
|
-
grouped.set(parsed.nodeId, byComponent);
|
|
4453
|
-
}
|
|
4454
|
-
let paths = byComponent.get(parsed.componentName);
|
|
4455
|
-
if (!paths) {
|
|
4456
|
-
paths = /* @__PURE__ */ new Set();
|
|
4457
|
-
byComponent.set(parsed.componentName, paths);
|
|
4458
|
-
}
|
|
4459
|
-
paths.add(parsed.path);
|
|
4460
|
-
}
|
|
4461
|
-
return grouped;
|
|
4462
|
-
}
|
|
4463
|
-
__name(groupOverridePaths, "groupOverridePaths");
|
|
4464
|
-
var isPrimitive = /* @__PURE__ */ __name((value) => value === null || typeof value !== "object", "isPrimitive");
|
|
4465
|
-
function collectDiffPaths(base, current, prefix = "", out = []) {
|
|
4466
|
-
if (isNodeRef(base) || isNodeRef(current)) {
|
|
4467
|
-
const same = isNodeRef(base) && isNodeRef(current) && base.$node === current.$node;
|
|
4468
|
-
if (!same) {
|
|
4469
|
-
out.push(prefix);
|
|
4470
|
-
}
|
|
4471
|
-
return out;
|
|
4472
|
-
}
|
|
4473
|
-
if (isPrimitive(base) || isPrimitive(current)) {
|
|
4474
|
-
if (base !== current) {
|
|
4475
|
-
out.push(prefix);
|
|
4476
|
-
}
|
|
4477
|
-
return out;
|
|
4478
|
-
}
|
|
4479
|
-
const baseIsArray = Array.isArray(base);
|
|
4480
|
-
const currentIsArray = Array.isArray(current);
|
|
4481
|
-
if (baseIsArray !== currentIsArray) {
|
|
4482
|
-
out.push(prefix);
|
|
4483
|
-
return out;
|
|
4484
|
-
}
|
|
4485
|
-
if (baseIsArray && currentIsArray) {
|
|
4486
|
-
if (base.length !== current.length) {
|
|
4487
|
-
out.push(prefix);
|
|
4488
|
-
return out;
|
|
4489
|
-
}
|
|
4490
|
-
base.forEach((item, index) => {
|
|
4491
|
-
collectDiffPaths(
|
|
4492
|
-
item,
|
|
4493
|
-
current[index],
|
|
4494
|
-
prefix ? `${prefix}/${index}` : String(index),
|
|
4495
|
-
out
|
|
4496
|
-
);
|
|
4497
|
-
});
|
|
4498
|
-
return out;
|
|
4499
|
-
}
|
|
4500
|
-
const baseRecord = base;
|
|
4501
|
-
const currentRecord = current;
|
|
4502
|
-
const keys = /* @__PURE__ */ new Set([
|
|
4503
|
-
...Object.keys(baseRecord),
|
|
4504
|
-
...Object.keys(currentRecord)
|
|
4505
|
-
]);
|
|
4506
|
-
for (const key of keys) {
|
|
4507
|
-
const childPrefix = prefix ? `${prefix}/${key}` : key;
|
|
4508
|
-
if (!(key in baseRecord) || !(key in currentRecord)) {
|
|
4509
|
-
out.push(childPrefix);
|
|
4510
|
-
continue;
|
|
4511
|
-
}
|
|
4512
|
-
collectDiffPaths(baseRecord[key], currentRecord[key], childPrefix, out);
|
|
4513
|
-
}
|
|
4514
|
-
return out;
|
|
4515
|
-
}
|
|
4516
|
-
__name(collectDiffPaths, "collectDiffPaths");
|
|
4517
|
-
function computeInstanceOverrides(baseSnapshot, instanceSnapshot, options) {
|
|
4518
|
-
const baseMaps = buildNodeKeyMapsFromSnapshot(baseSnapshot);
|
|
4519
|
-
const instanceMaps = buildNodeKeyMapsFromSnapshot(instanceSnapshot);
|
|
4520
|
-
const baseByEntity = indexSnapshotByEntity(baseSnapshot);
|
|
4521
|
-
const instanceByEntity = indexSnapshotByEntity(instanceSnapshot);
|
|
4522
|
-
const overrides = [];
|
|
4523
|
-
for (const [nodeKey, instanceEntityId] of instanceMaps.keyToId) {
|
|
4524
|
-
const baseEntityId = baseMaps.keyToId.get(nodeKey);
|
|
4525
|
-
if (baseEntityId === void 0) {
|
|
4526
|
-
if (options?.emitAdditionMarkers) {
|
|
4527
|
-
overrides.push(
|
|
4528
|
-
encodeOverride(nodeKey, ADDED_NODE_MARKER_COMPONENT, "")
|
|
4529
|
-
);
|
|
4530
|
-
}
|
|
4531
|
-
continue;
|
|
4532
|
-
}
|
|
4533
|
-
const baseComponents = baseByEntity.get(baseEntityId);
|
|
4534
|
-
const instanceComponents = instanceByEntity.get(instanceEntityId);
|
|
4535
|
-
if (!baseComponents) {
|
|
4536
|
-
continue;
|
|
4537
|
-
}
|
|
4538
|
-
const isRoot = nodeKey === baseMaps.rootKey;
|
|
4539
|
-
for (const [componentName, baseRaw] of baseComponents) {
|
|
4540
|
-
if (OVERRIDE_DIFF_EXCLUDED_COMPONENTS.has(componentName)) {
|
|
4541
|
-
continue;
|
|
4542
|
-
}
|
|
4543
|
-
if (isRoot && OVERRIDE_ROOT_EXCLUDED_COMPONENTS.has(componentName)) {
|
|
4544
|
-
continue;
|
|
4545
|
-
}
|
|
4546
|
-
const instanceRaw = instanceComponents?.get(componentName);
|
|
4547
|
-
if (instanceRaw === void 0) {
|
|
4548
|
-
continue;
|
|
4549
|
-
}
|
|
4550
|
-
const baseCanonical = canonicalizeComponentValue(
|
|
4551
|
-
componentName,
|
|
4552
|
-
baseRaw,
|
|
4553
|
-
baseMaps.idToKey
|
|
4554
|
-
);
|
|
4555
|
-
const instanceCanonical = canonicalizeComponentValue(
|
|
4556
|
-
componentName,
|
|
4557
|
-
instanceRaw,
|
|
4558
|
-
instanceMaps.idToKey
|
|
4559
|
-
);
|
|
4560
|
-
for (const path of collectDiffPaths(baseCanonical, instanceCanonical)) {
|
|
4561
|
-
overrides.push(encodeOverride(nodeKey, componentName, path));
|
|
4562
|
-
}
|
|
4563
|
-
}
|
|
4564
|
-
}
|
|
4565
|
-
return overrides;
|
|
4566
|
-
}
|
|
4567
|
-
__name(computeInstanceOverrides, "computeInstanceOverrides");
|
|
4568
|
-
var PATH_TOKEN_SPLIT = "/";
|
|
4569
|
-
function getAtPath(value, tokens) {
|
|
4570
|
-
let cursor = value;
|
|
4571
|
-
for (const token of tokens) {
|
|
4572
|
-
if (Array.isArray(cursor)) {
|
|
4573
|
-
cursor = cursor[Number(token)];
|
|
4574
|
-
} else {
|
|
4575
|
-
const record = asRecord3(cursor);
|
|
4576
|
-
if (!record) {
|
|
4577
|
-
return void 0;
|
|
4578
|
-
}
|
|
4579
|
-
cursor = record[token];
|
|
4580
|
-
}
|
|
4581
|
-
if (cursor === void 0) {
|
|
4582
|
-
return void 0;
|
|
4583
|
-
}
|
|
4584
|
-
}
|
|
4585
|
-
return cursor;
|
|
4586
|
-
}
|
|
4587
|
-
__name(getAtPath, "getAtPath");
|
|
4588
|
-
function setAtPath(target, tokens, value) {
|
|
4589
|
-
let cursor = target;
|
|
4590
|
-
for (let i = 0; i < tokens.length - 1; i++) {
|
|
4591
|
-
const token = tokens[i];
|
|
4592
|
-
if (Array.isArray(cursor)) {
|
|
4593
|
-
cursor = cursor[Number(token)];
|
|
4594
|
-
} else {
|
|
4595
|
-
const record = asRecord3(cursor);
|
|
4596
|
-
if (!record) {
|
|
4597
|
-
return;
|
|
4598
|
-
}
|
|
4599
|
-
cursor = record[token];
|
|
4600
|
-
}
|
|
4601
|
-
if (cursor === null || typeof cursor !== "object") {
|
|
4602
|
-
return;
|
|
4603
|
-
}
|
|
4604
|
-
}
|
|
4605
|
-
const last = tokens[tokens.length - 1];
|
|
4606
|
-
if (Array.isArray(cursor)) {
|
|
4607
|
-
cursor[Number(last)] = value;
|
|
4608
|
-
} else {
|
|
4609
|
-
const record = asRecord3(cursor);
|
|
4610
|
-
if (record) {
|
|
4611
|
-
if (value === void 0) {
|
|
4612
|
-
delete record[last];
|
|
4613
|
-
} else {
|
|
4614
|
-
record[last] = value;
|
|
4615
|
-
}
|
|
4616
|
-
}
|
|
4617
|
-
}
|
|
4618
|
-
}
|
|
4619
|
-
__name(setAtPath, "setAtPath");
|
|
4620
|
-
function mergeComponentValue(newFileCanonical, instanceCanonical, overridePaths) {
|
|
4621
|
-
if (!overridePaths || overridePaths.size === 0) {
|
|
4622
|
-
return clone(newFileCanonical);
|
|
4623
|
-
}
|
|
4624
|
-
if (overridePaths.has("")) {
|
|
4625
|
-
return clone(instanceCanonical);
|
|
4626
|
-
}
|
|
4627
|
-
const merged = clone(newFileCanonical);
|
|
4628
|
-
for (const path of overridePaths) {
|
|
4629
|
-
const tokens = path.split(PATH_TOKEN_SPLIT);
|
|
4630
|
-
const instanceValue = getAtPath(instanceCanonical, tokens);
|
|
4631
|
-
setAtPath(merged, tokens, clone(instanceValue));
|
|
4632
|
-
}
|
|
4633
|
-
return merged;
|
|
4634
|
-
}
|
|
4635
|
-
__name(mergeComponentValue, "mergeComponentValue");
|
|
4636
|
-
|
|
4637
|
-
// core/prefab/instantiateSubtree.ts
|
|
4638
|
-
var INSTANTIATE_EXCLUDED_COMPONENTS = /* @__PURE__ */ new Set([
|
|
4639
|
-
"Environment",
|
|
4640
|
-
"Postprocessing",
|
|
4641
|
-
"SelectionTransformState"
|
|
4642
|
-
]);
|
|
4643
|
-
function instantiateSubtree(world, objectManagementSystem, snapshot) {
|
|
4644
|
-
const snapshotRootIds = new Set(findSnapshotRootEntityIds(snapshot));
|
|
4645
|
-
const safeSnapshot = {
|
|
4646
|
-
entities: snapshot.entities,
|
|
4647
|
-
components: snapshot.components.filter((block) => !INSTANTIATE_EXCLUDED_COMPONENTS.has(block.component)).map(
|
|
4648
|
-
(block) => block.component === "PrefabInstance" ? {
|
|
4649
|
-
component: block.component,
|
|
4650
|
-
entries: block.entries.filter(
|
|
4651
|
-
(entry) => !snapshotRootIds.has(entry.entityId)
|
|
4652
|
-
)
|
|
4653
|
-
} : block
|
|
4654
|
-
).filter((block) => block.entries.length > 0)
|
|
4655
|
-
};
|
|
4656
|
-
const result = hydrateWorldFromSnapshotDetailed(
|
|
4657
|
-
safeSnapshot,
|
|
4658
|
-
world,
|
|
4659
|
-
objectManagementSystem,
|
|
4660
|
-
{ assignPrimaryCamera: false, applyTransformsScope: "created" }
|
|
4661
|
-
);
|
|
4662
|
-
const rootSourceId = findSnapshotRootEntityIds(safeSnapshot).find(
|
|
4663
|
-
(sourceId) => result.idMap.has(sourceId)
|
|
4664
|
-
);
|
|
4665
|
-
return {
|
|
4666
|
-
rootId: rootSourceId !== void 0 ? result.idMap.get(rootSourceId) ?? null : null,
|
|
4667
|
-
idMap: result.idMap
|
|
4668
|
-
};
|
|
4669
|
-
}
|
|
4670
|
-
__name(instantiateSubtree, "instantiateSubtree");
|
|
4671
|
-
|
|
4672
|
-
// core/prefab/types.ts
|
|
4673
|
-
var PREFAB_FILE_VERSION = 1;
|
|
4674
|
-
var PREFAB_FILE_VERSION_NESTED = 2;
|
|
4675
|
-
function prefabFileVersionFor(snapshot) {
|
|
4676
|
-
return findTopLevelNestedRegions(snapshot).length > 0 ? PREFAB_FILE_VERSION_NESTED : PREFAB_FILE_VERSION;
|
|
4677
|
-
}
|
|
4678
|
-
__name(prefabFileVersionFor, "prefabFileVersionFor");
|
|
4679
|
-
var isRecord = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
|
|
4680
|
-
function parsePrefabAsset(json) {
|
|
4681
|
-
if (!isRecord(json)) {
|
|
4682
|
-
return null;
|
|
4683
|
-
}
|
|
4684
|
-
if (typeof json.version !== "number" || json.version < 1) {
|
|
4685
|
-
return null;
|
|
4686
|
-
}
|
|
4687
|
-
const snapshot = json.snapshot;
|
|
4688
|
-
if (!isRecord(snapshot)) {
|
|
4689
|
-
return null;
|
|
4690
|
-
}
|
|
4691
|
-
const entities = snapshot.entities;
|
|
4692
|
-
const components = snapshot.components;
|
|
4693
|
-
if (!Array.isArray(entities) || !Array.isArray(components)) {
|
|
4694
|
-
return null;
|
|
4695
|
-
}
|
|
4696
|
-
if (!entities.every((id) => typeof id === "number")) {
|
|
4697
|
-
return null;
|
|
4698
|
-
}
|
|
4699
|
-
if (!components.every(
|
|
4700
|
-
(block) => isRecord(block) && typeof block.component === "string" && Array.isArray(block.entries)
|
|
4701
|
-
)) {
|
|
4702
|
-
return null;
|
|
4703
|
-
}
|
|
4704
|
-
return {
|
|
4705
|
-
version: json.version,
|
|
4706
|
-
type: json.type === "scene" ? "scene" : "prefab",
|
|
4707
|
-
name: typeof json.name === "string" ? json.name : void 0,
|
|
4708
|
-
snapshot
|
|
4709
|
-
};
|
|
4710
|
-
}
|
|
4711
|
-
__name(parsePrefabAsset, "parsePrefabAsset");
|
|
4712
|
-
|
|
4713
|
-
// core/prefab/spawnPrefab.ts
|
|
4714
|
-
var prefabAssetUrlResolver = null;
|
|
4715
|
-
function setPrefabAssetUrlResolver(resolver) {
|
|
4716
|
-
prefabAssetUrlResolver = resolver;
|
|
4717
|
-
}
|
|
4718
|
-
__name(setPrefabAssetUrlResolver, "setPrefabAssetUrlResolver");
|
|
4719
|
-
var resolveUrl = /* @__PURE__ */ __name((url) => prefabAssetUrlResolver ? prefabAssetUrlResolver(url) : url, "resolveUrl");
|
|
4720
|
-
function transformStringsDeep(value, fn) {
|
|
4721
|
-
if (typeof value === "string") {
|
|
4722
|
-
return fn(value);
|
|
4723
|
-
}
|
|
4724
|
-
if (Array.isArray(value)) {
|
|
4725
|
-
return value.map((item) => transformStringsDeep(item, fn));
|
|
4726
|
-
}
|
|
4727
|
-
if (value !== null && typeof value === "object") {
|
|
4728
|
-
const result = {};
|
|
4729
|
-
for (const [key, item] of Object.entries(value)) {
|
|
4730
|
-
result[key] = transformStringsDeep(item, fn);
|
|
4731
|
-
}
|
|
4732
|
-
return result;
|
|
4733
|
-
}
|
|
4734
|
-
return value;
|
|
4735
|
-
}
|
|
4736
|
-
__name(transformStringsDeep, "transformStringsDeep");
|
|
4737
|
-
var prefabCache = /* @__PURE__ */ new Map();
|
|
4738
|
-
function loadPrefab(url) {
|
|
4739
|
-
const cached = prefabCache.get(url);
|
|
4740
|
-
if (cached) {
|
|
4741
|
-
return cached;
|
|
4742
|
-
}
|
|
4743
|
-
const pending = (async () => {
|
|
4744
|
-
const response = await fetch(resolveUrl(url));
|
|
4745
|
-
if (!response.ok) {
|
|
4746
|
-
throw new Error(`Failed to fetch prefab "${url}" (${response.status})`);
|
|
4747
|
-
}
|
|
4748
|
-
const json = await response.json();
|
|
4749
|
-
const parsed = parsePrefabAsset(json);
|
|
4750
|
-
if (!parsed) {
|
|
4751
|
-
throw new Error(`Invalid prefab file at "${url}"`);
|
|
4752
|
-
}
|
|
4753
|
-
return {
|
|
4754
|
-
...parsed,
|
|
4755
|
-
snapshot: transformStringsDeep(
|
|
4756
|
-
parsed.snapshot,
|
|
4757
|
-
resolveUrl
|
|
4758
|
-
)
|
|
4759
|
-
};
|
|
4760
|
-
})();
|
|
4761
|
-
prefabCache.set(url, pending);
|
|
4762
|
-
pending.catch(() => {
|
|
4763
|
-
if (prefabCache.get(url) === pending) {
|
|
4764
|
-
prefabCache.delete(url);
|
|
4765
|
-
}
|
|
4766
|
-
});
|
|
4767
|
-
return pending;
|
|
4768
|
-
}
|
|
4769
|
-
__name(loadPrefab, "loadPrefab");
|
|
4770
|
-
function clearPrefabCache(url) {
|
|
4771
|
-
if (typeof url === "string") {
|
|
4772
|
-
prefabCache.delete(url);
|
|
4773
|
-
} else {
|
|
4774
|
-
prefabCache.clear();
|
|
4775
|
-
}
|
|
4776
|
-
}
|
|
4777
|
-
__name(clearPrefabCache, "clearPrefabCache");
|
|
4778
|
-
function resolveSource(source) {
|
|
4779
|
-
if (typeof source === "string") {
|
|
4780
|
-
return { url: source, asset: loadPrefab(source) };
|
|
4781
|
-
}
|
|
4782
|
-
if ("path" in source && typeof source.path === "string") {
|
|
4783
|
-
return { url: source.path, asset: loadPrefab(source.path) };
|
|
4784
|
-
}
|
|
4785
|
-
const asset = source;
|
|
4786
|
-
return { url: asset.name ?? "", asset };
|
|
4787
|
-
}
|
|
4788
|
-
__name(resolveSource, "resolveSource");
|
|
4789
|
-
async function spawnPrefab(world, source, options) {
|
|
4790
|
-
const { url, asset } = resolveSource(source);
|
|
4791
|
-
const prefab = await asset;
|
|
4792
|
-
const objectManagementSystem = world.getObjectManagementSystem();
|
|
4793
|
-
const { rootId } = instantiateSubtree(
|
|
4794
|
-
world,
|
|
4795
|
-
objectManagementSystem,
|
|
4796
|
-
prefab.snapshot
|
|
4797
|
-
);
|
|
4798
|
-
if (rootId === null) {
|
|
4799
|
-
throw new Error(
|
|
4800
|
-
`Prefab "${url || prefab.name || "unknown"}" contained no spawnable entities`
|
|
4801
|
-
);
|
|
4802
|
-
}
|
|
4803
|
-
if (!world.getComponent(rootId, PrefabInstance)) {
|
|
4804
|
-
world.addComponent(rootId, new PrefabInstance(url, []));
|
|
4805
|
-
}
|
|
4806
|
-
if (options?.parentId !== void 0 && options.parentId !== null) {
|
|
4807
|
-
objectManagementSystem.setParent(world, rootId, options.parentId, {
|
|
4808
|
-
preserveWorldTransform: false
|
|
4809
|
-
});
|
|
4810
|
-
}
|
|
4811
|
-
const transform = world.getComponent(rootId, TransformComponent);
|
|
4812
|
-
if (transform && (options?.position || options?.rotation || options?.scale)) {
|
|
4813
|
-
const write = /* @__PURE__ */ __name((target, src) => {
|
|
4814
|
-
if (!src) return;
|
|
4815
|
-
if (typeof src.x === "number") target.x = src.x;
|
|
4816
|
-
if (typeof src.y === "number") target.y = src.y;
|
|
4817
|
-
if (typeof src.z === "number") target.z = src.z;
|
|
4818
|
-
}, "write");
|
|
4819
|
-
write(transform.position, options.position);
|
|
4820
|
-
write(transform.rotation, options.rotation);
|
|
4821
|
-
write(transform.scale, options.scale);
|
|
4822
|
-
const object = world.getComponent(rootId, Object3DRef)?.object;
|
|
4823
|
-
if (object) {
|
|
4824
|
-
applyTransform(object, transform);
|
|
4825
|
-
object.updateMatrixWorld(true);
|
|
4826
|
-
}
|
|
4827
|
-
}
|
|
4828
|
-
return rootId;
|
|
4829
|
-
}
|
|
4830
|
-
__name(spawnPrefab, "spawnPrefab");
|
|
4831
|
-
function despawnPrefab(world, rootId, dispose = true) {
|
|
4832
|
-
const objectManagementSystem = world.getObjectManagementSystem();
|
|
4833
|
-
const subtree = collectEntitySubtree(world, [rootId]).reverse();
|
|
4834
|
-
let removed = 0;
|
|
4835
|
-
for (const entityId of subtree) {
|
|
4836
|
-
if (objectManagementSystem.deleteEntity(world, entityId, dispose)) {
|
|
4837
|
-
removed += 1;
|
|
4838
|
-
}
|
|
4839
|
-
}
|
|
4840
|
-
return removed;
|
|
4841
|
-
}
|
|
4842
|
-
__name(despawnPrefab, "despawnPrefab");
|
|
4843
|
-
var _Behaviour = class _Behaviour {
|
|
4844
|
-
/**
|
|
4845
|
-
* Engine-managed constructor. Hosts (`ScriptBehaviourSystem`) instantiate
|
|
4846
|
-
* subclasses with the owning world, the entity id, and the script's `data`
|
|
4847
|
-
* payload. User code should not call this directly.
|
|
4848
|
-
*
|
|
4849
|
-
* @param world - The owning ECS world.
|
|
4850
|
-
* @param entityId - The entity this script is bound to.
|
|
4851
|
-
* @param component - The `ScriptComponent.data` payload, or any object that
|
|
4852
|
-
* should be exposed to the script as `this.data`.
|
|
4853
|
-
*/
|
|
4854
|
-
constructor(world, entityId, component) {
|
|
4855
|
-
/**
|
|
4856
|
-
* Inspector-bound payload from the entity's `ScriptComponent`. Override the
|
|
4857
|
-
* type on subclasses with `declare data: MyDataShape` to get type safety
|
|
4858
|
-
* inside hooks. Saved with the project so values persist across reloads.
|
|
4859
|
-
*/
|
|
4860
|
-
this.data = {};
|
|
4861
|
-
/**
|
|
4862
|
-
* Seconds elapsed since the last frame. Set by the engine before each
|
|
4863
|
-
* {@link Behaviour.onUpdate}.
|
|
4864
|
-
*/
|
|
4865
|
-
this.deltaTime = 0;
|
|
4866
|
-
this.world = world;
|
|
4867
|
-
this.entityId = entityId;
|
|
4868
|
-
if (component) this.data = component;
|
|
4869
|
-
this.entity = this.getEntity();
|
|
4870
|
-
this.threeRef = this.getComponent(Object3DRef);
|
|
4871
|
-
this.transform = this.getComponent(TransformComponent);
|
|
4872
|
-
}
|
|
4873
|
-
/**
|
|
4874
|
-
* Engine-managed per-frame entry point. Refreshes {@link Behaviour.deltaTime}
|
|
4875
|
-
* and delegates to {@link Behaviour.onUpdate}.
|
|
4876
|
-
*
|
|
4877
|
-
* @remarks Do **not** override this method — override
|
|
4878
|
-
* {@link Behaviour.onUpdate} instead.
|
|
4879
|
-
*
|
|
4880
|
-
* @param world - The owning world (may differ from the constructor world
|
|
4881
|
-
* after hot reload).
|
|
4882
|
-
* @param deltaTime - Seconds since the last frame.
|
|
4883
|
-
*/
|
|
4884
|
-
update(world, deltaTime) {
|
|
4885
|
-
this.deltaTime = deltaTime;
|
|
4886
|
-
this.world = world;
|
|
4887
|
-
this.onUpdate();
|
|
4888
|
-
}
|
|
4889
|
-
/**
|
|
4890
|
-
* Optional cleanup hook invoked when the script is detached or the entity
|
|
4891
|
-
* is destroyed. Override to release timers, listeners, or other resources.
|
|
4892
|
-
*
|
|
4893
|
-
* @param world - The owning world at disposal time.
|
|
4894
|
-
*/
|
|
4895
|
-
dispose(world) {
|
|
4896
|
-
}
|
|
4897
|
-
/**
|
|
4898
|
-
* Instantiate a prefab asset into the world at runtime.
|
|
4899
|
-
*
|
|
4900
|
-
* `source` is typically an `AssetInput` field from this script's `data`
|
|
4901
|
-
* (drag a `.prefab` from the asset browser onto the field in the editor),
|
|
4902
|
-
* a URL string, or a pre-loaded `PrefabAsset`. Resolves with the new root
|
|
4903
|
-
* entity id.
|
|
4904
|
-
*
|
|
4905
|
-
* ```ts
|
|
4906
|
-
* data = { enemyPrefab: { path: "", type: "prefab" } };
|
|
4907
|
-
* async onUpdate() {
|
|
4908
|
-
* if (shouldSpawn) {
|
|
4909
|
-
* const id = await this.spawnPrefab(this.data.enemyPrefab, {
|
|
4910
|
-
* position: { x: 0, y: 0, z: -5 },
|
|
4911
|
-
* });
|
|
4912
|
-
* }
|
|
4913
|
-
* }
|
|
4914
|
-
* ```
|
|
4915
|
-
*/
|
|
4916
|
-
spawnPrefab(source, options) {
|
|
4917
|
-
return spawnPrefab(this.world, source, options);
|
|
4918
|
-
}
|
|
4919
|
-
/**
|
|
4920
|
-
* Remove a spawned prefab instance (the root entity and all descendants).
|
|
4921
|
-
* Returns the number of entities removed.
|
|
4922
|
-
*/
|
|
4923
|
-
despawn(rootEntityId) {
|
|
4924
|
-
return despawnPrefab(this.world, rootEntityId);
|
|
4925
|
-
}
|
|
4926
|
-
/**
|
|
4927
|
-
* Returns the entity's world-space position as a new `THREE.Vector3`, or
|
|
4928
|
-
* `null` if the entity has no scene presence.
|
|
4929
|
-
*/
|
|
4930
|
-
getWorldPosition() {
|
|
4931
|
-
if (!this.threeRef) {
|
|
4932
|
-
return null;
|
|
4933
|
-
}
|
|
4934
|
-
const position = new THREE19.Vector3();
|
|
4935
|
-
this.threeRef.object.getWorldPosition(position);
|
|
4936
|
-
return position;
|
|
4937
|
-
}
|
|
4938
|
-
/**
|
|
4939
|
-
* Returns the entity's forward direction in world space (the +Z axis of its
|
|
4940
|
-
* world matrix), or `null` if the entity has no scene presence.
|
|
4941
|
-
*/
|
|
4942
|
-
getWorldDirection() {
|
|
4943
|
-
if (!this.threeRef) {
|
|
4944
|
-
return null;
|
|
4945
|
-
}
|
|
4946
|
-
const target = new THREE19.Vector3();
|
|
4947
|
-
this.threeRef.object.getWorldDirection(target);
|
|
4948
|
-
return target;
|
|
4949
|
-
}
|
|
4950
|
-
/**
|
|
4951
|
-
* Returns a unit vector pointing from this entity toward the given world
|
|
4952
|
-
* position, or `null` if the entity has no scene presence.
|
|
4953
|
-
*
|
|
4954
|
-
* @param targetPosition - Destination point in world space.
|
|
4955
|
-
*/
|
|
4956
|
-
directionTo(targetPosition) {
|
|
4957
|
-
const currentPosition = this.getWorldPosition();
|
|
4958
|
-
if (!currentPosition) {
|
|
4959
|
-
return null;
|
|
4960
|
-
}
|
|
4961
|
-
return targetPosition.clone().sub(currentPosition).normalize();
|
|
4962
|
-
}
|
|
4963
|
-
/**
|
|
4964
|
-
* Returns the world-space distance from this entity to the given position,
|
|
4965
|
-
* or `null` if the entity has no scene presence.
|
|
4966
|
-
*
|
|
4967
|
-
* @param targetPosition - Destination point in world space.
|
|
4968
|
-
*/
|
|
4969
|
-
distanceTo(targetPosition) {
|
|
4970
|
-
const currentPosition = this.getWorldPosition();
|
|
4971
|
-
if (!currentPosition) {
|
|
4972
|
-
return null;
|
|
4973
|
-
}
|
|
4974
|
-
return currentPosition.distanceTo(targetPosition);
|
|
4975
|
-
}
|
|
4976
|
-
/**
|
|
4977
|
-
* Linearly interpolates the entity's position toward `targetPosition` and
|
|
4978
|
-
* writes the result back through {@link TransformComponent}. No-op if the
|
|
4979
|
-
* entity has no scene presence.
|
|
4980
|
-
*
|
|
4981
|
-
* @param targetPosition - Destination point in world space.
|
|
4982
|
-
* @param alpha - Interpolation factor in [0, 1]. Multiply by `deltaTime`
|
|
4983
|
-
* for frame-rate-independent smoothing.
|
|
4984
|
-
*/
|
|
4985
|
-
lerpTo(targetPosition, alpha) {
|
|
4986
|
-
if (!this.threeRef) {
|
|
4987
|
-
return;
|
|
4988
|
-
}
|
|
4989
|
-
const currentPosition = this.getWorldPosition();
|
|
4990
|
-
if (!currentPosition) {
|
|
4991
|
-
return;
|
|
4992
|
-
}
|
|
4993
|
-
const newPosition = currentPosition.lerp(targetPosition, alpha);
|
|
4994
|
-
this.transform.setPosition(newPosition);
|
|
4995
|
-
}
|
|
4996
|
-
/**
|
|
4997
|
-
* Spherically interpolates the entity's rotation toward `targetRotation`
|
|
4998
|
-
* and writes the result back through {@link TransformComponent}. No-op if
|
|
4999
|
-
* the entity has no scene presence.
|
|
5000
|
-
*
|
|
5001
|
-
* @param targetRotation - Destination orientation as a quaternion.
|
|
5002
|
-
* @param alpha - Interpolation factor in [0, 1].
|
|
5003
|
-
*/
|
|
5004
|
-
slerpTo(targetRotation, alpha) {
|
|
5005
|
-
if (!this.threeRef) {
|
|
5006
|
-
return;
|
|
5007
|
-
}
|
|
5008
|
-
const rotation = new THREE19.Quaternion();
|
|
5009
|
-
this.threeRef.object.getWorldQuaternion(rotation);
|
|
5010
|
-
rotation.slerp(targetRotation, alpha);
|
|
5011
|
-
this.transform.setRotation(rotation);
|
|
5012
|
-
}
|
|
5013
|
-
/**
|
|
5014
|
-
* Rotates the entity to face `targetPosition` in world space and writes the
|
|
5015
|
-
* resulting orientation back through {@link TransformComponent}. No-op if
|
|
5016
|
-
* the entity has no scene presence.
|
|
5017
|
-
*
|
|
5018
|
-
* @param targetPosition - Point in world space to face.
|
|
5019
|
-
*/
|
|
5020
|
-
lookAt(targetPosition) {
|
|
5021
|
-
if (!this.threeRef) {
|
|
5022
|
-
return;
|
|
3062
|
+
im.castShadow = comp.castShadow;
|
|
3063
|
+
im.receiveShadow = comp.receiveShadow;
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
5023
3066
|
}
|
|
5024
|
-
const clone2 = this.threeRef.object.clone();
|
|
5025
|
-
const rotation = new THREE19.Quaternion();
|
|
5026
|
-
clone2.lookAt(targetPosition);
|
|
5027
|
-
clone2.getWorldQuaternion(rotation);
|
|
5028
|
-
this.transform.setRotation(rotation);
|
|
5029
|
-
}
|
|
5030
|
-
/** Returns every component currently attached to this entity. */
|
|
5031
|
-
getComponents() {
|
|
5032
|
-
return this.world.getEntityById(this.entityId)?.components ?? [];
|
|
5033
|
-
}
|
|
5034
|
-
/**
|
|
5035
|
-
* Returns the entity's component of the given class, or `null` if it has
|
|
5036
|
-
* no such component.
|
|
5037
|
-
*
|
|
5038
|
-
* @typeParam T - Concrete component type.
|
|
5039
|
-
* @param componentClass - Component class constructor to look up.
|
|
5040
|
-
*
|
|
5041
|
-
* @example
|
|
5042
|
-
* ```ts
|
|
5043
|
-
* const mesh = this.getComponent(MeshComponent);
|
|
5044
|
-
* if (mesh) console.log(mesh.geometryRef);
|
|
5045
|
-
* ```
|
|
5046
|
-
*/
|
|
5047
|
-
getComponent(componentClass) {
|
|
5048
|
-
return this.world.getComponent(this.entityId, componentClass) ?? null;
|
|
5049
3067
|
}
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
3068
|
+
};
|
|
3069
|
+
__name(_InstancedMeshSystem, "InstancedMeshSystem");
|
|
3070
|
+
var InstancedMeshSystem = _InstancedMeshSystem;
|
|
3071
|
+
|
|
3072
|
+
// core/systems/RenderSystem.ts
|
|
3073
|
+
var _RenderSystem = class _RenderSystem {
|
|
3074
|
+
constructor(renderer, scene, camera, afterRender) {
|
|
3075
|
+
/** Composer the last size was pushed to, plus that size. */
|
|
3076
|
+
this.sizedComposer = null;
|
|
3077
|
+
this.sizedWidth = 0;
|
|
3078
|
+
this.sizedHeight = 0;
|
|
3079
|
+
this.sizedPixelRatio = 0;
|
|
3080
|
+
this.warnedUninitialized = false;
|
|
3081
|
+
this.renderer = renderer;
|
|
3082
|
+
this.scene = scene;
|
|
3083
|
+
this.camera = camera;
|
|
3084
|
+
this.afterRender = afterRender;
|
|
5056
3085
|
}
|
|
5057
3086
|
/**
|
|
5058
|
-
*
|
|
5059
|
-
*
|
|
5060
|
-
* @returns A {@link ParentLookup} with the parent component reference and
|
|
5061
|
-
* the parent entity view (or `null` if the entity is at the root).
|
|
3087
|
+
* `WebGPURenderer.render()` throws until `await renderer.init()` resolved.
|
|
3088
|
+
* Skip those frames (warning once) rather than throwing from the loop.
|
|
5062
3089
|
*/
|
|
5063
|
-
|
|
5064
|
-
const
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
return {
|
|
5068
|
-
parentIdComponent,
|
|
5069
|
-
parent: null
|
|
5070
|
-
};
|
|
3090
|
+
isRendererReady() {
|
|
3091
|
+
const renderer = this.renderer;
|
|
3092
|
+
if (renderer.isWebGPURenderer !== true || renderer.initialized !== false) {
|
|
3093
|
+
return true;
|
|
5071
3094
|
}
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
}
|
|
5077
|
-
/**
|
|
5078
|
-
* Returns every direct child entity of this one (entities whose
|
|
5079
|
-
* {@link ParentId} matches `entityId`).
|
|
5080
|
-
*/
|
|
5081
|
-
getChildren() {
|
|
5082
|
-
return this.world.getAllEntities().filter((entity) => {
|
|
5083
|
-
const parentIdComponent = entity.components.find(
|
|
5084
|
-
(component) => component instanceof ParentId
|
|
3095
|
+
if (!this.warnedUninitialized) {
|
|
3096
|
+
this.warnedUninitialized = true;
|
|
3097
|
+
console.warn(
|
|
3098
|
+
"[spatial-ecs] RenderSystem skipped a frame: the WebGPURenderer is not initialised yet. Call `await renderer.init()` before the first world.update()."
|
|
5085
3099
|
);
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
}
|
|
5089
|
-
/**
|
|
5090
|
-
* Called once before the first {@link Behaviour.onUpdate}. Override to
|
|
5091
|
-
* default and validate {@link Behaviour.data}, cache references, or set
|
|
5092
|
-
* initial state. Runs at preview/runtime only — never in the editor.
|
|
5093
|
-
*/
|
|
5094
|
-
init() {
|
|
5095
|
-
}
|
|
5096
|
-
/**
|
|
5097
|
-
* Called every frame while the script is enabled. Override with the
|
|
5098
|
-
* script's main per-frame logic. Runs at preview/runtime only — never in the
|
|
5099
|
-
* editor (use {@link ScriptObject} for editor-visible visuals).
|
|
5100
|
-
*/
|
|
5101
|
-
onUpdate() {
|
|
5102
|
-
}
|
|
5103
|
-
/** Called when the editor selects this entity. Optional UX hook. */
|
|
5104
|
-
onSelect() {
|
|
5105
|
-
}
|
|
5106
|
-
/** Called when the editor deselects this entity. Optional UX hook. */
|
|
5107
|
-
onDeselect() {
|
|
5108
|
-
}
|
|
5109
|
-
/**
|
|
5110
|
-
* Called when an image-tracking target this entity depends on becomes
|
|
5111
|
-
* visible. Optional AR hook.
|
|
5112
|
-
*
|
|
5113
|
-
* @param target - The newly-visible target entity view.
|
|
5114
|
-
*/
|
|
5115
|
-
onTargetFound(target) {
|
|
5116
|
-
}
|
|
5117
|
-
/**
|
|
5118
|
-
* Called when an image-tracking target this entity depends on is lost.
|
|
5119
|
-
* Optional AR hook.
|
|
5120
|
-
*
|
|
5121
|
-
* @param target - The target entity view that became invisible.
|
|
5122
|
-
*/
|
|
5123
|
-
onTargetLost(target) {
|
|
5124
|
-
}
|
|
5125
|
-
// ─── WebXR (VR / MR) hooks ────────────────────────────────────────────────
|
|
5126
|
-
// Dispatched by XRSessionSystem / XRInteractionSystem, following the same
|
|
5127
|
-
// pattern as the AR hooks above: public no-op methods that subclasses opt
|
|
5128
|
-
// into by overriding. They never fire outside an immersive session.
|
|
5129
|
-
/**
|
|
5130
|
-
* Called once when an immersive session starts. Optional XR hook.
|
|
5131
|
-
*
|
|
5132
|
-
* Use it to set up XR-only state. Inspect `capabilities` rather than guessing
|
|
5133
|
-
* by device: feature support differs sharply per headset (for example Vision
|
|
5134
|
-
* Pro grants no passthrough on the web today).
|
|
5135
|
-
*
|
|
5136
|
-
* @param capabilities - What the session actually granted, read from
|
|
5137
|
-
* `XRSession.enabledFeatures`.
|
|
5138
|
-
*/
|
|
5139
|
-
onXRSessionStart(capabilities) {
|
|
5140
|
-
}
|
|
5141
|
-
/** Called once when the immersive session ends. Optional XR hook. */
|
|
5142
|
-
onXRSessionEnd() {
|
|
5143
|
-
}
|
|
5144
|
-
/**
|
|
5145
|
-
* Called when a primary action begins — controller trigger, hand pinch, or
|
|
5146
|
-
* Vision Pro gaze-pinch. Optional XR hook.
|
|
5147
|
-
*
|
|
5148
|
-
* @param input - Normalized state for the source that acted.
|
|
5149
|
-
*/
|
|
5150
|
-
onSelectStart(input) {
|
|
5151
|
-
}
|
|
5152
|
-
/** Called when the primary action ends. Optional XR hook. */
|
|
5153
|
-
onSelectEnd(input) {
|
|
5154
|
-
}
|
|
5155
|
-
/**
|
|
5156
|
-
* Called when this entity is grabbed. Optional XR hook.
|
|
5157
|
-
*
|
|
5158
|
-
* Only fires for entities carrying an enabled, grabbable
|
|
5159
|
-
* `XRInteractableComponent`.
|
|
5160
|
-
*
|
|
5161
|
-
* @param input - The source doing the grabbing.
|
|
5162
|
-
*/
|
|
5163
|
-
/**
|
|
5164
|
-
* A SECOND hand joined a two-hand grab on this entity.
|
|
5165
|
-
*
|
|
5166
|
-
* The first hand anchors the object and keeps holding it; this fires for the
|
|
5167
|
-
* hand that came second — the foregrip on a rifle, say.
|
|
5168
|
-
*/
|
|
5169
|
-
onSecondaryGrab(_input) {
|
|
5170
|
-
}
|
|
5171
|
-
/** The second hand let go, leaving the object in the first hand alone. */
|
|
5172
|
-
onSecondaryRelease(_input) {
|
|
3100
|
+
}
|
|
3101
|
+
return false;
|
|
5173
3102
|
}
|
|
5174
3103
|
/**
|
|
5175
|
-
*
|
|
5176
|
-
*
|
|
5177
|
-
*
|
|
5178
|
-
* the fingers pass through it.
|
|
3104
|
+
* Resize the composer only when the canvas size or pixel ratio changed, or
|
|
3105
|
+
* when the composer itself was rebuilt. `setSize` resizes every render
|
|
3106
|
+
* target in the chain, so calling it every frame wasted GPU work.
|
|
5179
3107
|
*/
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
/** Called when this entity is released. Optional XR hook. */
|
|
5188
|
-
onRelease(input) {
|
|
5189
|
-
}
|
|
5190
|
-
/** A UI button on this entity (or a descendant) was clicked. Clicks fire on
|
|
5191
|
-
* RELEASE while still pointing at the widget — sliding off cancels. */
|
|
5192
|
-
onUiPress(_event) {
|
|
5193
|
-
}
|
|
5194
|
-
/** A pointer began hovering a UI widget on this entity (or a descendant). */
|
|
5195
|
-
onUiHoverStart(_event) {
|
|
5196
|
-
}
|
|
5197
|
-
/** The pointer left the widget. */
|
|
5198
|
-
onUiHoverEnd(_event) {
|
|
5199
|
-
}
|
|
5200
|
-
/** A UI toggle flipped; `event.value` is the new boolean. */
|
|
5201
|
-
onUiToggle(_event) {
|
|
5202
|
-
}
|
|
5203
|
-
/** A UI slider moved; `event.value` is the new number. Fires on real value
|
|
5204
|
-
* changes during the drag and once more on release. */
|
|
5205
|
-
onUiChange(_event) {
|
|
5206
|
-
}
|
|
5207
|
-
};
|
|
5208
|
-
__name(_Behaviour, "Behaviour");
|
|
5209
|
-
/**
|
|
5210
|
-
* Static marker used by `ScriptBehaviourSystem` to detect `Behaviour`
|
|
5211
|
-
* subclasses across bundle-identity splits (esbuild may produce a second
|
|
5212
|
-
* copy of the package when scripts are bundled, breaking `instanceof`).
|
|
5213
|
-
* Inherited by every subclass via the prototype chain.
|
|
5214
|
-
*
|
|
5215
|
-
* @internal
|
|
5216
|
-
*/
|
|
5217
|
-
_Behaviour.__reluBehaviourClass = true;
|
|
5218
|
-
var Behaviour = _Behaviour;
|
|
5219
|
-
|
|
5220
|
-
// core/systems/scriptShared.ts
|
|
5221
|
-
async function defaultModuleLoader(scriptUrl) {
|
|
5222
|
-
return await import(
|
|
5223
|
-
/* webpackIgnore: true */
|
|
5224
|
-
scriptUrl
|
|
5225
|
-
);
|
|
5226
|
-
}
|
|
5227
|
-
__name(defaultModuleLoader, "defaultModuleLoader");
|
|
5228
|
-
function toErrorMessage(error) {
|
|
5229
|
-
const sanitize = /* @__PURE__ */ __name((value) => value.replace(/localasset:\/\/[^/]+\//g, "localasset://").replace(/\/Users\/[^\s)]+/g, "[local path]"), "sanitize");
|
|
5230
|
-
if (error instanceof Error && error.message) {
|
|
5231
|
-
return sanitize(error.message);
|
|
5232
|
-
}
|
|
5233
|
-
if (typeof error === "string" && error) {
|
|
5234
|
-
return sanitize(error);
|
|
5235
|
-
}
|
|
5236
|
-
return "Unknown script error.";
|
|
5237
|
-
}
|
|
5238
|
-
__name(toErrorMessage, "toErrorMessage");
|
|
5239
|
-
function resolveScriptCtor(moduleValue, className, options) {
|
|
5240
|
-
const named = moduleValue[className];
|
|
5241
|
-
const fallback = moduleValue.default;
|
|
5242
|
-
const candidate = typeof named === "function" ? named : typeof fallback === "function" ? fallback : null;
|
|
5243
|
-
if (!candidate) {
|
|
5244
|
-
return null;
|
|
5245
|
-
}
|
|
5246
|
-
if (!(candidate.prototype instanceof options.baseClass)) {
|
|
5247
|
-
const marker = candidate[options.markerKey];
|
|
5248
|
-
if (!marker) {
|
|
5249
|
-
return null;
|
|
3108
|
+
syncComposerSize(composer) {
|
|
3109
|
+
const width = Math.max(1, this.renderer.domElement.clientWidth);
|
|
3110
|
+
const height = Math.max(1, this.renderer.domElement.clientHeight);
|
|
3111
|
+
const pixelRatio = typeof this.renderer.getPixelRatio === "function" ? this.renderer.getPixelRatio() : 1;
|
|
3112
|
+
const isNewComposer = composer !== this.sizedComposer;
|
|
3113
|
+
if (!isNewComposer && width === this.sizedWidth && height === this.sizedHeight && pixelRatio === this.sizedPixelRatio) {
|
|
3114
|
+
return;
|
|
5250
3115
|
}
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
}
|
|
5254
|
-
__name(resolveScriptCtor, "resolveScriptCtor");
|
|
5255
|
-
function normalizeScriptData(value) {
|
|
5256
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
5257
|
-
}
|
|
5258
|
-
__name(normalizeScriptData, "normalizeScriptData");
|
|
5259
|
-
function isPlainObject(value) {
|
|
5260
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
5261
|
-
}
|
|
5262
|
-
__name(isPlainObject, "isPlainObject");
|
|
5263
|
-
function mergeValueByDefaultShape(defaultValue, currentValue) {
|
|
5264
|
-
if (Array.isArray(defaultValue)) {
|
|
5265
|
-
return Array.isArray(currentValue) ? currentValue : defaultValue;
|
|
5266
|
-
}
|
|
5267
|
-
if (isPlainObject(defaultValue)) {
|
|
5268
|
-
if (!isPlainObject(currentValue)) {
|
|
5269
|
-
return defaultValue;
|
|
3116
|
+
if ((isNewComposer || pixelRatio !== this.sizedPixelRatio) && typeof composer.setPixelRatio === "function") {
|
|
3117
|
+
composer.setPixelRatio(pixelRatio);
|
|
5270
3118
|
}
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
next[key] = mergeValueByDefaultShape(defaultValue[key], currentValue[key]);
|
|
3119
|
+
if (typeof composer.setSize === "function") {
|
|
3120
|
+
composer.setSize(width, height);
|
|
5274
3121
|
}
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
}
|
|
5280
|
-
if (typeof defaultValue === "string") {
|
|
5281
|
-
return typeof currentValue === "string" ? currentValue : defaultValue;
|
|
5282
|
-
}
|
|
5283
|
-
if (typeof defaultValue === "boolean") {
|
|
5284
|
-
return typeof currentValue === "boolean" ? currentValue : defaultValue;
|
|
5285
|
-
}
|
|
5286
|
-
if (defaultValue === null) {
|
|
5287
|
-
return currentValue !== void 0 ? currentValue : null;
|
|
3122
|
+
this.sizedComposer = composer;
|
|
3123
|
+
this.sizedWidth = width;
|
|
3124
|
+
this.sizedHeight = height;
|
|
3125
|
+
this.sizedPixelRatio = pixelRatio;
|
|
5288
3126
|
}
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
function mergeDataByCurrentDefaults(defaults, current) {
|
|
5293
|
-
const next = {};
|
|
5294
|
-
for (const key of Object.keys(defaults)) {
|
|
5295
|
-
next[key] = mergeValueByDefaultShape(defaults[key], current[key]);
|
|
5296
|
-
}
|
|
5297
|
-
return next;
|
|
5298
|
-
}
|
|
5299
|
-
__name(mergeDataByCurrentDefaults, "mergeDataByCurrentDefaults");
|
|
5300
|
-
function isRawEntityInput(value) {
|
|
5301
|
-
if (!isPlainObject(value)) return false;
|
|
5302
|
-
return value.type === "entity";
|
|
5303
|
-
}
|
|
5304
|
-
__name(isRawEntityInput, "isRawEntityInput");
|
|
5305
|
-
function isRawComponentInput(value) {
|
|
5306
|
-
if (!isPlainObject(value)) return false;
|
|
5307
|
-
return value.type === "component";
|
|
5308
|
-
}
|
|
5309
|
-
__name(isRawComponentInput, "isRawComponentInput");
|
|
5310
|
-
function findComponentByKind(components, componentKind) {
|
|
5311
|
-
return components.find(
|
|
5312
|
-
(c) => c.constructor.name === `${componentKind}Component` || c.constructor.name === componentKind
|
|
5313
|
-
) ?? null;
|
|
5314
|
-
}
|
|
5315
|
-
__name(findComponentByKind, "findComponentByKind");
|
|
5316
|
-
function resolveInputData(world, rawData) {
|
|
5317
|
-
const resolved = { ...rawData };
|
|
5318
|
-
for (const [key, value] of Object.entries(rawData)) {
|
|
5319
|
-
if (isRawEntityInput(value)) {
|
|
5320
|
-
const entityId = value.value;
|
|
5321
|
-
const entityView = typeof entityId === "number" ? world.getEntityById(entityId) : null;
|
|
5322
|
-
resolved[key] = { ...value, value: entityView };
|
|
5323
|
-
} else if (isRawComponentInput(value)) {
|
|
5324
|
-
const ref = value.value;
|
|
5325
|
-
if (isPlainObject(ref) && typeof ref.entityId === "number" && typeof ref.componentKind === "string") {
|
|
5326
|
-
const { entityId: refEntityId, componentKind } = ref;
|
|
5327
|
-
const entityView = world.getEntityById(refEntityId);
|
|
5328
|
-
const component = entityView ? findComponentByKind(entityView.components, componentKind) : null;
|
|
5329
|
-
resolved[key] = { ...value, value: component };
|
|
5330
|
-
}
|
|
3127
|
+
update(_world) {
|
|
3128
|
+
if (!this.isRendererReady()) {
|
|
3129
|
+
return;
|
|
5331
3130
|
}
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
3131
|
+
if (this.scene.userData.ecsPostprocessingComposerActive === true) {
|
|
3132
|
+
const composer = this.scene.userData.ecsPostprocessingComposer;
|
|
3133
|
+
if (composer) {
|
|
3134
|
+
this.syncComposerSize(composer);
|
|
3135
|
+
composer.render();
|
|
3136
|
+
} else {
|
|
3137
|
+
this.renderer.render(this.scene, this.camera);
|
|
3138
|
+
}
|
|
3139
|
+
this.afterRender?.();
|
|
3140
|
+
return;
|
|
5341
3141
|
}
|
|
3142
|
+
this.sizedComposer = null;
|
|
3143
|
+
this.renderer.render(this.scene, this.camera);
|
|
3144
|
+
this.afterRender?.();
|
|
5342
3145
|
}
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
// core/systems/ScriptBehaviourSystem.ts
|
|
3146
|
+
};
|
|
3147
|
+
__name(_RenderSystem, "RenderSystem");
|
|
3148
|
+
var RenderSystem = _RenderSystem;
|
|
3149
|
+
var DEFAULT_SCRIPT_ERROR_RETRY_DELAY = 1;
|
|
5348
3150
|
function buildInstanceKey(entityId, scriptUrl, className) {
|
|
5349
3151
|
return `${entityId}:${scriptUrl}:${className}`;
|
|
5350
3152
|
}
|
|
@@ -5385,9 +3187,13 @@ function writeScriptEntries(component, entries) {
|
|
|
5385
3187
|
}
|
|
5386
3188
|
__name(writeScriptEntries, "writeScriptEntries");
|
|
5387
3189
|
var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
5388
|
-
constructor(moduleLoader, selectionContext) {
|
|
3190
|
+
constructor(moduleLoader, selectionContext, options) {
|
|
5389
3191
|
this.instances = /* @__PURE__ */ new Map();
|
|
5390
3192
|
this.loading = /* @__PURE__ */ new Map();
|
|
3193
|
+
/** Seconds of world time this system has seen (sum of `deltaTime`). */
|
|
3194
|
+
this.clock = 0;
|
|
3195
|
+
/** Instance key → clock time before which a failed script is not retried. */
|
|
3196
|
+
this.retryAt = /* @__PURE__ */ new Map();
|
|
5391
3197
|
this.selectedEntityId = null;
|
|
5392
3198
|
// undefined = nothing queued; null = queued "deselect all"; number = queued entity
|
|
5393
3199
|
this.pendingEntityId = void 0;
|
|
@@ -5404,6 +3210,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5404
3210
|
this.queueRaycast(event.clientX, event.clientY);
|
|
5405
3211
|
}, "onPointerUp");
|
|
5406
3212
|
this.moduleLoader = moduleLoader ?? defaultModuleLoader;
|
|
3213
|
+
const retryDelay = options?.errorRetryDelay;
|
|
3214
|
+
this.errorRetryDelay = typeof retryDelay === "number" && Number.isFinite(retryDelay) ? Math.max(0, retryDelay) : DEFAULT_SCRIPT_ERROR_RETRY_DELAY;
|
|
5407
3215
|
this.selectionCtx = selectionContext ?? null;
|
|
5408
3216
|
this.raycaster = new THREE19.Raycaster();
|
|
5409
3217
|
this.ndcPointer = new THREE19.Vector2();
|
|
@@ -5451,7 +3259,7 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5451
3259
|
* Calls onDeselect() on all behaviours of the previous entity and
|
|
5452
3260
|
* onSelect() on all behaviours of the newly selected entity.
|
|
5453
3261
|
*/
|
|
5454
|
-
applySelection(nextEntityId) {
|
|
3262
|
+
applySelection(world, nextEntityId) {
|
|
5455
3263
|
if (nextEntityId === this.selectedEntityId) return;
|
|
5456
3264
|
const prevEntityId = this.selectedEntityId;
|
|
5457
3265
|
this.selectedEntityId = nextEntityId;
|
|
@@ -5460,7 +3268,8 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5460
3268
|
if (record.entityId === prevEntityId) {
|
|
5461
3269
|
try {
|
|
5462
3270
|
record.behaviour.onDeselect();
|
|
5463
|
-
} catch {
|
|
3271
|
+
} catch (error) {
|
|
3272
|
+
this.reportRecordError(world, record, "onDeselect", error);
|
|
5464
3273
|
}
|
|
5465
3274
|
}
|
|
5466
3275
|
}
|
|
@@ -5470,18 +3279,39 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5470
3279
|
if (record.entityId === nextEntityId) {
|
|
5471
3280
|
try {
|
|
5472
3281
|
record.behaviour.onSelect();
|
|
5473
|
-
} catch {
|
|
3282
|
+
} catch (error) {
|
|
3283
|
+
this.reportRecordError(world, record, "onSelect", error);
|
|
5474
3284
|
}
|
|
5475
3285
|
}
|
|
5476
3286
|
}
|
|
5477
3287
|
}
|
|
5478
3288
|
}
|
|
3289
|
+
reportRecordError(world, record, phase, error) {
|
|
3290
|
+
reportScriptError(
|
|
3291
|
+
world,
|
|
3292
|
+
{
|
|
3293
|
+
entityId: record.entityId,
|
|
3294
|
+
scriptUrl: record.scriptUrl,
|
|
3295
|
+
className: record.className,
|
|
3296
|
+
phase,
|
|
3297
|
+
source: "behaviour"
|
|
3298
|
+
},
|
|
3299
|
+
error
|
|
3300
|
+
);
|
|
3301
|
+
}
|
|
3302
|
+
/** Hold a failed script back for {@link errorRetryDelay} seconds. */
|
|
3303
|
+
scheduleRetry(key) {
|
|
3304
|
+
this.retryAt.set(key, this.clock + this.errorRetryDelay);
|
|
3305
|
+
}
|
|
5479
3306
|
// ── ECS lifecycle ──────────────────────────────────────────────────────────
|
|
5480
3307
|
update(world, deltaTime) {
|
|
3308
|
+
if (Number.isFinite(deltaTime) && deltaTime > 0) {
|
|
3309
|
+
this.clock += deltaTime;
|
|
3310
|
+
}
|
|
5481
3311
|
if (this.pendingEntityId !== void 0) {
|
|
5482
3312
|
const next = this.pendingEntityId;
|
|
5483
3313
|
this.pendingEntityId = void 0;
|
|
5484
|
-
this.applySelection(next);
|
|
3314
|
+
this.applySelection(world, next);
|
|
5485
3315
|
}
|
|
5486
3316
|
const active = /* @__PURE__ */ new Map();
|
|
5487
3317
|
const entityIds = world.query(ScriptComponent);
|
|
@@ -5571,8 +3401,15 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5571
3401
|
if (script.entryIndex === 0) {
|
|
5572
3402
|
script.scriptComponent.scriptInstance = null;
|
|
5573
3403
|
}
|
|
5574
|
-
|
|
3404
|
+
script.scriptComponent.scriptInstances.delete(script.entryIndex);
|
|
3405
|
+
this.reportRecordError(world, record, "update", error);
|
|
3406
|
+
try {
|
|
3407
|
+
record.behaviour.dispose?.(world);
|
|
3408
|
+
} catch (disposeError) {
|
|
3409
|
+
this.reportRecordError(world, record, "dispose", disposeError);
|
|
3410
|
+
}
|
|
5575
3411
|
this.instances.delete(key);
|
|
3412
|
+
this.scheduleRetry(key);
|
|
5576
3413
|
}
|
|
5577
3414
|
}
|
|
5578
3415
|
if (this.selectedEntityId !== null) {
|
|
@@ -5587,10 +3424,22 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5587
3424
|
this.selectedEntityId = null;
|
|
5588
3425
|
}
|
|
5589
3426
|
}
|
|
3427
|
+
for (const key of this.retryAt.keys()) {
|
|
3428
|
+
if (!active.has(key)) {
|
|
3429
|
+
this.retryAt.delete(key);
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
5590
3432
|
for (const [key, script] of active.entries()) {
|
|
5591
3433
|
if (this.instances.has(key) || this.loading.has(key)) {
|
|
5592
3434
|
continue;
|
|
5593
3435
|
}
|
|
3436
|
+
const retryAt = this.retryAt.get(key);
|
|
3437
|
+
if (retryAt !== void 0) {
|
|
3438
|
+
if (this.clock < retryAt) {
|
|
3439
|
+
continue;
|
|
3440
|
+
}
|
|
3441
|
+
this.retryAt.delete(key);
|
|
3442
|
+
}
|
|
5594
3443
|
const entries = readScriptEntries(script.scriptComponent, script.entityId);
|
|
5595
3444
|
const targetEntry = entries[script.entryIndex];
|
|
5596
3445
|
if (targetEntry) {
|
|
@@ -5601,24 +3450,34 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5601
3450
|
};
|
|
5602
3451
|
writeScriptEntries(script.scriptComponent, entries);
|
|
5603
3452
|
}
|
|
5604
|
-
const promise = this.loadBehaviour(world, script).catch((
|
|
3453
|
+
const promise = this.loadBehaviour(world, script).catch((thrown) => {
|
|
3454
|
+
const { phase, error } = readScriptPhase(thrown, "load");
|
|
3455
|
+
const message = toErrorMessage(error);
|
|
5605
3456
|
const liveEntries = readScriptEntries(script.scriptComponent, script.entityId);
|
|
5606
3457
|
const liveEntry = liveEntries[script.entryIndex];
|
|
5607
3458
|
if (liveEntry) {
|
|
5608
3459
|
liveEntries[script.entryIndex] = {
|
|
5609
3460
|
...liveEntry,
|
|
5610
3461
|
runtimeState: "error",
|
|
5611
|
-
runtimeMessage: "Failed to load script
|
|
3462
|
+
runtimeMessage: phase === "load" ? `Failed to load script: ${message}` : message
|
|
5612
3463
|
};
|
|
5613
3464
|
writeScriptEntries(script.scriptComponent, liveEntries);
|
|
5614
3465
|
}
|
|
5615
3466
|
if (script.entryIndex === 0) {
|
|
5616
3467
|
script.scriptComponent.scriptInstance = null;
|
|
5617
3468
|
}
|
|
5618
|
-
|
|
5619
|
-
|
|
3469
|
+
reportScriptError(
|
|
3470
|
+
world,
|
|
3471
|
+
{
|
|
3472
|
+
entityId: script.entityId,
|
|
3473
|
+
scriptUrl: script.scriptEntry.scriptUrl,
|
|
3474
|
+
className: script.scriptEntry.className,
|
|
3475
|
+
phase,
|
|
3476
|
+
source: "behaviour"
|
|
3477
|
+
},
|
|
5620
3478
|
error
|
|
5621
3479
|
);
|
|
3480
|
+
this.scheduleRetry(key);
|
|
5622
3481
|
}).finally(() => {
|
|
5623
3482
|
this.loading.delete(key);
|
|
5624
3483
|
});
|
|
@@ -5648,6 +3507,7 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5648
3507
|
}
|
|
5649
3508
|
this.instances.clear();
|
|
5650
3509
|
this.loading.clear();
|
|
3510
|
+
this.retryAt.clear();
|
|
5651
3511
|
}
|
|
5652
3512
|
async loadBehaviour(world, script) {
|
|
5653
3513
|
const { entityId, scriptComponent, entryIndex, scriptEntry } = script;
|
|
@@ -5656,11 +3516,19 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5656
3516
|
scriptEntry.scriptUrl,
|
|
5657
3517
|
scriptEntry.className
|
|
5658
3518
|
);
|
|
5659
|
-
|
|
3519
|
+
let moduleValue;
|
|
3520
|
+
try {
|
|
3521
|
+
moduleValue = await this.moduleLoader(scriptEntry.scriptUrl);
|
|
3522
|
+
} catch (error) {
|
|
3523
|
+
throw withScriptPhase("load", error);
|
|
3524
|
+
}
|
|
5660
3525
|
const ctor = resolveBehaviourCtor(moduleValue, scriptEntry.className);
|
|
5661
3526
|
if (!ctor) {
|
|
5662
|
-
throw
|
|
5663
|
-
|
|
3527
|
+
throw withScriptPhase(
|
|
3528
|
+
"load",
|
|
3529
|
+
new Error(
|
|
3530
|
+
`Missing Behaviour export '${scriptEntry.className}' in ${scriptEntry.scriptUrl}`
|
|
3531
|
+
)
|
|
5664
3532
|
);
|
|
5665
3533
|
}
|
|
5666
3534
|
if (!world.hasEntity(entityId)) {
|
|
@@ -5677,21 +3545,26 @@ var _ScriptBehaviourSystem = class _ScriptBehaviourSystem {
|
|
|
5677
3545
|
}
|
|
5678
3546
|
const currentData = normalizeScriptData(liveEntry.data);
|
|
5679
3547
|
let behaviour;
|
|
3548
|
+
let mergedData;
|
|
5680
3549
|
try {
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
3550
|
+
try {
|
|
3551
|
+
behaviour = new ctor(
|
|
3552
|
+
world,
|
|
3553
|
+
entityId,
|
|
3554
|
+
void 0
|
|
3555
|
+
);
|
|
3556
|
+
} catch {
|
|
3557
|
+
behaviour = new ctor(world, entityId, currentData);
|
|
3558
|
+
}
|
|
3559
|
+
const defaults = normalizeScriptData(behaviour.data);
|
|
3560
|
+
mergedData = mergeDataByCurrentDefaults(defaults, currentData);
|
|
3561
|
+
const resolvedData = resolveInputData(world, mergedData);
|
|
3562
|
+
behaviour.data = resolvedData;
|
|
3563
|
+
if (!world.isEditorMode()) {
|
|
3564
|
+
behaviour.init();
|
|
3565
|
+
}
|
|
3566
|
+
} catch (error) {
|
|
3567
|
+
throw withScriptPhase("init", error);
|
|
5695
3568
|
}
|
|
5696
3569
|
liveEntries[entryIndex] = {
|
|
5697
3570
|
...liveEntry,
|
|
@@ -5798,9 +3671,12 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5798
3671
|
this.loading = /* @__PURE__ */ new Map();
|
|
5799
3672
|
/** Bumped by invalidate*() so in-flight loads that predate it are discarded. */
|
|
5800
3673
|
this.epoch = 0;
|
|
3674
|
+
/** World seen by the last update(), so invalidate*() can reset error dedupe. */
|
|
3675
|
+
this.lastWorld = null;
|
|
5801
3676
|
this.moduleLoader = moduleLoader ?? defaultModuleLoader;
|
|
5802
3677
|
}
|
|
5803
3678
|
update(world, deltaTime) {
|
|
3679
|
+
this.lastWorld = world;
|
|
5804
3680
|
const active = /* @__PURE__ */ new Map();
|
|
5805
3681
|
for (const entityId of world.query(ScriptObjectComponent)) {
|
|
5806
3682
|
const component = world.getComponent(entityId, ScriptObjectComponent);
|
|
@@ -5841,14 +3717,14 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5841
3717
|
component.data = stored;
|
|
5842
3718
|
record.lastWrittenData = stored;
|
|
5843
3719
|
} catch (error) {
|
|
5844
|
-
this.markError(world, entityId, component, error);
|
|
3720
|
+
this.markError(world, entityId, component, error, "update");
|
|
5845
3721
|
continue;
|
|
5846
3722
|
}
|
|
5847
3723
|
}
|
|
5848
3724
|
try {
|
|
5849
3725
|
record.instance.update?.(deltaTime);
|
|
5850
3726
|
} catch (error) {
|
|
5851
|
-
this.markError(world, entityId, component, error);
|
|
3727
|
+
this.markError(world, entityId, component, error, "update");
|
|
5852
3728
|
}
|
|
5853
3729
|
}
|
|
5854
3730
|
for (const [entityId, component] of active) {
|
|
@@ -5868,12 +3744,12 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5868
3744
|
className,
|
|
5869
3745
|
key,
|
|
5870
3746
|
epochAtStart
|
|
5871
|
-
).catch((
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
);
|
|
3747
|
+
).catch((thrown) => {
|
|
3748
|
+
const { phase, error } = readScriptPhase(thrown, "load");
|
|
3749
|
+
this.markError(world, entityId, void 0, error, phase, {
|
|
3750
|
+
scriptUrl,
|
|
3751
|
+
className
|
|
3752
|
+
});
|
|
5877
3753
|
}).finally(() => {
|
|
5878
3754
|
if (this.loading.get(entityId)?.key === key) {
|
|
5879
3755
|
this.loading.delete(entityId);
|
|
@@ -5886,7 +3762,12 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5886
3762
|
}
|
|
5887
3763
|
}
|
|
5888
3764
|
async loadScriptObject(world, entityId, scriptUrl, className, key, epochAtStart) {
|
|
5889
|
-
|
|
3765
|
+
let moduleValue;
|
|
3766
|
+
try {
|
|
3767
|
+
moduleValue = await this.moduleLoader(scriptUrl);
|
|
3768
|
+
} catch (error) {
|
|
3769
|
+
throw withScriptPhase("load", error);
|
|
3770
|
+
}
|
|
5890
3771
|
if (this.loading.get(entityId)?.key !== key || epochAtStart !== this.epoch || !world.hasEntity(entityId)) {
|
|
5891
3772
|
return;
|
|
5892
3773
|
}
|
|
@@ -5899,16 +3780,21 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5899
3780
|
markerKey: "__reluScriptObjectClass"
|
|
5900
3781
|
});
|
|
5901
3782
|
if (!ctor) {
|
|
5902
|
-
throw
|
|
5903
|
-
|
|
3783
|
+
throw withScriptPhase(
|
|
3784
|
+
"load",
|
|
3785
|
+
new Error(`Missing ScriptObject export '${className}' in ${scriptUrl}`)
|
|
5904
3786
|
);
|
|
5905
3787
|
}
|
|
5906
3788
|
const currentData = normalizeScriptData(component.data);
|
|
5907
3789
|
let instance;
|
|
5908
3790
|
try {
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
3791
|
+
try {
|
|
3792
|
+
instance = new ctor(world, entityId, void 0);
|
|
3793
|
+
} catch {
|
|
3794
|
+
instance = new ctor(world, entityId, currentData);
|
|
3795
|
+
}
|
|
3796
|
+
} catch (error) {
|
|
3797
|
+
throw withScriptPhase("init", error);
|
|
5912
3798
|
}
|
|
5913
3799
|
const literalDefaults = normalizeScriptData(instance.data);
|
|
5914
3800
|
const seed = Object.keys(literalDefaults).length > 0 ? mergeDataByCurrentDefaults(literalDefaults, currentData) : { ...currentData };
|
|
@@ -5930,14 +3816,17 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5930
3816
|
instance.dispose?.();
|
|
5931
3817
|
} catch {
|
|
5932
3818
|
}
|
|
5933
|
-
throw error;
|
|
3819
|
+
throw withScriptPhase("build", error);
|
|
5934
3820
|
}
|
|
5935
3821
|
if (!built || built.isObject3D !== true) {
|
|
5936
3822
|
try {
|
|
5937
3823
|
instance.dispose?.();
|
|
5938
3824
|
} catch {
|
|
5939
3825
|
}
|
|
5940
|
-
throw
|
|
3826
|
+
throw withScriptPhase(
|
|
3827
|
+
"build",
|
|
3828
|
+
new Error("build() must return a THREE.Object3D.")
|
|
3829
|
+
);
|
|
5941
3830
|
}
|
|
5942
3831
|
built.userData[SCRIPT_OBJECT_ROOT_FLAG] = true;
|
|
5943
3832
|
parent.add(built);
|
|
@@ -5985,12 +3874,24 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
5985
3874
|
this.instances.delete(entityId);
|
|
5986
3875
|
}
|
|
5987
3876
|
}
|
|
5988
|
-
markError(world, entityId, component, error) {
|
|
3877
|
+
markError(world, entityId, component, error, phase, identity) {
|
|
5989
3878
|
const comp = component ?? world.getComponent(entityId, ScriptObjectComponent) ?? null;
|
|
5990
3879
|
if (comp) {
|
|
5991
3880
|
comp.runtimeState = "error";
|
|
5992
3881
|
comp.runtimeMessage = toErrorMessage(error);
|
|
5993
3882
|
}
|
|
3883
|
+
const existing = this.instances.get(entityId);
|
|
3884
|
+
reportScriptError(
|
|
3885
|
+
world,
|
|
3886
|
+
{
|
|
3887
|
+
entityId,
|
|
3888
|
+
scriptUrl: identity?.scriptUrl ?? existing?.scriptUrl ?? comp?.scriptUrl ?? "",
|
|
3889
|
+
className: identity?.className ?? existing?.className ?? comp?.className ?? "",
|
|
3890
|
+
phase,
|
|
3891
|
+
source: "scriptObject"
|
|
3892
|
+
},
|
|
3893
|
+
error
|
|
3894
|
+
);
|
|
5994
3895
|
const record = this.instances.get(entityId);
|
|
5995
3896
|
if (record) {
|
|
5996
3897
|
this.teardownRecord(world, entityId, record, true);
|
|
@@ -6010,6 +3911,7 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
6010
3911
|
/** Dispose all live instances so the next update() reloads with fresh modules. */
|
|
6011
3912
|
invalidateAll() {
|
|
6012
3913
|
this.epoch += 1;
|
|
3914
|
+
this.lastWorld?.clearScriptErrors?.();
|
|
6013
3915
|
for (const [entityId, record] of [...this.instances]) {
|
|
6014
3916
|
try {
|
|
6015
3917
|
record.instance?.dispose?.();
|
|
@@ -6023,6 +3925,7 @@ var _ScriptObjectSystem = class _ScriptObjectSystem {
|
|
|
6023
3925
|
/** Invalidate only the entities whose script matches `scriptUrl`. */
|
|
6024
3926
|
invalidate(scriptUrl) {
|
|
6025
3927
|
this.epoch += 1;
|
|
3928
|
+
this.lastWorld?.clearScriptErrors?.(scriptUrl);
|
|
6026
3929
|
for (const [entityId, record] of [...this.instances]) {
|
|
6027
3930
|
if (record.scriptUrl !== scriptUrl) continue;
|
|
6028
3931
|
try {
|
|
@@ -6068,6 +3971,112 @@ var _TransformSyncSystem = class _TransformSyncSystem {
|
|
|
6068
3971
|
};
|
|
6069
3972
|
__name(_TransformSyncSystem, "TransformSyncSystem");
|
|
6070
3973
|
var TransformSyncSystem = _TransformSyncSystem;
|
|
3974
|
+
|
|
3975
|
+
// core/audio/AudioMixer.ts
|
|
3976
|
+
var BUSES = ["sfx", "voice", "music"];
|
|
3977
|
+
var DUCK_GAIN = 0.45;
|
|
3978
|
+
var DUCK_ATTACK = 0.05;
|
|
3979
|
+
var DUCK_RELEASE = 0.3;
|
|
3980
|
+
var _AudioMixer = class _AudioMixer {
|
|
3981
|
+
constructor(listener) {
|
|
3982
|
+
this.listener = listener;
|
|
3983
|
+
this.volumes = {
|
|
3984
|
+
sfx: 1,
|
|
3985
|
+
voice: 1,
|
|
3986
|
+
music: 1
|
|
3987
|
+
};
|
|
3988
|
+
this.routed = /* @__PURE__ */ new WeakMap();
|
|
3989
|
+
const input = listener.getInput();
|
|
3990
|
+
const make = /* @__PURE__ */ __name(() => {
|
|
3991
|
+
const gain = listener.context.createGain();
|
|
3992
|
+
gain.connect(input);
|
|
3993
|
+
return gain;
|
|
3994
|
+
}, "make");
|
|
3995
|
+
this.buses = { sfx: make(), voice: make(), music: make() };
|
|
3996
|
+
}
|
|
3997
|
+
/** The node a sound connects to for this bus. */
|
|
3998
|
+
input(bus) {
|
|
3999
|
+
return this.buses[bus] ?? this.buses.sfx;
|
|
4000
|
+
}
|
|
4001
|
+
/** Send a three.js sound through a bus. Does nothing when it's already there. */
|
|
4002
|
+
route(sound, bus) {
|
|
4003
|
+
if (this.routed.get(sound) === bus) return;
|
|
4004
|
+
const output = sound.getOutput();
|
|
4005
|
+
output.disconnect();
|
|
4006
|
+
output.connect(this.input(bus));
|
|
4007
|
+
this.routed.set(sound, bus);
|
|
4008
|
+
}
|
|
4009
|
+
setVolume(bus, volume) {
|
|
4010
|
+
const v = Math.max(0, volume);
|
|
4011
|
+
this.volumes[bus] = v;
|
|
4012
|
+
this.input(bus).gain.setTargetAtTime(v, this.listener.context.currentTime, 0.02);
|
|
4013
|
+
}
|
|
4014
|
+
getVolume(bus) {
|
|
4015
|
+
return this.volumes[bus];
|
|
4016
|
+
}
|
|
4017
|
+
/** Dip the music for `seconds`, then bring it back. A later duck replaces this one. */
|
|
4018
|
+
duckMusic(seconds) {
|
|
4019
|
+
const gain = this.buses.music.gain;
|
|
4020
|
+
const now = this.listener.context.currentTime;
|
|
4021
|
+
const full = this.volumes.music;
|
|
4022
|
+
gain.cancelScheduledValues(now);
|
|
4023
|
+
gain.setTargetAtTime(full * DUCK_GAIN, now, DUCK_ATTACK);
|
|
4024
|
+
gain.setTargetAtTime(full, now + seconds, DUCK_RELEASE);
|
|
4025
|
+
}
|
|
4026
|
+
dispose() {
|
|
4027
|
+
for (const bus of BUSES) this.buses[bus].disconnect();
|
|
4028
|
+
}
|
|
4029
|
+
};
|
|
4030
|
+
__name(_AudioMixer, "AudioMixer");
|
|
4031
|
+
var AudioMixer = _AudioMixer;
|
|
4032
|
+
|
|
4033
|
+
// core/audio/soundBank.ts
|
|
4034
|
+
function soundBankFiles(bank) {
|
|
4035
|
+
const files = /* @__PURE__ */ new Set();
|
|
4036
|
+
for (const slot of Object.values(bank.slots)) {
|
|
4037
|
+
for (const take of slot.takes) if (take.file) files.add(take.file);
|
|
4038
|
+
}
|
|
4039
|
+
return [...files];
|
|
4040
|
+
}
|
|
4041
|
+
__name(soundBankFiles, "soundBankFiles");
|
|
4042
|
+
function assertSoundBank(value) {
|
|
4043
|
+
const slots = value?.slots;
|
|
4044
|
+
if (!slots || typeof slots !== "object") {
|
|
4045
|
+
throw new Error("Not a sound bank: it has no slots.");
|
|
4046
|
+
}
|
|
4047
|
+
for (const [id, slot] of Object.entries(slots)) {
|
|
4048
|
+
if (!Array.isArray(slot?.takes)) {
|
|
4049
|
+
throw new Error(`Sound bank slot "${id}" has no takes list.`);
|
|
4050
|
+
}
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
__name(assertSoundBank, "assertSoundBank");
|
|
4054
|
+
var _SlotChooser = class _SlotChooser {
|
|
4055
|
+
constructor(random = Math.random) {
|
|
4056
|
+
this.random = random;
|
|
4057
|
+
this.lastPlay = /* @__PURE__ */ new Map();
|
|
4058
|
+
this.lastTake = /* @__PURE__ */ new Map();
|
|
4059
|
+
}
|
|
4060
|
+
/** The take to play now, or `null` to stay silent. `now` is in milliseconds. */
|
|
4061
|
+
choose(id, slot, now) {
|
|
4062
|
+
const takes = slot.takes.filter((t) => t.file);
|
|
4063
|
+
if (takes.length === 0) return null;
|
|
4064
|
+
const last = this.lastPlay.get(id);
|
|
4065
|
+
if (last !== void 0 && now - last < (slot.cooldownMs ?? 0)) return null;
|
|
4066
|
+
if (this.random() >= (slot.chance ?? 1)) return null;
|
|
4067
|
+
const previous = this.lastTake.get(id);
|
|
4068
|
+
const fresh = takes.filter((t) => t.file !== previous);
|
|
4069
|
+
const pool = fresh.length > 0 ? fresh : takes;
|
|
4070
|
+
const take = pool[Math.min(pool.length - 1, Math.floor(this.random() * pool.length))];
|
|
4071
|
+
this.lastPlay.set(id, now);
|
|
4072
|
+
this.lastTake.set(id, take.file);
|
|
4073
|
+
return take;
|
|
4074
|
+
}
|
|
4075
|
+
};
|
|
4076
|
+
__name(_SlotChooser, "SlotChooser");
|
|
4077
|
+
var SlotChooser = _SlotChooser;
|
|
4078
|
+
|
|
4079
|
+
// core/systems/AudioSystem.ts
|
|
6071
4080
|
function snapshotOptions(opts) {
|
|
6072
4081
|
return {
|
|
6073
4082
|
loop: opts.loop,
|
|
@@ -6087,10 +4096,106 @@ var _AudioSystem = class _AudioSystem {
|
|
|
6087
4096
|
this.prevOptions = /* @__PURE__ */ new Map();
|
|
6088
4097
|
/** Tracks entities that were stopped due to invisibility. */
|
|
6089
4098
|
this.stoppedDueToInvisibility = /* @__PURE__ */ new Set();
|
|
4099
|
+
this.world = null;
|
|
4100
|
+
this.mixer = null;
|
|
4101
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
4102
|
+
this.buffers = /* @__PURE__ */ new Map();
|
|
4103
|
+
this.chooser = new SlotChooser();
|
|
4104
|
+
this.voice = null;
|
|
6090
4105
|
this.isEditor = isEditor;
|
|
6091
4106
|
}
|
|
4107
|
+
/** Scripts can load a bank in `init`, before this system's first update. */
|
|
4108
|
+
attachWorld(world) {
|
|
4109
|
+
this.world = world;
|
|
4110
|
+
}
|
|
4111
|
+
/** The mixer, made with the listener on first use. */
|
|
4112
|
+
getMixer() {
|
|
4113
|
+
if (this.mixer) return this.mixer;
|
|
4114
|
+
const listener = this.world?.getObjectManagementSystem()?.getOrCreateAudioListener();
|
|
4115
|
+
if (!listener) return null;
|
|
4116
|
+
this.mixer = new AudioMixer(listener);
|
|
4117
|
+
return this.mixer;
|
|
4118
|
+
}
|
|
4119
|
+
/** Set a bus's volume (`0` silent, `1` as mixed). */
|
|
4120
|
+
setBusVolume(bus, volume) {
|
|
4121
|
+
this.getMixer()?.setVolume(bus, volume);
|
|
4122
|
+
}
|
|
4123
|
+
getBusVolume(bus) {
|
|
4124
|
+
return this.getMixer()?.getVolume(bus) ?? 1;
|
|
4125
|
+
}
|
|
4126
|
+
/**
|
|
4127
|
+
* Fetch a `.soundbank.json` and decode its recordings. Its slots add to any
|
|
4128
|
+
* loaded before, and a slot id used twice takes the later one.
|
|
4129
|
+
* @param source an asset path, or a script's `AssetInput` field
|
|
4130
|
+
*/
|
|
4131
|
+
async loadSoundBank(source) {
|
|
4132
|
+
if (this.isEditor) return;
|
|
4133
|
+
const url = typeof source === "string" ? source : source.path;
|
|
4134
|
+
const res = await fetch(resolvePrefabAssetUrl(url));
|
|
4135
|
+
if (!res.ok) throw new Error(`Couldn't load the sound bank ${url}.`);
|
|
4136
|
+
const bank = await res.json();
|
|
4137
|
+
assertSoundBank(bank);
|
|
4138
|
+
const context = this.getMixer()?.listener.context;
|
|
4139
|
+
if (!context) throw new Error("Audio isn't ready yet.");
|
|
4140
|
+
await Promise.all(
|
|
4141
|
+
soundBankFiles(bank).map(async (file) => {
|
|
4142
|
+
if (this.buffers.has(file)) return;
|
|
4143
|
+
const audio = await fetch(resolvePrefabAssetUrl(file));
|
|
4144
|
+
if (!audio.ok) throw new Error(`Couldn't load the sound ${file}.`);
|
|
4145
|
+
this.buffers.set(file, await context.decodeAudioData(await audio.arrayBuffer()));
|
|
4146
|
+
})
|
|
4147
|
+
);
|
|
4148
|
+
for (const [id, slot] of Object.entries(bank.slots)) this.slots.set(id, slot);
|
|
4149
|
+
}
|
|
4150
|
+
/**
|
|
4151
|
+
* Play a named sound from a loaded bank. Returns whether it sounded: a slot's
|
|
4152
|
+
* chance, cooldown and priority can each keep it quiet, and that's normal.
|
|
4153
|
+
*/
|
|
4154
|
+
playSlot(id, options = {}) {
|
|
4155
|
+
const slot = this.slots.get(id);
|
|
4156
|
+
const mixer = this.getMixer();
|
|
4157
|
+
if (!slot || !mixer) return false;
|
|
4158
|
+
const context = mixer.listener.context;
|
|
4159
|
+
const bus = slot.bus ?? "sfx";
|
|
4160
|
+
const now = context.currentTime;
|
|
4161
|
+
const priority = slot.priority ?? 0;
|
|
4162
|
+
const speaking = this.voice && now < this.voice.until ? this.voice : null;
|
|
4163
|
+
if (bus === "voice" && speaking && priority < speaking.priority) return false;
|
|
4164
|
+
const take = this.chooser.choose(id, slot, now * 1e3);
|
|
4165
|
+
const buffer = take ? this.buffers.get(take.file) : void 0;
|
|
4166
|
+
if (!take || !buffer) return false;
|
|
4167
|
+
if (context.state === "suspended") void context.resume();
|
|
4168
|
+
const source = context.createBufferSource();
|
|
4169
|
+
source.buffer = buffer;
|
|
4170
|
+
const gain = context.createGain();
|
|
4171
|
+
gain.gain.value = (slot.volume ?? 1) * (take.volume ?? 1) * (options.volume ?? 1);
|
|
4172
|
+
source.connect(gain);
|
|
4173
|
+
let tail = gain;
|
|
4174
|
+
if (options.position) {
|
|
4175
|
+
const panner = context.createPanner();
|
|
4176
|
+
panner.positionX.value = options.position.x;
|
|
4177
|
+
panner.positionY.value = options.position.y;
|
|
4178
|
+
panner.positionZ.value = options.position.z;
|
|
4179
|
+
gain.connect(panner);
|
|
4180
|
+
tail = panner;
|
|
4181
|
+
}
|
|
4182
|
+
tail.connect(mixer.input(bus));
|
|
4183
|
+
source.onended = () => {
|
|
4184
|
+
source.disconnect();
|
|
4185
|
+
gain.disconnect();
|
|
4186
|
+
tail.disconnect();
|
|
4187
|
+
};
|
|
4188
|
+
if (bus === "voice") {
|
|
4189
|
+
speaking?.source.stop();
|
|
4190
|
+
this.voice = { priority, until: now + buffer.duration, source };
|
|
4191
|
+
mixer.duckMusic(buffer.duration);
|
|
4192
|
+
}
|
|
4193
|
+
source.start();
|
|
4194
|
+
return true;
|
|
4195
|
+
}
|
|
6092
4196
|
update(world, _deltaTime) {
|
|
6093
4197
|
if (this.isEditor) return;
|
|
4198
|
+
this.world = world;
|
|
6094
4199
|
const entities = world.query(AudioComponent);
|
|
6095
4200
|
const liveEntityIds = new Set(entities);
|
|
6096
4201
|
for (const entityId of entities) {
|
|
@@ -6111,6 +4216,8 @@ var _AudioSystem = class _AudioSystem {
|
|
|
6111
4216
|
}
|
|
6112
4217
|
}
|
|
6113
4218
|
this._syncOptions(entityId, component, sound);
|
|
4219
|
+
const bus = component.options.bus ?? "sfx";
|
|
4220
|
+
this.getMixer()?.route(sound, bus);
|
|
6114
4221
|
const prevWasPlaying = this.prevPlayingState.get(entityId) ?? false;
|
|
6115
4222
|
if (prevWasPlaying && !sound.isPlaying && component.isPlaying && !component.isPaused && !this.stoppedDueToInvisibility.has(entityId)) {
|
|
6116
4223
|
component.isPlaying = false;
|
|
@@ -6118,6 +4225,9 @@ var _AudioSystem = class _AudioSystem {
|
|
|
6118
4225
|
if (component.isPlaying && !sound.isPlaying) {
|
|
6119
4226
|
if (sound.buffer) {
|
|
6120
4227
|
sound.play();
|
|
4228
|
+
if (bus === "voice") {
|
|
4229
|
+
this.getMixer()?.duckMusic(sound.buffer.duration / (component.options.pitch || 1));
|
|
4230
|
+
}
|
|
6121
4231
|
}
|
|
6122
4232
|
} else if (!component.isPlaying && sound.isPlaying) {
|
|
6123
4233
|
if (component.isPaused) {
|
|
@@ -6166,6 +4276,12 @@ var _AudioSystem = class _AudioSystem {
|
|
|
6166
4276
|
this.prevPlayingState.clear();
|
|
6167
4277
|
this.prevOptions.clear();
|
|
6168
4278
|
this.stoppedDueToInvisibility.clear();
|
|
4279
|
+
this.voice?.source.stop();
|
|
4280
|
+
this.voice = null;
|
|
4281
|
+
this.slots.clear();
|
|
4282
|
+
this.buffers.clear();
|
|
4283
|
+
this.mixer?.dispose();
|
|
4284
|
+
this.mixer = null;
|
|
6169
4285
|
}
|
|
6170
4286
|
};
|
|
6171
4287
|
__name(_AudioSystem, "AudioSystem");
|
|
@@ -6219,7 +4335,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
6219
4335
|
});
|
|
6220
4336
|
}
|
|
6221
4337
|
}
|
|
6222
|
-
this._syncOptions(entityId, component, video);
|
|
4338
|
+
this._syncOptions(world, entityId, component, video);
|
|
6223
4339
|
const prev = this.prevIntent.get(entityId) ?? { isPlaying: false, isPaused: false };
|
|
6224
4340
|
if (prev.isPlaying && video.paused && !video.seeking && component.isPlaying && !component.isPaused && !this.pausedDueToInvisibility.has(entityId)) {
|
|
6225
4341
|
component.isPlaying = false;
|
|
@@ -6258,7 +4374,7 @@ var _VideoSystem = class _VideoSystem {
|
|
|
6258
4374
|
}
|
|
6259
4375
|
}
|
|
6260
4376
|
/** Apply any changed options from the component to the video element and mesh. */
|
|
6261
|
-
_syncOptions(entityId, component, video) {
|
|
4377
|
+
_syncOptions(world, entityId, component, video) {
|
|
6262
4378
|
const opts = component.options;
|
|
6263
4379
|
const prev = this.prevOptions.get(entityId);
|
|
6264
4380
|
if (!prev || prev.loop !== opts.loop) {
|
|
@@ -6275,19 +4391,13 @@ var _VideoSystem = class _VideoSystem {
|
|
|
6275
4391
|
component.object.scale.set(opts.width, opts.height, 1);
|
|
6276
4392
|
}
|
|
6277
4393
|
const material = component.material;
|
|
6278
|
-
if (material
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
}
|
|
6285
|
-
if (!prev || prev.smoothness !== opts.smoothness) {
|
|
6286
|
-
material.uniforms.smoothness.value = opts.smoothness;
|
|
6287
|
-
}
|
|
6288
|
-
if (!prev || prev.spill !== opts.spill) {
|
|
6289
|
-
material.uniforms.spill.value = opts.spill;
|
|
6290
|
-
}
|
|
4394
|
+
if (material && (!prev || prev.backgroundColor !== opts.backgroundColor || prev.similarity !== opts.similarity || prev.smoothness !== opts.smoothness || prev.spill !== opts.spill)) {
|
|
4395
|
+
readWorldRenderBackend(world).updateChromaKeyMaterial(material, {
|
|
4396
|
+
keyColor: opts.backgroundColor,
|
|
4397
|
+
similarity: opts.similarity,
|
|
4398
|
+
smoothness: opts.smoothness,
|
|
4399
|
+
spill: opts.spill
|
|
4400
|
+
});
|
|
6291
4401
|
}
|
|
6292
4402
|
if (opts.positional && component.audioNode instanceof THREE19.PositionalAudio) {
|
|
6293
4403
|
const posAudio = component.audioNode;
|
|
@@ -6821,7 +4931,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6821
4931
|
record.twoHand = null;
|
|
6822
4932
|
this.reanchor(world, input, record, interactable);
|
|
6823
4933
|
this.grabs.set(input, record);
|
|
6824
|
-
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
4934
|
+
this.dispatch(world, entityId, "onGrab", (b) => b.onGrab(input));
|
|
6825
4935
|
return;
|
|
6826
4936
|
}
|
|
6827
4937
|
if (holders.length >= 2) return;
|
|
@@ -6884,7 +4994,12 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6884
4994
|
primaryHandOffset: this.handQuaternion(primary.input).invert().multiply(quatFromEulerVec(transform.rotation)),
|
|
6885
4995
|
initialQuaternion: quatFromEulerVec(transform.rotation)
|
|
6886
4996
|
};
|
|
6887
|
-
this.dispatch(
|
|
4997
|
+
this.dispatch(
|
|
4998
|
+
world,
|
|
4999
|
+
entityId,
|
|
5000
|
+
"onSecondaryGrab",
|
|
5001
|
+
(b) => b.onSecondaryGrab(secondary.input)
|
|
5002
|
+
);
|
|
6888
5003
|
}
|
|
6889
5004
|
/** World point → the object's UNSCALED local space. */
|
|
6890
5005
|
objectLocalPoint(transform, worldPoint) {
|
|
@@ -7124,7 +5239,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7124
5239
|
angularVelocity: new THREE19.Vector3()
|
|
7125
5240
|
});
|
|
7126
5241
|
if (role === "primary") {
|
|
7127
|
-
this.dispatch(world, entityId, (b) => b.onGrab(input));
|
|
5242
|
+
this.dispatch(world, entityId, "onGrab", (b) => b.onGrab(input));
|
|
7128
5243
|
}
|
|
7129
5244
|
}
|
|
7130
5245
|
/** Drive every held object, once each, after grabs and releases settle. */
|
|
@@ -7252,6 +5367,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7252
5367
|
this.dispatch(
|
|
7253
5368
|
world,
|
|
7254
5369
|
held.entityId,
|
|
5370
|
+
"onSecondaryRelease",
|
|
7255
5371
|
(b) => b.onSecondaryRelease(input)
|
|
7256
5372
|
);
|
|
7257
5373
|
} else {
|
|
@@ -7260,7 +5376,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7260
5376
|
next.record.twoHand = null;
|
|
7261
5377
|
next.record.restoreBodyType = held.restoreBodyType;
|
|
7262
5378
|
this.reanchor(world, next.input, next.record, interactable);
|
|
7263
|
-
this.dispatch(world, held.entityId, (b) => b.onRelease(input));
|
|
5379
|
+
this.dispatch(world, held.entityId, "onRelease", (b) => b.onRelease(input));
|
|
7264
5380
|
}
|
|
7265
5381
|
held.tracker.clear();
|
|
7266
5382
|
return;
|
|
@@ -7279,7 +5395,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7279
5395
|
}
|
|
7280
5396
|
}
|
|
7281
5397
|
held.tracker.clear();
|
|
7282
|
-
this.dispatch(world, held.entityId, (b) => b.onRelease(input));
|
|
5398
|
+
this.dispatch(world, held.entityId, "onRelease", (b) => b.onRelease(input));
|
|
7283
5399
|
}
|
|
7284
5400
|
releaseAll(world) {
|
|
7285
5401
|
for (const input of Array.from(this.grabs.keys())) {
|
|
@@ -7306,7 +5422,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7306
5422
|
input.rayDirection.clone().normalize()
|
|
7307
5423
|
);
|
|
7308
5424
|
}
|
|
7309
|
-
dispatch(world, entityId, visit) {
|
|
5425
|
+
dispatch(world, entityId, hook, visit) {
|
|
7310
5426
|
const script = world.getComponent(entityId, ScriptComponent);
|
|
7311
5427
|
const instances = script?.scriptInstances;
|
|
7312
5428
|
if (!instances) return;
|
|
@@ -7315,7 +5431,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7315
5431
|
try {
|
|
7316
5432
|
visit(instance);
|
|
7317
5433
|
} catch (error) {
|
|
7318
|
-
|
|
5434
|
+
reportBehaviourHookError(world, entityId, instance, hook, error);
|
|
7319
5435
|
}
|
|
7320
5436
|
}
|
|
7321
5437
|
}
|
|
@@ -7854,7 +5970,7 @@ var _XRSessionSystem = class _XRSessionSystem {
|
|
|
7854
5970
|
this.inputSystem.attachSession(session);
|
|
7855
5971
|
}
|
|
7856
5972
|
this.applyTrackingOrigin(world, session ?? null);
|
|
7857
|
-
this.forEachBehaviour(world, (behaviour) => {
|
|
5973
|
+
this.forEachBehaviour(world, "onXRSessionStart", (behaviour) => {
|
|
7858
5974
|
behaviour.onXRSessionStart(this.capabilities);
|
|
7859
5975
|
});
|
|
7860
5976
|
}
|
|
@@ -7909,7 +6025,7 @@ var _XRSessionSystem = class _XRSessionSystem {
|
|
|
7909
6025
|
this.session = null;
|
|
7910
6026
|
this.capabilities = NO_XR_CAPABILITIES;
|
|
7911
6027
|
this.inputSystem?.detachSession();
|
|
7912
|
-
this.forEachBehaviour(world, (behaviour) => {
|
|
6028
|
+
this.forEachBehaviour(world, "onXRSessionEnd", (behaviour) => {
|
|
7913
6029
|
behaviour.onXRSessionEnd();
|
|
7914
6030
|
});
|
|
7915
6031
|
}
|
|
@@ -7924,14 +6040,18 @@ var _XRSessionSystem = class _XRSessionSystem {
|
|
|
7924
6040
|
if (!inputs || inputs.length === 0) return;
|
|
7925
6041
|
for (const input of inputs) {
|
|
7926
6042
|
if (input.selectStart) {
|
|
7927
|
-
this.forEachBehaviour(
|
|
6043
|
+
this.forEachBehaviour(
|
|
6044
|
+
world,
|
|
6045
|
+
"onSelectStart",
|
|
6046
|
+
(b) => b.onSelectStart(input)
|
|
6047
|
+
);
|
|
7928
6048
|
}
|
|
7929
6049
|
if (input.selectEnd) {
|
|
7930
|
-
this.forEachBehaviour(world, (b) => b.onSelectEnd(input));
|
|
6050
|
+
this.forEachBehaviour(world, "onSelectEnd", (b) => b.onSelectEnd(input));
|
|
7931
6051
|
}
|
|
7932
6052
|
}
|
|
7933
6053
|
}
|
|
7934
|
-
forEachBehaviour(world, visit) {
|
|
6054
|
+
forEachBehaviour(world, hook, visit) {
|
|
7935
6055
|
for (const entityId of world.query(ScriptComponent)) {
|
|
7936
6056
|
const script = world.getComponent(entityId, ScriptComponent);
|
|
7937
6057
|
const instances = script?.scriptInstances;
|
|
@@ -7941,7 +6061,7 @@ var _XRSessionSystem = class _XRSessionSystem {
|
|
|
7941
6061
|
try {
|
|
7942
6062
|
visit(instance);
|
|
7943
6063
|
} catch (error) {
|
|
7944
|
-
|
|
6064
|
+
reportBehaviourHookError(world, entityId, instance, hook, error);
|
|
7945
6065
|
}
|
|
7946
6066
|
}
|
|
7947
6067
|
}
|
|
@@ -8758,12 +6878,13 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8758
6878
|
this.dispatchBubbling(
|
|
8759
6879
|
world,
|
|
8760
6880
|
this.mouseHover,
|
|
6881
|
+
"onUiHoverEnd",
|
|
8761
6882
|
(b, e) => b.onUiHoverEnd(e)
|
|
8762
6883
|
);
|
|
8763
6884
|
}
|
|
8764
6885
|
if (hovered !== null) {
|
|
8765
6886
|
this.setTint(world, hovered, HOVER_TINT);
|
|
8766
|
-
this.dispatchBubbling(world, hovered, (b, e) => b.onUiHoverStart(e));
|
|
6887
|
+
this.dispatchBubbling(world, hovered, "onUiHoverStart", (b, e) => b.onUiHoverStart(e));
|
|
8767
6888
|
}
|
|
8768
6889
|
this.mouseHover = hovered;
|
|
8769
6890
|
}
|
|
@@ -8829,7 +6950,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8829
6950
|
}
|
|
8830
6951
|
fire(world, press, input) {
|
|
8831
6952
|
if (press.kind === "button") {
|
|
8832
|
-
this.dispatchBubbling(world, press.entityId, (b, e) => b.onUiPress(e), input);
|
|
6953
|
+
this.dispatchBubbling(world, press.entityId, "onUiPress", (b, e) => b.onUiPress(e), input);
|
|
8833
6954
|
return;
|
|
8834
6955
|
}
|
|
8835
6956
|
if (press.kind === "toggle") {
|
|
@@ -8839,6 +6960,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8839
6960
|
this.dispatchBubbling(
|
|
8840
6961
|
world,
|
|
8841
6962
|
press.entityId,
|
|
6963
|
+
"onUiToggle",
|
|
8842
6964
|
(b, e) => b.onUiToggle(e),
|
|
8843
6965
|
input,
|
|
8844
6966
|
toggle.value
|
|
@@ -8850,6 +6972,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8850
6972
|
this.dispatchBubbling(
|
|
8851
6973
|
world,
|
|
8852
6974
|
press.entityId,
|
|
6975
|
+
"onUiChange",
|
|
8853
6976
|
(b, e) => b.onUiChange(e),
|
|
8854
6977
|
input,
|
|
8855
6978
|
slider.value
|
|
@@ -8879,6 +7002,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8879
7002
|
this.dispatchBubbling(
|
|
8880
7003
|
world,
|
|
8881
7004
|
entityId,
|
|
7005
|
+
"onUiChange",
|
|
8882
7006
|
(b, e) => b.onUiChange(e),
|
|
8883
7007
|
input,
|
|
8884
7008
|
next
|
|
@@ -8911,7 +7035,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8911
7035
|
* panel script hears its children. Bubbling (not a world broadcast) keeps
|
|
8912
7036
|
* two spawned copies of the same menu prefab independent.
|
|
8913
7037
|
*/
|
|
8914
|
-
dispatchBubbling(world, entityId, visit, input = null, value) {
|
|
7038
|
+
dispatchBubbling(world, entityId, hook, visit, input = null, value) {
|
|
8915
7039
|
const event = {
|
|
8916
7040
|
targetEntityId: entityId,
|
|
8917
7041
|
actionId: this.actionIdOf(world, entityId),
|
|
@@ -8931,7 +7055,7 @@ var _UIInteractionSystem = class _UIInteractionSystem {
|
|
|
8931
7055
|
try {
|
|
8932
7056
|
visit(instance, event);
|
|
8933
7057
|
} catch (error) {
|
|
8934
|
-
|
|
7058
|
+
reportBehaviourHookError(world, current, instance, hook, error);
|
|
8935
7059
|
}
|
|
8936
7060
|
}
|
|
8937
7061
|
}
|
|
@@ -9507,7 +7631,8 @@ var _UIPanelSystem = class _UIPanelSystem {
|
|
|
9507
7631
|
texture.magFilter = THREE19.LinearFilter;
|
|
9508
7632
|
texture.premultiplyAlpha = true;
|
|
9509
7633
|
try {
|
|
9510
|
-
const
|
|
7634
|
+
const renderer = world.getRenderer();
|
|
7635
|
+
const max = renderer.capabilities?.getMaxAnisotropy?.() ?? renderer.getMaxAnisotropy?.();
|
|
9511
7636
|
if (typeof max === "number") texture.anisotropy = Math.min(8, max);
|
|
9512
7637
|
} catch {
|
|
9513
7638
|
}
|
|
@@ -9821,6 +7946,171 @@ var _XRAnchorSystem = class _XRAnchorSystem {
|
|
|
9821
7946
|
};
|
|
9822
7947
|
__name(_XRAnchorSystem, "XRAnchorSystem");
|
|
9823
7948
|
var XRAnchorSystem = _XRAnchorSystem;
|
|
7949
|
+
var _q = new THREE19.Quaternion();
|
|
7950
|
+
var _q2 = new THREE19.Quaternion();
|
|
7951
|
+
var _s = new THREE19.Vector3();
|
|
7952
|
+
var _e = new THREE19.Vector3();
|
|
7953
|
+
var _w = new THREE19.Vector3();
|
|
7954
|
+
var _v = new THREE19.Vector3();
|
|
7955
|
+
var _p = new THREE19.Vector3();
|
|
7956
|
+
function setWorldQuaternion(o, q) {
|
|
7957
|
+
if (o.parent) {
|
|
7958
|
+
o.parent.getWorldQuaternion(_q2).invert();
|
|
7959
|
+
o.quaternion.copy(_q2.multiply(q));
|
|
7960
|
+
} else {
|
|
7961
|
+
o.quaternion.copy(q);
|
|
7962
|
+
}
|
|
7963
|
+
o.updateMatrixWorld(true);
|
|
7964
|
+
}
|
|
7965
|
+
__name(setWorldQuaternion, "setWorldQuaternion");
|
|
7966
|
+
function turn(o, q) {
|
|
7967
|
+
o.getWorldQuaternion(_q);
|
|
7968
|
+
setWorldQuaternion(o, q.clone().multiply(_q));
|
|
7969
|
+
}
|
|
7970
|
+
__name(turn, "turn");
|
|
7971
|
+
function twoBoneIK(upper, lower, end, target, pole) {
|
|
7972
|
+
upper.getWorldPosition(_s);
|
|
7973
|
+
lower.getWorldPosition(_e);
|
|
7974
|
+
end.getWorldPosition(_w);
|
|
7975
|
+
const a = _s.distanceTo(_e);
|
|
7976
|
+
const b = _e.distanceTo(_w);
|
|
7977
|
+
if (a < 1e-6 || b < 1e-6) return target.distanceTo(_w);
|
|
7978
|
+
const toT = _v.subVectors(target, _s);
|
|
7979
|
+
const want = toT.length();
|
|
7980
|
+
const c = THREE19.MathUtils.clamp(want, Math.abs(a - b) + 1e-4, a + b - 1e-4);
|
|
7981
|
+
const dir = toT.divideScalar(want || 1).clone();
|
|
7982
|
+
const pv = _p.subVectors(pole, _s);
|
|
7983
|
+
pv.addScaledVector(dir, -pv.dot(dir));
|
|
7984
|
+
if (pv.lengthSq() < 1e-8) pv.set(0, -1, 0).addScaledVector(dir, dir.y);
|
|
7985
|
+
pv.normalize();
|
|
7986
|
+
const cosA = THREE19.MathUtils.clamp((a * a + c * c - b * b) / (2 * a * c), -1, 1);
|
|
7987
|
+
const joint = _s.clone().addScaledVector(dir, a * cosA).addScaledVector(pv, a * Math.sqrt(1 - cosA * cosA));
|
|
7988
|
+
turn(upper, new THREE19.Quaternion().setFromUnitVectors(_e.clone().sub(_s).normalize(), joint.clone().sub(_s).normalize()));
|
|
7989
|
+
lower.getWorldPosition(_e);
|
|
7990
|
+
end.getWorldPosition(_w);
|
|
7991
|
+
const reach = _s.clone().addScaledVector(dir, c);
|
|
7992
|
+
turn(lower, new THREE19.Quaternion().setFromUnitVectors(_w.clone().sub(_e).normalize(), reach.clone().sub(_e).normalize()));
|
|
7993
|
+
return want - c;
|
|
7994
|
+
}
|
|
7995
|
+
__name(twoBoneIK, "twoBoneIK");
|
|
7996
|
+
function gripQuaternion(axis, back, forearm, out = new THREE19.Quaternion()) {
|
|
7997
|
+
let X = axis.clone();
|
|
7998
|
+
const Z = back.clone().addScaledVector(X, -back.dot(X)).normalize().negate();
|
|
7999
|
+
let Y = new THREE19.Vector3().crossVectors(Z, X);
|
|
8000
|
+
if (Y.dot(forearm) < 0) {
|
|
8001
|
+
X = X.negate();
|
|
8002
|
+
Y = Y.negate();
|
|
8003
|
+
}
|
|
8004
|
+
return out.setFromRotationMatrix(new THREE19.Matrix4().makeBasis(X, Y, Z));
|
|
8005
|
+
}
|
|
8006
|
+
__name(gripQuaternion, "gripQuaternion");
|
|
8007
|
+
|
|
8008
|
+
// core/systems/IKSystem.ts
|
|
8009
|
+
var LIMB_BONES = {
|
|
8010
|
+
leftHand: ["leftUpperArm", "leftLowerArm", "leftHand"],
|
|
8011
|
+
rightHand: ["rightUpperArm", "rightLowerArm", "rightHand"],
|
|
8012
|
+
leftFoot: ["leftUpperLeg", "leftLowerLeg", "leftFoot"],
|
|
8013
|
+
rightFoot: ["rightUpperLeg", "rightLowerLeg", "rightFoot"]
|
|
8014
|
+
};
|
|
8015
|
+
var _t = new THREE19.Vector3();
|
|
8016
|
+
var _p2 = new THREE19.Vector3();
|
|
8017
|
+
var _q3 = new THREE19.Quaternion();
|
|
8018
|
+
var _pq = new THREE19.Quaternion();
|
|
8019
|
+
var _IKSystem = class _IKSystem {
|
|
8020
|
+
constructor() {
|
|
8021
|
+
this.runtimes = /* @__PURE__ */ new Map();
|
|
8022
|
+
this.reach = /* @__PURE__ */ new Map();
|
|
8023
|
+
}
|
|
8024
|
+
/** How far a limb's end stayed from its target last frame, in metres (0 = reached). */
|
|
8025
|
+
getReachError(entityId, limb) {
|
|
8026
|
+
return this.reach.get(`${entityId}:${limb}`) ?? null;
|
|
8027
|
+
}
|
|
8028
|
+
restore(runtime) {
|
|
8029
|
+
for (const [bone, w] of runtime.written) {
|
|
8030
|
+
if (bone.quaternion.equals(w.written)) bone.quaternion.copy(w.before);
|
|
8031
|
+
}
|
|
8032
|
+
runtime.written.clear();
|
|
8033
|
+
}
|
|
8034
|
+
update(world) {
|
|
8035
|
+
const ids = world.query(IKComponent, ModelComponent);
|
|
8036
|
+
const alive = new Set(ids);
|
|
8037
|
+
for (const [id, runtime] of this.runtimes) {
|
|
8038
|
+
if (!alive.has(id)) {
|
|
8039
|
+
this.restore(runtime);
|
|
8040
|
+
this.runtimes.delete(id);
|
|
8041
|
+
}
|
|
8042
|
+
}
|
|
8043
|
+
if (ids.length === 0) return;
|
|
8044
|
+
let matricesFresh = false;
|
|
8045
|
+
for (const id of ids) {
|
|
8046
|
+
const ik = world.getComponent(id, IKComponent);
|
|
8047
|
+
const root = world.getComponent(id, ModelComponent)?.object;
|
|
8048
|
+
if (!ik || !root) continue;
|
|
8049
|
+
let runtime = this.runtimes.get(id);
|
|
8050
|
+
if (!runtime || runtime.rootUuid !== root.uuid) {
|
|
8051
|
+
if (runtime) this.restore(runtime);
|
|
8052
|
+
runtime = { rootUuid: root.uuid, limbs: /* @__PURE__ */ new Map(), written: /* @__PURE__ */ new Map() };
|
|
8053
|
+
this.runtimes.set(id, runtime);
|
|
8054
|
+
}
|
|
8055
|
+
for (const [bone, w] of runtime.written) {
|
|
8056
|
+
if (bone.quaternion.equals(w.written)) bone.quaternion.copy(w.before);
|
|
8057
|
+
}
|
|
8058
|
+
runtime.written.clear();
|
|
8059
|
+
if (!ik.enabled) continue;
|
|
8060
|
+
const active = ik.chains.filter((c) => c.enabled && c.weight > 0 && typeof c.target === "number");
|
|
8061
|
+
if (active.length === 0) continue;
|
|
8062
|
+
if (!matricesFresh) {
|
|
8063
|
+
world.getScene().updateMatrixWorld(true);
|
|
8064
|
+
matricesFresh = true;
|
|
8065
|
+
}
|
|
8066
|
+
for (const chain of active) {
|
|
8067
|
+
let limb = runtime.limbs.get(chain.limb);
|
|
8068
|
+
if (!limb) {
|
|
8069
|
+
const names = LIMB_BONES[chain.limb];
|
|
8070
|
+
const found = names.map((h) => findModelBone(root, { humanoid: h }));
|
|
8071
|
+
limb = { bones: found.every(Boolean) ? found : null };
|
|
8072
|
+
runtime.limbs.set(chain.limb, limb);
|
|
8073
|
+
}
|
|
8074
|
+
const target = world.getComponent(chain.target, Object3DRef)?.object;
|
|
8075
|
+
if (!limb.bones || !target) continue;
|
|
8076
|
+
const [upper, lower, end] = limb.bones;
|
|
8077
|
+
for (const bone of [upper, lower, end]) {
|
|
8078
|
+
if (!runtime.written.has(bone)) {
|
|
8079
|
+
runtime.written.set(bone, { before: bone.quaternion.clone(), written: new THREE19.Quaternion() });
|
|
8080
|
+
}
|
|
8081
|
+
}
|
|
8082
|
+
const animated = [upper.quaternion.clone(), lower.quaternion.clone(), end.quaternion.clone()];
|
|
8083
|
+
target.getWorldPosition(_t);
|
|
8084
|
+
const poleObject = typeof chain.pole === "number" ? world.getComponent(chain.pole, Object3DRef)?.object : null;
|
|
8085
|
+
if (poleObject) poleObject.getWorldPosition(_p2);
|
|
8086
|
+
else lower.getWorldPosition(_p2);
|
|
8087
|
+
const miss = twoBoneIK(upper, lower, end, _t, _p2);
|
|
8088
|
+
this.reach.set(`${id}:${chain.limb}`, Math.max(0, miss));
|
|
8089
|
+
if (chain.matchRotation) {
|
|
8090
|
+
target.getWorldQuaternion(_q3);
|
|
8091
|
+
end.parent?.getWorldQuaternion(_pq);
|
|
8092
|
+
end.quaternion.copy(_pq.invert().multiply(_q3));
|
|
8093
|
+
}
|
|
8094
|
+
if (chain.weight < 1) {
|
|
8095
|
+
[upper, lower, end].forEach((bone, i) => {
|
|
8096
|
+
bone.quaternion.copy(animated[i].slerp(bone.quaternion, chain.weight));
|
|
8097
|
+
});
|
|
8098
|
+
}
|
|
8099
|
+
for (const bone of [upper, lower, end]) {
|
|
8100
|
+
bone.updateMatrixWorld(true);
|
|
8101
|
+
const w = runtime.written.get(bone);
|
|
8102
|
+
if (w) w.written.copy(bone.quaternion);
|
|
8103
|
+
}
|
|
8104
|
+
}
|
|
8105
|
+
}
|
|
8106
|
+
}
|
|
8107
|
+
dispose() {
|
|
8108
|
+
for (const runtime of this.runtimes.values()) this.restore(runtime);
|
|
8109
|
+
this.runtimes.clear();
|
|
8110
|
+
}
|
|
8111
|
+
};
|
|
8112
|
+
__name(_IKSystem, "IKSystem");
|
|
8113
|
+
var IKSystem = _IKSystem;
|
|
9824
8114
|
function buildGeometry2(area) {
|
|
9825
8115
|
if (area.shape === "circle") {
|
|
9826
8116
|
const radius = Math.max(5e-3, area.width / 2);
|
|
@@ -10887,7 +9177,13 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
10887
9177
|
if (event === "start") instance.onHandPoseStart(detail);
|
|
10888
9178
|
else instance.onHandPoseEnd(detail);
|
|
10889
9179
|
} catch (error) {
|
|
10890
|
-
|
|
9180
|
+
reportBehaviourHookError(
|
|
9181
|
+
world,
|
|
9182
|
+
entityId,
|
|
9183
|
+
instance,
|
|
9184
|
+
event === "start" ? "onHandPoseStart" : "onHandPoseEnd",
|
|
9185
|
+
error
|
|
9186
|
+
);
|
|
10891
9187
|
}
|
|
10892
9188
|
}
|
|
10893
9189
|
}
|
|
@@ -10977,15 +9273,15 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
10977
9273
|
object.traverse((child) => {
|
|
10978
9274
|
if (!(child instanceof THREE19.Mesh) || !child.geometry) return;
|
|
10979
9275
|
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
10980
|
-
const
|
|
9276
|
+
const clone = new THREE19.Mesh(child.geometry, material);
|
|
10981
9277
|
child.updateWorldMatrix(true, false);
|
|
10982
9278
|
object.updateWorldMatrix(true, false);
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
9279
|
+
clone.matrixAutoUpdate = false;
|
|
9280
|
+
clone.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE19.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
9281
|
+
clone.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
9282
|
+
clone.raycast = () => {
|
|
10987
9283
|
};
|
|
10988
|
-
group.add(
|
|
9284
|
+
group.add(clone);
|
|
10989
9285
|
});
|
|
10990
9286
|
if (group.children.length === 0) {
|
|
10991
9287
|
material.dispose();
|
|
@@ -11055,6 +9351,6 @@ var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
|
11055
9351
|
__name(_XRHoverVisualSystem, "XRHoverVisualSystem");
|
|
11056
9352
|
var XRHoverVisualSystem = _XRHoverVisualSystem;
|
|
11057
9353
|
|
|
11058
|
-
export {
|
|
11059
|
-
//# sourceMappingURL=chunk-
|
|
11060
|
-
//# sourceMappingURL=chunk-
|
|
9354
|
+
export { ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioMixer, AudioSystem, CURLED_COS, CameraSyncSystem, DEFAULT_DIRECTION_TOLERANCE, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, DEFAULT_SCRIPT_ERROR_RETRY_DELAY, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HandPoseTracker, IKSystem, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NO_XR_CAPABILITIES, ObjectVisibilitySystem, PINCH_FINGERS, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, SlotChooser, TeleportAimGate, ThrowVelocityTracker, TransformSyncSystem, UIInteractionSystem, UIPanelSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRAnchorSystem, XRControllerVisualSystem, XREnvironmentSystem, XRHandPoseSystem, XRHitTestSystem, XRHoverVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, XR_HOVER_SHELL_FLAG, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, computeFingerCurl, computeHandShape, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, estimateHandScale, gripQuaternion, matchHandPose, readXrCapabilities, sampleTeleportArc, setWorldQuaternion, soundBankFiles, twoBoneIK };
|
|
9355
|
+
//# sourceMappingURL=chunk-JIJQFW6P.js.map
|
|
9356
|
+
//# sourceMappingURL=chunk-JIJQFW6P.js.map
|