@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.
- package/CHANGELOG.md +8 -0
- package/README.md +112 -81
- package/dist/iife/index.d.ts +683 -561
- package/dist/iife/index.global.js +3 -4
- package/dist/iife/index.global.js.map +1 -1
- package/dist/index.d.ts +683 -561
- package/dist/index.js +2193 -1291
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
- package/src/JSBCommand.ts +631 -0
- package/src/Spatial.ts +68 -0
- package/src/SpatialObject.ts +46 -0
- package/src/SpatialScene.ts +75 -0
- package/src/SpatialSession.ts +187 -0
- package/src/SpatialWebEvent.ts +23 -0
- package/src/SpatialWebEventCreator.ts +12 -0
- package/src/Spatialized2DElement.ts +51 -0
- package/src/SpatializedDynamic3DElement.ts +30 -0
- package/src/SpatializedElement.ts +331 -0
- package/src/SpatializedElementCreator.ts +45 -0
- package/src/SpatializedStatic3DElement.ts +111 -0
- package/src/WebMsgCommand.ts +88 -0
- package/src/index.ts +23 -1
- package/src/platform-adapter/CommandResultUtils.ts +22 -0
- package/src/platform-adapter/android/AndroidPlatform.ts +133 -0
- package/src/platform-adapter/index.ts +21 -0
- package/src/platform-adapter/interface.ts +36 -0
- package/src/platform-adapter/ssr/SSRPlatform.ts +43 -0
- package/src/platform-adapter/vision-os/VisionOSPlatform.ts +77 -0
- package/src/reality/component/ModelComponent.ts +11 -0
- package/src/reality/component/SpatialComponent.ts +17 -0
- package/src/reality/component/index.ts +2 -0
- package/src/reality/entity/SpatialEntity.ts +259 -0
- package/src/reality/entity/SpatialModelEntity.ts +15 -0
- package/src/reality/entity/index.ts +2 -0
- package/src/reality/geometry/SpatialBoxGeometry.ts +12 -0
- package/src/reality/geometry/SpatialConeGeometry.ts +15 -0
- package/src/reality/geometry/SpatialCylinderGeometry.ts +15 -0
- package/src/reality/geometry/SpatialGeometry.ts +12 -0
- package/src/reality/geometry/SpatialPlaneGeometry.ts +15 -0
- package/src/reality/geometry/SpatialSphereGeometry.ts +15 -0
- package/src/reality/geometry/index.ts +6 -0
- package/src/reality/index.ts +5 -0
- package/src/reality/material/SpatialMaterial.ts +14 -0
- package/src/reality/material/SpatialUnlitMaterial.ts +16 -0
- package/src/reality/material/index.ts +2 -0
- package/src/reality/realityCreator.ts +94 -0
- package/src/reality/resource/SpatialModelAsset.ts +11 -0
- package/src/reality/resource/index.ts +1 -0
- package/src/scene-polyfill.test.ts +376 -0
- package/src/scene-polyfill.ts +379 -0
- package/src/spatial-window-polyfill.ts +182 -0
- package/src/ssr-polyfill.ts +3 -0
- package/src/types/global.d.ts +33 -1
- package/src/types/internal.ts +13 -0
- package/src/types/types.ts +380 -0
- package/src/utils.ts +61 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +8 -0
- package/src/core/Spatial.ts +0 -50
- package/src/core/SpatialEntity.ts +0 -147
- package/src/core/SpatialHelper.ts +0 -230
- package/src/core/SpatialObject.ts +0 -26
- package/src/core/SpatialSession.ts +0 -457
- package/src/core/SpatialTransform.ts +0 -26
- package/src/core/SpatialWindowContainer.ts +0 -59
- package/src/core/component/EventSpatialComponent.ts +0 -32
- package/src/core/component/SpatialComponent.ts +0 -26
- package/src/core/component/SpatialInputComponent.ts +0 -24
- package/src/core/component/SpatialModel3DComponent.ts +0 -223
- package/src/core/component/SpatialModelComponent.ts +0 -39
- package/src/core/component/SpatialViewComponent.ts +0 -32
- package/src/core/component/SpatialWindowComponent.ts +0 -177
- package/src/core/component/index.ts +0 -14
- package/src/core/index.ts +0 -10
- package/src/core/private/WebSpatial.ts +0 -383
- package/src/core/private/remote-command/RemoteCommand.ts +0 -15
- package/src/core/private/remote-command/index.ts +0 -1
- package/src/core/resource/SpatialMeshResource.ts +0 -6
- package/src/core/resource/SpatialPhysicallyBasedMaterialResource.ts +0 -42
- package/src/core/resource/index.ts +0 -2
- 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
|
-
}
|