@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.
Files changed (296) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +10 -0
  3. package/dist/JSBCommand.d.ts +398 -0
  4. package/dist/JSBCommand.js +668 -0
  5. package/dist/JSBCommand.js.map +1 -0
  6. package/dist/Spatial.d.ts +63 -0
  7. package/dist/Spatial.js +60 -0
  8. package/dist/Spatial.js.map +1 -0
  9. package/dist/SpatialObject.d.ts +19 -0
  10. package/dist/SpatialObject.js +44 -0
  11. package/dist/SpatialObject.js.map +1 -0
  12. package/dist/SpatialScene.d.ts +51 -0
  13. package/dist/SpatialScene.js +74 -0
  14. package/dist/SpatialScene.js.map +1 -0
  15. package/dist/SpatialSession.d.ts +143 -0
  16. package/dist/SpatialSession.js +173 -0
  17. package/dist/SpatialSession.js.map +1 -0
  18. package/dist/SpatialWebEvent.d.ts +8 -0
  19. package/dist/SpatialWebEvent.js +18 -0
  20. package/dist/SpatialWebEvent.js.map +1 -0
  21. package/dist/SpatialWebEventCreator.d.ts +11 -0
  22. package/dist/SpatialWebEventCreator.js +11 -0
  23. package/dist/SpatialWebEventCreator.js.map +1 -0
  24. package/dist/Spatialized2DElement.d.ts +42 -0
  25. package/dist/Spatialized2DElement.js +47 -0
  26. package/dist/Spatialized2DElement.js.map +1 -0
  27. package/dist/SpatializedDynamic3DElement.d.ts +7 -0
  28. package/dist/SpatializedDynamic3DElement.js +43 -0
  29. package/dist/SpatializedDynamic3DElement.js.map +1 -0
  30. package/dist/SpatializedElement.d.ts +7 -0
  31. package/dist/SpatializedElement.js +206 -0
  32. package/dist/SpatializedElement.js.map +1 -0
  33. package/dist/SpatializedElementCreator.d.ts +15 -0
  34. package/dist/SpatializedElementCreator.js +47 -0
  35. package/dist/SpatializedElementCreator.js.map +1 -0
  36. package/dist/SpatializedStatic3DElement.d.ts +195 -0
  37. package/dist/SpatializedStatic3DElement.js +327 -0
  38. package/dist/SpatializedStatic3DElement.js.map +1 -0
  39. package/dist/WebMsgCommand.d.ts +7 -0
  40. package/dist/WebMsgCommand.js +23 -0
  41. package/dist/WebMsgCommand.js.map +1 -0
  42. package/dist/index.d.ts +35 -1251
  43. package/dist/index.js +21 -3650
  44. package/dist/index.js.map +1 -1
  45. package/dist/install-polyfills.d.ts +2 -0
  46. package/dist/install-polyfills.js +13 -0
  47. package/dist/install-polyfills.js.map +1 -0
  48. package/dist/isSSREnv.d.ts +3 -0
  49. package/dist/isSSREnv.js +6 -0
  50. package/dist/isSSREnv.js.map +1 -0
  51. package/dist/motion/AnimationObject.d.ts +7 -0
  52. package/dist/motion/AnimationObject.js +140 -0
  53. package/dist/motion/AnimationObject.js.map +1 -0
  54. package/dist/motion/compute/index.d.ts +10 -0
  55. package/dist/motion/compute/index.js +19 -0
  56. package/dist/motion/compute/index.js.map +1 -0
  57. package/dist/motion/compute/motionPropertyValues.d.ts +19 -0
  58. package/dist/motion/compute/motionPropertyValues.js +50 -0
  59. package/dist/motion/compute/motionPropertyValues.js.map +1 -0
  60. package/dist/motion/compute/normalize.d.ts +31 -0
  61. package/dist/motion/compute/normalize.js +201 -0
  62. package/dist/motion/compute/normalize.js.map +1 -0
  63. package/dist/motion/compute/validate.d.ts +22 -0
  64. package/dist/motion/compute/validate.js +103 -0
  65. package/dist/motion/compute/validate.js.map +1 -0
  66. package/dist/motion/index.d.ts +8 -0
  67. package/dist/motion/index.js +6 -0
  68. package/dist/motion/index.js.map +1 -0
  69. package/dist/motion/native/serializeMotionTimeline.d.ts +12 -0
  70. package/dist/motion/native/serializeMotionTimeline.js +21 -0
  71. package/dist/motion/native/serializeMotionTimeline.js.map +1 -0
  72. package/dist/physicalMetrics-W5uZ5xKb.d.ts +48 -0
  73. package/dist/physicalMetrics.d.ts +1 -0
  74. package/dist/physicalMetrics.js +58 -0
  75. package/dist/physicalMetrics.js.map +1 -0
  76. package/dist/platform-adapter/CommandResultUtils.d.ts +12 -0
  77. package/dist/platform-adapter/CommandResultUtils.js +21 -0
  78. package/dist/platform-adapter/CommandResultUtils.js.map +1 -0
  79. package/dist/platform-adapter/createPlatformSync.d.ts +16 -0
  80. package/dist/platform-adapter/createPlatformSync.js +30 -0
  81. package/dist/platform-adapter/createPlatformSync.js.map +1 -0
  82. package/dist/platform-adapter/index.d.ts +12 -0
  83. package/dist/platform-adapter/index.js +10 -0
  84. package/dist/platform-adapter/index.js.map +1 -0
  85. package/dist/platform-adapter/interface.d.ts +7 -0
  86. package/dist/platform-adapter/interface.js +1 -0
  87. package/dist/platform-adapter/interface.js.map +1 -0
  88. package/dist/platform-adapter/pico-os/PicoOSPlatform.d.ts +25 -0
  89. package/dist/platform-adapter/pico-os/PicoOSPlatform.js +168 -0
  90. package/dist/platform-adapter/pico-os/PicoOSPlatform.js.map +1 -0
  91. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.d.ts +66 -0
  92. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js +372 -0
  93. package/dist/platform-adapter/puppeteer/PuppeteerPlatform.js.map +1 -0
  94. package/dist/platform-adapter/spatialRequestMetadata.d.ts +6 -0
  95. package/dist/platform-adapter/spatialRequestMetadata.js +39 -0
  96. package/dist/platform-adapter/spatialRequestMetadata.js.map +1 -0
  97. package/dist/platform-adapter/spatialSceneQuery.d.ts +12 -0
  98. package/dist/platform-adapter/spatialSceneQuery.js +12 -0
  99. package/dist/platform-adapter/spatialSceneQuery.js.map +1 -0
  100. package/dist/platform-adapter/vision-os/VisionOSPlatform.d.ts +19 -0
  101. package/dist/platform-adapter/vision-os/VisionOSPlatform.js +77 -0
  102. package/dist/platform-adapter/vision-os/VisionOSPlatform.js.map +1 -0
  103. package/dist/platform-runtime.d.ts +12 -0
  104. package/dist/platform-runtime.js +14 -0
  105. package/dist/platform-runtime.js.map +1 -0
  106. package/dist/reality/Attachment.d.ts +19 -0
  107. package/dist/reality/Attachment.js +39 -0
  108. package/dist/reality/Attachment.js.map +1 -0
  109. package/dist/reality/component/ModelComponent.d.ts +14 -0
  110. package/dist/reality/component/ModelComponent.js +11 -0
  111. package/dist/reality/component/ModelComponent.js.map +1 -0
  112. package/dist/reality/component/SpatialComponent.d.ts +8 -0
  113. package/dist/reality/component/SpatialComponent.js +19 -0
  114. package/dist/reality/component/SpatialComponent.js.map +1 -0
  115. package/dist/reality/component/index.d.ts +8 -0
  116. package/dist/reality/component/index.js +3 -0
  117. package/dist/reality/component/index.js.map +1 -0
  118. package/dist/reality/entity/SpatialEntity.d.ts +7 -0
  119. package/dist/reality/entity/SpatialEntity.js +291 -0
  120. package/dist/reality/entity/SpatialEntity.js.map +1 -0
  121. package/dist/reality/entity/SpatialModelEntity.d.ts +17 -0
  122. package/dist/reality/entity/SpatialModelEntity.js +17 -0
  123. package/dist/reality/entity/SpatialModelEntity.js.map +1 -0
  124. package/dist/reality/entity/index.d.ts +8 -0
  125. package/dist/reality/entity/index.js +3 -0
  126. package/dist/reality/entity/index.js.map +1 -0
  127. package/dist/reality/geometry/SpatialBoxGeometry.d.ts +16 -0
  128. package/dist/reality/geometry/SpatialBoxGeometry.js +13 -0
  129. package/dist/reality/geometry/SpatialBoxGeometry.js.map +1 -0
  130. package/dist/reality/geometry/SpatialConeGeometry.d.ts +16 -0
  131. package/dist/reality/geometry/SpatialConeGeometry.js +13 -0
  132. package/dist/reality/geometry/SpatialConeGeometry.js.map +1 -0
  133. package/dist/reality/geometry/SpatialCylinderGeometry.d.ts +16 -0
  134. package/dist/reality/geometry/SpatialCylinderGeometry.js +13 -0
  135. package/dist/reality/geometry/SpatialCylinderGeometry.js.map +1 -0
  136. package/dist/reality/geometry/SpatialGeometry.d.ts +7 -0
  137. package/dist/reality/geometry/SpatialGeometry.js +13 -0
  138. package/dist/reality/geometry/SpatialGeometry.js.map +1 -0
  139. package/dist/reality/geometry/SpatialPlaneGeometry.d.ts +16 -0
  140. package/dist/reality/geometry/SpatialPlaneGeometry.js +13 -0
  141. package/dist/reality/geometry/SpatialPlaneGeometry.js.map +1 -0
  142. package/dist/reality/geometry/SpatialSphereGeometry.d.ts +16 -0
  143. package/dist/reality/geometry/SpatialSphereGeometry.js +13 -0
  144. package/dist/reality/geometry/SpatialSphereGeometry.js.map +1 -0
  145. package/dist/reality/geometry/index.d.ts +12 -0
  146. package/dist/reality/geometry/index.js +7 -0
  147. package/dist/reality/geometry/index.js.map +1 -0
  148. package/dist/reality/index.d.ts +18 -0
  149. package/dist/reality/index.js +7 -0
  150. package/dist/reality/index.js.map +1 -0
  151. package/dist/reality/material/SpatialMaterial.d.ts +7 -0
  152. package/dist/reality/material/SpatialMaterial.js +13 -0
  153. package/dist/reality/material/SpatialMaterial.js.map +1 -0
  154. package/dist/reality/material/SpatialUnlitMaterial.d.ts +16 -0
  155. package/dist/reality/material/SpatialUnlitMaterial.js +16 -0
  156. package/dist/reality/material/SpatialUnlitMaterial.js.map +1 -0
  157. package/dist/reality/material/index.d.ts +8 -0
  158. package/dist/reality/material/index.js +3 -0
  159. package/dist/reality/material/index.js.map +1 -0
  160. package/dist/reality/realityCreator.d.ts +22 -0
  161. package/dist/reality/realityCreator.js +89 -0
  162. package/dist/reality/realityCreator.js.map +1 -0
  163. package/dist/reality/resource/SpatialModelAsset.d.ts +15 -0
  164. package/dist/reality/resource/SpatialModelAsset.js +12 -0
  165. package/dist/reality/resource/SpatialModelAsset.js.map +1 -0
  166. package/dist/reality/resource/SpatialTextureResource.d.ts +16 -0
  167. package/dist/reality/resource/SpatialTextureResource.js +16 -0
  168. package/dist/reality/resource/SpatialTextureResource.js.map +1 -0
  169. package/dist/reality/resource/index.d.ts +9 -0
  170. package/dist/reality/resource/index.js +3 -0
  171. package/dist/reality/resource/index.js.map +1 -0
  172. package/dist/runtime/WebSpatialRuntimeError.d.ts +10 -0
  173. package/dist/runtime/WebSpatialRuntimeError.js +14 -0
  174. package/dist/runtime/WebSpatialRuntimeError.js.map +1 -0
  175. package/dist/runtime/capability-data.d.ts +12 -0
  176. package/dist/runtime/capability-data.js +134 -0
  177. package/dist/runtime/capability-data.js.map +1 -0
  178. package/dist/runtime/index.d.ts +8 -0
  179. package/dist/runtime/index.js +27 -0
  180. package/dist/runtime/index.js.map +1 -0
  181. package/dist/runtime/jsbAdapterPlatform.d.ts +9 -0
  182. package/dist/runtime/jsbAdapterPlatform.js +38 -0
  183. package/dist/runtime/jsbAdapterPlatform.js.map +1 -0
  184. package/dist/runtime/keys.d.ts +34 -0
  185. package/dist/runtime/keys.js +122 -0
  186. package/dist/runtime/keys.js.map +1 -0
  187. package/dist/runtime/semver.d.ts +8 -0
  188. package/dist/runtime/semver.js +32 -0
  189. package/dist/runtime/semver.js.map +1 -0
  190. package/dist/runtime/supports.d.ts +22 -0
  191. package/dist/runtime/supports.js +78 -0
  192. package/dist/runtime/supports.js.map +1 -0
  193. package/dist/runtime/types.d.ts +12 -0
  194. package/dist/runtime/types.js +1 -0
  195. package/dist/runtime/types.js.map +1 -0
  196. package/dist/runtime/userAgent.d.ts +20 -0
  197. package/dist/runtime/userAgent.js +41 -0
  198. package/dist/runtime/userAgent.js.map +1 -0
  199. package/dist/scene-polyfill.d.ts +18 -0
  200. package/dist/scene-polyfill.js +480 -0
  201. package/dist/scene-polyfill.js.map +1 -0
  202. package/dist/spatial-host.d.ts +13 -0
  203. package/dist/spatial-host.js +18 -0
  204. package/dist/spatial-host.js.map +1 -0
  205. package/dist/spatial-window-polyfill.d.ts +3 -0
  206. package/dist/spatial-window-polyfill.js +155 -0
  207. package/dist/spatial-window-polyfill.js.map +1 -0
  208. package/dist/spatializedElementMotion-_0XWPQCE.d.ts +1009 -0
  209. package/dist/types/animation.d.ts +7 -0
  210. package/dist/types/animation.js +1 -0
  211. package/dist/types/animation.js.map +1 -0
  212. package/dist/types/global.d.ts +38 -0
  213. package/dist/types/global.js +1 -0
  214. package/dist/types/global.js.map +1 -0
  215. package/dist/types/internal.d.ts +7 -0
  216. package/dist/types/internal.js +12 -0
  217. package/dist/types/internal.js.map +1 -0
  218. package/dist/types/motion/index.d.ts +7 -0
  219. package/dist/types/motion/index.js +3 -0
  220. package/dist/types/motion/index.js.map +1 -0
  221. package/dist/types/motion/spatializedElementMotion.d.ts +7 -0
  222. package/dist/types/motion/spatializedElementMotion.js +1 -0
  223. package/dist/types/motion/spatializedElementMotion.js.map +1 -0
  224. package/dist/types/motion/spatializedMotion.d.ts +7 -0
  225. package/dist/types/motion/spatializedMotion.js +16 -0
  226. package/dist/types/motion/spatializedMotion.js.map +1 -0
  227. package/dist/types/motion/spatializedPlayback.d.ts +11 -0
  228. package/dist/types/motion/spatializedPlayback.js +1 -0
  229. package/dist/types/motion/spatializedPlayback.js.map +1 -0
  230. package/dist/types/motion/spatializedVisual.d.ts +35 -0
  231. package/dist/types/motion/spatializedVisual.js +1 -0
  232. package/dist/types/motion/spatializedVisual.js.map +1 -0
  233. package/dist/types/types.d.ts +7 -0
  234. package/dist/types/types.js +117 -0
  235. package/dist/types/types.js.map +1 -0
  236. package/dist/utils.d.ts +44 -0
  237. package/dist/utils.js +86 -0
  238. package/dist/utils.js.map +1 -0
  239. package/package.json +20 -4
  240. package/src/JSBCommand.ts +132 -5
  241. package/src/SpatialObject.ts +10 -0
  242. package/src/Spatialized2DElement.ts +5 -0
  243. package/src/SpatializedDynamic3DElement.ts +5 -0
  244. package/src/SpatializedElement.ts +29 -0
  245. package/src/SpatializedStatic3DElement.ts +42 -3
  246. package/src/WebMsgCommand.ts +40 -0
  247. package/src/coverage-boost.test.ts +239 -216
  248. package/src/index.ts +25 -11
  249. package/src/install-polyfills.ts +38 -0
  250. package/src/jsbcommand.coverage.test.ts +23 -0
  251. package/src/motion/AnimationObject.test.ts +421 -0
  252. package/src/motion/AnimationObject.ts +208 -0
  253. package/src/motion/compute/index.ts +10 -0
  254. package/src/motion/compute/motionPropertyValues.test.ts +55 -0
  255. package/src/motion/compute/motionPropertyValues.ts +70 -0
  256. package/src/motion/compute/normalize.test.ts +99 -0
  257. package/src/motion/compute/normalize.ts +289 -0
  258. package/src/motion/compute/validate.test.ts +229 -0
  259. package/src/motion/compute/validate.ts +156 -0
  260. package/src/motion/index.ts +2 -0
  261. package/src/motion/native/serializeMotionTimeline.test.ts +61 -0
  262. package/src/motion/native/serializeMotionTimeline.ts +27 -0
  263. package/src/platform-adapter/createPlatformSync.ts +5 -3
  264. package/src/platform-adapter/pico-os/PicoOSPlatform.ts +76 -11
  265. package/src/platform-adapter/spatialRequestMetadata.test.ts +175 -0
  266. package/src/platform-adapter/spatialRequestMetadata.ts +48 -0
  267. package/src/platform-adapter/vision-os/VisionOSPlatform.ts +6 -1
  268. package/src/reality/entity/SpatialEntity.ts +127 -0
  269. package/src/runtime/capability-data.ts +104 -4
  270. package/src/runtime/index.ts +0 -11
  271. package/src/runtime/keys.ts +12 -1
  272. package/src/runtime/supports.test.ts +143 -4
  273. package/src/runtime/supports.ts +3 -1
  274. package/src/runtime/useAnimation.capability.test.ts +275 -0
  275. package/src/scene-polyfill.manifest.test.ts +306 -5
  276. package/src/scene-polyfill.request-metadata.test.ts +39 -0
  277. package/src/scene-polyfill.test.ts +33 -94
  278. package/src/scene-polyfill.ts +117 -87
  279. package/src/spatial-window-polyfill.ts +18 -2
  280. package/src/transform-roundtrip.test.ts +90 -0
  281. package/src/types/animation.ts +224 -0
  282. package/src/types/global.ts +1 -8
  283. package/src/types/motion/index.ts +10 -0
  284. package/src/types/motion/spatializedElementMotion.ts +49 -0
  285. package/src/types/motion/spatializedMotion.ts +147 -0
  286. package/src/types/motion/spatializedPlayback.ts +17 -0
  287. package/src/types/motion/spatializedVisual.ts +24 -0
  288. package/src/types/types.ts +3 -0
  289. package/src/utils.ts +54 -0
  290. package/tsup.config.ts +61 -36
  291. package/vitest.config.ts +5 -1
  292. package/dist/iife/index.d.ts +0 -1251
  293. package/dist/iife/index.global.js +0 -75
  294. package/dist/iife/index.global.js.map +0 -1
  295. package/src/platform-adapter/ssr/SSRPlatform.ts +0 -52
  296. /package/src/{ssr-polyfill.ts → isSSREnv.ts} +0 -0
package/src/JSBCommand.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import { getPlatform } from './platform-runtime'
2
+ import { pointToPhysical } from './physicalMetrics'
3
+ import {
4
+ getRuntime,
5
+ supports,
6
+ VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER,
7
+ } from './runtime/supports'
2
8
  import { SpatialComponent } from './reality/component/SpatialComponent'
3
9
  import { SpatialEntity } from './reality/entity/SpatialEntity'
4
10
  import { SpatialMaterial } from './reality/material/SpatialMaterial'
@@ -27,7 +33,12 @@ import {
27
33
  ModelSource,
28
34
  SpatialTextureResourceOptions,
29
35
  } from './types/types'
36
+ import type { AnimateTransformCommand } from './types/animation'
30
37
  import { composeSRT } from './utils'
38
+ import type {
39
+ ControlSpatializedElementAnimationCommand,
40
+ CreateSpatializedElementAnimationCommand,
41
+ } from './types/motion/spatializedElementMotion'
31
42
 
32
43
  abstract class JSBCommand {
33
44
  commandType: string = ''
@@ -628,6 +639,64 @@ export class CheckWebViewCanCreateCommand extends JSBCommand {
628
639
  }
629
640
  }
630
641
 
642
+ export class AnimateTransformJSBCommand extends JSBCommand {
643
+ commandType = 'AnimateTransform'
644
+
645
+ constructor(private command: AnimateTransformCommand) {
646
+ super()
647
+ }
648
+
649
+ protected getParams(): Record<string, any> | undefined {
650
+ const { type, animationId, entityId } = this.command
651
+ const params: Record<string, any> = { type, animationId }
652
+
653
+ if (entityId !== undefined) params.entityId = entityId
654
+
655
+ if (type === 'play') {
656
+ if (this.command.toTransform) {
657
+ params.toTransform = Array.from(this.command.toTransform)
658
+ }
659
+ if (this.command.fromTransform) {
660
+ params.fromTransform = Array.from(this.command.fromTransform)
661
+ }
662
+ if (this.command.duration !== undefined)
663
+ params.duration = this.command.duration
664
+ if (this.command.timingFunction !== undefined)
665
+ params.timingFunction = this.command.timingFunction
666
+ if (this.command.delay !== undefined) params.delay = this.command.delay
667
+ if (this.command.loop !== undefined) params.loop = this.command.loop
668
+ if (this.command.playbackRate !== undefined)
669
+ params.playbackRate = this.command.playbackRate
670
+ }
671
+
672
+ return params
673
+ }
674
+ }
675
+ // TODO(remove): temporary OTA0 compat shim — delete once #1330 lands and
676
+ // attachment JSB always uses the placement-shaped payload.
677
+ function usePlacementProtocol(): boolean {
678
+ // WS_SHELL_VERSION debug shells claim every capability via supports(), but
679
+ // the in-repo visionOS runtime still decodes only the legacy attachment
680
+ // payload — keep sending it there.
681
+ const rt = getRuntime()
682
+ if (
683
+ rt.type === 'visionos' &&
684
+ rt.shellVersion === VISIONOS_DEBUG_SHELL_VERSION_PLACEHOLDER
685
+ ) {
686
+ return false
687
+ }
688
+ return supports('AttachmentEntity', ['placement'])
689
+ }
690
+
691
+ function toPlacementVec3(position?: [number, number, number]): {
692
+ x: number
693
+ y: number
694
+ z: number
695
+ } {
696
+ const [x, y, z] = position ?? [0, 0, 0]
697
+ return { x, y, z }
698
+ }
699
+
631
700
  export class InitializeAttachmentCommand extends JSBCommand {
632
701
  commandType = 'InitializeAttachment'
633
702
  constructor(
@@ -637,12 +706,25 @@ export class InitializeAttachmentCommand extends JSBCommand {
637
706
  super()
638
707
  }
639
708
  protected getParams() {
709
+ const p = this.options
710
+ if (!usePlacementProtocol()) {
711
+ return {
712
+ id: this.attachmentId,
713
+ parentEntityId: p.parentEntityId,
714
+ position: p.position ?? [0, 0, 0],
715
+ size: p.size,
716
+ ownerViewId: p.ownerViewId,
717
+ }
718
+ }
719
+ // Runtimes advertising this capability decode a Vec3 position and meter
720
+ // dimensions instead of the legacy tuple and point size.
640
721
  return {
641
722
  id: this.attachmentId,
642
- parentEntityId: this.options.parentEntityId,
643
- position: this.options.position ?? [0, 0, 0],
644
- size: this.options.size,
645
- ownerViewId: this.options.ownerViewId,
723
+ placementId: p.parentEntityId,
724
+ position: toPlacementVec3(p.position),
725
+ width: pointToPhysical(p.size.width),
726
+ height: pointToPhysical(p.size.height),
727
+ ownerViewId: p.ownerViewId,
646
728
  }
647
729
  }
648
730
  }
@@ -656,9 +738,54 @@ export class UpdateAttachmentEntityCommand extends JSBCommand {
656
738
  super()
657
739
  }
658
740
  protected getParams() {
741
+ if (!usePlacementProtocol()) {
742
+ return {
743
+ id: this.attachmentId,
744
+ ...this.options,
745
+ }
746
+ }
747
+ const { position, size } = this.options
659
748
  return {
660
749
  id: this.attachmentId,
661
- ...this.options,
750
+ ...(position ? { position: toPlacementVec3(position) } : {}),
751
+ ...(size
752
+ ? {
753
+ width: pointToPhysical(size.width),
754
+ height: pointToPhysical(size.height),
755
+ }
756
+ : {}),
757
+ }
758
+ }
759
+ }
760
+
761
+ export class CreateSpatializedElementAnimationJSBCommand extends JSBCommand {
762
+ commandType = 'CreateSpatializedElementAnimation'
763
+
764
+ constructor(private command: CreateSpatializedElementAnimationCommand) {
765
+ super()
766
+ }
767
+
768
+ protected getParams() {
769
+ const { elementId, timeline } = this.command
770
+ return {
771
+ elementId,
772
+ timeline,
773
+ }
774
+ }
775
+ }
776
+
777
+ export class ControlSpatializedElementAnimationJSBCommand extends JSBCommand {
778
+ commandType = 'ControlSpatializedElementAnimation'
779
+
780
+ constructor(private command: ControlSpatializedElementAnimationCommand) {
781
+ super()
782
+ }
783
+
784
+ protected getParams() {
785
+ const { animationId, type } = this.command
786
+ return {
787
+ animationId,
788
+ type,
662
789
  }
663
790
  }
664
791
  }
@@ -38,6 +38,16 @@ export class SpatialObject {
38
38
  return
39
39
  }
40
40
 
41
+ const errorMessage =
42
+ typeof ret.errorMessage === 'string' ? ret.errorMessage.toLowerCase() : ''
43
+ const isMissingNativeObject = errorMessage.includes('not exsit')
44
+ if (isMissingNativeObject) {
45
+ // Treat native pre-teardown as an idempotent destroy during page back navigation.
46
+ this.onDestroy()
47
+ this.isDestroyed = true
48
+ return
49
+ }
50
+
41
51
  throw new Error(ret.errorMessage)
42
52
  }
43
53
 
@@ -12,6 +12,11 @@ import { Spatialized2DElementProperties } from './types/types'
12
12
  * allowing HTML elements to be positioned and interacted with in spatial applications.
13
13
  */
14
14
  export class Spatialized2DElement extends SpatializedElement {
15
+ /**
16
+ * Identifies the motion target kind supported by this element.
17
+ */
18
+ override readonly kind = 'spatialized2d' as const
19
+
15
20
  /**
16
21
  * Creates a new spatialized 2D element.
17
22
  * @param id Unique identifier for this element
@@ -11,6 +11,11 @@ import {
11
11
  } from './types/types'
12
12
 
13
13
  export class SpatializedDynamic3DElement extends SpatializedElement {
14
+ /**
15
+ * Identifies the motion target kind supported by this element.
16
+ */
17
+ override readonly kind = 'dynamic3d' as const
18
+
14
19
  children: SpatialEntityOrReality[] = []
15
20
  events: Record<string, (data: any) => void> = {}
16
21
 
@@ -1,8 +1,14 @@
1
1
  import { UpdateSpatializedElementTransform } from './JSBCommand'
2
+ import { AnimationObject } from './motion/AnimationObject'
2
3
  import { WebSpatialProtocolResult } from './platform-adapter/interface'
3
4
  import { SpatialObject } from './SpatialObject'
4
5
  import { SpatialWebEvent } from './SpatialWebEvent'
5
6
  import { createSpatialEvent } from './SpatialWebEventCreator'
7
+ import {
8
+ normalizeMotionConfig,
9
+ validateNormalizedMotionConfig,
10
+ } from './motion/compute'
11
+ import { motionConfigToNativeTimeline } from './motion/native/serializeMotionTimeline'
6
12
  import {
7
13
  CubeInfo,
8
14
  SpatialDragEndEvent,
@@ -27,6 +33,10 @@ import {
27
33
  SpatialTapMsg,
28
34
  SpatialWebMsgType,
29
35
  } from './WebMsgCommand'
36
+ import type {
37
+ SpatializedMotionConfig,
38
+ SpatializedMotionKind,
39
+ } from './types/motion/spatializedMotion'
30
40
 
31
41
  /**
32
42
  * Abstract base class for all spatialized elements in the WebSpatial environment.
@@ -34,6 +44,11 @@ import {
34
44
  * including transformation handling and gesture event processing.
35
45
  */
36
46
  export abstract class SpatializedElement extends SpatialObject {
47
+ /**
48
+ * Identifies the motion target kind supported by this spatialized element.
49
+ */
50
+ abstract readonly kind: SpatializedMotionKind
51
+
37
52
  /**
38
53
  * Creates a new spatialized element with the specified ID.
39
54
  * Registers the element to receive spatial events.
@@ -55,6 +70,20 @@ export abstract class SpatializedElement extends SpatialObject {
55
70
  properties: Partial<SpatializedElementProperties>,
56
71
  ): Promise<WebSpatialProtocolResult>
57
72
 
73
+ /**
74
+ * Creates a native-first AnimationObject bound to this spatialized element.
75
+ */
76
+ async createAnimation(
77
+ config: SpatializedMotionConfig,
78
+ ): Promise<AnimationObject> {
79
+ const normalized = normalizeMotionConfig(config)
80
+ validateNormalizedMotionConfig(normalized)
81
+ return AnimationObject.create({
82
+ elementId: this.id,
83
+ timeline: motionConfigToNativeTimeline(normalized),
84
+ })
85
+ }
86
+
58
87
  /**
59
88
  * Updates the transformation matrix of this element in 3D space.
60
89
  * This affects the position, rotation, and scale of the element.
@@ -4,6 +4,7 @@ import {
4
4
  ModelLoadingMode,
5
5
  ModelSource,
6
6
  SpatializedStatic3DElementProperties,
7
+ StageMode,
7
8
  } from './types/types'
8
9
  import {
9
10
  ModelLoadSuccess,
@@ -11,6 +12,7 @@ import {
11
12
  SpatialWebMsgType,
12
13
  AnimationStateChangeDetail,
13
14
  AnimationStateChangeMsg,
15
+ EntityTransformChangeMsg,
14
16
  } from './WebMsgCommand'
15
17
 
16
18
  /**
@@ -19,6 +21,11 @@ import {
19
21
  * and provides events for load success and failure.
20
22
  */
21
23
  export class SpatializedStatic3DElement extends SpatializedElement {
24
+ /**
25
+ * Identifies the motion target kind supported by this element.
26
+ */
27
+ override readonly kind = 'static3d' as const
28
+
22
29
  /**
23
30
  * Creates a new spatialized static 3D element with the specified ID and URL.
24
31
  * Registers the element to receive spatial events.
@@ -138,6 +145,9 @@ export class SpatializedStatic3DElement extends SpatializedElement {
138
145
  if (properties.loading !== undefined) {
139
146
  this._loading = properties.loading
140
147
  }
148
+ if (properties.stagemode !== undefined) {
149
+ this._stagemode = properties.stagemode
150
+ }
141
151
  return new UpdateSpatializedStatic3DElementProperties(
142
152
  this,
143
153
  properties,
@@ -297,6 +307,8 @@ export class SpatializedStatic3DElement extends SpatializedElement {
297
307
  this._currentTime = data.detail.currentTime ?? 0
298
308
  this._anchorTimestamp = data.detail.timestamp ?? Date.now()
299
309
  this._onAnimationStateChangeCallback?.(data.detail)
310
+ } else if (data.type === SpatialWebMsgType.entitytransformchange) {
311
+ this._entityTransform = new DOMMatrixReadOnly(data.detail.transform)
300
312
  } else {
301
313
  // Handle other spatial events using the base class implementation
302
314
  super.onReceiveEvent(data)
@@ -363,9 +375,35 @@ export class SpatializedStatic3DElement extends SpatializedElement {
363
375
  this._onLoadFailureCallback = callback
364
376
  }
365
377
 
366
- updateModelTransform(transform: DOMMatrixReadOnly) {
367
- const modelTransform = Array.from(transform.toFloat64Array())
368
- this.updateProperties({ modelTransform })
378
+ /**
379
+ * Built-in interaction mode. In `'orbit'` the native layer drives the
380
+ * transform and `entityTransform` is read-only.
381
+ */
382
+ private _stagemode: StageMode = 'none'
383
+
384
+ get stagemode(): StageMode {
385
+ return this._stagemode
386
+ }
387
+
388
+ /**
389
+ * Latest transform of the model, including native-driven manipulations such
390
+ * as orbit interaction.
391
+ */
392
+ private _entityTransform: DOMMatrixReadOnly = new DOMMatrixReadOnly()
393
+
394
+ get entityTransform(): DOMMatrixReadOnly {
395
+ return this._entityTransform
396
+ }
397
+
398
+ set entityTransform(transform: DOMMatrixReadOnly) {
399
+ // In orbit mode the native layer owns the transform, so ignore writes.
400
+ if (this._stagemode === 'orbit') return
401
+ this._entityTransform = transform
402
+ // The public API is `entityTransform`, but the JSB property stays
403
+ // `modelTransform` so the native side remains backward compatible.
404
+ this.updateProperties({
405
+ modelTransform: Array.from(transform.toFloat64Array()),
406
+ })
369
407
  }
370
408
  }
371
409
 
@@ -379,3 +417,4 @@ type Static3DReceiveEventData =
379
417
  | ModelLoadFailure
380
418
  | ReceiveEventData
381
419
  | AnimationStateChangeMsg
420
+ | EntityTransformChangeMsg
@@ -21,6 +21,14 @@ export enum SpatialWebMsgType {
21
21
 
22
22
  animationstatechange = 'animationstatechange',
23
23
 
24
+ // Native-driven transform updates (e.g. while in `stagemode="orbit"`)
25
+ entitytransformchange = 'entitytransformchange',
26
+
27
+ // Animation terminal events (keyed by animationId, not by this enum)
28
+ animationcompleted = 'animationcompleted',
29
+ animationstopped = 'animationstopped',
30
+ animationfailed = 'animationfailed',
31
+
24
32
  objectdestroy = 'objectdestroy',
25
33
  }
26
34
 
@@ -97,3 +105,35 @@ export interface AnimationStateChangeMsg {
97
105
  type: SpatialWebMsgType.animationstatechange
98
106
  detail: AnimationStateChangeDetail
99
107
  }
108
+
109
+ export interface EntityTransformChangeDetail {
110
+ /** Column-major 4x4 matrix (16 numbers) representing the manipulated transform. */
111
+ transform: number[]
112
+ }
113
+
114
+ export interface EntityTransformChangeMsg {
115
+ type: SpatialWebMsgType.entitytransformchange
116
+ detail: EntityTransformChangeDetail
117
+ }
118
+
119
+ // Animation terminal event payloads (delivered via SpatialWebEvent keyed by animationId)
120
+
121
+ export interface AnimationCompletedEventPayload {
122
+ type: 'completed'
123
+ /** Column-major 4x4 matrix (16 numbers) representing the final native transform. */
124
+ transform: number[]
125
+ }
126
+
127
+ export interface AnimationCanceledEventPayload {
128
+ type: 'canceled'
129
+ /** Column-major 4x4 matrix (16 numbers) representing the restored transform after cancel. */
130
+ transform: number[]
131
+ }
132
+
133
+ export interface AnimationFailedEventPayload {
134
+ type: 'failed'
135
+ animationId: string
136
+ command: 'play' | 'pause' | 'resume' | 'cancel'
137
+ code?: string
138
+ reason: string
139
+ }