@webspatial/core-sdk 1.0.3 → 1.0.5

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 (82) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +112 -81
  3. package/dist/iife/index.d.ts +683 -561
  4. package/dist/iife/index.global.js +3 -4
  5. package/dist/iife/index.global.js.map +1 -1
  6. package/dist/index.d.ts +683 -561
  7. package/dist/index.js +2175 -1291
  8. package/dist/index.js.map +1 -1
  9. package/package.json +7 -4
  10. package/src/JSBCommand.ts +631 -0
  11. package/src/Spatial.ts +68 -0
  12. package/src/SpatialObject.ts +46 -0
  13. package/src/SpatialScene.ts +75 -0
  14. package/src/SpatialSession.ts +187 -0
  15. package/src/SpatialWebEvent.ts +23 -0
  16. package/src/SpatialWebEventCreator.ts +12 -0
  17. package/src/Spatialized2DElement.ts +51 -0
  18. package/src/SpatializedDynamic3DElement.ts +30 -0
  19. package/src/SpatializedElement.ts +331 -0
  20. package/src/SpatializedElementCreator.ts +45 -0
  21. package/src/SpatializedStatic3DElement.ts +111 -0
  22. package/src/WebMsgCommand.ts +88 -0
  23. package/src/index.ts +23 -1
  24. package/src/platform-adapter/CommandResultUtils.ts +22 -0
  25. package/src/platform-adapter/android/AndroidPlatform.ts +133 -0
  26. package/src/platform-adapter/index.ts +21 -0
  27. package/src/platform-adapter/interface.ts +36 -0
  28. package/src/platform-adapter/ssr/SSRPlatform.ts +43 -0
  29. package/src/platform-adapter/vision-os/VisionOSPlatform.ts +77 -0
  30. package/src/reality/component/ModelComponent.ts +11 -0
  31. package/src/reality/component/SpatialComponent.ts +17 -0
  32. package/src/reality/component/index.ts +2 -0
  33. package/src/reality/entity/SpatialEntity.ts +255 -0
  34. package/src/reality/entity/SpatialModelEntity.ts +15 -0
  35. package/src/reality/entity/index.ts +2 -0
  36. package/src/reality/geometry/SpatialBoxGeometry.ts +12 -0
  37. package/src/reality/geometry/SpatialConeGeometry.ts +15 -0
  38. package/src/reality/geometry/SpatialCylinderGeometry.ts +15 -0
  39. package/src/reality/geometry/SpatialGeometry.ts +12 -0
  40. package/src/reality/geometry/SpatialPlaneGeometry.ts +15 -0
  41. package/src/reality/geometry/SpatialSphereGeometry.ts +15 -0
  42. package/src/reality/geometry/index.ts +6 -0
  43. package/src/reality/index.ts +5 -0
  44. package/src/reality/material/SpatialMaterial.ts +14 -0
  45. package/src/reality/material/SpatialUnlitMaterial.ts +16 -0
  46. package/src/reality/material/index.ts +2 -0
  47. package/src/reality/realityCreator.ts +94 -0
  48. package/src/reality/resource/SpatialModelAsset.ts +11 -0
  49. package/src/reality/resource/index.ts +1 -0
  50. package/src/scene-polyfill.test.ts +376 -0
  51. package/src/scene-polyfill.ts +359 -0
  52. package/src/spatial-window-polyfill.ts +182 -0
  53. package/src/ssr-polyfill.ts +3 -0
  54. package/src/types/global.d.ts +33 -1
  55. package/src/types/internal.ts +13 -0
  56. package/src/types/types.ts +380 -0
  57. package/src/utils.ts +61 -0
  58. package/tsconfig.json +1 -1
  59. package/vitest.config.ts +8 -0
  60. package/src/core/Spatial.ts +0 -50
  61. package/src/core/SpatialEntity.ts +0 -147
  62. package/src/core/SpatialHelper.ts +0 -230
  63. package/src/core/SpatialObject.ts +0 -26
  64. package/src/core/SpatialSession.ts +0 -457
  65. package/src/core/SpatialTransform.ts +0 -26
  66. package/src/core/SpatialWindowContainer.ts +0 -59
  67. package/src/core/component/EventSpatialComponent.ts +0 -32
  68. package/src/core/component/SpatialComponent.ts +0 -26
  69. package/src/core/component/SpatialInputComponent.ts +0 -24
  70. package/src/core/component/SpatialModel3DComponent.ts +0 -223
  71. package/src/core/component/SpatialModelComponent.ts +0 -39
  72. package/src/core/component/SpatialViewComponent.ts +0 -32
  73. package/src/core/component/SpatialWindowComponent.ts +0 -177
  74. package/src/core/component/index.ts +0 -14
  75. package/src/core/index.ts +0 -10
  76. package/src/core/private/WebSpatial.ts +0 -383
  77. package/src/core/private/remote-command/RemoteCommand.ts +0 -15
  78. package/src/core/private/remote-command/index.ts +0 -1
  79. package/src/core/resource/SpatialMeshResource.ts +0 -6
  80. package/src/core/resource/SpatialPhysicallyBasedMaterialResource.ts +0 -42
  81. package/src/core/resource/index.ts +0 -2
  82. package/src/core/types.ts +0 -32
@@ -1,230 +0,0 @@
1
- import { SpatialViewComponent, StyleParam } from './component'
2
- import { Spatial } from './Spatial'
3
- import { SpatialEntity } from './SpatialEntity'
4
- import { SpatialSession } from './SpatialSession'
5
- import { Vec3 } from './SpatialTransform'
6
-
7
- /**
8
- * Helper class used to quickly add spatial content to standard web pages
9
- * [Experimental] expect APIs to potentially change in future versions
10
- */
11
- export class SpatialHelper {
12
- private static _instance: SpatialHelper | null = null
13
- static get instance() {
14
- if (this._instance) {
15
- return this._instance
16
- } else {
17
- let spatial = new Spatial()
18
- if (spatial.isSupported()) {
19
- let session = spatial.requestSession()
20
- if (session) {
21
- this._instance = new SpatialHelper(session)
22
- return this._instance
23
- }
24
- }
25
- }
26
- return null
27
- }
28
-
29
- constructor(public session: SpatialSession) {}
30
-
31
- shape = {
32
- createShapeEntity: async (shape = 'box') => {
33
- var box = await this.session.createMeshResource({ shape: shape })
34
- var mat = await this.session.createPhysicallyBasedMaterialResource()
35
- await mat.update()
36
-
37
- var customModel = await this.session.createModelComponent()
38
- customModel.setMaterials([mat])
39
- customModel.setMesh(box)
40
-
41
- var boxEntity = await this.session.createEntity()
42
- await boxEntity.setComponent(customModel)
43
- boxEntity.transform.position.z = 0
44
- boxEntity.transform.scale = new Vec3(0.5, 0.5, 0.5)
45
- await boxEntity.updateTransform()
46
- return boxEntity
47
- },
48
- createModelEntity: async (url: string) => {
49
- var customModel = await this.session.createModelComponent({ url })
50
- var boxEntity = await this.session.createEntity()
51
- await boxEntity.setComponent(customModel)
52
- await boxEntity.updateTransform()
53
- return boxEntity
54
- },
55
- wrapInBoundingBoxEntity: async (entityToWrap: SpatialEntity) => {
56
- var bb = await entityToWrap.getBoundingBox()
57
-
58
- // Scale to fit
59
- var targetSize = 1.0
60
- var scale =
61
- targetSize / Math.max(bb.extents.x, bb.extents.y, bb.extents.z)
62
- entityToWrap.transform.scale.x = scale
63
- entityToWrap.transform.scale.y = scale
64
- entityToWrap.transform.scale.z = scale
65
-
66
- // Center within view
67
- entityToWrap.transform.position.x = -bb.center.x * scale
68
- entityToWrap.transform.position.y = -bb.center.y * scale
69
- entityToWrap.transform.position.z = -bb.center.z * scale
70
- await entityToWrap.updateTransform()
71
-
72
- // wrap in boudning box
73
- var boudningEntity = await SpatialHelper.instance?.session.createEntity()!
74
- await entityToWrap.setParent(boudningEntity!)
75
- return boudningEntity
76
- },
77
- }
78
-
79
- navigation = {
80
- openPanel: async (
81
- url: string,
82
- options?: { resolution: { width: number; height: number } },
83
- ) => {
84
- if (options?.resolution) {
85
- await this.session
86
- .getCurrentWindowContainer()
87
- ._setOpenSettings({ resolution: options.resolution })
88
- }
89
-
90
- // Create window container
91
- var wg = await this.session.createWindowContainer({
92
- style: 'Plain',
93
- windowComponent: null,
94
- windowContainer: null,
95
- })
96
-
97
- // Create a root entity displaying a webpage
98
- var ent = await this.session!.createEntity({
99
- windowComponent: null,
100
- windowContainer: wg,
101
- })
102
- var i = await this.session!.createWindowComponent({
103
- windowComponent: null,
104
- windowContainer: wg,
105
- })
106
- await i.loadURL(url)
107
- await ent.setCoordinateSpace('Root')
108
- await ent.setComponent(i)
109
-
110
- // Add enitity the window container
111
- await wg.setRootEntity(ent)
112
-
113
- // Restore default size
114
- await this.session
115
- .getCurrentWindowContainer()
116
- ._setOpenSettings({ resolution: { width: 900, height: 700 } })
117
-
118
- return {
119
- windowContainer: wg,
120
- }
121
- },
122
- openVolume: async (
123
- url: string,
124
- options?: { resolution: { width: number; height: number } },
125
- ) => {
126
- var wg = await this.session.createWindowContainer({
127
- style: 'Volumetric',
128
- windowComponent: null,
129
- windowContainer: null,
130
- })
131
-
132
- // Create a root view entity within the window container
133
- var rootEnt = await this.session!.createEntity({
134
- windowComponent: null,
135
- windowContainer: wg,
136
- })
137
- await rootEnt.setComponent(
138
- await this.session!.createViewComponent({
139
- windowComponent: null,
140
- windowContainer: wg,
141
- }),
142
- )
143
- await rootEnt.setCoordinateSpace('Root')
144
- await wg.setRootEntity(rootEnt)
145
-
146
- // Add webpage to the window container
147
- var ent = await this.session!.createEntity({
148
- windowComponent: null,
149
- windowContainer: wg,
150
- })
151
- var i = await this.session!.createWindowComponent({
152
- windowComponent: null,
153
- windowContainer: wg,
154
- })
155
- await i.loadURL(url)
156
- if (options?.resolution) {
157
- await i.setResolution(
158
- options.resolution.width,
159
- options.resolution.height,
160
- )
161
- } else {
162
- await i.setResolution(1000, 1000)
163
- }
164
- ent.transform.position.z = -0.49
165
- await ent.updateTransform()
166
- await ent.setCoordinateSpace('App')
167
- await ent.setComponent(i)
168
- await ent.setParent(rootEnt)
169
- },
170
- }
171
-
172
- dom = {
173
- attachSpatialView: async (divOnPage: HTMLElement) => {
174
- // Create SpatialView
175
- var viewEnt = await this.session.createEntity()
176
- await viewEnt.setCoordinateSpace('Dom') // Set coordinate space so its transform is relative to the webpage's pixels
177
- await viewEnt.setComponent(await this.session.createViewComponent())
178
-
179
- // Add to the root window component to display
180
- var wc = await this.session.getCurrentWindowComponent()
181
- var ent = await wc.getEntity()
182
- await viewEnt.setParent(ent!)
183
-
184
- // Keep spatialView positioned where the div is
185
- var update = () => {
186
- var rect = divOnPage.getBoundingClientRect()
187
- viewEnt.transform.position.x = rect.x + rect.width / 2
188
- viewEnt.transform.position.y = rect.y + rect.height / 2 + window.scrollY
189
- viewEnt.updateTransform()
190
- viewEnt
191
- .getComponent(SpatialViewComponent)!
192
- .setResolution(rect.width, rect.height)
193
- }
194
- var mo = new MutationObserver(update)
195
- mo.observe(divOnPage, { attributes: true })
196
- var ro = new ResizeObserver(update)
197
- ro.observe(divOnPage)
198
- const addRemoveObserver = new MutationObserver(mutations => {
199
- mutations.forEach(mutation => {
200
- mutation.removedNodes.forEach(node => {
201
- if (node instanceof HTMLElement) {
202
- update()
203
- }
204
- })
205
- mutation.addedNodes.forEach(node => {
206
- if (node instanceof HTMLElement) {
207
- update()
208
- }
209
- })
210
- })
211
- })
212
- addRemoveObserver.observe(document.body, {
213
- childList: true,
214
- subtree: true,
215
- })
216
- update()
217
- return {
218
- entity: viewEnt,
219
- }
220
- },
221
- }
222
-
223
- setBackgroundStyle = async (
224
- style: StyleParam,
225
- backgroundColor = '#00000000',
226
- ) => {
227
- document.documentElement.style.backgroundColor = backgroundColor
228
- await this.session!.getCurrentWindowComponent().setStyle(style)
229
- }
230
- }
@@ -1,26 +0,0 @@
1
- import { WebSpatial } from './private/WebSpatial'
2
- import { WebSpatialResource } from './private/WebSpatial'
3
-
4
- /**
5
- * @hidden
6
- * Parent class of spatial objects, should not be used directly
7
- */
8
- export class SpatialObject {
9
- /** @hidden */
10
- constructor(
11
- /** @hidden */
12
- public _resource: WebSpatialResource,
13
- ) {}
14
-
15
- /**
16
- * Marks resource to be released (it should no longer be used)
17
- */
18
- async destroy() {
19
- await WebSpatial.destroyResource(this._resource)
20
- await this.onDestroy()
21
- }
22
-
23
- public name: string = ''
24
-
25
- protected async onDestroy() {}
26
- }
@@ -1,457 +0,0 @@
1
- import { SpatialEntity } from './SpatialEntity'
2
- import { SpatialWindowContainer } from './SpatialWindowContainer'
3
- import {
4
- WebSpatial,
5
- WebSpatialResource,
6
- WindowContainer,
7
- } from './private/WebSpatial'
8
- import {
9
- LoadingMethodKind,
10
- sceneDataShape,
11
- WindowContainerOptions,
12
- WindowStyle,
13
- } from './types'
14
-
15
- import {
16
- SpatialMeshResource,
17
- SpatialPhysicallyBasedMaterialResource,
18
- } from './resource'
19
- import {
20
- SpatialModelComponent,
21
- SpatialInputComponent,
22
- SpatialWindowComponent,
23
- SpatialViewComponent,
24
- SpatialModel3DComponent,
25
- } from './component'
26
- import { RemoteCommand } from './private/remote-command'
27
-
28
- type CreateResourceOptions = {
29
- windowContainer?: SpatialWindowContainer | null
30
- windowComponent?: SpatialWindowComponent | null
31
- }
32
-
33
- /**
34
- * Animation callback with timestamp
35
- */
36
- type animCallback = (time: DOMHighResTimeStamp) => Promise<any>
37
-
38
- /**
39
- * Parses the resource owners of the created object. If unedfined, will use the current window container and web panel. If null the created resource will not be destroyed unless explicitly destroyed.
40
- * @param options
41
- * @returns parsed results
42
- */
43
- function _parseParentResources(
44
- options?: CreateResourceOptions,
45
- ): [WindowContainer | null, WebSpatialResource | null] {
46
- var parentWindowContainer: WindowContainer | null = null
47
- if (options?.windowContainer !== null) {
48
- parentWindowContainer = options?.windowContainer
49
- ? options?.windowContainer._wg
50
- : WebSpatial.getCurrentWindowContainer()
51
- }
52
-
53
- var parentWindow: WebSpatialResource | null = null
54
- if (options?.windowComponent !== null) {
55
- parentWindow = options?.windowComponent
56
- ? options?.windowComponent._resource
57
- : WebSpatial.getCurrentWebPanel()
58
- }
59
-
60
- return [parentWindowContainer, parentWindow]
61
- }
62
-
63
- /**
64
- * Session use to establish a connection to the spatial renderer of the system. All resources must be created by the session
65
- */
66
- export class SpatialSession {
67
- /** @hidden */
68
- _engineUpdateListeners = Array<animCallback>()
69
- /** @hidden */
70
- _frameLoopStarted = false
71
-
72
- /**
73
- * Add event listener callback to be called each frame
74
- * @param callback callback to be called each update
75
- */
76
- addOnEngineUpdateEventListener(callback: animCallback) {
77
- this._engineUpdateListeners.push(callback)
78
-
79
- if (!this._frameLoopStarted) {
80
- this._frameLoopStarted = true
81
- WebSpatial.onFrame(async (time: number) => {
82
- await Promise.all(
83
- this._engineUpdateListeners.map(cb => {
84
- return cb(time)
85
- }),
86
- )
87
- })
88
- }
89
- }
90
-
91
- /**
92
- * Creates a Entity
93
- * @returns Entity
94
- */
95
- async createEntity(options?: CreateResourceOptions) {
96
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
97
- let entity = await WebSpatial.createResource(
98
- 'Entity',
99
- parentWindowContainer,
100
- parentWindow,
101
- )
102
- return new SpatialEntity(entity)
103
- }
104
-
105
- /**
106
- * Creates a WindowComponent
107
- * [TODO] should creation of components be moved to entity? and these made private?
108
- * @returns WindowComponent
109
- */
110
- async createWindowComponent(options?: CreateResourceOptions) {
111
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
112
- let entity = await WebSpatial.createResource(
113
- 'SpatialWebView',
114
- parentWindowContainer,
115
- parentWindow,
116
- )
117
- return new SpatialWindowComponent(entity)
118
- }
119
-
120
- /**
121
- * Creates a ViewComponent used to display 3D content within the entity
122
- * @returns SpatialViewComponent
123
- */
124
- async createViewComponent(options?: CreateResourceOptions) {
125
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
126
- let entity = await WebSpatial.createResource(
127
- 'SpatialView',
128
- parentWindowContainer,
129
- parentWindow,
130
- )
131
- return new SpatialViewComponent(entity)
132
- }
133
-
134
- /**
135
- * Creates a ModelComponent used to display geometry + material of a 3D model
136
- * @returns ModelComponent
137
- */
138
- async createModelComponent(
139
- options?: { url: string } & CreateResourceOptions,
140
- ) {
141
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
142
- var opts = undefined
143
- if (options) {
144
- opts = { modelURL: options.url }
145
- }
146
- let entity = await WebSpatial.createResource(
147
- 'ModelComponent',
148
- parentWindowContainer,
149
- parentWindow,
150
- opts,
151
- )
152
- return new SpatialModelComponent(entity)
153
- }
154
-
155
- /**
156
- * Creates a Model3DComponent
157
- * @returns Model3DComponent
158
- */
159
- async createModel3DComponent(
160
- options?: { url: string } & CreateResourceOptions,
161
- ) {
162
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
163
- var opts = undefined
164
- if (options) {
165
- opts = { modelURL: options.url }
166
- }
167
- let entity = await WebSpatial.createResource(
168
- 'Model3DComponent',
169
- parentWindowContainer,
170
- parentWindow,
171
- opts,
172
- )
173
- return new SpatialModel3DComponent(entity)
174
- }
175
-
176
- /**
177
- * Creates a InputComponent
178
- * [Experimental] Creates a InputComponent used to handle click and drag events of the entity containing a model
179
- * @returns InputComponent
180
- */
181
- async createInputComponent(options?: CreateResourceOptions) {
182
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
183
- let entity = await WebSpatial.createResource(
184
- 'InputComponent',
185
- parentWindowContainer,
186
- parentWindow,
187
- )
188
- return new SpatialInputComponent(entity)
189
- }
190
-
191
- /**
192
- * Creates a MeshResource containing geometry data
193
- * @returns MeshResource
194
- */
195
- async createMeshResource(
196
- options?: { shape?: string } & CreateResourceOptions,
197
- ) {
198
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
199
- let entity = await WebSpatial.createResource(
200
- 'MeshResource',
201
- parentWindowContainer,
202
- parentWindow,
203
- options,
204
- )
205
- return new SpatialMeshResource(entity)
206
- }
207
-
208
- /**
209
- * Creates a PhysicallyBasedMaterial containing PBR material data
210
- * @returns PhysicallyBasedMaterial
211
- */
212
- async createPhysicallyBasedMaterialResource(
213
- options?: {} & CreateResourceOptions,
214
- ) {
215
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
216
- let entity = await WebSpatial.createResource(
217
- 'PhysicallyBasedMaterial',
218
- parentWindowContainer,
219
- parentWindow,
220
- options,
221
- )
222
- return new SpatialPhysicallyBasedMaterialResource(entity)
223
- }
224
- /**
225
- * Creates a WindowContainer
226
- * @returns SpatialWindowContainer
227
- * */
228
- async createWindowContainer(
229
- options?: {
230
- style: WindowStyle
231
- } & CreateResourceOptions,
232
- ) {
233
- var style = options?.style ? options?.style : 'Plain'
234
- var [parentWindowContainer, parentWindow] = _parseParentResources(options)
235
- return new SpatialWindowContainer(
236
- await WebSpatial.createWindowContainer(
237
- style,
238
- parentWindowContainer,
239
- parentWindow,
240
- ),
241
- )
242
- }
243
-
244
- /**
245
- * Creates a Scene to display content within an anchored area managed by the OS
246
- * @hidden
247
- * @param {WindowStyle} [style='Plain'] - The style of the Scene container to be created with. Defaults to 'Plain'.
248
- * @param {Object} [cfg={}] - Configuration object for the Scene.
249
- * @returns Boolean
250
- */
251
- async _createScene(
252
- style: WindowStyle = 'Plain',
253
- cfg: {
254
- sceneData: sceneDataShape
255
- },
256
- ) {
257
- return await WebSpatial.createScene(style, cfg)
258
- }
259
-
260
- /**
261
- * Retrieves the window for this page
262
- * @returns the window component corresponding to the js running on this page
263
- * [TODO] discuss implications of this not being async
264
- */
265
- getCurrentWindowComponent() {
266
- return new SpatialWindowComponent(WebSpatial.getCurrentWebPanel())
267
- }
268
-
269
- /**
270
- * Retrieves the parent window for this page or null if this is the root page
271
- * @returns the window component or null
272
- */
273
- async getParentWindowComponent() {
274
- let parentResp: any = await WebSpatial.updateResource(
275
- WebSpatial.getCurrentWebPanel(),
276
- { getParentID: '' },
277
- )
278
- if (parentResp.data.parentID === '') {
279
- return new Promise<SpatialWindowComponent | null>((res, rej) => {
280
- res(null)
281
- })
282
- } else {
283
- var res = new WebSpatialResource()
284
- res.id = parentResp.data.parentID
285
- return new SpatialWindowComponent(res)
286
- }
287
- }
288
-
289
- /**
290
- * Logs a message to the native apps console
291
- * @param msg mesage to log
292
- */
293
- async log(...msg: any[]) {
294
- await WebSpatial.sendCommand(
295
- new RemoteCommand('log', {
296
- logString: msg.map(x => {
297
- return JSON.stringify(x)
298
- }),
299
- }),
300
- )
301
- }
302
-
303
- /**
304
- * @hidden
305
- * Debugging only, used to ping the native renderer
306
- */
307
- async _ping(msg: string) {
308
- return await WebSpatial.ping(msg)
309
- }
310
-
311
- /**
312
- * @hidden
313
- * Debugging to get internal state from native code
314
- * @returns stats from native code. Objects tracks number of native objects that were created but not yet explicitly destroyed. RefObjects tracks bjects that still have references. After an object is destroyed, we should be cleaning up all of the native references. Expect objects.count == refObjects.count , if not, there is likely a leak.
315
- */
316
- async _getStats() {
317
- return (await WebSpatial.getStats()) as {
318
- backend: string
319
- objects: { count: number }
320
- refObjects: { count: number }
321
- }
322
- }
323
-
324
- /**
325
- * @hidden
326
- */
327
- async _inspect(spatialObjectId: string = WebSpatial.getCurrentWebPanel().id) {
328
- return WebSpatial.inspect(spatialObjectId)
329
- }
330
-
331
- /**
332
- * @hidden
333
- */
334
- async _inspectRootWindowContainer() {
335
- return WebSpatial.inspectRootWindowContainer()
336
- }
337
-
338
- /** Opens the immersive space */
339
- async openImmersiveSpace() {
340
- return await WebSpatial.openImmersiveSpace()
341
- }
342
-
343
- /** Closes the immersive space */
344
- async dismissImmersiveSpace() {
345
- return await WebSpatial.dismissImmersiveSpace()
346
- }
347
-
348
- private static _immersiveWindowContainer =
349
- null as null | SpatialWindowContainer
350
- /**
351
- * Retreives the window container corresponding to the Immersive space
352
- * @returns the immersive window container
353
- */
354
- async getImmersiveWindowContainer() {
355
- if (SpatialSession._immersiveWindowContainer) {
356
- return SpatialSession._immersiveWindowContainer
357
- } else {
358
- SpatialSession._immersiveWindowContainer = new SpatialWindowContainer(
359
- WebSpatial.getImmersiveWindowContainer(),
360
- )
361
- return SpatialSession._immersiveWindowContainer
362
- }
363
- }
364
-
365
- // Retreives the window container that is the parent to this spatial web page
366
- private static _currentWindowContainer = null as null | SpatialWindowContainer
367
-
368
- /**
369
- * Gets the current window container for the window
370
- * [TODO] discuss what happens if it doesnt yet have a window container
371
- * @returns the current window container for the window
372
- */
373
- getCurrentWindowContainer() {
374
- if (SpatialSession._currentWindowContainer) {
375
- return SpatialSession._currentWindowContainer
376
- } else {
377
- SpatialSession._currentWindowContainer = new SpatialWindowContainer(
378
- WebSpatial.getCurrentWindowContainer(),
379
- )
380
- return SpatialSession._currentWindowContainer
381
- }
382
- }
383
-
384
- /**
385
- * Start a transaction that queues up commands to submit them all at once to reduce ipc overhead
386
- * @param fn function to be run, within this function, promises will not resolve
387
- * @returns promise for the entire transaction completion
388
- */
389
- transaction(fn: Function) {
390
- WebSpatial.startTransaction()
391
- fn()
392
- return WebSpatial.sendTransaction()
393
- }
394
-
395
- /**
396
- * Creates a window context object that is compatable with SpatialWindowComponent's setFromWindow API
397
- * @returns window context
398
- */
399
- async createWindowContext() {
400
- let openedWindow = window.open('webspatial://createWindowContext')
401
- if (WebSpatial.getBackend() != 'AVP') {
402
- // Currently there is a bug with webview which requires us to trigger a navigation before native code can interact with created webview
403
- var counter = 0
404
- while ((openedWindow!.window as any).testAPI == null) {
405
- if (counter > 15) {
406
- openedWindow?.close()
407
- openedWindow = window.open('about:blank')
408
- counter = 0
409
- this.log('unexpected error when trying to open new window, retrying.')
410
- }
411
- var locName = 'about:blank?x' + counter
412
- openedWindow!!.location.href = locName
413
- counter++
414
-
415
- await new Promise(resolve => setTimeout(resolve, 10))
416
- }
417
- ;(openedWindow! as any)._webSpatialID = (
418
- openedWindow!.window as any
419
- ).testAPI.getWindowID()
420
- } else {
421
- while ((openedWindow!.window as any)._webSpatialID == undefined) {
422
- await new Promise(resolve => setTimeout(resolve, 10))
423
- }
424
- }
425
- openedWindow!.document.head.innerHTML = `<meta name="viewport" content="width=device-width, initial-scale=1">
426
- <base href="${document.baseURI}">
427
- `
428
- return openedWindow
429
- }
430
-
431
- // Get Entity by id. Currently for debugging only.
432
- /** @hidden */
433
- async _getEntity(id: string) {
434
- const entityInfo = await WebSpatial.inspect(id)
435
- const [_, x, y, z] = entityInfo.position.match(/(\d+\.?\d*)/g)
436
- const [__, sx, sy, sz] = entityInfo.scale.match(/(\d+\.?\d*)/g)
437
-
438
- var res = new WebSpatialResource()
439
- res.id = id
440
- res.windowContainerId = WebSpatial.getCurrentWindowContainer().id
441
- const entity = new SpatialEntity(res)
442
- entity.transform.position.x = parseFloat(x)
443
- entity.transform.position.y = parseFloat(y)
444
- entity.transform.position.z = parseFloat(z)
445
-
446
- entity.transform.scale.x = parseFloat(sx)
447
- entity.transform.scale.y = parseFloat(sy)
448
- entity.transform.scale.z = parseFloat(sz)
449
-
450
- return entity
451
- }
452
- // set loading view.
453
- /** @hidden */
454
- async setLoading(method: LoadingMethodKind, style?: string) {
455
- return WebSpatial.setLoading(method, style)
456
- }
457
- }