@needle-tools/engine 3.5.1-alpha → 3.5.3-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 +22 -0
- package/dist/needle-engine.js +29554 -29281
- package/dist/needle-engine.min.js +357 -356
- package/dist/needle-engine.umd.cjs +354 -353
- package/lib/engine/codegen/register_types.js +4 -2
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/debug/debug_overlay.js +2 -1
- package/lib/engine/debug/debug_overlay.js.map +1 -1
- package/lib/engine/engine_components.js +2 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_element_loading.js +4 -4
- package/lib/engine/engine_element_loading.js.map +1 -1
- package/lib/engine/engine_gameobject.js +2 -0
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_input.js +4 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.d.ts +2 -0
- package/lib/engine/engine_license.js +25 -4
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_physics_rapier.js +2 -1
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +16 -1
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.js +10 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
- package/lib/engine-components/Component.js +0 -3
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.d.ts +9 -0
- package/lib/engine-components/SceneSwitcher.js +128 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +2 -1
- package/lib/engine-components/codegen/components.js +2 -1
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/Extension.d.ts +3 -2
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.d.ts +9 -5
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +64 -20
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +2 -0
- package/lib/engine-components/export/usdz/USDZExporter.js +44 -9
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/AudioExtension.d.ts +9 -0
- package/lib/engine-components/export/usdz/extensions/behavior/AudioExtension.js +48 -0
- package/lib/engine-components/export/usdz/extensions/behavior/AudioExtension.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.d.ts +4 -5
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js +19 -10
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +9 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +75 -5
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.d.ts +20 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js +45 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js.map +1 -1
- package/lib/engine-components/ui/BaseUIComponent.d.ts +1 -0
- package/lib/engine-components/ui/BaseUIComponent.js +8 -4
- package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
- package/lib/engine-components/ui/Canvas.js +1 -1
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +3 -0
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Image.d.ts +3 -1
- package/lib/engine-components/ui/Image.js +15 -1
- package/lib/engine-components/ui/Image.js.map +1 -1
- package/lib/engine-components/ui/Interfaces.d.ts +1 -1
- package/lib/engine-components/ui/Layout.js +2 -0
- package/lib/engine-components/ui/Layout.js.map +1 -1
- package/lib/engine-components/ui/PointerEvents.d.ts +8 -1
- package/lib/engine-components/ui/PointerEvents.js +9 -1
- package/lib/engine-components/ui/PointerEvents.js.map +1 -1
- package/lib/engine-components/ui/RaycastUtils.js +5 -0
- package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
- package/lib/engine-components/ui/RectTransform.d.ts +2 -2
- package/lib/engine-components/ui/RectTransform.js +11 -12
- package/lib/engine-components/ui/RectTransform.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +0 -2
- package/lib/engine-components/ui/Text.js +0 -5
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/vite/license.js +2 -2
- package/src/engine/codegen/register_types.js +4 -2
- package/src/engine/debug/debug_overlay.ts +2 -1
- package/src/engine/engine_components.ts +2 -1
- package/src/engine/engine_element_loading.ts +4 -4
- package/src/engine/engine_gameobject.ts +3 -0
- package/src/engine/engine_input.ts +4 -1
- package/src/engine/engine_license.ts +25 -4
- package/src/engine/engine_physics_rapier.ts +2 -1
- package/src/engine/engine_serialization_core.ts +17 -1
- package/src/engine/extensions/NEEDLE_lighting_settings.ts +11 -1
- package/src/engine-components/Component.ts +1 -3
- package/src/engine-components/SceneSwitcher.ts +136 -1
- package/src/engine-components/codegen/components.ts +2 -1
- package/src/engine-components/export/usdz/Extension.ts +3 -2
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +89 -21
- package/src/engine-components/export/usdz/USDZExporter.ts +48 -11
- package/src/engine-components/export/usdz/extensions/behavior/AudioExtension.ts +63 -0
- package/src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +28 -16
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +98 -21
- package/src/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.ts +48 -2
- package/src/engine-components/ui/BaseUIComponent.ts +8 -3
- package/src/engine-components/ui/Canvas.ts +1 -1
- package/src/engine-components/ui/EventSystem.ts +5 -1
- package/src/engine-components/ui/Image.ts +16 -1
- package/src/engine-components/ui/Interfaces.ts +1 -1
- package/src/engine-components/ui/Layout.ts +2 -0
- package/src/engine-components/ui/PointerEvents.ts +16 -2
- package/src/engine-components/ui/RaycastUtils.ts +6 -1
- package/src/engine-components/ui/RectTransform.ts +11 -11
- package/src/engine-components/ui/Text.ts +1 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.3-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/license.js
CHANGED
|
@@ -13,8 +13,8 @@ export const needleLicense = (command, config, userSettings) => {
|
|
|
13
13
|
if (isNeedleEngineFile || isViteChunkFile) {
|
|
14
14
|
const needleConfig = await loadConfig();
|
|
15
15
|
if (needleConfig) {
|
|
16
|
-
if (needleConfig.
|
|
17
|
-
src = src.replace("
|
|
16
|
+
if (typeof needleConfig.license === "string") {
|
|
17
|
+
src = src.replace("const NEEDLE_ENGINE_LICENSE_TYPE: string = \"\";", "const NEEDLE_ENGINE_LICENSE_TYPE: string = \"" + needleConfig.license + "\";");
|
|
18
18
|
return { code: src, map: null }
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -14,6 +14,7 @@ import { Animator } from "../../engine-components/Animator";
|
|
|
14
14
|
import { AnimatorController } from "../../engine-components/AnimatorController";
|
|
15
15
|
import { Antialiasing } from "../../engine-components/postprocessing/Effects/Antialiasing";
|
|
16
16
|
import { AttachedObject } from "../../engine-components/webxr/WebXRController";
|
|
17
|
+
import { AudioExtension } from "../../engine-components/export/usdz/extensions/behavior/AudioExtension";
|
|
17
18
|
import { AudioListener } from "../../engine-components/AudioListener";
|
|
18
19
|
import { AudioSource } from "../../engine-components/AudioSource";
|
|
19
20
|
import { AudioTrackHandler } from "../../engine-components/timeline/TimelineTracks";
|
|
@@ -116,6 +117,7 @@ import { ParticleSystemRenderer } from "../../engine-components/ParticleSystem";
|
|
|
116
117
|
import { PixelationEffect } from "../../engine-components/postprocessing/Effects/Pixelation";
|
|
117
118
|
import { PlayableDirector } from "../../engine-components/timeline/PlayableDirector";
|
|
118
119
|
import { PlayAnimationOnClick } from "../../engine-components/export/usdz/extensions/behavior/BehaviourComponents";
|
|
120
|
+
import { PlayAudioOnClick } from "../../engine-components/export/usdz/extensions/behavior/BehaviourComponents";
|
|
119
121
|
import { PlayerColor } from "../../engine-components/PlayerColor";
|
|
120
122
|
import { PlayerState } from "../../engine-components-experimental/networking/PlayerSync";
|
|
121
123
|
import { PlayerSync } from "../../engine-components-experimental/networking/PlayerSync";
|
|
@@ -184,7 +186,6 @@ import { TriggerModel } from "../../engine-components/export/usdz/extensions/beh
|
|
|
184
186
|
import { UIRaycastUtils } from "../../engine-components/ui/RaycastUtils";
|
|
185
187
|
import { UIRootComponent } from "../../engine-components/ui/BaseUIComponent";
|
|
186
188
|
import { UsageMarker } from "../../engine-components/Interactable";
|
|
187
|
-
import { USDZBehaviours } from "../../engine-components/export/usdz/extensions/behavior/Behaviour";
|
|
188
189
|
import { USDZExporter } from "../../engine-components/export/usdz/USDZExporter";
|
|
189
190
|
import { USDZText } from "../../engine-components/export/usdz/extensions/USDZText";
|
|
190
191
|
import { VariantAction } from "../../engine-components/export/usdz/extensions/behavior/Actions";
|
|
@@ -229,6 +230,7 @@ TypeStore.add("Animator", Animator);
|
|
|
229
230
|
TypeStore.add("AnimatorController", AnimatorController);
|
|
230
231
|
TypeStore.add("Antialiasing", Antialiasing);
|
|
231
232
|
TypeStore.add("AttachedObject", AttachedObject);
|
|
233
|
+
TypeStore.add("AudioExtension", AudioExtension);
|
|
232
234
|
TypeStore.add("AudioListener", AudioListener);
|
|
233
235
|
TypeStore.add("AudioSource", AudioSource);
|
|
234
236
|
TypeStore.add("AudioTrackHandler", AudioTrackHandler);
|
|
@@ -331,6 +333,7 @@ TypeStore.add("ParticleSystemRenderer", ParticleSystemRenderer);
|
|
|
331
333
|
TypeStore.add("PixelationEffect", PixelationEffect);
|
|
332
334
|
TypeStore.add("PlayableDirector", PlayableDirector);
|
|
333
335
|
TypeStore.add("PlayAnimationOnClick", PlayAnimationOnClick);
|
|
336
|
+
TypeStore.add("PlayAudioOnClick", PlayAudioOnClick);
|
|
334
337
|
TypeStore.add("PlayerColor", PlayerColor);
|
|
335
338
|
TypeStore.add("PlayerState", PlayerState);
|
|
336
339
|
TypeStore.add("PlayerSync", PlayerSync);
|
|
@@ -399,7 +402,6 @@ TypeStore.add("TriggerModel", TriggerModel);
|
|
|
399
402
|
TypeStore.add("UIRaycastUtils", UIRaycastUtils);
|
|
400
403
|
TypeStore.add("UIRootComponent", UIRootComponent);
|
|
401
404
|
TypeStore.add("UsageMarker", UsageMarker);
|
|
402
|
-
TypeStore.add("USDZBehaviours", USDZBehaviours);
|
|
403
405
|
TypeStore.add("USDZExporter", USDZExporter);
|
|
404
406
|
TypeStore.add("USDZText", USDZText);
|
|
405
407
|
TypeStore.add("VariantAction", VariantAction);
|
|
@@ -107,7 +107,8 @@ const currentMessages = new Set<string>();
|
|
|
107
107
|
function showMessage(type: LogType, element: HTMLElement, msg: string) {
|
|
108
108
|
const container = getLogsContainer(element);
|
|
109
109
|
if (container.childElementCount >= 20) {
|
|
110
|
-
|
|
110
|
+
const last = container.lastElementChild;
|
|
111
|
+
returnMessageContainer(last as HTMLElement);
|
|
111
112
|
}
|
|
112
113
|
// truncate long messages before they go into the cache/set
|
|
113
114
|
if(msg.length > 300) msg = msg.substring(0, 300) + "...";
|
|
@@ -160,7 +160,8 @@ export function getComponent<T>(obj: Object3D, componentType: Constructor<T>) {
|
|
|
160
160
|
|
|
161
161
|
export function getComponents<T>(obj: Object3D, componentType: Constructor<T>, arr?: T[] | null): T[] {
|
|
162
162
|
if (!arr) arr = [];
|
|
163
|
-
|
|
163
|
+
onGetComponent(obj, componentType, arr);
|
|
164
|
+
return arr;
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
export function getComponentInChildren<T>(obj: Object3D, componentType: Constructor<T>, includeInactive?: boolean) {
|
|
@@ -3,7 +3,7 @@ import { Mathf } from "./engine_math";
|
|
|
3
3
|
import { LoadingProgressArgs } from "./engine_setup";
|
|
4
4
|
import { getParam } from "./engine_utils";
|
|
5
5
|
import { logoSVG } from "./assets"
|
|
6
|
-
import { hasProLicense } from "./engine_license";
|
|
6
|
+
import { hasCommercialLicense, hasProLicense } from "./engine_license";
|
|
7
7
|
|
|
8
8
|
const debug = getParam("debugloadingbar");
|
|
9
9
|
const debugRendering = getParam("debugloadingbarrendering");
|
|
@@ -186,7 +186,7 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
186
186
|
if (loadingStyle === "light")
|
|
187
187
|
this._loadingElement.style.backgroundColor = "#ddd";
|
|
188
188
|
else
|
|
189
|
-
this._loadingElement.style.backgroundColor = "#
|
|
189
|
+
this._loadingElement.style.backgroundColor = "#222";
|
|
190
190
|
this._loadingElement.style.display = "flex";
|
|
191
191
|
this._loadingElement.style.alignItems = "center";
|
|
192
192
|
this._loadingElement.style.justifyContent = "center";
|
|
@@ -289,7 +289,7 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
289
289
|
messageContainer.style.fontSize = ".8em";
|
|
290
290
|
messageContainer.style.paddingTop = ".5em";
|
|
291
291
|
messageContainer.style.fontWeight = "200";
|
|
292
|
-
messageContainer.style.fontFamily = "Roboto, sans-serif";
|
|
292
|
+
messageContainer.style.fontFamily = "Roboto, sans-serif, Arial";
|
|
293
293
|
// messageContainer.style.border = "1px solid rgba(255,255,255,.1)";
|
|
294
294
|
messageContainer.style.justifyContent = "center";
|
|
295
295
|
this._loadingElement.appendChild(messageContainer);
|
|
@@ -301,7 +301,7 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
if (!
|
|
304
|
+
if (!hasCommercialLicense()) {
|
|
305
305
|
const nonCommercialContainer = document.createElement("div");
|
|
306
306
|
nonCommercialContainer.style.paddingTop = ".6em";
|
|
307
307
|
nonCommercialContainer.style.fontSize = ".8em";
|
|
@@ -113,6 +113,9 @@ export function destroy(instance: Object3D | Component, recursive: boolean = tru
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
function internalDestroy(instance: Object3D | Component, recursive: boolean = true, dispose: boolean = false, isRoot: boolean = true) {
|
|
116
|
+
if (instance === null || instance === undefined)
|
|
117
|
+
return;
|
|
118
|
+
|
|
116
119
|
const comp = instance as Component;
|
|
117
120
|
if (comp.isComponent) {
|
|
118
121
|
comp.__internalDisable();
|
|
@@ -611,9 +611,12 @@ export class Input extends EventTarget implements IInput {
|
|
|
611
611
|
|
|
612
612
|
const lf = this._pointerPositionsLastFrame[evt.button];
|
|
613
613
|
lf.copy(this._pointerPositions[evt.button]);
|
|
614
|
+
// accumulate delta (it's reset in end of frame), if we just write it here it's not correct when the browser console is open
|
|
615
|
+
const delta = this._pointerPositionsDelta[evt.button];
|
|
614
616
|
const dx = evt.clientX - lf.x;
|
|
615
617
|
const dy = evt.clientY - lf.y;
|
|
616
|
-
|
|
618
|
+
delta.x += dx;
|
|
619
|
+
delta.y += dy;
|
|
617
620
|
|
|
618
621
|
this._pointerPositions[evt.button].x = evt.clientX;
|
|
619
622
|
this._pointerPositions[evt.button].y = evt.clientY;
|
|
@@ -7,10 +7,28 @@ const debug = getParam("debuglicense");
|
|
|
7
7
|
|
|
8
8
|
// This is modified by a bundler (e.g. vite)
|
|
9
9
|
// Do not edit manually
|
|
10
|
-
const
|
|
10
|
+
const NEEDLE_ENGINE_LICENSE_TYPE: string = "";
|
|
11
|
+
if (debug) console.log("License Type: " + NEEDLE_ENGINE_LICENSE_TYPE)
|
|
11
12
|
|
|
12
13
|
export function hasProLicense() {
|
|
13
|
-
|
|
14
|
+
switch (NEEDLE_ENGINE_LICENSE_TYPE) {
|
|
15
|
+
case "pro":
|
|
16
|
+
case "enterprise":
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function hasIndieLicense() {
|
|
23
|
+
switch (NEEDLE_ENGINE_LICENSE_TYPE) {
|
|
24
|
+
case "indie":
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function hasCommercialLicense() {
|
|
31
|
+
return hasProLicense() || hasIndieLicense();
|
|
14
32
|
}
|
|
15
33
|
|
|
16
34
|
|
|
@@ -52,7 +70,8 @@ function insertNonCommercialUseHint(ctx: IContext) {
|
|
|
52
70
|
}
|
|
53
71
|
}, 100);
|
|
54
72
|
|
|
55
|
-
|
|
73
|
+
if (!hasCommercialLicense())
|
|
74
|
+
logNonCommercialUse();
|
|
56
75
|
|
|
57
76
|
let svg = `<img class="logo" src="${logoSVG}" style="width: 40px; height: 40px; margin-right: 2px; vertical-align: middle; margin-bottom: 2px;"/>`;
|
|
58
77
|
const logoElement = document.createElement("div");
|
|
@@ -66,7 +85,9 @@ function insertNonCommercialUseHint(ctx: IContext) {
|
|
|
66
85
|
// textElement.innerHTML = "Needle Engine<br/><span class=\"non-commercial\">Non Commercial</span>";
|
|
67
86
|
licenseElement.appendChild(textElement);
|
|
68
87
|
|
|
69
|
-
licenseElement.title = "Needle Engine
|
|
88
|
+
licenseElement.title = "Needle Engine";
|
|
89
|
+
if (!hasCommercialLicense())
|
|
90
|
+
licenseElement.title += " non commercial version";
|
|
70
91
|
licenseElement.addEventListener("click", () => {
|
|
71
92
|
globalThis.open("https://needle.tools", "_blank");
|
|
72
93
|
});
|
|
@@ -207,7 +207,8 @@ export class RapierPhysics implements IPhysicsEngine {
|
|
|
207
207
|
private async internalInitialization() {
|
|
208
208
|
// NEEDLE_PHYSICS_INIT_START
|
|
209
209
|
// use .env file with VITE_NEEDLE_USE_RAPIER=false to treeshape rapier
|
|
210
|
-
|
|
210
|
+
// @ts-ignore
|
|
211
|
+
if ("env" in import.meta && import.meta.env.VITE_NEEDLE_USE_RAPIER === "false") {
|
|
211
212
|
return false;
|
|
212
213
|
}
|
|
213
214
|
// Can be transformed during build time to disable rapier
|
|
@@ -434,7 +434,14 @@ function implictlyAssignPrimitiveTypes(obj: any, serializedData: any) {
|
|
|
434
434
|
if (targetMember !== undefined) continue;
|
|
435
435
|
// resolve serialized primitive types
|
|
436
436
|
if (isPrimitiveType(data[key]) && !isPrimitiveType(member)) {
|
|
437
|
-
|
|
437
|
+
|
|
438
|
+
const prop = tryFindPropertyDescriptor(member, key);
|
|
439
|
+
if (!prop?.writable === false || (prop && prop.set === undefined)) {
|
|
440
|
+
if (debug)
|
|
441
|
+
console.warn("Property is not writable \"" + key + "\"", member, prop, data[key], member[key]);
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
// console.log("ASSIGN", key, member, member[key], targetMember, data[key], prop);
|
|
438
445
|
member[key] = data[key];
|
|
439
446
|
}
|
|
440
447
|
}
|
|
@@ -442,6 +449,15 @@ function implictlyAssignPrimitiveTypes(obj: any, serializedData: any) {
|
|
|
442
449
|
}
|
|
443
450
|
}
|
|
444
451
|
|
|
452
|
+
function tryFindPropertyDescriptor(obj: object, key: string) : PropertyDescriptor | undefined {
|
|
453
|
+
while(obj){
|
|
454
|
+
const desc = Object.getOwnPropertyDescriptor(obj, key);
|
|
455
|
+
if(desc) return desc;
|
|
456
|
+
obj = Object.getPrototypeOf(obj);
|
|
457
|
+
}
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
|
|
445
461
|
function isPrimitiveType(val): boolean {
|
|
446
462
|
switch (typeof val) {
|
|
447
463
|
case "number":
|
|
@@ -48,8 +48,9 @@ export class NEEDLE_lighting_settings implements GLTFLoaderPlugin {
|
|
|
48
48
|
let settings: SceneLightSettings | undefined = undefined;
|
|
49
49
|
// If the result scene has only one child we add the LightingSettingsComponent to that child
|
|
50
50
|
if (_result.scene.children.length === 1) {
|
|
51
|
+
const obj = _result.scene.children[0];
|
|
51
52
|
// add a component to the root of the scene
|
|
52
|
-
settings = GameObject.addNewComponent(
|
|
53
|
+
settings = GameObject.addNewComponent(obj, SceneLightSettings, false);
|
|
53
54
|
}
|
|
54
55
|
// if the scene already has multiple children we add it as a new object
|
|
55
56
|
else {
|
|
@@ -117,6 +118,15 @@ export class SceneLightSettings extends Behaviour {
|
|
|
117
118
|
}
|
|
118
119
|
});
|
|
119
120
|
}
|
|
121
|
+
|
|
122
|
+
// make sure the component is in the end of the list
|
|
123
|
+
// (e.g. if we have an animation on the first component from an instance and add the scenelightingcomponent the animation binding will break)
|
|
124
|
+
const comps = this.gameObject.userData?.components;
|
|
125
|
+
if (comps) {
|
|
126
|
+
const index = comps.indexOf(this);
|
|
127
|
+
comps.splice(index, 1);
|
|
128
|
+
comps.push(this);
|
|
129
|
+
}
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
onDestroy(): void {
|
|
@@ -195,9 +195,6 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
|
|
|
195
195
|
* @param instance component to move to the GO
|
|
196
196
|
*/
|
|
197
197
|
public static moveComponent(go: IGameObject, instance: Component): void {
|
|
198
|
-
if (instance.gameObject == null) {
|
|
199
|
-
throw new Error("Did you mean to create a new component? Use addNewComponent");
|
|
200
|
-
}
|
|
201
198
|
moveComponentInstance(go, instance as any);
|
|
202
199
|
}
|
|
203
200
|
|
|
@@ -277,6 +274,7 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
|
|
|
277
274
|
// these are implemented via threejs object extensions
|
|
278
275
|
abstract activeSelf: boolean;
|
|
279
276
|
abstract addNewComponent<T>(type: Constructor<T>): T | null;
|
|
277
|
+
// TODO: add method for addExisting component
|
|
280
278
|
abstract removeComponent(comp: Component): Component;
|
|
281
279
|
abstract getOrAddComponent<T>(typeName: Constructor<T> | null): T;
|
|
282
280
|
abstract getComponent<T>(type: Constructor<T>): T | null;
|
|
@@ -56,11 +56,27 @@ export class SceneSwitcher extends Behaviour {
|
|
|
56
56
|
@serializable()
|
|
57
57
|
useSceneLighting: boolean = true;
|
|
58
58
|
|
|
59
|
+
/** how many scenes after the currently active scene should be preloaded */
|
|
60
|
+
@serializable()
|
|
61
|
+
preloadNext: number = 1;
|
|
62
|
+
|
|
63
|
+
/** how many scenes before the currently active scene should be preloaded */
|
|
64
|
+
@serializable()
|
|
65
|
+
preloadPrevious: number = 1;
|
|
66
|
+
|
|
67
|
+
/** how many scenes can be loaded in parallel */
|
|
68
|
+
@serializable()
|
|
69
|
+
preloadConcurrent: number = 2;
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
get currentIndex(): number { return this._currentIndex; }
|
|
59
73
|
|
|
60
74
|
private _currentIndex: number = -1;
|
|
61
75
|
private _currentScene: AssetReference | undefined = undefined;
|
|
62
76
|
private _engineElementOverserver: MutationObserver | undefined = undefined;
|
|
63
77
|
|
|
78
|
+
private _preloadScheduler?: PreLoadScheduler;
|
|
79
|
+
|
|
64
80
|
async start() {
|
|
65
81
|
if (this._currentIndex === -1 && !await this.tryLoadFromQueryParam()) {
|
|
66
82
|
const value = this.context.domElement.getAttribute(ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME);
|
|
@@ -100,6 +116,13 @@ export class SceneSwitcher extends Behaviour {
|
|
|
100
116
|
this._engineElementOverserver.observe(this.context.domElement, {
|
|
101
117
|
attributes: true
|
|
102
118
|
});
|
|
119
|
+
|
|
120
|
+
if (!this._preloadScheduler)
|
|
121
|
+
this._preloadScheduler = new PreLoadScheduler(this);
|
|
122
|
+
this._preloadScheduler.maxLoadAhead = this.preloadNext;
|
|
123
|
+
this._preloadScheduler.maxLoadBehind = this.preloadPrevious;
|
|
124
|
+
this._preloadScheduler.maxConcurrent = this.preloadConcurrent;
|
|
125
|
+
this._preloadScheduler.begin();
|
|
103
126
|
}
|
|
104
127
|
|
|
105
128
|
onDisable(): void {
|
|
@@ -107,6 +130,7 @@ export class SceneSwitcher extends Behaviour {
|
|
|
107
130
|
this.context.input.removeEventListener(InputEvents.KeyDown, this.onKeyDown);
|
|
108
131
|
this.context.input.removeEventListener(InputEvents.PointerMove, this.onPointerMove);
|
|
109
132
|
this.context.input.removeEventListener(InputEvents.PointerUp, this.onPointerUp);
|
|
133
|
+
this._preloadScheduler?.stop();
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
private onPopState = async (_state: PopStateEvent) => {
|
|
@@ -189,7 +213,7 @@ export class SceneSwitcher extends Behaviour {
|
|
|
189
213
|
select(index: number | string): Promise<boolean> {
|
|
190
214
|
if (debug) console.log("select", index);
|
|
191
215
|
|
|
192
|
-
if(typeof index === "object"){
|
|
216
|
+
if (typeof index === "object") {
|
|
193
217
|
// If a user tries to reference a scene object in a UnityEvent and invoke select(obj)
|
|
194
218
|
// Then the object will be serialized as a object { guid : ... } or with the index json pointer
|
|
195
219
|
// This case is not supported right now. Object references in the editor must not be scene references
|
|
@@ -271,6 +295,15 @@ export class SceneSwitcher extends Behaviour {
|
|
|
271
295
|
return false;
|
|
272
296
|
}
|
|
273
297
|
|
|
298
|
+
preload(index: number) {
|
|
299
|
+
if (index >= 0 && index < this.scenes.length) {
|
|
300
|
+
const scene = this.scenes[index];
|
|
301
|
+
if(scene instanceof AssetReference)
|
|
302
|
+
return scene.preload();
|
|
303
|
+
}
|
|
304
|
+
return couldNotLoadScenePromise;
|
|
305
|
+
}
|
|
306
|
+
|
|
274
307
|
private tryLoadFromQueryParam() {
|
|
275
308
|
if (!this.queryParameterName?.length) return couldNotLoadScenePromise;
|
|
276
309
|
// try restore the scene from the url
|
|
@@ -308,3 +341,105 @@ export class SceneSwitcher extends Behaviour {
|
|
|
308
341
|
return couldNotLoadScenePromise;
|
|
309
342
|
}
|
|
310
343
|
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class PreLoadScheduler {
|
|
349
|
+
maxLoadAhead: number;
|
|
350
|
+
maxLoadBehind: number;
|
|
351
|
+
maxConcurrent: number;
|
|
352
|
+
|
|
353
|
+
private _isRunning: boolean = false;
|
|
354
|
+
private _rooms: SceneSwitcher;
|
|
355
|
+
private _roomTasks: LoadTask[] = [];
|
|
356
|
+
private _maxConcurrentLoads: number = 1;
|
|
357
|
+
|
|
358
|
+
constructor(rooms: SceneSwitcher, ahead: number = 1, behind: number = 1, maxConcurrent: number = 2) {
|
|
359
|
+
this._rooms = rooms;
|
|
360
|
+
this.maxLoadAhead = ahead;
|
|
361
|
+
this.maxLoadBehind = behind;
|
|
362
|
+
this.maxConcurrent = maxConcurrent;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
begin() {
|
|
366
|
+
if (this._isRunning) return;
|
|
367
|
+
if (debug) console.log("Preload begin")
|
|
368
|
+
this._isRunning = true;
|
|
369
|
+
let lastRoom: number = -1;
|
|
370
|
+
let searchDistance: number;
|
|
371
|
+
let searchCall: number;
|
|
372
|
+
const array = this._rooms.scenes;
|
|
373
|
+
let interval = setInterval(() => {
|
|
374
|
+
if (this.allLoaded()) {
|
|
375
|
+
if (debug)
|
|
376
|
+
console.log("All scenes loaded");
|
|
377
|
+
this.stop();
|
|
378
|
+
}
|
|
379
|
+
if (!this._isRunning) {
|
|
380
|
+
clearInterval(interval);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (this.canLoadNewScene() === false) return;
|
|
384
|
+
if (lastRoom !== this._rooms.currentIndex) {
|
|
385
|
+
lastRoom = this._rooms.currentIndex;
|
|
386
|
+
searchCall = 0;
|
|
387
|
+
searchDistance = 0;
|
|
388
|
+
}
|
|
389
|
+
const searchForward = searchCall % 2 === 0;
|
|
390
|
+
if (searchForward) searchDistance += 1;
|
|
391
|
+
searchCall += 1;
|
|
392
|
+
const maxSearchDistance = searchForward ? this.maxLoadAhead : this.maxLoadBehind;
|
|
393
|
+
if (searchDistance > maxSearchDistance) return;
|
|
394
|
+
let roomIndex = searchForward ? lastRoom + searchDistance : lastRoom - searchDistance;
|
|
395
|
+
if (roomIndex < 0) return;
|
|
396
|
+
// if (roomIndex < 0) roomIndex = array.length + roomIndex;
|
|
397
|
+
if (roomIndex < 0 || roomIndex >= array.length) return;
|
|
398
|
+
const scene = array[roomIndex];
|
|
399
|
+
new LoadTask(roomIndex, scene, this._roomTasks);
|
|
400
|
+
}, 200);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
stop() {
|
|
404
|
+
this._isRunning = false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
canLoadNewScene(): boolean {
|
|
408
|
+
return this._roomTasks.length < this._maxConcurrentLoads;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
allLoaded(): boolean {
|
|
412
|
+
for (const room of this._rooms.scenes) {
|
|
413
|
+
if (room.isLoaded() === false) return false;
|
|
414
|
+
}
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
class LoadTask {
|
|
420
|
+
|
|
421
|
+
index: number;
|
|
422
|
+
asset: AssetReference;
|
|
423
|
+
tasks: LoadTask[];
|
|
424
|
+
|
|
425
|
+
constructor(index: number, asset: AssetReference, tasks: LoadTask[]) {
|
|
426
|
+
this.index = index;
|
|
427
|
+
this.asset = asset;
|
|
428
|
+
this.tasks = tasks;
|
|
429
|
+
tasks.push(this);
|
|
430
|
+
this.awaitLoading();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private async awaitLoading() {
|
|
434
|
+
if (!this.asset.isLoaded()) {
|
|
435
|
+
if (debug)
|
|
436
|
+
console.log("Preload start: " + this.asset.uri, this.index);
|
|
437
|
+
await this.asset.preload();
|
|
438
|
+
if (debug)
|
|
439
|
+
console.log("Preload finished: " + this.asset.uri, this.index);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const i = this.tasks.indexOf(this);
|
|
443
|
+
if (i >= 0) this.tasks.splice(i, 1);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
@@ -12,6 +12,7 @@ export { Animator } from "../Animator";
|
|
|
12
12
|
export { AnimatorController } from "../AnimatorController";
|
|
13
13
|
export { Antialiasing } from "../postprocessing/Effects/Antialiasing";
|
|
14
14
|
export { AttachedObject } from "../webxr/WebXRController";
|
|
15
|
+
export { AudioExtension } from "../export/usdz/extensions/behavior/AudioExtension";
|
|
15
16
|
export { AudioListener } from "../AudioListener";
|
|
16
17
|
export { AudioSource } from "../AudioSource";
|
|
17
18
|
export { AudioTrackHandler } from "../timeline/TimelineTracks";
|
|
@@ -114,6 +115,7 @@ export { ParticleSystemRenderer } from "../ParticleSystem";
|
|
|
114
115
|
export { PixelationEffect } from "../postprocessing/Effects/Pixelation";
|
|
115
116
|
export { PlayableDirector } from "../timeline/PlayableDirector";
|
|
116
117
|
export { PlayAnimationOnClick } from "../export/usdz/extensions/behavior/BehaviourComponents";
|
|
118
|
+
export { PlayAudioOnClick } from "../export/usdz/extensions/behavior/BehaviourComponents";
|
|
117
119
|
export { PlayerColor } from "../PlayerColor";
|
|
118
120
|
export { PointerEventData } from "../ui/PointerEvents";
|
|
119
121
|
export { PostProcessingHandler } from "../postprocessing/PostProcessingHandler";
|
|
@@ -179,7 +181,6 @@ export { TriggerModel } from "../export/usdz/extensions/behavior/BehavioursBuild
|
|
|
179
181
|
export { UIRaycastUtils } from "../ui/RaycastUtils";
|
|
180
182
|
export { UIRootComponent } from "../ui/BaseUIComponent";
|
|
181
183
|
export { UsageMarker } from "../Interactable";
|
|
182
|
-
export { USDZBehaviours } from "../export/usdz/extensions/behavior/Behaviour";
|
|
183
184
|
export { USDZExporter } from "../export/usdz/USDZExporter";
|
|
184
185
|
export { USDZText } from "../export/usdz/extensions/USDZText";
|
|
185
186
|
export { VariantAction } from "../export/usdz/extensions/behavior/Actions";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { USDObject } from "./ThreeUSDZExporter";
|
|
1
|
+
import { USDObject, USDZExporterContext } from "./ThreeUSDZExporter";
|
|
2
|
+
import { Object3D } from "three";
|
|
2
3
|
|
|
3
4
|
export interface IUSDExporterExtension {
|
|
4
5
|
|
|
5
6
|
get extensionName(): string;
|
|
6
7
|
onBeforeBuildDocument?(context);
|
|
7
8
|
onAfterBuildDocument?(context);
|
|
8
|
-
onExportObject?(object, model : USDObject, context);
|
|
9
|
+
onExportObject?(object: Object3D, model : USDObject, context: USDZExporterContext);
|
|
9
10
|
onAfterSerialize?(context);
|
|
10
11
|
onAfterHierarchy?(context, writer : any);
|
|
11
12
|
}
|