@webspatial/core-sdk 1.7.0 → 2.0.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/CHANGELOG.md +61 -0
- package/README.md +10 -0
- package/dist/JSBCommand.d.ts +398 -0
- package/dist/JSBCommand.js +668 -0
- package/dist/JSBCommand.js.map +1 -0
- package/dist/Spatial.d.ts +63 -0
- package/dist/Spatial.js +60 -0
- package/dist/Spatial.js.map +1 -0
- package/dist/SpatialObject.d.ts +19 -0
- package/dist/SpatialObject.js +44 -0
- package/dist/SpatialObject.js.map +1 -0
- package/dist/SpatialScene.d.ts +51 -0
- package/dist/SpatialScene.js +74 -0
- package/dist/SpatialScene.js.map +1 -0
- package/dist/SpatialSession.d.ts +143 -0
- package/dist/SpatialSession.js +173 -0
- package/dist/SpatialSession.js.map +1 -0
- package/dist/SpatialWebEvent.d.ts +8 -0
- package/dist/SpatialWebEvent.js +18 -0
- package/dist/SpatialWebEvent.js.map +1 -0
- package/dist/SpatialWebEventCreator.d.ts +11 -0
- package/dist/SpatialWebEventCreator.js +11 -0
- package/dist/SpatialWebEventCreator.js.map +1 -0
- package/dist/Spatialized2DElement.d.ts +42 -0
- package/dist/Spatialized2DElement.js +47 -0
- package/dist/Spatialized2DElement.js.map +1 -0
- package/dist/SpatializedDynamic3DElement.d.ts +7 -0
- package/dist/SpatializedDynamic3DElement.js +43 -0
- package/dist/SpatializedDynamic3DElement.js.map +1 -0
- package/dist/SpatializedElement.d.ts +7 -0
- package/dist/SpatializedElement.js +206 -0
- package/dist/SpatializedElement.js.map +1 -0
- package/dist/SpatializedElementCreator.d.ts +15 -0
- package/dist/SpatializedElementCreator.js +47 -0
- package/dist/SpatializedElementCreator.js.map +1 -0
- package/dist/SpatializedStatic3DElement.d.ts +195 -0
- package/dist/SpatializedStatic3DElement.js +327 -0
- package/dist/SpatializedStatic3DElement.js.map +1 -0
- package/dist/WebMsgCommand.d.ts +7 -0
- package/dist/WebMsgCommand.js +23 -0
- package/dist/WebMsgCommand.js.map +1 -0
- package/dist/index.d.ts +35 -1251
- package/dist/index.js +21 -3650
- package/dist/index.js.map +1 -1
- package/dist/install-polyfills.d.ts +2 -0
- package/dist/install-polyfills.js +13 -0
- package/dist/install-polyfills.js.map +1 -0
- package/dist/isSSREnv.d.ts +3 -0
- package/dist/isSSREnv.js +6 -0
- package/dist/isSSREnv.js.map +1 -0
- package/dist/motion/AnimationObject.d.ts +7 -0
- package/dist/motion/AnimationObject.js +140 -0
- package/dist/motion/AnimationObject.js.map +1 -0
- package/dist/motion/compute/index.d.ts +10 -0
- package/dist/motion/compute/index.js +19 -0
- package/dist/motion/compute/index.js.map +1 -0
- package/dist/motion/compute/motionPropertyValues.d.ts +19 -0
- package/dist/motion/compute/motionPropertyValues.js +50 -0
- package/dist/motion/compute/motionPropertyValues.js.map +1 -0
- package/dist/motion/compute/normalize.d.ts +31 -0
- package/dist/motion/compute/normalize.js +201 -0
- package/dist/motion/compute/normalize.js.map +1 -0
- package/dist/motion/compute/validate.d.ts +22 -0
- package/dist/motion/compute/validate.js +103 -0
- package/dist/motion/compute/validate.js.map +1 -0
- package/dist/motion/index.d.ts +8 -0
- package/dist/motion/index.js +6 -0
- package/dist/motion/index.js.map +1 -0
- package/dist/motion/native/serializeMotionTimeline.d.ts +12 -0
- package/dist/motion/native/serializeMotionTimeline.js +21 -0
- package/dist/motion/native/serializeMotionTimeline.js.map +1 -0
- package/dist/physicalMetrics-W5uZ5xKb.d.ts +48 -0
- package/dist/physicalMetrics.d.ts +1 -0
- package/dist/physicalMetrics.js +58 -0
- package/dist/physicalMetrics.js.map +1 -0
- package/dist/platform-adapter/CommandResultUtils.d.ts +12 -0
- package/dist/platform-adapter/CommandResultUtils.js +21 -0
- package/dist/platform-adapter/CommandResultUtils.js.map +1 -0
- package/dist/platform-adapter/createPlatformSync.d.ts +16 -0
- package/dist/platform-adapter/createPlatformSync.js +30 -0
- package/dist/platform-adapter/createPlatformSync.js.map +1 -0
- package/dist/platform-adapter/index.d.ts +12 -0
- package/dist/platform-adapter/index.js +10 -0
- package/dist/platform-adapter/index.js.map +1 -0
- package/dist/platform-adapter/interface.d.ts +7 -0
- package/dist/platform-adapter/interface.js +1 -0
- package/dist/platform-adapter/interface.js.map +1 -0
- package/dist/platform-adapter/pico-os/PicoOSPlatform.d.ts +25 -0
- package/dist/platform-adapter/pico-os/PicoOSPlatform.js +168 -0
- package/dist/platform-adapter/pico-os/PicoOSPlatform.js.map +1 -0
- package/dist/platform-adapter/puppeteer/PuppeteerPlatform.d.ts +66 -0
- package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js +372 -0
- package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js.map +1 -0
- package/dist/platform-adapter/spatialRequestMetadata.d.ts +6 -0
- package/dist/platform-adapter/spatialRequestMetadata.js +39 -0
- package/dist/platform-adapter/spatialRequestMetadata.js.map +1 -0
- package/dist/platform-adapter/spatialSceneQuery.d.ts +12 -0
- package/dist/platform-adapter/spatialSceneQuery.js +12 -0
- package/dist/platform-adapter/spatialSceneQuery.js.map +1 -0
- package/dist/platform-adapter/vision-os/VisionOSPlatform.d.ts +19 -0
- package/dist/platform-adapter/vision-os/VisionOSPlatform.js +77 -0
- package/dist/platform-adapter/vision-os/VisionOSPlatform.js.map +1 -0
- package/dist/platform-runtime.d.ts +12 -0
- package/dist/platform-runtime.js +14 -0
- package/dist/platform-runtime.js.map +1 -0
- package/dist/reality/Attachment.d.ts +19 -0
- package/dist/reality/Attachment.js +39 -0
- package/dist/reality/Attachment.js.map +1 -0
- package/dist/reality/component/ModelComponent.d.ts +14 -0
- package/dist/reality/component/ModelComponent.js +11 -0
- package/dist/reality/component/ModelComponent.js.map +1 -0
- package/dist/reality/component/SpatialComponent.d.ts +8 -0
- package/dist/reality/component/SpatialComponent.js +19 -0
- package/dist/reality/component/SpatialComponent.js.map +1 -0
- package/dist/reality/component/index.d.ts +8 -0
- package/dist/reality/component/index.js +3 -0
- package/dist/reality/component/index.js.map +1 -0
- package/dist/reality/entity/SpatialEntity.d.ts +7 -0
- package/dist/reality/entity/SpatialEntity.js +291 -0
- package/dist/reality/entity/SpatialEntity.js.map +1 -0
- package/dist/reality/entity/SpatialModelEntity.d.ts +17 -0
- package/dist/reality/entity/SpatialModelEntity.js +17 -0
- package/dist/reality/entity/SpatialModelEntity.js.map +1 -0
- package/dist/reality/entity/index.d.ts +8 -0
- package/dist/reality/entity/index.js +3 -0
- package/dist/reality/entity/index.js.map +1 -0
- package/dist/reality/geometry/SpatialBoxGeometry.d.ts +16 -0
- package/dist/reality/geometry/SpatialBoxGeometry.js +13 -0
- package/dist/reality/geometry/SpatialBoxGeometry.js.map +1 -0
- package/dist/reality/geometry/SpatialConeGeometry.d.ts +16 -0
- package/dist/reality/geometry/SpatialConeGeometry.js +13 -0
- package/dist/reality/geometry/SpatialConeGeometry.js.map +1 -0
- package/dist/reality/geometry/SpatialCylinderGeometry.d.ts +16 -0
- package/dist/reality/geometry/SpatialCylinderGeometry.js +13 -0
- package/dist/reality/geometry/SpatialCylinderGeometry.js.map +1 -0
- package/dist/reality/geometry/SpatialGeometry.d.ts +7 -0
- package/dist/reality/geometry/SpatialGeometry.js +13 -0
- package/dist/reality/geometry/SpatialGeometry.js.map +1 -0
- package/dist/reality/geometry/SpatialPlaneGeometry.d.ts +16 -0
- package/dist/reality/geometry/SpatialPlaneGeometry.js +13 -0
- package/dist/reality/geometry/SpatialPlaneGeometry.js.map +1 -0
- package/dist/reality/geometry/SpatialSphereGeometry.d.ts +16 -0
- package/dist/reality/geometry/SpatialSphereGeometry.js +13 -0
- package/dist/reality/geometry/SpatialSphereGeometry.js.map +1 -0
- package/dist/reality/geometry/index.d.ts +12 -0
- package/dist/reality/geometry/index.js +7 -0
- package/dist/reality/geometry/index.js.map +1 -0
- package/dist/reality/index.d.ts +18 -0
- package/dist/reality/index.js +7 -0
- package/dist/reality/index.js.map +1 -0
- package/dist/reality/material/SpatialMaterial.d.ts +7 -0
- package/dist/reality/material/SpatialMaterial.js +13 -0
- package/dist/reality/material/SpatialMaterial.js.map +1 -0
- package/dist/reality/material/SpatialUnlitMaterial.d.ts +16 -0
- package/dist/reality/material/SpatialUnlitMaterial.js +16 -0
- package/dist/reality/material/SpatialUnlitMaterial.js.map +1 -0
- package/dist/reality/material/index.d.ts +8 -0
- package/dist/reality/material/index.js +3 -0
- package/dist/reality/material/index.js.map +1 -0
- package/dist/reality/realityCreator.d.ts +22 -0
- package/dist/reality/realityCreator.js +89 -0
- package/dist/reality/realityCreator.js.map +1 -0
- package/dist/reality/resource/SpatialModelAsset.d.ts +15 -0
- package/dist/reality/resource/SpatialModelAsset.js +12 -0
- package/dist/reality/resource/SpatialModelAsset.js.map +1 -0
- package/dist/reality/resource/SpatialTextureResource.d.ts +16 -0
- package/dist/reality/resource/SpatialTextureResource.js +16 -0
- package/dist/reality/resource/SpatialTextureResource.js.map +1 -0
- package/dist/reality/resource/index.d.ts +9 -0
- package/dist/reality/resource/index.js +3 -0
- package/dist/reality/resource/index.js.map +1 -0
- package/dist/runtime/WebSpatialRuntimeError.d.ts +10 -0
- package/dist/runtime/WebSpatialRuntimeError.js +14 -0
- package/dist/runtime/WebSpatialRuntimeError.js.map +1 -0
- package/dist/runtime/capability-data.d.ts +12 -0
- package/dist/runtime/capability-data.js +134 -0
- package/dist/runtime/capability-data.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.js +27 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/jsbAdapterPlatform.d.ts +9 -0
- package/dist/runtime/jsbAdapterPlatform.js +38 -0
- package/dist/runtime/jsbAdapterPlatform.js.map +1 -0
- package/dist/runtime/keys.d.ts +34 -0
- package/dist/runtime/keys.js +122 -0
- package/dist/runtime/keys.js.map +1 -0
- package/dist/runtime/semver.d.ts +8 -0
- package/dist/runtime/semver.js +32 -0
- package/dist/runtime/semver.js.map +1 -0
- package/dist/runtime/supports.d.ts +22 -0
- package/dist/runtime/supports.js +78 -0
- package/dist/runtime/supports.js.map +1 -0
- package/dist/runtime/types.d.ts +12 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/userAgent.d.ts +20 -0
- package/dist/runtime/userAgent.js +41 -0
- package/dist/runtime/userAgent.js.map +1 -0
- package/dist/scene-polyfill.d.ts +18 -0
- package/dist/scene-polyfill.js +480 -0
- package/dist/scene-polyfill.js.map +1 -0
- package/dist/spatial-host.d.ts +13 -0
- package/dist/spatial-host.js +18 -0
- package/dist/spatial-host.js.map +1 -0
- package/dist/spatial-window-polyfill.d.ts +3 -0
- package/dist/spatial-window-polyfill.js +155 -0
- package/dist/spatial-window-polyfill.js.map +1 -0
- package/dist/spatializedElementMotion-_0XWPQCE.d.ts +1009 -0
- package/dist/types/animation.d.ts +7 -0
- package/dist/types/animation.js +1 -0
- package/dist/types/animation.js.map +1 -0
- package/dist/types/global.d.ts +38 -0
- package/dist/types/global.js +1 -0
- package/dist/types/global.js.map +1 -0
- package/dist/types/internal.d.ts +7 -0
- package/dist/types/internal.js +12 -0
- package/dist/types/internal.js.map +1 -0
- package/dist/types/motion/index.d.ts +7 -0
- package/dist/types/motion/index.js +3 -0
- package/dist/types/motion/index.js.map +1 -0
- package/dist/types/motion/spatializedElementMotion.d.ts +7 -0
- package/dist/types/motion/spatializedElementMotion.js +1 -0
- package/dist/types/motion/spatializedElementMotion.js.map +1 -0
- package/dist/types/motion/spatializedMotion.d.ts +7 -0
- package/dist/types/motion/spatializedMotion.js +16 -0
- package/dist/types/motion/spatializedMotion.js.map +1 -0
- package/dist/types/motion/spatializedPlayback.d.ts +11 -0
- package/dist/types/motion/spatializedPlayback.js +1 -0
- package/dist/types/motion/spatializedPlayback.js.map +1 -0
- package/dist/types/motion/spatializedVisual.d.ts +35 -0
- package/dist/types/motion/spatializedVisual.js +1 -0
- package/dist/types/motion/spatializedVisual.js.map +1 -0
- package/dist/types/types.d.ts +7 -0
- package/dist/types/types.js +117 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils.d.ts +44 -0
- package/dist/utils.js +86 -0
- package/dist/utils.js.map +1 -0
- package/package.json +20 -4
- package/src/JSBCommand.ts +132 -5
- package/src/SpatialObject.ts +10 -0
- package/src/Spatialized2DElement.ts +5 -0
- package/src/SpatializedDynamic3DElement.ts +5 -0
- package/src/SpatializedElement.ts +29 -0
- package/src/SpatializedStatic3DElement.ts +42 -3
- package/src/WebMsgCommand.ts +40 -0
- package/src/coverage-boost.test.ts +239 -216
- package/src/index.ts +25 -11
- package/src/install-polyfills.ts +38 -0
- package/src/jsbcommand.coverage.test.ts +23 -0
- package/src/motion/AnimationObject.test.ts +421 -0
- package/src/motion/AnimationObject.ts +208 -0
- package/src/motion/compute/index.ts +10 -0
- package/src/motion/compute/motionPropertyValues.test.ts +55 -0
- package/src/motion/compute/motionPropertyValues.ts +70 -0
- package/src/motion/compute/normalize.test.ts +99 -0
- package/src/motion/compute/normalize.ts +289 -0
- package/src/motion/compute/validate.test.ts +229 -0
- package/src/motion/compute/validate.ts +156 -0
- package/src/motion/index.ts +2 -0
- package/src/motion/native/serializeMotionTimeline.test.ts +61 -0
- package/src/motion/native/serializeMotionTimeline.ts +27 -0
- package/src/platform-adapter/createPlatformSync.ts +5 -3
- package/src/platform-adapter/pico-os/PicoOSPlatform.ts +76 -11
- package/src/platform-adapter/spatialRequestMetadata.test.ts +175 -0
- package/src/platform-adapter/spatialRequestMetadata.ts +48 -0
- package/src/platform-adapter/vision-os/VisionOSPlatform.ts +6 -1
- package/src/reality/entity/SpatialEntity.ts +127 -0
- package/src/runtime/capability-data.ts +104 -4
- package/src/runtime/index.ts +0 -11
- package/src/runtime/keys.ts +12 -1
- package/src/runtime/supports.test.ts +143 -4
- package/src/runtime/supports.ts +3 -1
- package/src/runtime/useAnimation.capability.test.ts +275 -0
- package/src/scene-polyfill.manifest.test.ts +306 -5
- package/src/scene-polyfill.request-metadata.test.ts +39 -0
- package/src/scene-polyfill.test.ts +33 -94
- package/src/scene-polyfill.ts +117 -87
- package/src/spatial-window-polyfill.ts +18 -2
- package/src/transform-roundtrip.test.ts +90 -0
- package/src/types/animation.ts +224 -0
- package/src/types/global.ts +1 -8
- package/src/types/motion/index.ts +10 -0
- package/src/types/motion/spatializedElementMotion.ts +49 -0
- package/src/types/motion/spatializedMotion.ts +147 -0
- package/src/types/motion/spatializedPlayback.ts +17 -0
- package/src/types/motion/spatializedVisual.ts +24 -0
- package/src/types/types.ts +3 -0
- package/src/utils.ts +54 -0
- package/tsup.config.ts +61 -36
- package/vitest.config.ts +5 -1
- package/dist/iife/index.d.ts +0 -1251
- package/dist/iife/index.global.js +0 -75
- package/dist/iife/index.global.js.map +0 -1
- package/src/platform-adapter/ssr/SSRPlatform.ts +0 -52
- /package/src/{ssr-polyfill.ts → isSSREnv.ts} +0 -0
package/src/scene-polyfill.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { FocusScene } from './JSBCommand'
|
|
2
2
|
import { openSpatialSceneSync } from './spatial-host'
|
|
3
|
-
import { SpatialScene } from './SpatialScene'
|
|
4
3
|
import {
|
|
5
4
|
SpatialSceneCreationOptions,
|
|
6
5
|
SpatialSceneType,
|
|
7
|
-
SpatialSceneState,
|
|
8
6
|
isValidSceneUnit,
|
|
9
7
|
isValidSpatialSceneType,
|
|
10
8
|
isValidWorldScalingType,
|
|
@@ -74,33 +72,93 @@ function deepMergePlain<
|
|
|
74
72
|
return out
|
|
75
73
|
}
|
|
76
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Pick a value from a manifest-like object where both snake_case and camelCase may exist.
|
|
77
|
+
*
|
|
78
|
+
* Rule: if both keys exist on the same object, snake_case wins.
|
|
79
|
+
*/
|
|
80
|
+
function preferSnake<T>(
|
|
81
|
+
src: Record<string, any> | undefined,
|
|
82
|
+
snakeKey: string,
|
|
83
|
+
camelKey: string,
|
|
84
|
+
): T | undefined {
|
|
85
|
+
if (!src) return undefined
|
|
86
|
+
if (src[snakeKey] !== undefined) return src[snakeKey] as T
|
|
87
|
+
if (src[camelKey] !== undefined) return src[camelKey] as T
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Normalize resizability keys from manifest input into the runtime camelCase shape.
|
|
93
|
+
*
|
|
94
|
+
* Accepts both:
|
|
95
|
+
* - camelCase: minWidth/minHeight/maxWidth/maxHeight
|
|
96
|
+
* - snake_case: min_width/min_height/max_width/max_height
|
|
97
|
+
*
|
|
98
|
+
* Rule: if both exist on the same object, snake_case wins.
|
|
99
|
+
*/
|
|
100
|
+
function normalizeResizability(
|
|
101
|
+
src: Record<string, any> | undefined,
|
|
102
|
+
): SpatialSceneCreationOptions['resizability'] | undefined {
|
|
103
|
+
if (!src || typeof src !== 'object' || Array.isArray(src)) return undefined
|
|
104
|
+
const out: any = {}
|
|
105
|
+
const minWidth = preferSnake<any>(src, 'min_width', 'minWidth')
|
|
106
|
+
if (minWidth !== undefined) out.minWidth = minWidth
|
|
107
|
+
const minHeight = preferSnake<any>(src, 'min_height', 'minHeight')
|
|
108
|
+
if (minHeight !== undefined) out.minHeight = minHeight
|
|
109
|
+
const maxWidth = preferSnake<any>(src, 'max_width', 'maxWidth')
|
|
110
|
+
if (maxWidth !== undefined) out.maxWidth = maxWidth
|
|
111
|
+
const maxHeight = preferSnake<any>(src, 'max_height', 'maxHeight')
|
|
112
|
+
if (maxHeight !== undefined) out.maxHeight = maxHeight
|
|
113
|
+
return Object.keys(out).length > 0 ? out : undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
/**
|
|
78
117
|
* Normalize XRSpatialSceneDefaults (manifest shape) into SpatialSceneCreationOptions (runtime shape).
|
|
79
|
-
*
|
|
80
|
-
* -
|
|
81
|
-
* -
|
|
118
|
+
*
|
|
119
|
+
* - Remaps supported snake_case aliases into camelCase keys.
|
|
120
|
+
* - Keeps output camelCase-only (snake_case keys are treated as input aliases).
|
|
121
|
+
* - Units are not formatted here; downstream formatting is handled by formatSceneConfig.
|
|
122
|
+
*
|
|
123
|
+
* Rule: if both snake_case and camelCase are present on the same object, snake_case wins.
|
|
82
124
|
*/
|
|
83
125
|
function normalizeXRDefaultsToSceneOptions(
|
|
84
126
|
src: XRSpatialSceneDefaults | Record<string, any>,
|
|
85
127
|
): SpatialSceneCreationOptions {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
128
|
+
const input: any = src || {}
|
|
129
|
+
const out: any = {}
|
|
130
|
+
|
|
131
|
+
const ds = preferSnake<any>(input, 'default_size', 'defaultSize')
|
|
132
|
+
if (ds !== undefined) out.defaultSize = ds
|
|
133
|
+
|
|
134
|
+
const res = input.resizability
|
|
135
|
+
const normalizedRes = normalizeResizability(res)
|
|
136
|
+
if (normalizedRes) out.resizability = normalizedRes
|
|
137
|
+
|
|
138
|
+
const worldScaling = preferSnake<any>(input, 'world_scaling', 'worldScaling')
|
|
139
|
+
if (worldScaling !== undefined) out.worldScaling = worldScaling
|
|
140
|
+
|
|
141
|
+
const worldAlignment = preferSnake<any>(
|
|
142
|
+
input,
|
|
143
|
+
'world_alignment',
|
|
144
|
+
'worldAlignment',
|
|
145
|
+
)
|
|
146
|
+
if (worldAlignment !== undefined) out.worldAlignment = worldAlignment
|
|
147
|
+
|
|
148
|
+
const baseplateVisibility = preferSnake<any>(
|
|
149
|
+
input,
|
|
150
|
+
'baseplate_visibility',
|
|
151
|
+
'baseplateVisibility',
|
|
152
|
+
)
|
|
153
|
+
if (baseplateVisibility !== undefined)
|
|
154
|
+
out.baseplateVisibility = baseplateVisibility
|
|
155
|
+
|
|
97
156
|
return out
|
|
98
157
|
}
|
|
99
158
|
|
|
100
159
|
class SceneManager {
|
|
101
160
|
private originalOpen: any
|
|
102
161
|
private static instance: SceneManager
|
|
103
|
-
private manifestReady: Promise<void> | null = null
|
|
104
162
|
static getInstance() {
|
|
105
163
|
if (!SceneManager.instance) {
|
|
106
164
|
SceneManager.instance = new SceneManager()
|
|
@@ -109,7 +167,9 @@ class SceneManager {
|
|
|
109
167
|
}
|
|
110
168
|
|
|
111
169
|
init(window: WindowProxy) {
|
|
112
|
-
|
|
170
|
+
// Load manifest defaults in the background; scene creation reads the
|
|
171
|
+
// resolved xr_window_defaults / xr_volume_defaults once available.
|
|
172
|
+
void this.setupManifest()
|
|
113
173
|
this.originalOpen = window.open.bind(window)
|
|
114
174
|
;(window as any).open = this.open
|
|
115
175
|
}
|
|
@@ -125,10 +185,6 @@ class SceneManager {
|
|
|
125
185
|
return this.configMap[name]
|
|
126
186
|
}
|
|
127
187
|
|
|
128
|
-
waitManifest(): Promise<void> {
|
|
129
|
-
return this.manifestReady ?? Promise.resolve()
|
|
130
|
-
}
|
|
131
|
-
|
|
132
188
|
// Ensure URL is absolute; only convert when a relative path is provided
|
|
133
189
|
// - Keep external and special schemes untouched (http, https, data, blob, about, file, mailto, etc.)
|
|
134
190
|
// - Handle protocol-relative URLs (//example.com/path)
|
|
@@ -158,12 +214,41 @@ class SceneManager {
|
|
|
158
214
|
const xr = manifest?.xr_spatial_scene
|
|
159
215
|
if (!xr || typeof xr !== 'object') return
|
|
160
216
|
const { overrides, ...topLevel } = xr as XRSpatialSceneConfig
|
|
161
|
-
// Merge top-level defaults with per-scene overrides.
|
|
162
|
-
const windowRaw = deepMergePlain(topLevel, overrides?.window_scene)
|
|
163
|
-
const volumeRaw = deepMergePlain(topLevel, overrides?.volume_scene)
|
|
164
|
-
const windowNext = normalizeXRDefaultsToSceneOptions(windowRaw)
|
|
165
217
|
|
|
166
|
-
|
|
218
|
+
// Normalize top-level defaults and per-type overrides separately, then deep-merge.
|
|
219
|
+
// - Ensures overrides keep higher priority than top-level defaults.
|
|
220
|
+
// - Ensures snake_case vs camelCase resolution is applied within the same object only.
|
|
221
|
+
// - This affects only manifest-resolved defaults; initScene callback chaining remains unchanged
|
|
222
|
+
// because callbackReturnMap stores the raw callback return values.
|
|
223
|
+
const normalizedTopLevel = normalizeXRDefaultsToSceneOptions(
|
|
224
|
+
topLevel as any,
|
|
225
|
+
)
|
|
226
|
+
const overrideObj: any = overrides as any
|
|
227
|
+
const windowOverrideSrc = preferSnake<any>(
|
|
228
|
+
overrideObj,
|
|
229
|
+
'window_scene',
|
|
230
|
+
'windowScene',
|
|
231
|
+
)
|
|
232
|
+
const volumeOverrideSrc = preferSnake<any>(
|
|
233
|
+
overrideObj,
|
|
234
|
+
'volume_scene',
|
|
235
|
+
'volumeScene',
|
|
236
|
+
)
|
|
237
|
+
const normalizedWindowOverride = windowOverrideSrc
|
|
238
|
+
? normalizeXRDefaultsToSceneOptions(windowOverrideSrc)
|
|
239
|
+
: undefined
|
|
240
|
+
const normalizedVolumeOverride = volumeOverrideSrc
|
|
241
|
+
? normalizeXRDefaultsToSceneOptions(volumeOverrideSrc)
|
|
242
|
+
: undefined
|
|
243
|
+
|
|
244
|
+
const windowNext = deepMergePlain(
|
|
245
|
+
normalizedTopLevel,
|
|
246
|
+
normalizedWindowOverride,
|
|
247
|
+
)
|
|
248
|
+
const volumeNext = deepMergePlain(
|
|
249
|
+
normalizedTopLevel,
|
|
250
|
+
normalizedVolumeOverride,
|
|
251
|
+
)
|
|
167
252
|
if (windowNext && Object.keys(windowNext).length > 0) {
|
|
168
253
|
xr_window_defaults = windowNext
|
|
169
254
|
}
|
|
@@ -194,9 +279,12 @@ class SceneManager {
|
|
|
194
279
|
const host = window.location.host
|
|
195
280
|
const protocol = window.location.protocol
|
|
196
281
|
const finalURL = `${protocol}//${host}/${token}/?command=${command}`
|
|
197
|
-
const
|
|
282
|
+
const sourceParams = new URL(url).searchParams
|
|
198
283
|
const final = new URL(finalURL)
|
|
199
|
-
|
|
284
|
+
for (const key of ['rid', 'wsepoch']) {
|
|
285
|
+
const value = sourceParams.get(key)
|
|
286
|
+
if (value) final.searchParams.set(key, value)
|
|
287
|
+
}
|
|
200
288
|
return this.originalOpen(final.toString(), target, features)
|
|
201
289
|
}
|
|
202
290
|
}
|
|
@@ -570,65 +658,7 @@ function getSceneDefaultConfig(sceneType: SpatialSceneType) {
|
|
|
570
658
|
: xr_volume_defaults || defaultSceneConfigVolume
|
|
571
659
|
}
|
|
572
660
|
|
|
573
|
-
async function injectScenePolyfill() {
|
|
574
|
-
if (!window.opener) return
|
|
575
|
-
|
|
576
|
-
const state = await SpatialScene.getInstance().getState()
|
|
577
|
-
|
|
578
|
-
// only run this in pending state
|
|
579
|
-
if (state !== SpatialSceneState.pending) return
|
|
580
|
-
|
|
581
|
-
function onContentLoaded(callback: any) {
|
|
582
|
-
if (
|
|
583
|
-
document.readyState === 'interactive' ||
|
|
584
|
-
document.readyState === 'complete'
|
|
585
|
-
) {
|
|
586
|
-
callback()
|
|
587
|
-
} else {
|
|
588
|
-
document.addEventListener('DOMContentLoaded', callback)
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
onContentLoaded(async () => {
|
|
593
|
-
await SceneManager.getInstance().waitManifest()
|
|
594
|
-
const sceneType = window.xrCurrentSceneType ?? 'window'
|
|
595
|
-
const rawDefault = getSceneDefaultConfig(sceneType)
|
|
596
|
-
// Provide a formatted 'pre' to the callback for consistent units and types.
|
|
597
|
-
const pre = deepCloneJSON(rawDefault)
|
|
598
|
-
|
|
599
|
-
let cfg = pre
|
|
600
|
-
if (typeof window.xrCurrentSceneDefaults === 'function') {
|
|
601
|
-
try {
|
|
602
|
-
cfg = await window.xrCurrentSceneDefaults?.(pre)
|
|
603
|
-
} catch (error) {
|
|
604
|
-
console.error(error)
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
// fixme: this duration is too short so that hide and show is at racing, so add a little delay to avoid
|
|
608
|
-
await new Promise((resolve, reject) => {
|
|
609
|
-
setTimeout(() => {
|
|
610
|
-
resolve(null)
|
|
611
|
-
}, 1000)
|
|
612
|
-
})
|
|
613
|
-
|
|
614
|
-
// Merge callback return with base defaults to ensure missing fields are filled.
|
|
615
|
-
const mergedCfg = deepMergePlain(deepCloneJSON(rawDefault), cfg)
|
|
616
|
-
const [formattedConfig, errors] = formatSceneConfig(mergedCfg, sceneType)
|
|
617
|
-
if (errors.length > 0) {
|
|
618
|
-
console.warn(
|
|
619
|
-
`window.xrCurrentSceneDefaults with errors: ${errors.join(', ')}`,
|
|
620
|
-
)
|
|
621
|
-
}
|
|
622
|
-
const finalCfg = {
|
|
623
|
-
...formattedConfig,
|
|
624
|
-
type: sceneType,
|
|
625
|
-
}
|
|
626
|
-
await SpatialScene.getInstance().updateSceneCreationConfig(finalCfg)
|
|
627
|
-
})
|
|
628
|
-
}
|
|
629
|
-
|
|
630
661
|
export function injectSceneHook() {
|
|
631
662
|
hijackWindowOpen(window)
|
|
632
663
|
hijackWindowATag(window)
|
|
633
|
-
injectScenePolyfill()
|
|
634
664
|
}
|
|
@@ -78,10 +78,20 @@ function hijackDocumentElementStyle() {
|
|
|
78
78
|
const rawDocumentStyle = document.documentElement.style
|
|
79
79
|
const styleProxy = new Proxy(rawDocumentStyle, {
|
|
80
80
|
set: function (target, key, value) {
|
|
81
|
-
|
|
81
|
+
let ret: boolean
|
|
82
82
|
|
|
83
83
|
if (key === SpatialGlobalCustomVars.backgroundMaterial) {
|
|
84
|
-
|
|
84
|
+
target.setProperty(
|
|
85
|
+
SpatialGlobalCustomVars.backgroundMaterial,
|
|
86
|
+
String(value),
|
|
87
|
+
)
|
|
88
|
+
ret = true
|
|
89
|
+
} else {
|
|
90
|
+
ret = Reflect.set(target, key, value)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (key === SpatialGlobalCustomVars.backgroundMaterial) {
|
|
94
|
+
setCurrentWindowStyle(String(value))
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
if (
|
|
@@ -106,6 +116,12 @@ function hijackDocumentElementStyle() {
|
|
|
106
116
|
return ret
|
|
107
117
|
},
|
|
108
118
|
get: function (target, prop: string) {
|
|
119
|
+
if (prop === SpatialGlobalCustomVars.backgroundMaterial) {
|
|
120
|
+
return target.getPropertyValue(
|
|
121
|
+
SpatialGlobalCustomVars.backgroundMaterial,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
109
125
|
if (typeof target[prop as keyof CSSStyleDeclaration] === 'function') {
|
|
110
126
|
return function (this: any, ...args: any[]) {
|
|
111
127
|
if (prop === 'setProperty') {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
import { composeSRT, decomposeSRT } from './utils'
|
|
3
|
+
|
|
4
|
+
function approxEqual(a: number, b: number, eps = 1e-6) {
|
|
5
|
+
return Math.abs(a - b) < eps
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
describe('composeSRT / decomposeSRT round-trip', () => {
|
|
9
|
+
test('identity transform round-trips', () => {
|
|
10
|
+
const pos = { x: 0, y: 0, z: 0 }
|
|
11
|
+
const rot = { x: 0, y: 0, z: 0 }
|
|
12
|
+
const scl = { x: 1, y: 1, z: 1 }
|
|
13
|
+
|
|
14
|
+
const matrix = composeSRT(pos, rot, scl)
|
|
15
|
+
const arr = Array.from(matrix.toFloat64Array())
|
|
16
|
+
const result = decomposeSRT(arr)
|
|
17
|
+
|
|
18
|
+
expect(approxEqual(result.position!.x, 0)).toBe(true)
|
|
19
|
+
expect(approxEqual(result.position!.y, 0)).toBe(true)
|
|
20
|
+
expect(approxEqual(result.position!.z, 0)).toBe(true)
|
|
21
|
+
expect(approxEqual(result.scale!.x, 1)).toBe(true)
|
|
22
|
+
expect(approxEqual(result.scale!.y, 1)).toBe(true)
|
|
23
|
+
expect(approxEqual(result.scale!.z, 1)).toBe(true)
|
|
24
|
+
expect(approxEqual(result.rotation!.x, 0)).toBe(true)
|
|
25
|
+
expect(approxEqual(result.rotation!.y, 0)).toBe(true)
|
|
26
|
+
expect(approxEqual(result.rotation!.z, 0)).toBe(true)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('translation-only round-trips', () => {
|
|
30
|
+
const pos = { x: 3, y: -5, z: 10 }
|
|
31
|
+
const rot = { x: 0, y: 0, z: 0 }
|
|
32
|
+
const scl = { x: 1, y: 1, z: 1 }
|
|
33
|
+
|
|
34
|
+
const matrix = composeSRT(pos, rot, scl)
|
|
35
|
+
const arr = Array.from(matrix.toFloat64Array())
|
|
36
|
+
const result = decomposeSRT(arr)
|
|
37
|
+
|
|
38
|
+
expect(approxEqual(result.position!.x, 3)).toBe(true)
|
|
39
|
+
expect(approxEqual(result.position!.y, -5)).toBe(true)
|
|
40
|
+
expect(approxEqual(result.position!.z, 10)).toBe(true)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('scale-only round-trips', () => {
|
|
44
|
+
const pos = { x: 0, y: 0, z: 0 }
|
|
45
|
+
const rot = { x: 0, y: 0, z: 0 }
|
|
46
|
+
const scl = { x: 2, y: 0.5, z: 3 }
|
|
47
|
+
|
|
48
|
+
const matrix = composeSRT(pos, rot, scl)
|
|
49
|
+
const arr = Array.from(matrix.toFloat64Array())
|
|
50
|
+
const result = decomposeSRT(arr)
|
|
51
|
+
|
|
52
|
+
expect(approxEqual(result.scale!.x, 2)).toBe(true)
|
|
53
|
+
expect(approxEqual(result.scale!.y, 0.5)).toBe(true)
|
|
54
|
+
expect(approxEqual(result.scale!.z, 3)).toBe(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('rotation-only round-trips (45 deg Y)', () => {
|
|
58
|
+
const pos = { x: 0, y: 0, z: 0 }
|
|
59
|
+
const rot = { x: 0, y: 45, z: 0 }
|
|
60
|
+
const scl = { x: 1, y: 1, z: 1 }
|
|
61
|
+
|
|
62
|
+
const matrix = composeSRT(pos, rot, scl)
|
|
63
|
+
const arr = Array.from(matrix.toFloat64Array())
|
|
64
|
+
const result = decomposeSRT(arr)
|
|
65
|
+
|
|
66
|
+
expect(approxEqual(result.rotation!.x, 0)).toBe(true)
|
|
67
|
+
expect(approxEqual(result.rotation!.y, 45)).toBe(true)
|
|
68
|
+
expect(approxEqual(result.rotation!.z, 0)).toBe(true)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('combined SRT round-trips', () => {
|
|
72
|
+
const pos = { x: 1, y: 2, z: 3 }
|
|
73
|
+
const rot = { x: 30, y: 45, z: 60 }
|
|
74
|
+
const scl = { x: 2, y: 3, z: 0.5 }
|
|
75
|
+
|
|
76
|
+
const matrix = composeSRT(pos, rot, scl)
|
|
77
|
+
const arr = Array.from(matrix.toFloat64Array())
|
|
78
|
+
const result = decomposeSRT(arr)
|
|
79
|
+
|
|
80
|
+
expect(approxEqual(result.position!.x, 1)).toBe(true)
|
|
81
|
+
expect(approxEqual(result.position!.y, 2)).toBe(true)
|
|
82
|
+
expect(approxEqual(result.position!.z, 3)).toBe(true)
|
|
83
|
+
expect(approxEqual(result.scale!.x, 2, 1e-4)).toBe(true)
|
|
84
|
+
expect(approxEqual(result.scale!.y, 3, 1e-4)).toBe(true)
|
|
85
|
+
expect(approxEqual(result.scale!.z, 0.5, 1e-4)).toBe(true)
|
|
86
|
+
expect(approxEqual(result.rotation!.x, 30, 0.1)).toBe(true)
|
|
87
|
+
expect(approxEqual(result.rotation!.y, 45, 0.1)).toBe(true)
|
|
88
|
+
expect(approxEqual(result.rotation!.z, 60, 0.1)).toBe(true)
|
|
89
|
+
})
|
|
90
|
+
})
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import type { Vec3 } from './types'
|
|
2
|
+
|
|
3
|
+
// ---- Timing function ----
|
|
4
|
+
|
|
5
|
+
export type TimingFunction = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut'
|
|
6
|
+
|
|
7
|
+
// ---- Transform values ----
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Transform values used in animation callbacks (`onComplete`, `onCancel`).
|
|
11
|
+
* Rotation values are Euler angles in **degrees**, matching the input convention
|
|
12
|
+
* of `AnimationConfig` and the entity `rotation` prop.
|
|
13
|
+
*/
|
|
14
|
+
export interface TransformValues {
|
|
15
|
+
position?: Vec3
|
|
16
|
+
rotation?: Vec3
|
|
17
|
+
scale?: Vec3
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ---- Play state ----
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Represents the current state of an animation session as exposed by
|
|
24
|
+
* `api.playState`. The internal `delaying` state maps to `'running'`
|
|
25
|
+
* because from the developer's perspective the session is actively progressing.
|
|
26
|
+
*/
|
|
27
|
+
export type AnimationPlayState =
|
|
28
|
+
| 'idle'
|
|
29
|
+
| 'queued'
|
|
30
|
+
| 'running'
|
|
31
|
+
| 'paused'
|
|
32
|
+
| 'finished'
|
|
33
|
+
|
|
34
|
+
// ---- Animation config ----
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for `useAnimation`.
|
|
38
|
+
*
|
|
39
|
+
* `to` is required and declares which transform fields are animated.
|
|
40
|
+
* `from` is optional; omitting it causes the native layer to snapshot
|
|
41
|
+
* the entity's current transform at playback time.
|
|
42
|
+
*/
|
|
43
|
+
export interface AnimationConfig {
|
|
44
|
+
/**
|
|
45
|
+
* Target transform values (required).
|
|
46
|
+
* Rotation values are Euler angles in degrees.
|
|
47
|
+
* Single-axis rotation > 180 deg may produce unexpected results (shortest-path SLERP).
|
|
48
|
+
*/
|
|
49
|
+
to: TransformValues
|
|
50
|
+
|
|
51
|
+
/** Starting transform values. Omit to animate from the entity's current state. */
|
|
52
|
+
from?: TransformValues
|
|
53
|
+
|
|
54
|
+
/** Duration in seconds. Default: 0.3 */
|
|
55
|
+
duration?: number
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Easing curve. Default: 'easeInOut'
|
|
59
|
+
* Only these four values are valid; other strings will throw at validation time.
|
|
60
|
+
*/
|
|
61
|
+
timingFunction?: TimingFunction
|
|
62
|
+
|
|
63
|
+
/** Delay before playback starts, in seconds. Default: 0 */
|
|
64
|
+
delay?: number
|
|
65
|
+
|
|
66
|
+
/** Start automatically when the entity mounts. Default: true */
|
|
67
|
+
autoStart?: boolean
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Loop behavior.
|
|
71
|
+
* - true: reset to `from` and replay (infinite reset loop)
|
|
72
|
+
* - { reverse: true }: alternate direction each cycle (infinite reverse loop)
|
|
73
|
+
* - undefined / false: play once
|
|
74
|
+
*/
|
|
75
|
+
loop?: boolean | { reverse?: boolean }
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Playback speed multiplier. Default: 1
|
|
79
|
+
* Values > 1 speed up; values between 0 and 1 slow down.
|
|
80
|
+
* Must be a positive finite number (> 0).
|
|
81
|
+
* Applied at session creation time and remains constant for the session.
|
|
82
|
+
* Maps to AnimationView.speed on the native (AVP) side.
|
|
83
|
+
*/
|
|
84
|
+
playbackRate?: number
|
|
85
|
+
|
|
86
|
+
/** Called when the session is established successfully. */
|
|
87
|
+
onStart?: () => void
|
|
88
|
+
|
|
89
|
+
/** Called when a non-looping animation finishes naturally. */
|
|
90
|
+
onComplete?: (finalValues: TransformValues) => void
|
|
91
|
+
|
|
92
|
+
/** Called when playback is canceled via api.cancel(). Receives the restored transform. */
|
|
93
|
+
onCancel?: (currentValues: TransformValues) => void
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Called when an asynchronous error occurs during a bridge or native operation.
|
|
97
|
+
* If not provided, the SDK logs the error via console.error.
|
|
98
|
+
*/
|
|
99
|
+
onError?: (error: AnimationError) => void
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ---- Animation error ----
|
|
103
|
+
|
|
104
|
+
export interface AnimationError {
|
|
105
|
+
/** The session that encountered the error. */
|
|
106
|
+
animationId: string
|
|
107
|
+
/** The command that failed. */
|
|
108
|
+
command: 'play' | 'pause' | 'resume' | 'cancel'
|
|
109
|
+
/** Optional machine-readable error code. */
|
|
110
|
+
code?: string
|
|
111
|
+
/** Human-readable failure reason. */
|
|
112
|
+
reason: string
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---- Animation API (returned by useAnimation) ----
|
|
116
|
+
|
|
117
|
+
export interface AnimationApi {
|
|
118
|
+
/** Start the animation, or continue it from paused progress. */
|
|
119
|
+
play(): void
|
|
120
|
+
|
|
121
|
+
/** Pause the animation at the current progress. */
|
|
122
|
+
pause(): void
|
|
123
|
+
|
|
124
|
+
/** Cancel the animation and restore `from`, or the start snapshot when `from` is omitted. */
|
|
125
|
+
cancel(): void
|
|
126
|
+
|
|
127
|
+
/** Whether the session is currently queued, delaying, or running (false while paused or idle). */
|
|
128
|
+
readonly isAnimating: boolean
|
|
129
|
+
|
|
130
|
+
/** Whether the animation is currently paused. */
|
|
131
|
+
readonly isPaused: boolean
|
|
132
|
+
|
|
133
|
+
/** Current session state. */
|
|
134
|
+
readonly playState: AnimationPlayState
|
|
135
|
+
|
|
136
|
+
/** Whether the most recent current session completed naturally. */
|
|
137
|
+
readonly finished: boolean
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ---- Animated props (opaque, passed to entity `animation` prop) ----
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Opaque object returned as the first tuple element of `useAnimation`.
|
|
144
|
+
* Pass it directly to the entity's `animation` prop.
|
|
145
|
+
* Application code should not read or modify its internal fields.
|
|
146
|
+
*/
|
|
147
|
+
export interface AnimatedProps {
|
|
148
|
+
/** @internal Unique identifier for this animation object. */
|
|
149
|
+
readonly __animationObjectId: string
|
|
150
|
+
/** @internal Transform fields targeted by this animation. */
|
|
151
|
+
readonly __animatedFields: readonly ('position' | 'rotation' | 'scale')[]
|
|
152
|
+
/** @internal Whether the animation currently has an alive session. */
|
|
153
|
+
readonly __animating: boolean
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---- Cross-layer command / result ----
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Float4x4 is a 16-element column-major matrix stored in a Float64Array,
|
|
160
|
+
* matching `DOMMatrix.toFloat64Array()`.
|
|
161
|
+
*/
|
|
162
|
+
export type Float4x4 = Float64Array
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Unified command sent from React SDK -> Core SDK -> native.
|
|
166
|
+
*/
|
|
167
|
+
export interface AnimateTransformCommand {
|
|
168
|
+
/**
|
|
169
|
+
* Unique session identifier. A new `animationId` is generated for each
|
|
170
|
+
* `play` command; `pause`, `resume`, and `stop` reuse the session's id.
|
|
171
|
+
*/
|
|
172
|
+
animationId: string
|
|
173
|
+
type: 'play' | 'pause' | 'resume' | 'cancel'
|
|
174
|
+
/** Required when type is 'play'; ignored otherwise. */
|
|
175
|
+
entityId?: string
|
|
176
|
+
toTransform?: Float4x4
|
|
177
|
+
fromTransform?: Float4x4
|
|
178
|
+
duration?: number
|
|
179
|
+
timingFunction?: TimingFunction
|
|
180
|
+
delay?: number
|
|
181
|
+
loop?: boolean | { reverse?: boolean }
|
|
182
|
+
/** Playback speed multiplier. Default: 1. Must be positive (> 0). Maps to AnimationView.speed on AVP. */
|
|
183
|
+
playbackRate?: number
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Result returned by `SpatialEntity.animateTransform({ type: 'play' })`.
|
|
188
|
+
*/
|
|
189
|
+
export interface AnimateTransformResult {
|
|
190
|
+
animationId: string
|
|
191
|
+
/** Resolves when a non-looping animation completes naturally. */
|
|
192
|
+
finished: Promise<TransformValues>
|
|
193
|
+
/**
|
|
194
|
+
* Resolves when the animation is canceled and restored to `from`.
|
|
195
|
+
* After cancel, `finished` MUST remain pending (not rejected).
|
|
196
|
+
*/
|
|
197
|
+
canceled: Promise<TransformValues>
|
|
198
|
+
/**
|
|
199
|
+
* Resolves when the animation fails due to a native or bridge error.
|
|
200
|
+
* Optional because older native runtimes may not emit the failed event.
|
|
201
|
+
*/
|
|
202
|
+
failed?: Promise<AnimationError>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// ---- Internal animated props (cross-layer communication) ----
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @internal
|
|
209
|
+
* Extended interface for `AnimatedProps` used internally by the entity layer
|
|
210
|
+
* to bind/unbind animations and query suppressed transform fields.
|
|
211
|
+
* Application code should never use this interface directly.
|
|
212
|
+
*/
|
|
213
|
+
export interface AnimatedPropsInternal extends AnimatedProps {
|
|
214
|
+
/** Called by the entity layer when the entity instance becomes available. */
|
|
215
|
+
__bind: (
|
|
216
|
+
entity: import('../reality/entity/SpatialEntity').SpatialEntity,
|
|
217
|
+
) => void
|
|
218
|
+
/** Called by the entity layer when the entity is destroyed or animation prop changes. */
|
|
219
|
+
__unbind: () => void
|
|
220
|
+
/** Returns the transform fields currently suppressed by an alive animation session. */
|
|
221
|
+
__getSuppressedFields: () =>
|
|
222
|
+
| readonly ('position' | 'rotation' | 'scale')[]
|
|
223
|
+
| null
|
|
224
|
+
}
|
package/src/types/global.ts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import type { PhysicalMetricsValueShape } from '../physicalMetrics'
|
|
2
|
-
import type { SpatialSceneCreationOptions, SpatialSceneType } from './types'
|
|
3
|
-
|
|
4
2
|
declare global {
|
|
5
3
|
const __WEBSPATIAL_CORE_SDK_VERSION__: string
|
|
6
4
|
|
|
7
5
|
interface Window {
|
|
8
|
-
xrCurrentSceneType: SpatialSceneType
|
|
9
|
-
xrCurrentSceneDefaults: (
|
|
10
|
-
defaultConfig: SpatialSceneCreationOptions,
|
|
11
|
-
) => Promise<SpatialSceneCreationOptions>
|
|
12
|
-
|
|
13
6
|
// Location for webspatial custom functions
|
|
14
7
|
__WebSpatialData: {
|
|
15
8
|
androidNativeMessage: Function
|
|
@@ -35,11 +28,11 @@ declare global {
|
|
|
35
28
|
WebSpatailNativeVersion: string
|
|
36
29
|
|
|
37
30
|
__webspatialsdk__?: {
|
|
38
|
-
XR_ENV?: string
|
|
39
31
|
'natvie-version'?: string
|
|
40
32
|
'react-sdk-version'?: string
|
|
41
33
|
'core-sdk-version'?: string
|
|
42
34
|
physicalMetrics?: PhysicalMetricsValueShape
|
|
35
|
+
pageEpoch?: string | number
|
|
43
36
|
}
|
|
44
37
|
|
|
45
38
|
/** Present when `supports('xrInnerDepth')` is true; otherwise `undefined`. */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './spatializedVisual'
|
|
2
|
+
export * from './spatializedPlayback'
|
|
3
|
+
export type {
|
|
4
|
+
SpatializedMotionKind,
|
|
5
|
+
SpatializedMotionSegmentConfig,
|
|
6
|
+
SpatializedMotionTimelineConfig,
|
|
7
|
+
SpatializedMotionConfig,
|
|
8
|
+
SpatializedMotionPlayState,
|
|
9
|
+
SpatializedPlaybackApi,
|
|
10
|
+
} from './spatializedMotion'
|