@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,146 @@
1
+ import { SpatialObject } from './SpatialObject'
2
+ import { SpatialTransform } from './SpatialTransform'
3
+ import { SpatialWindowContainer } from './SpatialWindowContainer'
4
+ import { WebSpatial } from './private/WebSpatial'
5
+ import { SpatialComponent } from './component'
6
+
7
+ /**
8
+ * Entity used to describe an object that can be added to the scene
9
+ */
10
+ export class SpatialEntity extends SpatialObject {
11
+ /**
12
+ * Transform corresponding to the entity
13
+ * note: updateTransform must be called for transform to be synced to rendering
14
+ */
15
+ transform = new SpatialTransform()
16
+
17
+ /** @hidden */
18
+ private _destroyed = false
19
+ /** @hidden */
20
+ private get _entity() {
21
+ return this._resource
22
+ }
23
+
24
+ /**
25
+ * Syncs the transform with the renderer, must be called to observe updates
26
+ */
27
+ async updateTransform() {
28
+ await WebSpatial.updateResource(this._entity, this.transform)
29
+ }
30
+
31
+ /**
32
+ * Syncs the zIndex with the renderer
33
+ */
34
+ async updateZIndex(zIndex: number) {
35
+ await WebSpatial.updateResource(this._entity, { zIndex })
36
+ }
37
+
38
+ private components: Map<Function, SpatialComponent> = new Map()
39
+
40
+ /**
41
+ * Attaches a component to the entity to be displayed
42
+ * [TODO] review pass by value vs ref and ownership model for this
43
+ */
44
+ async setComponent(component: SpatialComponent) {
45
+ await WebSpatial.setComponent(this._entity, component._resource)
46
+ this.components.set(component.constructor, component)
47
+ }
48
+
49
+ /**
50
+ * Removes a component from the entity
51
+ */
52
+ async removeComponent<T extends SpatialComponent>(
53
+ type: new (...args: any[]) => T,
54
+ ) {
55
+ var c = this.getComponent(type)
56
+ if (c != undefined) {
57
+ await WebSpatial.removeComponent(this._entity, c._resource)
58
+ this.components.delete(c.constructor)
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Gets a component from the entity
64
+ */
65
+ getComponent<T extends SpatialComponent>(
66
+ type: new (...args: any[]) => T,
67
+ ): T | undefined {
68
+ return this.components.get(type) as T | undefined
69
+ }
70
+
71
+ /**
72
+ * @hidden
73
+ * Sets the window container that this entity should be rendered by (this does not effect resource ownership)
74
+ * @param wg the window container that should render this entity
75
+ */
76
+ async _setParentWindowContainer(wg: SpatialWindowContainer) {
77
+ await WebSpatial.updateResource(this._entity, {
78
+ setParentWindowContainerID: wg._wg.id,
79
+ })
80
+ }
81
+
82
+ /**
83
+ * Sets a parent entity, if that entity or its parents are attached to a window container, this entity will be displayed
84
+ * @param e parent entity or null to remove current parent
85
+ */
86
+ async setParent(e: SpatialEntity | null) {
87
+ await WebSpatial.updateResource(this._entity, {
88
+ setParent: e ? e._entity.id : '',
89
+ })
90
+ }
91
+
92
+ /**
93
+ * Sets the coordinate space of this entity (Default: App)
94
+ * "App" = game engine style coordinates in meters
95
+ * "Dom" = Windowing coordinates in dom units (eg. 0,0,0 is top left of window)
96
+ * "Root" = Coordinate space is ignored and content is displayed and updated as window container's root object, window containers can only have one root entity
97
+ * [TODO] review this api
98
+ * @param space coordinate space mode
99
+ */
100
+ async setCoordinateSpace(space: 'App' | 'Dom' | 'Root') {
101
+ await WebSpatial.updateResource(this._entity, { setCoordinateSpace: space })
102
+ }
103
+
104
+ /**
105
+ * Query the 3d boudning box of the entity
106
+ * @returns The bounding box of the entity
107
+ */
108
+ async getBoundingBox() {
109
+ var res: any = await WebSpatial.updateResource(this._entity, {
110
+ getBoundingBox: true,
111
+ })
112
+ return res.data as {
113
+ center: { x: number; y: number; z: number }
114
+ extents: { x: number; y: number; z: number }
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Sets if the entity should be visible (default: True)
120
+ * @param visible
121
+ */
122
+ async setVisible(visible: boolean) {
123
+ await WebSpatial.updateResource(this._entity, { visible })
124
+ }
125
+
126
+ /**
127
+ * Removes a reference to the entity by the renderer and this object should no longer be used. [TODO] Attached components will not be destroyed
128
+ */
129
+ async destroy() {
130
+ this._destroyed = true
131
+ await WebSpatial.destroyResource(this._entity)
132
+ }
133
+
134
+ /**
135
+ * Check if destroy has been called
136
+ */
137
+ isDestroyed() {
138
+ return this._destroyed
139
+ }
140
+
141
+ // Set Entity name. Currently for debugging only.
142
+ /** @hidden */
143
+ async _setName(name: string) {
144
+ return WebSpatial.updateResource(this._entity, { name })
145
+ }
146
+ }
@@ -0,0 +1,197 @@
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({ style: 'Plain' })
92
+
93
+ // Create a root entity displaying a webpage
94
+ var ent = await this.session!.createEntity()
95
+ var i = await this.session!.createWindowComponent({ windowContainer: wg })
96
+ await i.loadURL(url)
97
+ await ent.setCoordinateSpace('Root')
98
+ await ent.setComponent(i)
99
+
100
+ // Add enitity the window container
101
+ await wg.setRootEntity(ent)
102
+
103
+ // Restore default size
104
+ await this.session
105
+ .getCurrentWindowContainer()
106
+ ._setOpenSettings({ resolution: { width: 900, height: 700 } })
107
+ },
108
+ openVolume: async (
109
+ url: string,
110
+ options?: { resolution: { width: number; height: number } },
111
+ ) => {
112
+ var wg = await this.session.createWindowContainer({ style: 'Volumetric' })
113
+
114
+ // Create a root view entity within the window container
115
+ var rootEnt = await this.session!.createEntity()
116
+ await rootEnt.setComponent(
117
+ await this.session!.createViewComponent({ windowContainer: wg }),
118
+ )
119
+ await rootEnt.setCoordinateSpace('Root')
120
+ await wg.setRootEntity(rootEnt)
121
+
122
+ // Add webpage to the window container
123
+ var ent = await this.session!.createEntity()
124
+ var i = await this.session!.createWindowComponent({ windowContainer: wg })
125
+ await i.loadURL(url)
126
+ if (options?.resolution) {
127
+ await i.setResolution(options.resolution.width, options.resolution.height)
128
+ } else {
129
+ await i.setResolution(1000, 1000)
130
+ }
131
+ ent.transform.position.z = -0.49
132
+ await ent.updateTransform()
133
+ await ent.setCoordinateSpace('App')
134
+ await ent.setComponent(i)
135
+ await ent.setParent(rootEnt)
136
+ },
137
+ }
138
+
139
+ dom = {
140
+ attachSpatialView: async (divOnPage: HTMLElement) => {
141
+ // Create SpatialView
142
+ var viewEnt = await this.session.createEntity()
143
+ await viewEnt.setCoordinateSpace('Dom') // Set coordinate space so its transform is relative to the webpage's pixels
144
+ await viewEnt.setComponent(await this.session.createViewComponent())
145
+
146
+ // Add to the root window component to display
147
+ var wc = await this.session.getCurrentWindowComponent()
148
+ var ent = await wc.getEntity()
149
+ await viewEnt.setParent(ent!)
150
+
151
+ // Keep spatialView positioned where the div is
152
+ var update = () => {
153
+ var rect = divOnPage.getBoundingClientRect()
154
+ viewEnt.transform.position.x = rect.x + rect.width / 2
155
+ viewEnt.transform.position.y = rect.y + rect.height / 2 + window.scrollY
156
+ viewEnt.updateTransform()
157
+ viewEnt
158
+ .getComponent(SpatialViewComponent)!
159
+ .setResolution(rect.width, rect.height)
160
+ }
161
+ var mo = new MutationObserver(update)
162
+ mo.observe(divOnPage, { attributes: true })
163
+ var ro = new ResizeObserver(update)
164
+ ro.observe(divOnPage)
165
+ const addRemoveObserver = new MutationObserver(mutations => {
166
+ mutations.forEach(mutation => {
167
+ mutation.removedNodes.forEach(node => {
168
+ if (node instanceof HTMLElement) {
169
+ update()
170
+ }
171
+ })
172
+ mutation.addedNodes.forEach(node => {
173
+ if (node instanceof HTMLElement) {
174
+ update()
175
+ }
176
+ })
177
+ })
178
+ })
179
+ addRemoveObserver.observe(document.body, {
180
+ childList: true,
181
+ subtree: true,
182
+ })
183
+ update()
184
+ return {
185
+ entity: viewEnt,
186
+ }
187
+ },
188
+ }
189
+
190
+ setBackgroundStyle = async (
191
+ style: StyleParam,
192
+ backgroundColor = '#00000000',
193
+ ) => {
194
+ document.documentElement.style.backgroundColor = backgroundColor
195
+ await this.session!.getCurrentWindowComponent().setStyle(style)
196
+ }
197
+ }
@@ -0,0 +1,24 @@
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
+ protected async onDestroy() {}
24
+ }