@needle-tools/engine 3.2.11-alpha → 3.2.13-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/CHANGELOG.md +9 -0
- package/dist/needle-engine.js +9274 -9206
- package/dist/needle-engine.min.js +273 -273
- package/dist/needle-engine.umd.cjs +271 -271
- package/lib/engine/codegen/register_types.js +2 -0
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_context.js +3 -0
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.js +1 -1
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +2 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -2
- package/lib/engine/engine_utils.d.ts +2 -2
- package/lib/engine/engine_utils.js +4 -4
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine-components/Component.d.ts +2 -2
- package/lib/engine-components/Component.js +9 -4
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.d.ts +5 -0
- package/lib/engine-components/SceneSwitcher.js +32 -4
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +9 -4
- package/lib/engine-components/export/usdz/USDZExporter.js +77 -25
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/vite/alias.js +1 -4
- package/plugins/vite/copyfiles.js +46 -40
- package/plugins/vite/index.js +2 -0
- package/plugins/vite/meta.js +5 -2
- package/plugins/vite/peer.js +28 -0
- package/plugins/vite/reload.js +17 -13
- package/src/engine/codegen/register_types.js +2 -0
- package/src/engine/engine_context.ts +2 -0
- package/src/engine/engine_mainloop_utils.ts +1 -1
- package/src/engine/engine_serialization_core.ts +1 -1
- package/src/engine/engine_types.ts +2 -2
- package/src/engine/engine_utils.ts +7 -7
- package/src/engine-components/Component.ts +9 -4
- package/src/engine-components/SceneSwitcher.ts +38 -5
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/export/usdz/USDZExporter.ts +73 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.13-alpha",
|
|
4
4
|
"description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in",
|
|
5
5
|
"main": "dist/needle-engine.umd.cjs",
|
|
6
6
|
"type": "module",
|
package/plugins/vite/alias.js
CHANGED
|
@@ -33,10 +33,7 @@ export const needleViteAlias = (command, config, userSettings) => {
|
|
|
33
33
|
return {
|
|
34
34
|
name: "needle-alias",
|
|
35
35
|
config(config) {
|
|
36
|
-
|
|
37
|
-
console.log('[needle-alias] ProjectDirectory: ' + projectDir);
|
|
38
|
-
}, 150);
|
|
39
|
-
|
|
36
|
+
console.log('[needle-alias] ProjectDirectory: ' + projectDir);
|
|
40
37
|
if (!config.resolve) config.resolve = {};
|
|
41
38
|
if (!config.resolve.alias) config.resolve.alias = {};
|
|
42
39
|
const aliasDict = config.resolve.alias;
|
|
@@ -11,57 +11,63 @@ export const needleCopyFiles = (command, config, userSettings) => {
|
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const copyIncludesFromEngine = config?.copyIncludesFromEngine ?? true;
|
|
15
|
-
|
|
16
14
|
return {
|
|
17
15
|
name: 'needle-copy-files',
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
buildStart() {
|
|
17
|
+
return run(false, config);
|
|
18
|
+
},
|
|
19
|
+
closeBundle() {
|
|
20
|
+
return run(true, config);
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function run(isBuild, config) {
|
|
26
|
+
const copyIncludesFromEngine = config?.copyIncludesFromEngine ?? true;
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
const baseDir = process.cwd();
|
|
29
|
+
const pluginName = "needle-copy-files";
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
assetsDirName = needleConfig.assetsDirectory;
|
|
29
|
-
}
|
|
31
|
+
let assetsDirName = "assets";
|
|
32
|
+
let outdirName = "dist";
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const needleConfig = tryLoadProjectConfig();
|
|
35
|
+
if (needleConfig) {
|
|
36
|
+
assetsDirName = needleConfig.assetsDirectory;
|
|
37
|
+
}
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
if (copyIncludesFromEngine !== false) {
|
|
40
|
+
// copy include from engine
|
|
41
|
+
const engineIncludeDir = resolve(baseDir, 'node_modules', '@needle-tools', 'engine', 'src', 'include');
|
|
42
|
+
if (existsSync(engineIncludeDir)) {
|
|
43
|
+
console.log(`[${pluginName}] - Copy engine include to ${baseDir}/include`)
|
|
44
|
+
const projectIncludeDir = resolve(baseDir, 'include');
|
|
45
|
+
copyRecursiveSync(engineIncludeDir, projectIncludeDir);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
if (isBuild) {
|
|
50
|
+
const outDir = resolve(baseDir, outdirName);
|
|
51
|
+
if (!existsSync(outDir)) {
|
|
52
|
+
mkdirSync(outDir);
|
|
53
|
+
}
|
|
54
|
+
// copy assets dir
|
|
55
|
+
const assetsDir = resolve(baseDir, assetsDirName);
|
|
56
|
+
if (existsSync(assetsDir)) {
|
|
57
|
+
console.log(`[${pluginName}] - Copy assets to ${outdirName}/${builtAssetsDirectory()}`)
|
|
58
|
+
const targetDir = resolve(outDir, 'assets');
|
|
59
|
+
copyRecursiveSync(assetsDir, targetDir);
|
|
60
|
+
}
|
|
61
|
+
// copy include dir
|
|
62
|
+
const includeDir = resolve(baseDir, 'include');
|
|
63
|
+
if (existsSync(includeDir)) {
|
|
64
|
+
console.log(`[${pluginName}] - Copy include to ${outdirName}/include`)
|
|
65
|
+
const targetDir = resolve(outDir, 'include');
|
|
66
|
+
copyRecursiveSync(includeDir, targetDir);
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
64
|
-
|
|
65
71
|
function copyRecursiveSync(src, dest) {
|
|
66
72
|
var exists = existsSync(src);
|
|
67
73
|
var stats = exists && statSync(src);
|
package/plugins/vite/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { needleCopyFiles } from "./copyfiles.js";
|
|
|
8
8
|
import { needleViteAlias } from "./alias.js";
|
|
9
9
|
import { needleTransformCodegen } from "./transform-codegen.js";
|
|
10
10
|
import { needleLicense } from "./license.js";
|
|
11
|
+
import { needlePeerjs } from "./peer.js";
|
|
11
12
|
|
|
12
13
|
export * from "./gzip.js";
|
|
13
14
|
export * from "./config.js";
|
|
@@ -30,6 +31,7 @@ export const needlePlugins = async (command, config, userSettings) => {
|
|
|
30
31
|
needleCopyFiles(command, config, userSettings),
|
|
31
32
|
needleTransformCodegen(command, config, userSettings),
|
|
32
33
|
needleDrop(command, config, userSettings),
|
|
34
|
+
needlePeerjs(command, config, userSettings)
|
|
33
35
|
];
|
|
34
36
|
array.push(await editorConnection(command, config, userSettings, array));
|
|
35
37
|
return array;
|
package/plugins/vite/meta.js
CHANGED
|
@@ -91,6 +91,9 @@ export const needleMeta = (command, config, userSettings) => {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
// if(!tags.filter(t => t.attrs?.name === "generator"))
|
|
95
|
+
tags.push({ tag: 'meta', attrs: { name: 'generator', content: 'Needle' } });
|
|
96
|
+
|
|
94
97
|
return { html, tags }
|
|
95
98
|
},
|
|
96
99
|
}
|
|
@@ -124,8 +127,8 @@ function removeMetaTag(html, name) {
|
|
|
124
127
|
function insertNeedleCredits(html) {
|
|
125
128
|
const needleCredits = `<!-- 🌵 Made with Needle — https://needle.tools -->`;
|
|
126
129
|
html = html.replace(
|
|
127
|
-
/<head
|
|
128
|
-
needleCredits + "\n<head
|
|
130
|
+
/<head/,
|
|
131
|
+
needleCredits + "\n<head",
|
|
129
132
|
);
|
|
130
133
|
return html;
|
|
131
134
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
const peerjsString = `/* needle: injected fix for peerjs */
|
|
3
|
+
window.global = window;
|
|
4
|
+
var parcelRequire;`
|
|
5
|
+
|
|
6
|
+
export const needlePeerjs = (command, config, userSettings) => {
|
|
7
|
+
|
|
8
|
+
if (userSettings.noPeer === true) return;
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
name: 'needle-peerjs',
|
|
12
|
+
transformIndexHtml: {
|
|
13
|
+
enforce: 'pre',
|
|
14
|
+
transform(html, _ctx) {
|
|
15
|
+
return {
|
|
16
|
+
html,
|
|
17
|
+
tags: [
|
|
18
|
+
{
|
|
19
|
+
tag: 'script',
|
|
20
|
+
children: peerjsString,
|
|
21
|
+
injectTo: 'body-prepend',
|
|
22
|
+
},
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
package/plugins/vite/reload.js
CHANGED
|
@@ -61,22 +61,26 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
61
61
|
transformIndexHtml: {
|
|
62
62
|
enforce: 'pre',
|
|
63
63
|
transform(html, _) {
|
|
64
|
-
if (config?.allowHotReload === false) return
|
|
65
|
-
if (userSettings?.allowHotReload === false) return
|
|
64
|
+
if (config?.allowHotReload === false) return html;
|
|
65
|
+
if (userSettings?.allowHotReload === false) return html;
|
|
66
66
|
const file = path.join(__dirname, 'reload-client.js');
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
return {
|
|
68
|
+
html,
|
|
69
|
+
tags: [
|
|
70
|
+
{
|
|
71
|
+
tag: 'script',
|
|
72
|
+
attrs: {
|
|
73
|
+
type: 'module',
|
|
74
|
+
},
|
|
75
|
+
children: readFileSync(file, 'utf8'),
|
|
76
|
+
injectTo: 'body',
|
|
72
77
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
];
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
},
|
|
78
|
-
}
|
|
79
|
-
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
|
|
@@ -108,6 +108,7 @@ import { PlayerSync } from "../../engine-components-experimental/networking/Play
|
|
|
108
108
|
import { PointerEventData } from "../../engine-components/ui/PointerEvents";
|
|
109
109
|
import { PostProcessingHandler } from "../../engine-components/postprocessing/PostProcessingHandler";
|
|
110
110
|
import { PresentationMode } from "../../engine-components-experimental/Presentation";
|
|
111
|
+
import { QuickLookOverlay } from "../../engine-components/export/usdz/USDZExporter";
|
|
111
112
|
import { RawImage } from "../../engine-components/ui/Image";
|
|
112
113
|
import { Raycaster } from "../../engine-components/ui/Raycaster";
|
|
113
114
|
import { Rect } from "../../engine-components/ui/RectTransform";
|
|
@@ -296,6 +297,7 @@ TypeStore.add("PlayerSync", PlayerSync);
|
|
|
296
297
|
TypeStore.add("PointerEventData", PointerEventData);
|
|
297
298
|
TypeStore.add("PostProcessingHandler", PostProcessingHandler);
|
|
298
299
|
TypeStore.add("PresentationMode", PresentationMode);
|
|
300
|
+
TypeStore.add("QuickLookOverlay", QuickLookOverlay);
|
|
299
301
|
TypeStore.add("RawImage", RawImage);
|
|
300
302
|
TypeStore.add("Raycaster", Raycaster);
|
|
301
303
|
TypeStore.add("Rect", Rect);
|
|
@@ -34,6 +34,7 @@ const debug = utils.getParam("debugSetup");
|
|
|
34
34
|
const stats = utils.getParam("stats");
|
|
35
35
|
const debugActive = utils.getParam("debugactive");
|
|
36
36
|
const debugframerate = utils.getParam("debugframerate");
|
|
37
|
+
const debugCoroutine = utils.getParam("debugcoroutine");
|
|
37
38
|
|
|
38
39
|
// this is where functions that setup unity scenes will be pushed into
|
|
39
40
|
// those will be accessed from our custom html element to load them into their context
|
|
@@ -859,6 +860,7 @@ export class Context implements IContext {
|
|
|
859
860
|
// TODO we might want to keep coroutines playing even if the component is disabled or inactive
|
|
860
861
|
const remove = !evt.comp || evt.comp.destroyed || !evt.main || evt.comp["enabled"] === false;
|
|
861
862
|
if (remove) {
|
|
863
|
+
if (debugCoroutine) console.log("Removing coroutine", evt.comp, evt.comp["enabled"])
|
|
862
864
|
evts.splice(i, 1);
|
|
863
865
|
--i;
|
|
864
866
|
continue;
|
|
@@ -150,7 +150,7 @@ export function processNewScripts(context: IContext) {
|
|
|
150
150
|
|
|
151
151
|
export function processRemoveFromScene(script: IComponent) {
|
|
152
152
|
if (!script) return;
|
|
153
|
-
script.__internalDisable();
|
|
153
|
+
script.__internalDisable(true);
|
|
154
154
|
removeScriptFromContext(script, script.context);
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -279,7 +279,7 @@ export function deserializeObject(obj: ISerializable, serializedData: object, co
|
|
|
279
279
|
for (const key in typeInfo) {
|
|
280
280
|
const serializedEntryInfo = typeInfo[key];
|
|
281
281
|
const data = serializedData[key];
|
|
282
|
-
|
|
282
|
+
if(debug) console.log(key, data, obj, serializedEntryInfo)
|
|
283
283
|
|
|
284
284
|
if (obj[key] !== undefined && data === undefined) {
|
|
285
285
|
// if a field is marked as serialized and has some default value
|
|
@@ -123,9 +123,9 @@ export interface IComponent {
|
|
|
123
123
|
/** @internal */
|
|
124
124
|
__internalStart();
|
|
125
125
|
/** @internal */
|
|
126
|
-
__internalEnable();
|
|
126
|
+
__internalEnable(isAddingOrRemovingFromScene?: boolean);
|
|
127
127
|
/** @internal */
|
|
128
|
-
__internalDisable();
|
|
128
|
+
__internalDisable(isAddingOrRemovingFromScene?: boolean);
|
|
129
129
|
/** @internal */
|
|
130
130
|
__internalDestroy();
|
|
131
131
|
/** @internal */
|
|
@@ -97,12 +97,12 @@ export function setOrAddParamsToUrl(url: URLSearchParams, paramName: string, par
|
|
|
97
97
|
url.append(paramName, paramValue.toString());
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export function pushState(title: string, urlParams: URLSearchParams) {
|
|
101
|
-
window.history.pushState(
|
|
100
|
+
export function pushState(title: string, urlParams: URLSearchParams, state?: any) {
|
|
101
|
+
window.history.pushState(state, title, "?" + urlParams.toString());
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
export function setState(title: string, urlParams: URLSearchParams) {
|
|
105
|
-
window.history.replaceState(
|
|
104
|
+
export function setState(title: string, urlParams: URLSearchParams, state?: any) {
|
|
105
|
+
window.history.replaceState(state, title, "?" + urlParams.toString());
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// for room id
|
|
@@ -212,7 +212,7 @@ const debugGetPath = getParam("debugresolveurl");
|
|
|
212
212
|
export const relativePathPrefix = "rel:";
|
|
213
213
|
|
|
214
214
|
/** @deprecated use resolveUrl instead */
|
|
215
|
-
export function getPath(source:SourceIdentifier|undefined, uri:string)
|
|
215
|
+
export function getPath(source: SourceIdentifier | undefined, uri: string): string {
|
|
216
216
|
return resolveUrl(source, uri);
|
|
217
217
|
}
|
|
218
218
|
/**
|
|
@@ -226,7 +226,7 @@ export function resolveUrl(source: SourceIdentifier | undefined, uri: string): s
|
|
|
226
226
|
if (debugGetPath) console.warn("getPath: uri is undefined, returning uri", uri);
|
|
227
227
|
return uri;
|
|
228
228
|
}
|
|
229
|
-
if(uri.startsWith("./")) {
|
|
229
|
+
if (uri.startsWith("./")) {
|
|
230
230
|
return uri;
|
|
231
231
|
}
|
|
232
232
|
if (uri.startsWith("http")) {
|
|
@@ -237,7 +237,7 @@ export function resolveUrl(source: SourceIdentifier | undefined, uri: string): s
|
|
|
237
237
|
if (debugGetPath) console.warn("getPath: source is undefined, returning uri", uri);
|
|
238
238
|
return uri;
|
|
239
239
|
}
|
|
240
|
-
if(uri.startsWith(relativePathPrefix)){
|
|
240
|
+
if (uri.startsWith(relativePathPrefix)) {
|
|
241
241
|
uri = uri.substring(4);
|
|
242
242
|
}
|
|
243
243
|
const pathIndex = source.lastIndexOf("/");
|
|
@@ -470,7 +470,7 @@ export class Component implements IComponent, EventTarget {
|
|
|
470
470
|
|
|
471
471
|
|
|
472
472
|
/** @internal */
|
|
473
|
-
__internalEnable(): boolean {
|
|
473
|
+
__internalEnable(isAddingToScene?: boolean): boolean {
|
|
474
474
|
if (this.__destroyed) {
|
|
475
475
|
if (isDevEnvironment()) {
|
|
476
476
|
console.warn("[Needle Engine Dev] Trying to enable destroyed component");
|
|
@@ -481,7 +481,10 @@ export class Component implements IComponent, EventTarget {
|
|
|
481
481
|
// But a user can change enable during awake
|
|
482
482
|
if (!this.__didAwake) return false;
|
|
483
483
|
if (this.__didEnable) {
|
|
484
|
-
|
|
484
|
+
// We dont want to change the enable state if we are adding to scene
|
|
485
|
+
// But we want to change the state when e.g. a user changes the enable state during awake
|
|
486
|
+
if (isAddingToScene !== true)
|
|
487
|
+
this.__isEnabled = true;
|
|
485
488
|
return false;
|
|
486
489
|
}
|
|
487
490
|
// console.trace("INTERNAL ENABLE");
|
|
@@ -492,12 +495,14 @@ export class Component implements IComponent, EventTarget {
|
|
|
492
495
|
}
|
|
493
496
|
|
|
494
497
|
/** @internal */
|
|
495
|
-
__internalDisable() {
|
|
498
|
+
__internalDisable(isRemovingFromScene?: boolean) {
|
|
496
499
|
// Don't change enable before awake
|
|
497
500
|
// But a user can change enable during awake
|
|
498
501
|
if (!this.__didAwake) return;
|
|
499
502
|
if (!this.__didEnable) {
|
|
500
|
-
|
|
503
|
+
// We dont want to change the enable state if we are removing from a scene
|
|
504
|
+
if (isRemovingFromScene !== true)
|
|
505
|
+
this.__isEnabled = false;
|
|
501
506
|
return;
|
|
502
507
|
}
|
|
503
508
|
this.__didEnable = false;
|
|
@@ -14,7 +14,7 @@ ContextRegistry.registerCallback(ContextEvent.ContextRegistered, async _ => {
|
|
|
14
14
|
// We need to defer import to not get issues with circular dependencies
|
|
15
15
|
import("../engine/engine_element").then(res => {
|
|
16
16
|
const webcomponent = res.NeedleEngineHTMLElement;
|
|
17
|
-
if(debug) console.log("SceneSwitcher: registering scene attribute", webcomponent.observedAttributes);
|
|
17
|
+
if (debug) console.log("SceneSwitcher: registering scene attribute", webcomponent.observedAttributes);
|
|
18
18
|
if (!webcomponent.observedAttributes.includes(ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME))
|
|
19
19
|
webcomponent.observedAttributes.push(ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME);
|
|
20
20
|
});
|
|
@@ -22,6 +22,12 @@ ContextRegistry.registerCallback(ContextEvent.ContextRegistered, async _ => {
|
|
|
22
22
|
|
|
23
23
|
const couldNotLoadScenePromise = Promise.resolve(false);
|
|
24
24
|
|
|
25
|
+
export type LoadSceneEvent = {
|
|
26
|
+
switcher: SceneSwitcher;
|
|
27
|
+
scene: AssetReference;
|
|
28
|
+
index: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
export class SceneSwitcher extends Behaviour {
|
|
26
32
|
|
|
27
33
|
@serializable(AssetReference)
|
|
@@ -108,7 +114,17 @@ export class SceneSwitcher extends Behaviour {
|
|
|
108
114
|
let wasUsingHistory = this.useHistory;
|
|
109
115
|
try {
|
|
110
116
|
this.useHistory = false;
|
|
111
|
-
|
|
117
|
+
let didResolve = false;
|
|
118
|
+
if (this.queryParameterName)
|
|
119
|
+
didResolve = await this.tryLoadFromQueryParam();
|
|
120
|
+
if (!didResolve) {
|
|
121
|
+
const state = _state.state;
|
|
122
|
+
if (state !== null && state.startsWith(this.guid)) {
|
|
123
|
+
const value = state.substr(this.guid.length + 2);
|
|
124
|
+
console.log(value);
|
|
125
|
+
await this.trySelectSceneFromValue(value);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
112
128
|
}
|
|
113
129
|
finally {
|
|
114
130
|
this.useHistory = wasUsingHistory;
|
|
@@ -192,7 +208,15 @@ export class SceneSwitcher extends Behaviour {
|
|
|
192
208
|
const index = this._currentIndex = this.scenes?.indexOf(scene) ?? -1;
|
|
193
209
|
this._currentScene = scene;
|
|
194
210
|
try {
|
|
211
|
+
const loadStartEvt = new CustomEvent<LoadSceneEvent>("loadscene-start", { detail: { scene: scene, switcher: this, index: index } })
|
|
212
|
+
this.dispatchEvent(loadStartEvt);
|
|
195
213
|
await scene.loadAssetAsync();
|
|
214
|
+
const finishedEvt = new CustomEvent<LoadSceneEvent>("loadscene-finished", { detail: { scene: scene, switcher: this, index: index } });
|
|
215
|
+
this.dispatchEvent(finishedEvt);
|
|
216
|
+
if (finishedEvt.defaultPrevented) {
|
|
217
|
+
if (debug) console.warn("Adding loaded scene prevented:", scene, finishedEvt);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
196
220
|
if (!scene.asset) {
|
|
197
221
|
if (debug) console.warn("Failed loading scene:", scene);
|
|
198
222
|
return false;
|
|
@@ -201,9 +225,18 @@ export class SceneSwitcher extends Behaviour {
|
|
|
201
225
|
GameObject.add(scene.asset, this.gameObject);
|
|
202
226
|
if (this.useSceneLighting)
|
|
203
227
|
this.context.sceneLighting.enable(scene)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
228
|
+
if (this.useHistory) {
|
|
229
|
+
// save the loaded scene as an url parameter
|
|
230
|
+
if (this.queryParameterName?.length)
|
|
231
|
+
setParamWithoutReload(this.queryParameterName, index.toString(), this.useHistory);
|
|
232
|
+
// or set the history state without updating the url parameter
|
|
233
|
+
else {
|
|
234
|
+
const lastState = history.state;
|
|
235
|
+
const stateName = this.guid + "::" + index;
|
|
236
|
+
if (lastState !== stateName)
|
|
237
|
+
history.pushState(stateName, "unused", location.href);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
207
240
|
return true;
|
|
208
241
|
}
|
|
209
242
|
}
|
|
@@ -103,6 +103,7 @@ export { PlayableDirector } from "../timeline/PlayableDirector";
|
|
|
103
103
|
export { PlayerColor } from "../PlayerColor";
|
|
104
104
|
export { PointerEventData } from "../ui/PointerEvents";
|
|
105
105
|
export { PostProcessingHandler } from "../postprocessing/PostProcessingHandler";
|
|
106
|
+
export { QuickLookOverlay } from "../export/usdz/USDZExporter";
|
|
106
107
|
export { RawImage } from "../ui/Image";
|
|
107
108
|
export { Raycaster } from "../ui/Raycaster";
|
|
108
109
|
export { Rect } from "../ui/RectTransform";
|