@webspatial/core-sdk 0.0.1-alpha

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 (99) hide show
  1. package/README.md +112 -0
  2. package/dist/core/Spatial.d.ts +27 -0
  3. package/dist/core/Spatial.d.ts.map +1 -0
  4. package/dist/core/Spatial.js +41 -0
  5. package/dist/core/SpatialEntity.d.ts +92 -0
  6. package/dist/core/SpatialEntity.d.ts.map +1 -0
  7. package/dist/core/SpatialEntity.js +121 -0
  8. package/dist/core/SpatialHelper.d.ts +39 -0
  9. package/dist/core/SpatialHelper.d.ts.map +1 -0
  10. package/dist/core/SpatialHelper.js +169 -0
  11. package/dist/core/SpatialObject.d.ts +19 -0
  12. package/dist/core/SpatialObject.d.ts.map +1 -0
  13. package/dist/core/SpatialObject.js +22 -0
  14. package/dist/core/SpatialSession.d.ts +166 -0
  15. package/dist/core/SpatialSession.d.ts.map +1 -0
  16. package/dist/core/SpatialSession.js +310 -0
  17. package/dist/core/SpatialTransform.d.ts +23 -0
  18. package/dist/core/SpatialTransform.d.ts.map +1 -0
  19. package/dist/core/SpatialTransform.js +31 -0
  20. package/dist/core/SpatialWindowContainer.d.ts +31 -0
  21. package/dist/core/SpatialWindowContainer.d.ts.map +1 -0
  22. package/dist/core/SpatialWindowContainer.js +48 -0
  23. package/dist/core/component/EventSpatialComponent.d.ts +22 -0
  24. package/dist/core/component/EventSpatialComponent.d.ts.map +1 -0
  25. package/dist/core/component/EventSpatialComponent.js +23 -0
  26. package/dist/core/component/SpatialComponent.d.ts +11 -0
  27. package/dist/core/component/SpatialComponent.d.ts.map +1 -0
  28. package/dist/core/component/SpatialComponent.js +23 -0
  29. package/dist/core/component/SpatialInputComponent.d.ts +22 -0
  30. package/dist/core/component/SpatialInputComponent.d.ts.map +1 -0
  31. package/dist/core/component/SpatialInputComponent.js +14 -0
  32. package/dist/core/component/SpatialModel3DComponent.d.ts +86 -0
  33. package/dist/core/component/SpatialModel3DComponent.d.ts.map +1 -0
  34. package/dist/core/component/SpatialModel3DComponent.js +176 -0
  35. package/dist/core/component/SpatialModelComponent.d.ts +22 -0
  36. package/dist/core/component/SpatialModelComponent.d.ts.map +1 -0
  37. package/dist/core/component/SpatialModelComponent.js +34 -0
  38. package/dist/core/component/SpatialViewComponent.d.ts +22 -0
  39. package/dist/core/component/SpatialViewComponent.d.ts.map +1 -0
  40. package/dist/core/component/SpatialViewComponent.js +30 -0
  41. package/dist/core/component/SpatialWindowComponent.d.ts +86 -0
  42. package/dist/core/component/SpatialWindowComponent.d.ts.map +1 -0
  43. package/dist/core/component/SpatialWindowComponent.js +114 -0
  44. package/dist/core/component/index.d.ts +7 -0
  45. package/dist/core/component/index.d.ts.map +1 -0
  46. package/dist/core/component/index.js +6 -0
  47. package/dist/core/index.d.ts +11 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +9 -0
  50. package/dist/core/private/WebSpatial.d.ts +46 -0
  51. package/dist/core/private/WebSpatial.d.ts.map +1 -0
  52. package/dist/core/private/WebSpatial.js +282 -0
  53. package/dist/core/private/remote-command/RemoteCommand.d.ts +8 -0
  54. package/dist/core/private/remote-command/RemoteCommand.d.ts.map +1 -0
  55. package/dist/core/private/remote-command/RemoteCommand.js +11 -0
  56. package/dist/core/private/remote-command/index.d.ts +2 -0
  57. package/dist/core/private/remote-command/index.d.ts.map +1 -0
  58. package/dist/core/private/remote-command/index.js +1 -0
  59. package/dist/core/resource/SpatialMeshResource.d.ts +7 -0
  60. package/dist/core/resource/SpatialMeshResource.d.ts.map +1 -0
  61. package/dist/core/resource/SpatialMeshResource.js +6 -0
  62. package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.d.ts +37 -0
  63. package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.d.ts.map +1 -0
  64. package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.js +37 -0
  65. package/dist/core/resource/index.d.ts +3 -0
  66. package/dist/core/resource/index.d.ts.map +1 -0
  67. package/dist/core/resource/index.js +2 -0
  68. package/dist/core/types.d.ts +23 -0
  69. package/dist/core/types.d.ts.map +1 -0
  70. package/dist/core/types.js +1 -0
  71. package/dist/index.d.ts +2 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +1 -0
  74. package/package.json +35 -0
  75. package/src/core/Spatial.ts +48 -0
  76. package/src/core/SpatialEntity.ts +146 -0
  77. package/src/core/SpatialHelper.ts +197 -0
  78. package/src/core/SpatialObject.ts +24 -0
  79. package/src/core/SpatialSession.ts +434 -0
  80. package/src/core/SpatialTransform.ts +26 -0
  81. package/src/core/SpatialWindowContainer.ts +51 -0
  82. package/src/core/component/EventSpatialComponent.ts +32 -0
  83. package/src/core/component/SpatialComponent.ts +26 -0
  84. package/src/core/component/SpatialInputComponent.ts +24 -0
  85. package/src/core/component/SpatialModel3DComponent.ts +213 -0
  86. package/src/core/component/SpatialModelComponent.ts +39 -0
  87. package/src/core/component/SpatialViewComponent.ts +32 -0
  88. package/src/core/component/SpatialWindowComponent.ts +168 -0
  89. package/src/core/component/index.ts +14 -0
  90. package/src/core/index.ts +10 -0
  91. package/src/core/private/WebSpatial.ts +356 -0
  92. package/src/core/private/remote-command/RemoteCommand.ts +15 -0
  93. package/src/core/private/remote-command/index.ts +1 -0
  94. package/src/core/resource/SpatialMeshResource.ts +6 -0
  95. package/src/core/resource/SpatialPhysicallyBasedMaterialResource.ts +42 -0
  96. package/src/core/resource/index.ts +2 -0
  97. package/src/core/types.ts +27 -0
  98. package/src/index.ts +1 -0
  99. package/tsconfig.json +26 -0
@@ -0,0 +1,434 @@
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
+ /**
29
+ * Animation callback with timestamp
30
+ */
31
+ type animCallback = (time: DOMHighResTimeStamp) => Promise<any>
32
+
33
+ /**
34
+ * 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.
35
+ * @param options
36
+ * @returns parsed results
37
+ */
38
+ function _parseParentResources(options?: {
39
+ windowContainer?: SpatialWindowContainer | null
40
+ windowComponent?: SpatialWindowComponent | null
41
+ }): [WindowContainer | null, WebSpatialResource | null] {
42
+ var parentWindowContainer: WindowContainer | null = null
43
+ if (options?.windowContainer !== null) {
44
+ parentWindowContainer = options?.windowContainer
45
+ ? options?.windowContainer._wg
46
+ : WebSpatial.getCurrentWindowContainer()
47
+ }
48
+
49
+ var parentWindow: WebSpatialResource | null = null
50
+ if (options?.windowComponent !== null) {
51
+ parentWindow = options?.windowComponent
52
+ ? options?.windowComponent._resource
53
+ : WebSpatial.getCurrentWebPanel()
54
+ }
55
+
56
+ return [parentWindowContainer, parentWindow]
57
+ }
58
+
59
+ /**
60
+ * Session use to establish a connection to the spatial renderer of the system. All resources must be created by the session
61
+ */
62
+ export class SpatialSession {
63
+ /** @hidden */
64
+ _engineUpdateListeners = Array<animCallback>()
65
+ /** @hidden */
66
+ _frameLoopStarted = false
67
+
68
+ /**
69
+ * Add event listener callback to be called each frame
70
+ * @param callback callback to be called each update
71
+ */
72
+ addOnEngineUpdateEventListener(callback: animCallback) {
73
+ this._engineUpdateListeners.push(callback)
74
+
75
+ if (!this._frameLoopStarted) {
76
+ this._frameLoopStarted = true
77
+ WebSpatial.onFrame(async (time: number) => {
78
+ await Promise.all(
79
+ this._engineUpdateListeners.map(cb => {
80
+ return cb(time)
81
+ }),
82
+ )
83
+ })
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Creates a Entity
89
+ * @returns Entity
90
+ */
91
+ async createEntity() {
92
+ let entity = await WebSpatial.createResource(
93
+ 'Entity',
94
+ WebSpatial.getCurrentWindowContainer(),
95
+ WebSpatial.getCurrentWebPanel(),
96
+ )
97
+ return new SpatialEntity(entity)
98
+ }
99
+
100
+ /**
101
+ * Creates a WindowComponent
102
+ * [TODO] should creation of components be moved to entity? and these made private?
103
+ * @returns WindowComponent
104
+ */
105
+ async createWindowComponent(options?: {
106
+ windowContainer?: SpatialWindowContainer
107
+ }) {
108
+ let entity = await WebSpatial.createResource(
109
+ 'SpatialWebView',
110
+ options?.windowContainer
111
+ ? options?.windowContainer._wg
112
+ : WebSpatial.getCurrentWindowContainer(),
113
+ WebSpatial.getCurrentWebPanel(),
114
+ )
115
+ return new SpatialWindowComponent(entity)
116
+ }
117
+
118
+ /**
119
+ * Creates a ViewComponent used to display 3D content within the entity
120
+ * @returns SpatialViewComponent
121
+ */
122
+ async createViewComponent(options?: {
123
+ windowContainer?: SpatialWindowContainer
124
+ }) {
125
+ let entity = await WebSpatial.createResource(
126
+ 'SpatialView',
127
+ options?.windowContainer
128
+ ? options?.windowContainer._wg
129
+ : WebSpatial.getCurrentWindowContainer(),
130
+ WebSpatial.getCurrentWebPanel(),
131
+ )
132
+ return new SpatialViewComponent(entity)
133
+ }
134
+
135
+ /**
136
+ * Creates a ModelComponent used to display geometry + material of a 3D model
137
+ * @returns ModelComponent
138
+ */
139
+ async createModelComponent(options?: { url: string }) {
140
+ var opts = undefined
141
+ if (options) {
142
+ opts = { modelURL: options.url }
143
+ }
144
+ let entity = await WebSpatial.createResource(
145
+ 'ModelComponent',
146
+ WebSpatial.getCurrentWindowContainer(),
147
+ WebSpatial.getCurrentWebPanel(),
148
+ opts,
149
+ )
150
+ return new SpatialModelComponent(entity)
151
+ }
152
+
153
+ /**
154
+ * Creates a Model3DComponent
155
+ * @returns Model3DComponent
156
+ */
157
+ async createModel3DComponent(options?: { url: string }) {
158
+ var opts = undefined
159
+ if (options) {
160
+ opts = { modelURL: options.url }
161
+ }
162
+ let entity = await WebSpatial.createResource(
163
+ 'Model3DComponent',
164
+ WebSpatial.getCurrentWindowContainer(),
165
+ WebSpatial.getCurrentWebPanel(),
166
+ opts,
167
+ )
168
+ return new SpatialModel3DComponent(entity)
169
+ }
170
+
171
+ /**
172
+ * Creates a InputComponent
173
+ * [Experimental] Creates a InputComponent used to handle click and drag events of the entity containing a model
174
+ * @returns InputComponent
175
+ */
176
+ async createInputComponent() {
177
+ let entity = await WebSpatial.createResource(
178
+ 'InputComponent',
179
+ WebSpatial.getCurrentWindowContainer(),
180
+ WebSpatial.getCurrentWebPanel(),
181
+ )
182
+ return new SpatialInputComponent(entity)
183
+ }
184
+
185
+ /**
186
+ * Creates a MeshResource containing geometry data
187
+ * @returns MeshResource
188
+ */
189
+ async createMeshResource(options?: { shape?: string }) {
190
+ let entity = await WebSpatial.createResource(
191
+ 'MeshResource',
192
+ WebSpatial.getCurrentWindowContainer(),
193
+ WebSpatial.getCurrentWebPanel(),
194
+ options,
195
+ )
196
+ return new SpatialMeshResource(entity)
197
+ }
198
+
199
+ /**
200
+ * Creates a PhysicallyBasedMaterial containing PBR material data
201
+ * @returns PhysicallyBasedMaterial
202
+ */
203
+ async createPhysicallyBasedMaterialResource(options?: {}) {
204
+ let entity = await WebSpatial.createResource(
205
+ 'PhysicallyBasedMaterial',
206
+ WebSpatial.getCurrentWindowContainer(),
207
+ WebSpatial.getCurrentWebPanel(),
208
+ options,
209
+ )
210
+ return new SpatialPhysicallyBasedMaterialResource(entity)
211
+ }
212
+ /**
213
+ * Creates a WindowContainer
214
+ * @returns SpatialWindowContainer
215
+ * */
216
+ async createWindowContainer(options?: {
217
+ style: WindowStyle
218
+ windowContainer?: SpatialWindowContainer | null
219
+ windowComponent?: SpatialWindowComponent | null
220
+ }) {
221
+ var style = options?.style ? options?.style : 'Plain'
222
+ var [parentWindowContainer, parentWindow] = _parseParentResources(options)
223
+ return new SpatialWindowContainer(
224
+ await WebSpatial.createWindowContainer(
225
+ style,
226
+ parentWindowContainer,
227
+ parentWindow,
228
+ ),
229
+ )
230
+ }
231
+
232
+ /**
233
+ * Creates a Scene to display content within an anchored area managed by the OS
234
+ * @hidden
235
+ * @param {WindowStyle} [style='Plain'] - The style of the Scene container to be created with. Defaults to 'Plain'.
236
+ * @param {Object} [cfg={}] - Configuration object for the Scene.
237
+ * @returns Boolean
238
+ */
239
+ async _createScene(
240
+ style: WindowStyle = 'Plain',
241
+ cfg: {
242
+ sceneData: sceneDataShape
243
+ },
244
+ ) {
245
+ return await WebSpatial.createScene(style, cfg)
246
+ }
247
+
248
+ /**
249
+ * Retrieves the window for this page
250
+ * @returns the window component corresponding to the js running on this page
251
+ * [TODO] discuss implications of this not being async
252
+ */
253
+ getCurrentWindowComponent() {
254
+ return new SpatialWindowComponent(WebSpatial.getCurrentWebPanel())
255
+ }
256
+
257
+ /**
258
+ * Retrieves the parent window for this page or null if this is the root page
259
+ * @returns the window component or null
260
+ */
261
+ async getParentWindowComponent() {
262
+ let parentResp: any = await WebSpatial.updateResource(
263
+ WebSpatial.getCurrentWebPanel(),
264
+ { getParentID: '' },
265
+ )
266
+ if (parentResp.data.parentID === '') {
267
+ return new Promise<SpatialWindowComponent | null>((res, rej) => {
268
+ res(null)
269
+ })
270
+ } else {
271
+ var res = new WebSpatialResource()
272
+ res.id = parentResp.data.parentID
273
+ return new SpatialWindowComponent(res)
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Logs a message to the native apps console
279
+ * @param msg mesage to log
280
+ */
281
+ async log(...msg: any[]) {
282
+ await WebSpatial.sendCommand(new RemoteCommand('log', { logString: msg }))
283
+ }
284
+
285
+ /**
286
+ * @hidden
287
+ * Debugging only, used to ping the native renderer
288
+ */
289
+ async _ping(msg: string) {
290
+ return await WebSpatial.ping(msg)
291
+ }
292
+
293
+ /**
294
+ * @hidden
295
+ * Debugging to get internal state from native code
296
+ * @returns data as a js object
297
+ */
298
+ async _getStats() {
299
+ return (await WebSpatial.getStats()) as { objects: any; refObjects: any }
300
+ }
301
+
302
+ /**
303
+ * @hidden
304
+ */
305
+ async _inspect(spatialObjectId: string = WebSpatial.getCurrentWebPanel().id) {
306
+ return WebSpatial.inspect(spatialObjectId)
307
+ }
308
+
309
+ /**
310
+ * @hidden
311
+ */
312
+ async _inspectRootWindowContainer() {
313
+ return WebSpatial.inspectRootWindowContainer()
314
+ }
315
+
316
+ /** Opens the immersive space */
317
+ async openImmersiveSpace() {
318
+ return await WebSpatial.openImmersiveSpace()
319
+ }
320
+
321
+ /** Closes the immersive space */
322
+ async dismissImmersiveSpace() {
323
+ return await WebSpatial.dismissImmersiveSpace()
324
+ }
325
+
326
+ private static _immersiveWindowContainer =
327
+ null as null | SpatialWindowContainer
328
+ /**
329
+ * Retreives the window container corresponding to the Immersive space
330
+ * @returns the immersive window container
331
+ */
332
+ async getImmersiveWindowContainer() {
333
+ if (SpatialSession._immersiveWindowContainer) {
334
+ return SpatialSession._immersiveWindowContainer
335
+ } else {
336
+ SpatialSession._immersiveWindowContainer = new SpatialWindowContainer(
337
+ WebSpatial.getImmersiveWindowContainer(),
338
+ )
339
+ return SpatialSession._immersiveWindowContainer
340
+ }
341
+ }
342
+
343
+ // Retreives the window container that is the parent to this spatial web page
344
+ private static _currentWindowContainer = null as null | SpatialWindowContainer
345
+
346
+ /**
347
+ * Gets the current window container for the window
348
+ * [TODO] discuss what happens if it doesnt yet have a window container
349
+ * @returns the current window container for the window
350
+ */
351
+ getCurrentWindowContainer() {
352
+ if (SpatialSession._currentWindowContainer) {
353
+ return SpatialSession._currentWindowContainer
354
+ } else {
355
+ SpatialSession._currentWindowContainer = new SpatialWindowContainer(
356
+ WebSpatial.getCurrentWindowContainer(),
357
+ )
358
+ return SpatialSession._currentWindowContainer
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Start a transaction that queues up commands to submit them all at once to reduce ipc overhead
364
+ * @param fn function to be run, within this function, promises will not resolve
365
+ * @returns promise for the entire transaction completion
366
+ */
367
+ transaction(fn: Function) {
368
+ WebSpatial.startTransaction()
369
+ fn()
370
+ return WebSpatial.sendTransaction()
371
+ }
372
+
373
+ /**
374
+ * Creates a window context object that is compatable with SpatialWindowComponent's setFromWindow API
375
+ * @returns window context
376
+ */
377
+ async createWindowContext() {
378
+ let openedWindow = window.open('webspatial://createWindowContext')
379
+ if (WebSpatial.getBackend() != 'AVP') {
380
+ // Currently there is a bug with webview which requires us to trigger a navigation before native code can interact with created webview
381
+ var counter = 0
382
+ while ((openedWindow!.window as any).testAPI == null) {
383
+ if (counter > 15) {
384
+ openedWindow?.close()
385
+ openedWindow = window.open('about:blank')
386
+ counter = 0
387
+ this.log('unexpected error when trying to open new window, retrying.')
388
+ }
389
+ var locName = 'about:blank?x' + counter
390
+ openedWindow!!.location.href = locName
391
+ counter++
392
+
393
+ await new Promise(resolve => setTimeout(resolve, 10))
394
+ }
395
+ ;(openedWindow! as any)._webSpatialID = (
396
+ openedWindow!.window as any
397
+ ).testAPI.getWindowID()
398
+ } else {
399
+ while ((openedWindow!.window as any)._webSpatialID == undefined) {
400
+ await new Promise(resolve => setTimeout(resolve, 10))
401
+ }
402
+ }
403
+ openedWindow!.document.head.innerHTML =
404
+ '<meta name="viewport" content="width=device-width, initial-scale=1">'
405
+ return openedWindow
406
+ }
407
+
408
+ // Get Entity by id. Currently for debugging only.
409
+ /** @hidden */
410
+ async _getEntity(id: string) {
411
+ const entityInfo = await WebSpatial.inspect(id)
412
+ const [_, x, y, z] = entityInfo.position.match(/(\d+\.?\d*)/g)
413
+ const [__, sx, sy, sz] = entityInfo.scale.match(/(\d+\.?\d*)/g)
414
+
415
+ var res = new WebSpatialResource()
416
+ res.id = id
417
+ res.windowContainerId = WebSpatial.getCurrentWindowContainer().id
418
+ const entity = new SpatialEntity(res)
419
+ entity.transform.position.x = parseFloat(x)
420
+ entity.transform.position.y = parseFloat(y)
421
+ entity.transform.position.z = parseFloat(z)
422
+
423
+ entity.transform.scale.x = parseFloat(sx)
424
+ entity.transform.scale.y = parseFloat(sy)
425
+ entity.transform.scale.z = parseFloat(sz)
426
+
427
+ return entity
428
+ }
429
+ // set loading view.
430
+ /** @hidden */
431
+ async setLoading(method: LoadingMethodKind, style?: string) {
432
+ return WebSpatial.setLoading(method, style)
433
+ }
434
+ }
@@ -0,0 +1,26 @@
1
+ export class Vec3 {
2
+ constructor(
3
+ public x = 0,
4
+ public y = 0,
5
+ public z = 0,
6
+ ) {}
7
+ }
8
+
9
+ export class Vec4 {
10
+ constructor(
11
+ public x = 0,
12
+ public y = 0,
13
+ public z = 0,
14
+ public w = 1,
15
+ ) {}
16
+ }
17
+
18
+ /**
19
+ * Transform containing position, orientation and scale
20
+ */
21
+ export class SpatialTransform {
22
+ position = new Vec3(0, 0, 0)
23
+ /** Quaternion value for x,y,z,w */
24
+ orientation = new Vec4(0, 0, 0, 1)
25
+ scale = new Vec3(1, 1, 1)
26
+ }
@@ -0,0 +1,51 @@
1
+ import {
2
+ WebSpatial,
3
+ WebSpatialResource,
4
+ WindowContainer,
5
+ } from './private/WebSpatial'
6
+ import { SpatialEntity } from './SpatialEntity'
7
+
8
+ /**
9
+ * Anchored window managed by the OS
10
+ */
11
+ export class SpatialWindowContainer {
12
+ /** @hidden */
13
+ constructor(
14
+ /** @hidden */
15
+ public _wg: WindowContainer,
16
+ ) {}
17
+ /**
18
+ * @hidden
19
+ * Sets sets the open configuration for opening new window containers
20
+ * @param options style options
21
+ */
22
+ async _setOpenSettings(options: { resolution: { width: number; height: number } }) {
23
+ await WebSpatial.updateWindowContainer(this._wg, {
24
+ nextOpenSettings: options,
25
+ })
26
+ }
27
+
28
+ /**
29
+ * Retrieves the root entity of the windowContainer
30
+ * @returns the root entity of the windowContainer if one exists
31
+ */
32
+ async getRootEntity() {
33
+ let reqResp: any = await WebSpatial.updateWindowContainer(this._wg, {
34
+ getRootEntityID: '',
35
+ })
36
+ if (reqResp.data.rootEntId === '') {
37
+ return null
38
+ } else {
39
+ var res = new WebSpatialResource()
40
+ res.id = reqResp.data.rootEntId
41
+ return new SpatialEntity(res)
42
+ }
43
+ }
44
+ /*
45
+ * Sets the root entity that this windowContainer will display (this does not effect resource ownership)
46
+ * @param entity to display
47
+ */
48
+ async setRootEntity(entity: SpatialEntity) {
49
+ await entity._setParentWindowContainer(this)
50
+ }
51
+ }
@@ -0,0 +1,32 @@
1
+ import { WebSpatial, WebSpatialResource } from '../private/WebSpatial'
2
+ import { SpatialComponent } from './SpatialComponent'
3
+
4
+ /**
5
+ * @description
6
+ * Represents a spatial component that handles events related to spatial interactions.
7
+ * This class extends `SpatialComponent` and provides additional functionality for managing
8
+ * event-driven spatial behaviors.
9
+ *
10
+ * @hidden
11
+ * This class is intended for internal use and should not be exposed in the public API.
12
+ */
13
+ export abstract class EventSpatialComponent extends SpatialComponent {
14
+ // Class implementation goes here
15
+ constructor(_resource: WebSpatialResource) {
16
+ super(_resource)
17
+ WebSpatial.registerEventReceiver(_resource.id, (data: any) => {
18
+ this.onRecvEvent(data)
19
+ })
20
+ }
21
+
22
+ /**
23
+ * @description
24
+ * Abstract method to be implemented by subclasses. Called when a spatial event is received.
25
+ * @param data The data associated with the received event.
26
+ */
27
+ protected abstract onRecvEvent(data: any): void
28
+
29
+ protected override async onDestroy() {
30
+ WebSpatial.unregisterEventReceiver(this._resource.id)
31
+ }
32
+ }
@@ -0,0 +1,26 @@
1
+ import { WebSpatial, WebSpatialResource } from '../private/WebSpatial'
2
+ import { SpatialEntity } from '../SpatialEntity'
3
+ import { SpatialObject } from '../SpatialObject'
4
+
5
+ /** @hidden */
6
+ export class SpatialComponent extends SpatialObject {
7
+ /**
8
+ * Gets the entity this component is attached to
9
+ * @returns entity or null
10
+ */
11
+ async getEntity() {
12
+ let reqResp: any = await WebSpatial.updateResource(
13
+ WebSpatial.getCurrentWebPanel(),
14
+ { getEntityID: '' },
15
+ )
16
+ if (reqResp.data.parentID === '') {
17
+ return new Promise<SpatialEntity | null>((res, rej) => {
18
+ res(null)
19
+ })
20
+ } else {
21
+ var res = new WebSpatialResource()
22
+ res.id = reqResp.data.parentID
23
+ return new SpatialEntity(res)
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,24 @@
1
+ import { Vec3 } from '../SpatialTransform'
2
+ import { EventSpatialComponent } from './EventSpatialComponent'
3
+
4
+ /**
5
+ * Translate event, matching similar behavior to https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drag_event
6
+ */
7
+ type TranslateEvent = {
8
+ eventType: 'dragstart' | 'dragend' | 'drag'
9
+ translate?: Vec3
10
+ }
11
+ /**
12
+ * Used to handle input events on an entity
13
+ */
14
+ export class SpatialInputComponent extends EventSpatialComponent {
15
+ protected override onRecvEvent(data: any): void {
16
+ this.onTranslate(data)
17
+ }
18
+
19
+ /**
20
+ * Callback fired when a translate event occurs
21
+ * @param data translate event data
22
+ */
23
+ public onTranslate(data: TranslateEvent) {}
24
+ }