@webspatial/core-sdk 1.0.4 → 1.1.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 (82) hide show
  1. package/CHANGELOG.md +8 -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 +2193 -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 +259 -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 +379 -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
@@ -0,0 +1,133 @@
1
+ import { PlatformAbility, CommandResult } from '../interface'
2
+ import {
3
+ CommandResultFailure,
4
+ CommandResultSuccess,
5
+ } from '../CommandResultUtils'
6
+ import { CheckWebViewCanCreateCommand } from '../../JSBCommand'
7
+ import { SpatialWebEvent } from '../../SpatialWebEvent'
8
+
9
+ interface JSBResponse {
10
+ success: boolean
11
+ data: any
12
+ }
13
+ type JSBError = {
14
+ code: string
15
+ message: string
16
+ }
17
+
18
+ let creatingElementCount = 0
19
+
20
+ let requestId = 0
21
+
22
+ const MAX_ID = 100000
23
+
24
+ function nextRequestId() {
25
+ requestId = (requestId + 1) % MAX_ID
26
+ return `rId_${requestId}`
27
+ }
28
+
29
+ export class AndroidPlatform implements PlatformAbility {
30
+ async callJSB(cmd: string, msg: string): Promise<CommandResult> {
31
+ // android JS Bridge interface only support sync invoking
32
+ // in order to implement promise API, register every request by requestId and remove when resolve/reject.
33
+ return new Promise((resolve, reject) => {
34
+ try {
35
+ const rId = nextRequestId()
36
+
37
+ SpatialWebEvent.addEventReceiver(rId, (result: JSBResponse) => {
38
+ SpatialWebEvent.removeEventReceiver(rId)
39
+ if (result.success) {
40
+ resolve(CommandResultSuccess(result.data))
41
+ } else {
42
+ const { code, message } = result.data as JSBError
43
+ resolve(CommandResultFailure(code, message))
44
+ }
45
+ })
46
+
47
+ const ans = window.webspatialBridge.postMessage(rId, cmd, msg)
48
+ if (ans !== '') {
49
+ SpatialWebEvent.removeEventReceiver(rId)
50
+ // sync call
51
+ const result = JSON.parse(ans) as JSBResponse
52
+ if (result.success) {
53
+ resolve(CommandResultSuccess(result.data))
54
+ } else {
55
+ const { code, message } = result.data as JSBError
56
+ resolve(CommandResultFailure(code, message))
57
+ }
58
+ }
59
+ } catch (error: unknown) {
60
+ console.error(
61
+ `AndroidPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`,
62
+ )
63
+ const { code, message } = error as JSBError
64
+ resolve(CommandResultFailure(code, message))
65
+ }
66
+ })
67
+ }
68
+
69
+ async callWebSpatialProtocol(
70
+ command: string,
71
+ query?: string,
72
+ target?: string,
73
+ features?: string,
74
+ ): Promise<CommandResult> {
75
+ // Waiting for request to create spatial div
76
+ await new Promise(resolve => setTimeout(resolve, 16 * creatingElementCount))
77
+ // Count the current total number of created spatial div queues
78
+ creatingElementCount++
79
+ // Create a spatial div through JSB polling request
80
+ let canCreate = await new CheckWebViewCanCreateCommand().execute()
81
+ while (!canCreate.data.can) {
82
+ await new Promise(resolve => setTimeout(resolve, 16))
83
+ canCreate = await new CheckWebViewCanCreateCommand().execute()
84
+ }
85
+ // Request successful, call window.open
86
+ const { windowProxy } = this.openWindow(command, query, target, features)
87
+ // Polling waiting for windowProxy to convert into a real window object
88
+ while (!windowProxy?.open) {
89
+ await new Promise(resolve => setTimeout(resolve, 16))
90
+ }
91
+ // Make the page renderable through window.open
92
+ windowProxy?.open('about:blank', '_self')
93
+ // Polling to check if SpatialId injection is successful
94
+ while (!windowProxy?.__SpatialId) {
95
+ await new Promise(resolve => setTimeout(resolve, 16))
96
+ }
97
+ let spatialId = windowProxy?.__SpatialId
98
+ creatingElementCount--
99
+ return Promise.resolve(
100
+ CommandResultSuccess({ windowProxy: windowProxy, id: spatialId }),
101
+ )
102
+ }
103
+
104
+ callWebSpatialProtocolSync(
105
+ command: string,
106
+ query?: string,
107
+ target?: string,
108
+ features?: string,
109
+ ): CommandResult {
110
+ const { spatialId: id = '', windowProxy } = this.openWindow(
111
+ command,
112
+ query,
113
+ target,
114
+ features,
115
+ )
116
+
117
+ return CommandResultSuccess({ windowProxy, id })
118
+ }
119
+
120
+ private openWindow(
121
+ command: string,
122
+ query?: string,
123
+ target?: string,
124
+ features?: string,
125
+ ) {
126
+ const windowProxy = window.open(
127
+ `webspatial://${command}?${query || ''}`,
128
+ target,
129
+ features,
130
+ )
131
+ return { spatialId: '', windowProxy }
132
+ }
133
+ }
@@ -0,0 +1,21 @@
1
+ import { isSSREnv } from '../ssr-polyfill'
2
+ import { PlatformAbility } from './interface'
3
+ import { SSRPlatform } from './ssr/SSRPlatform'
4
+
5
+ export function createPlatform(): PlatformAbility {
6
+ if (isSSREnv()) {
7
+ return new SSRPlatform()
8
+ }
9
+
10
+ if (
11
+ window.navigator.userAgent.includes('Android') ||
12
+ window.navigator.userAgent.includes('Linux')
13
+ ) {
14
+ const AndroidPlatform = require('./android/AndroidPlatform').AndroidPlatform
15
+ return new AndroidPlatform()
16
+ } else {
17
+ const VisionOSPlatform =
18
+ require('./vision-os/VisionOSPlatform').VisionOSPlatform
19
+ return new VisionOSPlatform()
20
+ }
21
+ }
@@ -0,0 +1,36 @@
1
+ export interface CommandResult {
2
+ success: boolean
3
+ data: any
4
+ errorCode: string | undefined
5
+ errorMessage: string | undefined
6
+ }
7
+
8
+ export interface WebSpatialProtocolResult extends CommandResult {
9
+ success: boolean
10
+ data:
11
+ | {
12
+ windowProxy: WindowProxy
13
+ id: string
14
+ }
15
+ | undefined
16
+ errorCode: string | undefined
17
+ errorMessage: string | undefined
18
+ }
19
+
20
+ export interface PlatformAbility {
21
+ callJSB(cmd: string, msg: string): Promise<CommandResult>
22
+ callWebSpatialProtocol(
23
+ schema: string,
24
+ query?: string,
25
+ target?: string,
26
+ features?: string,
27
+ ): Promise<WebSpatialProtocolResult>
28
+
29
+ callWebSpatialProtocolSync(
30
+ schema: string,
31
+ query?: string,
32
+ target?: string,
33
+ features?: string,
34
+ resultCallback?: (result: CommandResult) => void,
35
+ ): WebSpatialProtocolResult
36
+ }
@@ -0,0 +1,43 @@
1
+ import {
2
+ CommandResult,
3
+ PlatformAbility,
4
+ WebSpatialProtocolResult,
5
+ } from '../interface'
6
+
7
+ export class SSRPlatform implements PlatformAbility {
8
+ callJSB(cmd: string, msg: string): Promise<CommandResult> {
9
+ return Promise.resolve({
10
+ success: true,
11
+ data: undefined,
12
+ errorCode: undefined,
13
+ errorMessage: undefined,
14
+ })
15
+ }
16
+ callWebSpatialProtocol(
17
+ schema: string,
18
+ query?: string,
19
+ target?: string,
20
+ features?: string,
21
+ ): Promise<WebSpatialProtocolResult> {
22
+ return Promise.resolve({
23
+ success: true,
24
+ data: undefined,
25
+ errorCode: undefined,
26
+ errorMessage: undefined,
27
+ })
28
+ }
29
+ callWebSpatialProtocolSync(
30
+ schema: string,
31
+ query?: string,
32
+ target?: string,
33
+ features?: string,
34
+ resultCallback?: (result: CommandResult) => void,
35
+ ): WebSpatialProtocolResult {
36
+ return {
37
+ success: true,
38
+ data: undefined,
39
+ errorCode: undefined,
40
+ errorMessage: undefined,
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,77 @@
1
+ import { PlatformAbility, CommandResult } from '../interface'
2
+ import {
3
+ CommandResultFailure,
4
+ CommandResultSuccess,
5
+ } from '../CommandResultUtils'
6
+
7
+
8
+ type JSBError = {
9
+ message: string
10
+ }
11
+
12
+ export class VisionOSPlatform implements PlatformAbility {
13
+ async callJSB(cmd: string, msg: string): Promise<CommandResult> {
14
+ try {
15
+ const result = await window.webkit.messageHandlers.bridge.postMessage(
16
+ `${cmd}::${msg}`,
17
+ )
18
+ return CommandResultSuccess(result)
19
+ } catch (error: unknown) {
20
+ // console.error(`VisionOSPlatform cmd: ${cmd}, msg: ${msg} error: ${error}`)
21
+ const { code, message } = JSON.parse((error as JSBError).message)
22
+ return CommandResultFailure(code, message)
23
+ }
24
+ }
25
+
26
+ callWebSpatialProtocol(
27
+ command: string,
28
+ query?: string,
29
+ target?: string,
30
+ features?: string,
31
+ ): Promise<CommandResult> {
32
+ const { spatialId: id, windowProxy } = this.openWindow(
33
+ command,
34
+ query,
35
+ target,
36
+ features,
37
+ )
38
+ return Promise.resolve(
39
+ CommandResultSuccess({ windowProxy: windowProxy, id }),
40
+ )
41
+ }
42
+
43
+ callWebSpatialProtocolSync(
44
+ command: string,
45
+ query?: string,
46
+ target?: string,
47
+ features?: string,
48
+ ): CommandResult {
49
+ const { spatialId: id = '', windowProxy } = this.openWindow(
50
+ command,
51
+ query,
52
+ target,
53
+ features,
54
+ )
55
+
56
+ return CommandResultSuccess({ windowProxy, id })
57
+ }
58
+
59
+ private openWindow(
60
+ command: string,
61
+ query?: string,
62
+ target?: string,
63
+ features?: string,
64
+ ) {
65
+ const windowProxy = window.open(
66
+ `webspatial://${command}?${query || ''}`,
67
+ target,
68
+ features,
69
+ )
70
+ const ua = windowProxy?.navigator.userAgent
71
+ const spatialId = ua?.match(
72
+ /\b([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})\b/gi,
73
+ )?.[0]
74
+
75
+ return { spatialId, windowProxy }
76
+ }
77
+ }
@@ -0,0 +1,11 @@
1
+ import { ModelComponentOptions } from '../../types/types'
2
+ import { SpatialComponent } from './SpatialComponent'
3
+
4
+ export class ModelComponent extends SpatialComponent {
5
+ constructor(
6
+ id: string,
7
+ public options: ModelComponentOptions,
8
+ ) {
9
+ super(id)
10
+ }
11
+ }
@@ -0,0 +1,17 @@
1
+ import { SpatialObject } from '../../SpatialObject'
2
+ import { SpatialWebEvent } from '../../SpatialWebEvent'
3
+ import { ObjectDestroyMsg, SpatialWebMsgType } from '../../WebMsgCommand'
4
+
5
+ export class SpatialComponent extends SpatialObject {
6
+ constructor(id: string) {
7
+ super(id)
8
+ SpatialWebEvent.addEventReceiver(id, this.onReceiveEvent)
9
+ }
10
+
11
+ private onReceiveEvent = (data: ObjectDestroyMsg) => {
12
+ const { type } = data
13
+ if (type === SpatialWebMsgType.objectdestroy) {
14
+ this.isDestroyed = true
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,2 @@
1
+ export * from './SpatialComponent'
2
+ export * from './ModelComponent'
@@ -0,0 +1,259 @@
1
+ import {
2
+ ConvertFromEntityToEntityCommand,
3
+ ConvertFromEntityToSceneCommand,
4
+ ConvertFromSceneToEntityCommand,
5
+ SetParentForEntityCommand,
6
+ } from './../../JSBCommand'
7
+ import {
8
+ SpatialEntityEventType,
9
+ SpatialEntityOrReality,
10
+ SpatialEntityUserData,
11
+ Vec3,
12
+ } from '../../types/types'
13
+ import {
14
+ AddComponentToEntityCommand,
15
+ AddEntityToEntityCommand,
16
+ RemoveEntityFromParentCommand,
17
+ UpdateEntityEventCommand,
18
+ UpdateEntityPropertiesCommand,
19
+ } from '../../JSBCommand'
20
+ import { SpatialObject } from '../../SpatialObject'
21
+ import { SpatialEntityProperties } from '../../types/types'
22
+ import { SpatialComponent } from '../component/SpatialComponent'
23
+ import { SpatialWebEvent } from '../../SpatialWebEvent'
24
+ import { createSpatialEvent } from '../../SpatialWebEventCreator'
25
+ import {
26
+ CubeInfoMsg,
27
+ ObjectDestroyMsg,
28
+ SpatialDragEndMsg,
29
+ SpatialDragMsg,
30
+ SpatialMagnifyMsg,
31
+ SpatialRotateEndMsg,
32
+ SpatialRotateMsg,
33
+ SpatialTapMsg,
34
+ SpatialWebMsgType,
35
+ TransformMsg,
36
+ } from '../../WebMsgCommand'
37
+
38
+ export class SpatialEntity extends SpatialObject {
39
+ position: Vec3 = { x: 0, y: 0, z: 0 }
40
+ rotation: Vec3 = { x: 0, y: 0, z: 0 }
41
+ scale: Vec3 = { x: 1, y: 1, z: 1 }
42
+
43
+ events: Record<string, (data: any) => void> = {}
44
+ children: SpatialEntity[] = []
45
+ parent: SpatialEntityOrReality | null = null
46
+ constructor(
47
+ id: string,
48
+ public userData?: SpatialEntityUserData,
49
+ ) {
50
+ super(id)
51
+ SpatialWebEvent.addEventReceiver(id, this.onReceiveEvent)
52
+ }
53
+
54
+ async addComponent(component: SpatialComponent) {
55
+ return new AddComponentToEntityCommand(this, component).execute()
56
+ }
57
+ async setPosition(position: Vec3) {
58
+ return this.updateTransform({ position })
59
+ }
60
+ async setRotation(rotation: Vec3) {
61
+ return this.updateTransform({ rotation })
62
+ }
63
+ async setScale(scale: Vec3) {
64
+ return this.updateTransform({ scale })
65
+ }
66
+
67
+ async addEntity(ent: SpatialEntity) {
68
+ const ans = await new SetParentForEntityCommand(ent.id, this.id).execute()
69
+ this.children.push(ent)
70
+ ent.parent = this
71
+ return ans
72
+ }
73
+ async removeFromParent() {
74
+ const ans = await new SetParentForEntityCommand(
75
+ this.id,
76
+ undefined,
77
+ ).execute()
78
+ if (this.parent) {
79
+ this.parent.children = this.parent.children.filter(
80
+ child => child.id !== this.id,
81
+ )
82
+ this.parent = null
83
+ }
84
+ return ans
85
+ }
86
+
87
+ async updateTransform(properties: Partial<SpatialEntityProperties>) {
88
+ this.position = properties.position ?? this.position
89
+ this.rotation = properties.rotation ?? this.rotation
90
+ this.scale = properties.scale ?? this.scale
91
+ return new UpdateEntityPropertiesCommand(this, properties).execute()
92
+ }
93
+
94
+ async addEvent(type: SpatialEntityEventType, callback: (data: any) => void) {
95
+ if (this.events[type]) {
96
+ // replace if exist
97
+ this.events[type] = callback
98
+ } else {
99
+ try {
100
+ await this.updateEntityEvent(type, true)
101
+ this.events[type] = callback
102
+ } catch (error) {
103
+ console.error('addEvent failed', type)
104
+ }
105
+ }
106
+ }
107
+
108
+ async removeEvent(eventName: SpatialEntityEventType) {
109
+ if (this.events[eventName]) {
110
+ delete this.events[eventName]
111
+ try {
112
+ await this.updateEntityEvent(eventName, false)
113
+ } catch (error) {
114
+ console.error('removeEvent failed', eventName)
115
+ }
116
+ }
117
+ }
118
+
119
+ async updateEntityEvent(
120
+ eventName: SpatialEntityEventType,
121
+ isEnable: boolean,
122
+ ) {
123
+ return new UpdateEntityEventCommand(this, eventName, isEnable).execute()
124
+ }
125
+ private onReceiveEvent = (
126
+ data: // | CubeInfoMsg
127
+ // | TransformMsg
128
+ | SpatialTapMsg
129
+ // | SpatialDragMsg
130
+ // | SpatialDragEndMsg
131
+ // | SpatialRotateMsg
132
+ // | SpatialRotateEndMsg
133
+ | ObjectDestroyMsg,
134
+ ) => {
135
+ // console.log('SpatialEntityEvent', data)
136
+ const { type } = data
137
+ if (type === SpatialWebMsgType.objectdestroy) {
138
+ this.isDestroyed = true
139
+ }
140
+ // tap
141
+ else if (type === SpatialWebMsgType.spatialtap) {
142
+ const evt = createSpatialEvent(
143
+ SpatialWebMsgType.spatialtap,
144
+ (data as SpatialTapMsg).detail,
145
+ )
146
+ this.dispatchEvent(evt)
147
+ } else if (type === SpatialWebMsgType.spatialdragstart) {
148
+ const evt = createSpatialEvent(
149
+ SpatialWebMsgType.spatialdragstart,
150
+ (data as SpatialDragMsg).detail,
151
+ )
152
+ this.dispatchEvent(evt)
153
+ } else if (type === SpatialWebMsgType.spatialdrag) {
154
+ const evt = createSpatialEvent(
155
+ SpatialWebMsgType.spatialdrag,
156
+ (data as SpatialDragMsg).detail,
157
+ )
158
+ this.dispatchEvent(evt)
159
+ } else if (type === SpatialWebMsgType.spatialdragend) {
160
+ const evt = createSpatialEvent(
161
+ SpatialWebMsgType.spatialdragend,
162
+ (data as SpatialDragEndMsg).detail,
163
+ )
164
+ this.dispatchEvent(evt)
165
+ }
166
+ // rotate
167
+ else if (type === SpatialWebMsgType.spatialrotatestart) {
168
+ const evt = createSpatialEvent(
169
+ SpatialWebMsgType.spatialrotatestart,
170
+ (data as SpatialRotateMsg).detail,
171
+ )
172
+ this.dispatchEvent(evt)
173
+ } else if (type === SpatialWebMsgType.spatialrotate) {
174
+ const evt = createSpatialEvent(
175
+ SpatialWebMsgType.spatialrotate,
176
+ (data as SpatialRotateMsg).detail,
177
+ )
178
+ this.dispatchEvent(evt)
179
+ } else if (type === SpatialWebMsgType.spatialrotateend) {
180
+ const evt = createSpatialEvent(
181
+ SpatialWebMsgType.spatialrotateend,
182
+ (data as SpatialRotateEndMsg).detail,
183
+ )
184
+ this.dispatchEvent(evt)
185
+ }
186
+ // magnify
187
+ else if (type === SpatialWebMsgType.spatialmagnifystart) {
188
+ const evt = createSpatialEvent(
189
+ SpatialWebMsgType.spatialmagnifystart,
190
+ (data as SpatialMagnifyMsg).detail,
191
+ )
192
+ this.dispatchEvent(evt)
193
+ } else if (type === SpatialWebMsgType.spatialmagnify) {
194
+ const evt = createSpatialEvent(
195
+ SpatialWebMsgType.spatialmagnify,
196
+ (data as SpatialMagnifyMsg).detail,
197
+ )
198
+ this.dispatchEvent(evt)
199
+ } else if (type === SpatialWebMsgType.spatialmagnifyend) {
200
+ const evt = createSpatialEvent(
201
+ SpatialWebMsgType.spatialmagnifyend,
202
+ (data as SpatialMagnifyMsg).detail,
203
+ )
204
+ this.dispatchEvent(evt)
205
+ }
206
+ }
207
+
208
+ dispatchEvent(evt: CustomEvent) {
209
+ // Set origin once at the first dispatch in the bubbling chain
210
+ if (!(evt as any).__origin) {
211
+ Object.defineProperty(evt, '__origin', { value: this, enumerable: false })
212
+ }
213
+ this.events[evt.type]?.(evt)
214
+ if (evt.bubbles && !evt.cancelBubble) {
215
+ if (this.parent && this.parent instanceof SpatialEntity) {
216
+ this.parent.dispatchEvent(evt)
217
+ }
218
+ }
219
+ }
220
+
221
+ protected onDestroy(): void {
222
+ SpatialWebEvent.removeEventReceiver(this.id)
223
+ // handle children
224
+ this.children.forEach(child => {
225
+ child.parent = null
226
+ })
227
+ this.children = []
228
+ // handle parent
229
+ if (this.parent) {
230
+ this.parent.children = this.parent.children.filter(
231
+ child => child.id !== this.id,
232
+ )
233
+ this.parent = null
234
+ }
235
+ }
236
+ // onUpdate(properties: SpatialEntityProperties) {
237
+ // this.position = properties.position
238
+ // this.rotation = properties.rotation
239
+ // this.scale = properties.scale
240
+ // }
241
+ async convertFromEntityToEntity(
242
+ fromEntityId: string,
243
+ toEntityId: string,
244
+ position: Vec3,
245
+ ) {
246
+ return new ConvertFromEntityToEntityCommand(
247
+ fromEntityId,
248
+ toEntityId,
249
+ position,
250
+ ).execute()
251
+ }
252
+
253
+ async convertFromEntityToScene(fromEntityId: string, position: Vec3) {
254
+ return new ConvertFromEntityToSceneCommand(fromEntityId, position).execute()
255
+ }
256
+ async convertFromSceneToEntity(entityId: string, position: Vec3) {
257
+ return new ConvertFromSceneToEntityCommand(entityId, position).execute()
258
+ }
259
+ }
@@ -0,0 +1,15 @@
1
+ import {
2
+ SpatialEntityUserData,
3
+ SpatialModelEntityCreationOptions,
4
+ } from '../../types/types'
5
+ import { SpatialEntity } from './SpatialEntity'
6
+
7
+ export class SpatialModelEntity extends SpatialEntity {
8
+ constructor(
9
+ public id: string,
10
+ public options?: SpatialModelEntityCreationOptions,
11
+ public userData?: SpatialEntityUserData,
12
+ ) {
13
+ super(id, userData)
14
+ }
15
+ }
@@ -0,0 +1,2 @@
1
+ export * from './SpatialEntity'
2
+ export * from './SpatialModelEntity'
@@ -0,0 +1,12 @@
1
+ import { SpatialBoxGeometryOptions, SpatialGeometryType } from '../../types/types'
2
+ import { SpatialGeometry } from './SpatialGeometry'
3
+
4
+ export class SpatialBoxGeometry extends SpatialGeometry {
5
+ static type: SpatialGeometryType = 'BoxGeometry'
6
+ constructor(
7
+ public id: string,
8
+ public options: SpatialBoxGeometryOptions,
9
+ ) {
10
+ super(id, options)
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ import {
2
+ SpatialGeometryType,
3
+ SpatialConeGeometryOptions,
4
+ } from '../../types/types'
5
+ import { SpatialGeometry } from './SpatialGeometry'
6
+
7
+ export class SpatialConeGeometry extends SpatialGeometry {
8
+ static type: SpatialGeometryType = 'ConeGeometry'
9
+ constructor(
10
+ public id: string,
11
+ public options: SpatialConeGeometryOptions,
12
+ ) {
13
+ super(id, options)
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ import {
2
+ SpatialGeometryType,
3
+ SpatialCylinderGeometryOptions,
4
+ } from '../../types/types'
5
+ import { SpatialGeometry } from './SpatialGeometry'
6
+
7
+ export class SpatialCylinderGeometry extends SpatialGeometry {
8
+ static type: SpatialGeometryType = 'CylinderGeometry'
9
+ constructor(
10
+ public id: string,
11
+ public options: SpatialCylinderGeometryOptions,
12
+ ) {
13
+ super(id, options)
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ import { SpatialObject } from '../../SpatialObject'
2
+ import { SpatialGeometryOptions, SpatialGeometryType } from '../../types/types'
3
+
4
+ export class SpatialGeometry extends SpatialObject {
5
+ static type: SpatialGeometryType
6
+ constructor(
7
+ public id: string,
8
+ public options: SpatialGeometryOptions,
9
+ ) {
10
+ super(id)
11
+ }
12
+ }