@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.
- package/README.md +112 -0
- package/dist/core/Spatial.d.ts +27 -0
- package/dist/core/Spatial.d.ts.map +1 -0
- package/dist/core/Spatial.js +41 -0
- package/dist/core/SpatialEntity.d.ts +92 -0
- package/dist/core/SpatialEntity.d.ts.map +1 -0
- package/dist/core/SpatialEntity.js +121 -0
- package/dist/core/SpatialHelper.d.ts +39 -0
- package/dist/core/SpatialHelper.d.ts.map +1 -0
- package/dist/core/SpatialHelper.js +169 -0
- package/dist/core/SpatialObject.d.ts +19 -0
- package/dist/core/SpatialObject.d.ts.map +1 -0
- package/dist/core/SpatialObject.js +22 -0
- package/dist/core/SpatialSession.d.ts +166 -0
- package/dist/core/SpatialSession.d.ts.map +1 -0
- package/dist/core/SpatialSession.js +310 -0
- package/dist/core/SpatialTransform.d.ts +23 -0
- package/dist/core/SpatialTransform.d.ts.map +1 -0
- package/dist/core/SpatialTransform.js +31 -0
- package/dist/core/SpatialWindowContainer.d.ts +31 -0
- package/dist/core/SpatialWindowContainer.d.ts.map +1 -0
- package/dist/core/SpatialWindowContainer.js +48 -0
- package/dist/core/component/EventSpatialComponent.d.ts +22 -0
- package/dist/core/component/EventSpatialComponent.d.ts.map +1 -0
- package/dist/core/component/EventSpatialComponent.js +23 -0
- package/dist/core/component/SpatialComponent.d.ts +11 -0
- package/dist/core/component/SpatialComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialComponent.js +23 -0
- package/dist/core/component/SpatialInputComponent.d.ts +22 -0
- package/dist/core/component/SpatialInputComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialInputComponent.js +14 -0
- package/dist/core/component/SpatialModel3DComponent.d.ts +86 -0
- package/dist/core/component/SpatialModel3DComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialModel3DComponent.js +176 -0
- package/dist/core/component/SpatialModelComponent.d.ts +22 -0
- package/dist/core/component/SpatialModelComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialModelComponent.js +34 -0
- package/dist/core/component/SpatialViewComponent.d.ts +22 -0
- package/dist/core/component/SpatialViewComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialViewComponent.js +30 -0
- package/dist/core/component/SpatialWindowComponent.d.ts +86 -0
- package/dist/core/component/SpatialWindowComponent.d.ts.map +1 -0
- package/dist/core/component/SpatialWindowComponent.js +114 -0
- package/dist/core/component/index.d.ts +7 -0
- package/dist/core/component/index.d.ts.map +1 -0
- package/dist/core/component/index.js +6 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/private/WebSpatial.d.ts +46 -0
- package/dist/core/private/WebSpatial.d.ts.map +1 -0
- package/dist/core/private/WebSpatial.js +282 -0
- package/dist/core/private/remote-command/RemoteCommand.d.ts +8 -0
- package/dist/core/private/remote-command/RemoteCommand.d.ts.map +1 -0
- package/dist/core/private/remote-command/RemoteCommand.js +11 -0
- package/dist/core/private/remote-command/index.d.ts +2 -0
- package/dist/core/private/remote-command/index.d.ts.map +1 -0
- package/dist/core/private/remote-command/index.js +1 -0
- package/dist/core/resource/SpatialMeshResource.d.ts +7 -0
- package/dist/core/resource/SpatialMeshResource.d.ts.map +1 -0
- package/dist/core/resource/SpatialMeshResource.js +6 -0
- package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.d.ts +37 -0
- package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.d.ts.map +1 -0
- package/dist/core/resource/SpatialPhysicallyBasedMaterialResource.js +37 -0
- package/dist/core/resource/index.d.ts +3 -0
- package/dist/core/resource/index.d.ts.map +1 -0
- package/dist/core/resource/index.js +2 -0
- package/dist/core/types.d.ts +23 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/package.json +35 -0
- package/src/core/Spatial.ts +48 -0
- package/src/core/SpatialEntity.ts +146 -0
- package/src/core/SpatialHelper.ts +197 -0
- package/src/core/SpatialObject.ts +24 -0
- package/src/core/SpatialSession.ts +434 -0
- package/src/core/SpatialTransform.ts +26 -0
- package/src/core/SpatialWindowContainer.ts +51 -0
- package/src/core/component/EventSpatialComponent.ts +32 -0
- package/src/core/component/SpatialComponent.ts +26 -0
- package/src/core/component/SpatialInputComponent.ts +24 -0
- package/src/core/component/SpatialModel3DComponent.ts +213 -0
- package/src/core/component/SpatialModelComponent.ts +39 -0
- package/src/core/component/SpatialViewComponent.ts +32 -0
- package/src/core/component/SpatialWindowComponent.ts +168 -0
- package/src/core/component/index.ts +14 -0
- package/src/core/index.ts +10 -0
- package/src/core/private/WebSpatial.ts +356 -0
- package/src/core/private/remote-command/RemoteCommand.ts +15 -0
- package/src/core/private/remote-command/index.ts +1 -0
- package/src/core/resource/SpatialMeshResource.ts +6 -0
- package/src/core/resource/SpatialPhysicallyBasedMaterialResource.ts +42 -0
- package/src/core/resource/index.ts +2 -0
- package/src/core/types.ts +27 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# **Full API documentation**
|
|
2
|
+
|
|
3
|
+
* [API Docs](https://github.com/webspatial/webspatial.github.io/blob/main/docs/globals.md)
|
|
4
|
+
|
|
5
|
+
# **Introduction**
|
|
6
|
+
|
|
7
|
+
The core-sdk library is responsible for interacting with the target platforms native APIs to expose behavior not commonly found on the web.
|
|
8
|
+
|
|
9
|
+
# **Hello world example**
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
import { Spatial, SpatialHelper } from '@webspatial/core-sdk'
|
|
13
|
+
|
|
14
|
+
var main = async () => {
|
|
15
|
+
var spatial = new Spatial()
|
|
16
|
+
var versionInfo = "clientVersion:" + spatial.getClientVersion() + "\nnativeVersion:" + spatial.getNativeVersion() + "\nisSupported:" + spatial.isSupported()
|
|
17
|
+
|
|
18
|
+
let sh = SpatialHelper.instance!
|
|
19
|
+
if (sh) {
|
|
20
|
+
// Create a new window container
|
|
21
|
+
var container = await sh.session.createWindowContainer({ style: 'Volumetric' })
|
|
22
|
+
|
|
23
|
+
// Setup volume for the entity
|
|
24
|
+
var rootEntity = await sh.session.createEntity()
|
|
25
|
+
await rootEntity.setCoordinateSpace("Root")
|
|
26
|
+
rootEntity.setComponent(await sh.session.createViewComponent())
|
|
27
|
+
|
|
28
|
+
// Create a mesh. and add it tot the root volume
|
|
29
|
+
var box = await sh.shape.createShapeEntity("box")
|
|
30
|
+
await box.setParent(rootEntity)
|
|
31
|
+
|
|
32
|
+
// add the volume to the window
|
|
33
|
+
await container.setRootEntity(rootEntity)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
main()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
# **Initialization**
|
|
40
|
+
|
|
41
|
+
Create a new spatial object which is the root entry point to the API. This object should be available in standard browsers as well as webspatial environments. This object can check client and native versions of the library and detect if webspatial is available in this setup.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
var spatial = new Spatial()
|
|
45
|
+
if(spatial.isSupported()){
|
|
46
|
+
var session = spatial.requestSession()
|
|
47
|
+
if(session){
|
|
48
|
+
console.log("session supported and created")
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
# **Async/Await/Promises**
|
|
54
|
+
|
|
55
|
+
Due to the architecture of webspatial, the client library communicates to native code over a JS Bridge provided by the platform. Because of this, function calls may not be completed immediately. To accomidate this, the majority of webspatial api use [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to keep track of completion. It is recommended you create an async main function to allow you to use the await syntax for app setup.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
var main = async ()=>{
|
|
59
|
+
// Your code goes here
|
|
60
|
+
};
|
|
61
|
+
main()'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
# **WindowContainer**
|
|
65
|
+
|
|
66
|
+
To create a new WindowContainer (aka WindowGroup on apple vision pro)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
var windowContainer = await session.createWindowContainer({ style: 'Volumetric' })
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Depending on if you want to display content as a panel or within a volume, you can choose to use "Plain" or "Volumetric" style.
|
|
73
|
+
|
|
74
|
+
# **Entity/Component api**
|
|
75
|
+
|
|
76
|
+
To start displaying content within a WindowContainer, you must create an entity.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
// Create entity
|
|
80
|
+
var entity = await session.createEntity()
|
|
81
|
+
|
|
82
|
+
// Create component
|
|
83
|
+
await entity.setComponent(
|
|
84
|
+
await session.createViewComponent({ windowContainer: windowContainer }),
|
|
85
|
+
)
|
|
86
|
+
await entity.setCoordinateSpace('Root')
|
|
87
|
+
|
|
88
|
+
// Set root entity on the window container.
|
|
89
|
+
// Note the entity much have:
|
|
90
|
+
// - Root coordinate space
|
|
91
|
+
// - have a ViewComponent for Volumetric windowContainer
|
|
92
|
+
// - have a WindowComponent for Plain windowContainer
|
|
93
|
+
await windowContainer.setRootEntity(entity)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Entity maps to an object that will be displayed. Components tell how that object should be displayed.
|
|
97
|
+
You can find more examples here when you run the server locally:
|
|
98
|
+
|
|
99
|
+
* http://localhost:5173/src/docsWebsite/index.html?examplePath=webElement
|
|
100
|
+
|
|
101
|
+
# **Helper**
|
|
102
|
+
|
|
103
|
+
This library, similar to (webGL or webXR) may be a bit too verbose to use directly. You can use the helper we provide to do some common tasks such as opening a new webpage panel or use our higher level react API.
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
import { SpatialHelper } from '@webspatial/core-sdk'
|
|
107
|
+
SpatialHelper.instance.navigation.openPanel(
|
|
108
|
+
'https://www.npmjs.com/package/@webspatial/core-sdk',
|
|
109
|
+
{ resolution: { width: 600, height: 100 } },
|
|
110
|
+
)
|
|
111
|
+
```
|
|
112
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SpatialSession } from './SpatialSession';
|
|
2
|
+
/**
|
|
3
|
+
* Base object designed to be placed on navigator.spatial to mirror navigator.xr for webxr
|
|
4
|
+
*/
|
|
5
|
+
export declare class Spatial {
|
|
6
|
+
/**
|
|
7
|
+
* Requests a session object from the browser
|
|
8
|
+
* @returns The session or null if not availible in the current browser
|
|
9
|
+
* [TODO] discuss implications of this not being async
|
|
10
|
+
*/
|
|
11
|
+
requestSession(): SpatialSession | null;
|
|
12
|
+
/**
|
|
13
|
+
* @returns true if web spatial is supported by this webpage
|
|
14
|
+
*/
|
|
15
|
+
isSupported(): any;
|
|
16
|
+
/**
|
|
17
|
+
* Gets the native version, format is "x.x.x"
|
|
18
|
+
* @returns native version string
|
|
19
|
+
*/
|
|
20
|
+
getNativeVersion(): any;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the client version, format is "x.x.x"
|
|
23
|
+
* @returns client version string
|
|
24
|
+
*/
|
|
25
|
+
getClientVersion(): string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=Spatial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spatial.d.ts","sourceRoot":"","sources":["../../src/core/Spatial.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD;;GAEG;AACH,qBAAa,OAAO;IAClB;;;;OAIG;IACH,cAAc;IAWd;;OAEG;IACH,WAAW;IAOX;;;OAGG;IACH,gBAAgB;IAIhB;;;OAGG;IACH,gBAAgB;CAGjB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SpatialSession } from './SpatialSession';
|
|
2
|
+
/**
|
|
3
|
+
* Base object designed to be placed on navigator.spatial to mirror navigator.xr for webxr
|
|
4
|
+
*/
|
|
5
|
+
export class Spatial {
|
|
6
|
+
/**
|
|
7
|
+
* Requests a session object from the browser
|
|
8
|
+
* @returns The session or null if not availible in the current browser
|
|
9
|
+
* [TODO] discuss implications of this not being async
|
|
10
|
+
*/
|
|
11
|
+
requestSession() {
|
|
12
|
+
if (this.isSupported() &&
|
|
13
|
+
this.getNativeVersion() === this.getClientVersion()) {
|
|
14
|
+
return new SpatialSession();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @returns true if web spatial is supported by this webpage
|
|
22
|
+
*/
|
|
23
|
+
isSupported() {
|
|
24
|
+
return (window.WebSpatailEnabled &&
|
|
25
|
+
this.getNativeVersion() === this.getClientVersion());
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the native version, format is "x.x.x"
|
|
29
|
+
* @returns native version string
|
|
30
|
+
*/
|
|
31
|
+
getNativeVersion() {
|
|
32
|
+
return window.WebSpatailNativeVersion;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets the client version, format is "x.x.x"
|
|
36
|
+
* @returns client version string
|
|
37
|
+
*/
|
|
38
|
+
getClientVersion() {
|
|
39
|
+
return '0.0.1';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { SpatialObject } from './SpatialObject';
|
|
2
|
+
import { SpatialTransform } from './SpatialTransform';
|
|
3
|
+
import { SpatialWindowContainer } from './SpatialWindowContainer';
|
|
4
|
+
import { SpatialComponent } from './component';
|
|
5
|
+
/**
|
|
6
|
+
* Entity used to describe an object that can be added to the scene
|
|
7
|
+
*/
|
|
8
|
+
export declare class SpatialEntity extends SpatialObject {
|
|
9
|
+
/**
|
|
10
|
+
* Transform corresponding to the entity
|
|
11
|
+
* note: updateTransform must be called for transform to be synced to rendering
|
|
12
|
+
*/
|
|
13
|
+
transform: SpatialTransform;
|
|
14
|
+
/** @hidden */
|
|
15
|
+
private _destroyed;
|
|
16
|
+
/** @hidden */
|
|
17
|
+
private get _entity();
|
|
18
|
+
/**
|
|
19
|
+
* Syncs the transform with the renderer, must be called to observe updates
|
|
20
|
+
*/
|
|
21
|
+
updateTransform(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Syncs the zIndex with the renderer
|
|
24
|
+
*/
|
|
25
|
+
updateZIndex(zIndex: number): Promise<void>;
|
|
26
|
+
private components;
|
|
27
|
+
/**
|
|
28
|
+
* Attaches a component to the entity to be displayed
|
|
29
|
+
* [TODO] review pass by value vs ref and ownership model for this
|
|
30
|
+
*/
|
|
31
|
+
setComponent(component: SpatialComponent): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Removes a component from the entity
|
|
34
|
+
*/
|
|
35
|
+
removeComponent<T extends SpatialComponent>(type: new (...args: any[]) => T): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Gets a component from the entity
|
|
38
|
+
*/
|
|
39
|
+
getComponent<T extends SpatialComponent>(type: new (...args: any[]) => T): T | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* @hidden
|
|
42
|
+
* Sets the window container that this entity should be rendered by (this does not effect resource ownership)
|
|
43
|
+
* @param wg the window container that should render this entity
|
|
44
|
+
*/
|
|
45
|
+
_setParentWindowContainer(wg: SpatialWindowContainer): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Sets a parent entity, if that entity or its parents are attached to a window container, this entity will be displayed
|
|
48
|
+
* @param e parent entity or null to remove current parent
|
|
49
|
+
*/
|
|
50
|
+
setParent(e: SpatialEntity | null): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Sets the coordinate space of this entity (Default: App)
|
|
53
|
+
* "App" = game engine style coordinates in meters
|
|
54
|
+
* "Dom" = Windowing coordinates in dom units (eg. 0,0,0 is top left of window)
|
|
55
|
+
* "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
|
|
56
|
+
* [TODO] review this api
|
|
57
|
+
* @param space coordinate space mode
|
|
58
|
+
*/
|
|
59
|
+
setCoordinateSpace(space: 'App' | 'Dom' | 'Root'): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Query the 3d boudning box of the entity
|
|
62
|
+
* @returns The bounding box of the entity
|
|
63
|
+
*/
|
|
64
|
+
getBoundingBox(): Promise<{
|
|
65
|
+
center: {
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
z: number;
|
|
69
|
+
};
|
|
70
|
+
extents: {
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
z: number;
|
|
74
|
+
};
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Sets if the entity should be visible (default: True)
|
|
78
|
+
* @param visible
|
|
79
|
+
*/
|
|
80
|
+
setVisible(visible: boolean): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Removes a reference to the entity by the renderer and this object should no longer be used. [TODO] Attached components will not be destroyed
|
|
83
|
+
*/
|
|
84
|
+
destroy(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Check if destroy has been called
|
|
87
|
+
*/
|
|
88
|
+
isDestroyed(): boolean;
|
|
89
|
+
/** @hidden */
|
|
90
|
+
_setName(name: string): Promise<unknown>;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=SpatialEntity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpatialEntity.d.ts","sourceRoot":"","sources":["../../src/core/SpatialEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C;;GAEG;AACH,qBAAa,aAAc,SAAQ,aAAa;IAC9C;;;OAGG;IACH,SAAS,mBAAyB;IAElC,cAAc;IACd,OAAO,CAAC,UAAU,CAAQ;IAC1B,cAAc;IACd,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACG,eAAe;IAIrB;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM;IAIjC,OAAO,CAAC,UAAU,CAA6C;IAE/D;;;OAGG;IACG,YAAY,CAAC,SAAS,EAAE,gBAAgB;IAK9C;;OAEG;IACG,eAAe,CAAC,CAAC,SAAS,gBAAgB,EAC9C,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC;IASjC;;OAEG;IACH,YAAY,CAAC,CAAC,SAAS,gBAAgB,EACrC,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAC9B,CAAC,GAAG,SAAS;IAIhB;;;;OAIG;IACG,yBAAyB,CAAC,EAAE,EAAE,sBAAsB;IAM1D;;;OAGG;IACG,SAAS,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI;IAMvC;;;;;;;OAOG;IACG,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM;IAItD;;;OAGG;IACG,cAAc;gBAKR;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE;iBAClC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE;;IAIhD;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,OAAO;IAIjC;;OAEG;IACG,OAAO;IAKb;;OAEG;IACH,WAAW;IAKX,cAAc;IACR,QAAQ,CAAC,IAAI,EAAE,MAAM;CAG5B"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { SpatialObject } from './SpatialObject';
|
|
2
|
+
import { SpatialTransform } from './SpatialTransform';
|
|
3
|
+
import { WebSpatial } from './private/WebSpatial';
|
|
4
|
+
/**
|
|
5
|
+
* Entity used to describe an object that can be added to the scene
|
|
6
|
+
*/
|
|
7
|
+
export class SpatialEntity extends SpatialObject {
|
|
8
|
+
/**
|
|
9
|
+
* Transform corresponding to the entity
|
|
10
|
+
* note: updateTransform must be called for transform to be synced to rendering
|
|
11
|
+
*/
|
|
12
|
+
transform = new SpatialTransform();
|
|
13
|
+
/** @hidden */
|
|
14
|
+
_destroyed = false;
|
|
15
|
+
/** @hidden */
|
|
16
|
+
get _entity() {
|
|
17
|
+
return this._resource;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Syncs the transform with the renderer, must be called to observe updates
|
|
21
|
+
*/
|
|
22
|
+
async updateTransform() {
|
|
23
|
+
await WebSpatial.updateResource(this._entity, this.transform);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Syncs the zIndex with the renderer
|
|
27
|
+
*/
|
|
28
|
+
async updateZIndex(zIndex) {
|
|
29
|
+
await WebSpatial.updateResource(this._entity, { zIndex });
|
|
30
|
+
}
|
|
31
|
+
components = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* Attaches a component to the entity to be displayed
|
|
34
|
+
* [TODO] review pass by value vs ref and ownership model for this
|
|
35
|
+
*/
|
|
36
|
+
async setComponent(component) {
|
|
37
|
+
await WebSpatial.setComponent(this._entity, component._resource);
|
|
38
|
+
this.components.set(component.constructor, component);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Removes a component from the entity
|
|
42
|
+
*/
|
|
43
|
+
async removeComponent(type) {
|
|
44
|
+
var c = this.getComponent(type);
|
|
45
|
+
if (c != undefined) {
|
|
46
|
+
await WebSpatial.removeComponent(this._entity, c._resource);
|
|
47
|
+
this.components.delete(c.constructor);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Gets a component from the entity
|
|
52
|
+
*/
|
|
53
|
+
getComponent(type) {
|
|
54
|
+
return this.components.get(type);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @hidden
|
|
58
|
+
* Sets the window container that this entity should be rendered by (this does not effect resource ownership)
|
|
59
|
+
* @param wg the window container that should render this entity
|
|
60
|
+
*/
|
|
61
|
+
async _setParentWindowContainer(wg) {
|
|
62
|
+
await WebSpatial.updateResource(this._entity, {
|
|
63
|
+
setParentWindowContainerID: wg._wg.id,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sets a parent entity, if that entity or its parents are attached to a window container, this entity will be displayed
|
|
68
|
+
* @param e parent entity or null to remove current parent
|
|
69
|
+
*/
|
|
70
|
+
async setParent(e) {
|
|
71
|
+
await WebSpatial.updateResource(this._entity, {
|
|
72
|
+
setParent: e ? e._entity.id : '',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sets the coordinate space of this entity (Default: App)
|
|
77
|
+
* "App" = game engine style coordinates in meters
|
|
78
|
+
* "Dom" = Windowing coordinates in dom units (eg. 0,0,0 is top left of window)
|
|
79
|
+
* "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
|
|
80
|
+
* [TODO] review this api
|
|
81
|
+
* @param space coordinate space mode
|
|
82
|
+
*/
|
|
83
|
+
async setCoordinateSpace(space) {
|
|
84
|
+
await WebSpatial.updateResource(this._entity, { setCoordinateSpace: space });
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Query the 3d boudning box of the entity
|
|
88
|
+
* @returns The bounding box of the entity
|
|
89
|
+
*/
|
|
90
|
+
async getBoundingBox() {
|
|
91
|
+
var res = await WebSpatial.updateResource(this._entity, {
|
|
92
|
+
getBoundingBox: true,
|
|
93
|
+
});
|
|
94
|
+
return res.data;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Sets if the entity should be visible (default: True)
|
|
98
|
+
* @param visible
|
|
99
|
+
*/
|
|
100
|
+
async setVisible(visible) {
|
|
101
|
+
await WebSpatial.updateResource(this._entity, { visible });
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Removes a reference to the entity by the renderer and this object should no longer be used. [TODO] Attached components will not be destroyed
|
|
105
|
+
*/
|
|
106
|
+
async destroy() {
|
|
107
|
+
this._destroyed = true;
|
|
108
|
+
await WebSpatial.destroyResource(this._entity);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if destroy has been called
|
|
112
|
+
*/
|
|
113
|
+
isDestroyed() {
|
|
114
|
+
return this._destroyed;
|
|
115
|
+
}
|
|
116
|
+
// Set Entity name. Currently for debugging only.
|
|
117
|
+
/** @hidden */
|
|
118
|
+
async _setName(name) {
|
|
119
|
+
return WebSpatial.updateResource(this._entity, { name });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { StyleParam } from './component';
|
|
2
|
+
import { SpatialEntity } from './SpatialEntity';
|
|
3
|
+
import { SpatialSession } from './SpatialSession';
|
|
4
|
+
/**
|
|
5
|
+
* Helper class used to quickly add spatial content to standard web pages
|
|
6
|
+
* [Experimental] expect APIs to potentially change in future versions
|
|
7
|
+
*/
|
|
8
|
+
export declare class SpatialHelper {
|
|
9
|
+
session: SpatialSession;
|
|
10
|
+
private static _instance;
|
|
11
|
+
static get instance(): SpatialHelper | null;
|
|
12
|
+
constructor(session: SpatialSession);
|
|
13
|
+
shape: {
|
|
14
|
+
createShapeEntity: (shape?: string) => Promise<SpatialEntity>;
|
|
15
|
+
createModelEntity: (url: string) => Promise<SpatialEntity>;
|
|
16
|
+
wrapInBoundingBoxEntity: (entityToWrap: SpatialEntity) => Promise<SpatialEntity>;
|
|
17
|
+
};
|
|
18
|
+
navigation: {
|
|
19
|
+
openPanel: (url: string, options?: {
|
|
20
|
+
resolution: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
};
|
|
24
|
+
}) => Promise<void>;
|
|
25
|
+
openVolume: (url: string, options?: {
|
|
26
|
+
resolution: {
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
};
|
|
30
|
+
}) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
dom: {
|
|
33
|
+
attachSpatialView: (divOnPage: HTMLElement) => Promise<{
|
|
34
|
+
entity: SpatialEntity;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
37
|
+
setBackgroundStyle: (style: StyleParam, backgroundColor?: string) => Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=SpatialHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpatialHelper.d.ts","sourceRoot":"","sources":["../../src/core/SpatialHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGjD;;;GAGG;AACH,qBAAa,aAAa;IAkBL,OAAO,EAAE,cAAc;IAjB1C,OAAO,CAAC,MAAM,CAAC,SAAS,CAA6B;IACrD,MAAM,KAAK,QAAQ,yBAclB;gBAEkB,OAAO,EAAE,cAAc;IAE1C,KAAK;;iCAiB4B,MAAM;gDAOS,aAAa;MAsB5D;IAED,UAAU;yBAED,MAAM,YACD;YAAE,UAAU,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;0BA2BtD,MAAM,YACD;YAAE,UAAU,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;MA2B9D;IAED,GAAG;uCACoC,WAAW;;;MAgDjD;IAED,kBAAkB,UACT,UAAU,6CAKlB;CACF"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { SpatialViewComponent } from './component';
|
|
2
|
+
import { Spatial } from './Spatial';
|
|
3
|
+
import { Vec3 } from './SpatialTransform';
|
|
4
|
+
/**
|
|
5
|
+
* Helper class used to quickly add spatial content to standard web pages
|
|
6
|
+
* [Experimental] expect APIs to potentially change in future versions
|
|
7
|
+
*/
|
|
8
|
+
export class SpatialHelper {
|
|
9
|
+
session;
|
|
10
|
+
static _instance = null;
|
|
11
|
+
static get instance() {
|
|
12
|
+
if (this._instance) {
|
|
13
|
+
return this._instance;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
let spatial = new Spatial();
|
|
17
|
+
if (spatial.isSupported()) {
|
|
18
|
+
let session = spatial.requestSession();
|
|
19
|
+
if (session) {
|
|
20
|
+
this._instance = new SpatialHelper(session);
|
|
21
|
+
return this._instance;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
constructor(session) {
|
|
28
|
+
this.session = session;
|
|
29
|
+
}
|
|
30
|
+
shape = {
|
|
31
|
+
createShapeEntity: async (shape = 'box') => {
|
|
32
|
+
var box = await this.session.createMeshResource({ shape: shape });
|
|
33
|
+
var mat = await this.session.createPhysicallyBasedMaterialResource();
|
|
34
|
+
await mat.update();
|
|
35
|
+
var customModel = await this.session.createModelComponent();
|
|
36
|
+
customModel.setMaterials([mat]);
|
|
37
|
+
customModel.setMesh(box);
|
|
38
|
+
var boxEntity = await this.session.createEntity();
|
|
39
|
+
await boxEntity.setComponent(customModel);
|
|
40
|
+
boxEntity.transform.position.z = 0;
|
|
41
|
+
boxEntity.transform.scale = new Vec3(0.5, 0.5, 0.5);
|
|
42
|
+
await boxEntity.updateTransform();
|
|
43
|
+
return boxEntity;
|
|
44
|
+
},
|
|
45
|
+
createModelEntity: async (url) => {
|
|
46
|
+
var customModel = await this.session.createModelComponent({ url });
|
|
47
|
+
var boxEntity = await this.session.createEntity();
|
|
48
|
+
await boxEntity.setComponent(customModel);
|
|
49
|
+
await boxEntity.updateTransform();
|
|
50
|
+
return boxEntity;
|
|
51
|
+
},
|
|
52
|
+
wrapInBoundingBoxEntity: async (entityToWrap) => {
|
|
53
|
+
var bb = await entityToWrap.getBoundingBox();
|
|
54
|
+
// Scale to fit
|
|
55
|
+
var targetSize = 1.0;
|
|
56
|
+
var scale = targetSize / Math.max(bb.extents.x, bb.extents.y, bb.extents.z);
|
|
57
|
+
entityToWrap.transform.scale.x = scale;
|
|
58
|
+
entityToWrap.transform.scale.y = scale;
|
|
59
|
+
entityToWrap.transform.scale.z = scale;
|
|
60
|
+
// Center within view
|
|
61
|
+
entityToWrap.transform.position.x = -bb.center.x * scale;
|
|
62
|
+
entityToWrap.transform.position.y = -bb.center.y * scale;
|
|
63
|
+
entityToWrap.transform.position.z = -bb.center.z * scale;
|
|
64
|
+
await entityToWrap.updateTransform();
|
|
65
|
+
// wrap in boudning box
|
|
66
|
+
var boudningEntity = await SpatialHelper.instance?.session.createEntity();
|
|
67
|
+
await entityToWrap.setParent(boudningEntity);
|
|
68
|
+
return boudningEntity;
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
navigation = {
|
|
72
|
+
openPanel: async (url, options) => {
|
|
73
|
+
if (options?.resolution) {
|
|
74
|
+
await this.session
|
|
75
|
+
.getCurrentWindowContainer()
|
|
76
|
+
._setOpenSettings({ resolution: options.resolution });
|
|
77
|
+
}
|
|
78
|
+
// Create window container
|
|
79
|
+
var wg = await this.session.createWindowContainer({ style: 'Plain' });
|
|
80
|
+
// Create a root entity displaying a webpage
|
|
81
|
+
var ent = await this.session.createEntity();
|
|
82
|
+
var i = await this.session.createWindowComponent({ windowContainer: wg });
|
|
83
|
+
await i.loadURL(url);
|
|
84
|
+
await ent.setCoordinateSpace('Root');
|
|
85
|
+
await ent.setComponent(i);
|
|
86
|
+
// Add enitity the window container
|
|
87
|
+
await wg.setRootEntity(ent);
|
|
88
|
+
// Restore default size
|
|
89
|
+
await this.session
|
|
90
|
+
.getCurrentWindowContainer()
|
|
91
|
+
._setOpenSettings({ resolution: { width: 900, height: 700 } });
|
|
92
|
+
},
|
|
93
|
+
openVolume: async (url, options) => {
|
|
94
|
+
var wg = await this.session.createWindowContainer({ style: 'Volumetric' });
|
|
95
|
+
// Create a root view entity within the window container
|
|
96
|
+
var rootEnt = await this.session.createEntity();
|
|
97
|
+
await rootEnt.setComponent(await this.session.createViewComponent({ windowContainer: wg }));
|
|
98
|
+
await rootEnt.setCoordinateSpace('Root');
|
|
99
|
+
await wg.setRootEntity(rootEnt);
|
|
100
|
+
// Add webpage to the window container
|
|
101
|
+
var ent = await this.session.createEntity();
|
|
102
|
+
var i = await this.session.createWindowComponent({ windowContainer: wg });
|
|
103
|
+
await i.loadURL(url);
|
|
104
|
+
if (options?.resolution) {
|
|
105
|
+
await i.setResolution(options.resolution.width, options.resolution.height);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
await i.setResolution(1000, 1000);
|
|
109
|
+
}
|
|
110
|
+
ent.transform.position.z = -0.49;
|
|
111
|
+
await ent.updateTransform();
|
|
112
|
+
await ent.setCoordinateSpace('App');
|
|
113
|
+
await ent.setComponent(i);
|
|
114
|
+
await ent.setParent(rootEnt);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
dom = {
|
|
118
|
+
attachSpatialView: async (divOnPage) => {
|
|
119
|
+
// Create SpatialView
|
|
120
|
+
var viewEnt = await this.session.createEntity();
|
|
121
|
+
await viewEnt.setCoordinateSpace('Dom'); // Set coordinate space so its transform is relative to the webpage's pixels
|
|
122
|
+
await viewEnt.setComponent(await this.session.createViewComponent());
|
|
123
|
+
// Add to the root window component to display
|
|
124
|
+
var wc = await this.session.getCurrentWindowComponent();
|
|
125
|
+
var ent = await wc.getEntity();
|
|
126
|
+
await viewEnt.setParent(ent);
|
|
127
|
+
// Keep spatialView positioned where the div is
|
|
128
|
+
var update = () => {
|
|
129
|
+
var rect = divOnPage.getBoundingClientRect();
|
|
130
|
+
viewEnt.transform.position.x = rect.x + rect.width / 2;
|
|
131
|
+
viewEnt.transform.position.y = rect.y + rect.height / 2 + window.scrollY;
|
|
132
|
+
viewEnt.updateTransform();
|
|
133
|
+
viewEnt
|
|
134
|
+
.getComponent(SpatialViewComponent)
|
|
135
|
+
.setResolution(rect.width, rect.height);
|
|
136
|
+
};
|
|
137
|
+
var mo = new MutationObserver(update);
|
|
138
|
+
mo.observe(divOnPage, { attributes: true });
|
|
139
|
+
var ro = new ResizeObserver(update);
|
|
140
|
+
ro.observe(divOnPage);
|
|
141
|
+
const addRemoveObserver = new MutationObserver(mutations => {
|
|
142
|
+
mutations.forEach(mutation => {
|
|
143
|
+
mutation.removedNodes.forEach(node => {
|
|
144
|
+
if (node instanceof HTMLElement) {
|
|
145
|
+
update();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
mutation.addedNodes.forEach(node => {
|
|
149
|
+
if (node instanceof HTMLElement) {
|
|
150
|
+
update();
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
addRemoveObserver.observe(document.body, {
|
|
156
|
+
childList: true,
|
|
157
|
+
subtree: true,
|
|
158
|
+
});
|
|
159
|
+
update();
|
|
160
|
+
return {
|
|
161
|
+
entity: viewEnt,
|
|
162
|
+
};
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
setBackgroundStyle = async (style, backgroundColor = '#00000000') => {
|
|
166
|
+
document.documentElement.style.backgroundColor = backgroundColor;
|
|
167
|
+
await this.session.getCurrentWindowComponent().setStyle(style);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { WebSpatialResource } from './private/WebSpatial';
|
|
2
|
+
/**
|
|
3
|
+
* @hidden
|
|
4
|
+
* Parent class of spatial objects, should not be used directly
|
|
5
|
+
*/
|
|
6
|
+
export declare class SpatialObject {
|
|
7
|
+
/** @hidden */
|
|
8
|
+
_resource: WebSpatialResource;
|
|
9
|
+
/** @hidden */
|
|
10
|
+
constructor(
|
|
11
|
+
/** @hidden */
|
|
12
|
+
_resource: WebSpatialResource);
|
|
13
|
+
/**
|
|
14
|
+
* Marks resource to be released (it should no longer be used)
|
|
15
|
+
*/
|
|
16
|
+
destroy(): Promise<void>;
|
|
17
|
+
protected onDestroy(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=SpatialObject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpatialObject.d.ts","sourceRoot":"","sources":["../../src/core/SpatialObject.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD;;;GAGG;AACH,qBAAa,aAAa;IAGtB,cAAc;IACP,SAAS,EAAE,kBAAkB;IAHtC,cAAc;;IAEZ,cAAc;IACP,SAAS,EAAE,kBAAkB;IAGtC;;OAEG;IACG,OAAO;cAKG,SAAS;CAC1B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { WebSpatial } from './private/WebSpatial';
|
|
2
|
+
/**
|
|
3
|
+
* @hidden
|
|
4
|
+
* Parent class of spatial objects, should not be used directly
|
|
5
|
+
*/
|
|
6
|
+
export class SpatialObject {
|
|
7
|
+
_resource;
|
|
8
|
+
/** @hidden */
|
|
9
|
+
constructor(
|
|
10
|
+
/** @hidden */
|
|
11
|
+
_resource) {
|
|
12
|
+
this._resource = _resource;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Marks resource to be released (it should no longer be used)
|
|
16
|
+
*/
|
|
17
|
+
async destroy() {
|
|
18
|
+
await WebSpatial.destroyResource(this._resource);
|
|
19
|
+
await this.onDestroy();
|
|
20
|
+
}
|
|
21
|
+
async onDestroy() { }
|
|
22
|
+
}
|