@needle-tools/engine 4.4.6-beta.5 → 4.5.0-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 +5 -1
- package/dist/{needle-engine.bundle-b88a74b7.light.umd.cjs → needle-engine.bundle-032ef70a.light.umd.cjs} +137 -137
- package/dist/{needle-engine.bundle-44ccb388.min.js → needle-engine.bundle-19ca6713.min.js} +158 -158
- package/dist/{needle-engine.bundle-0e0a2f91.umd.cjs → needle-engine.bundle-8bee539f.umd.cjs} +146 -146
- package/dist/{needle-engine.bundle-2a735987.js → needle-engine.bundle-916d62ca.js} +2993 -2961
- package/dist/{needle-engine.bundle-99f00c44.light.js → needle-engine.bundle-a2aadea9.light.js} +2993 -2961
- package/dist/{needle-engine.bundle-d8024eb1.light.min.js → needle-engine.bundle-ff2e699c.light.min.js} +158 -158
- package/dist/needle-engine.js +538 -539
- package/dist/needle-engine.light.js +538 -539
- package/dist/needle-engine.light.min.js +1 -1
- package/dist/needle-engine.light.umd.cjs +1 -1
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +4 -4
- package/lib/engine/api.js +4 -4
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_application.d.ts +5 -0
- package/lib/engine/engine_application.js +11 -11
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_context.js +9 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_lifecycle_api.d.ts +2 -1
- package/lib/engine/engine_lifecycle_api.js +2 -1
- package/lib/engine/engine_lifecycle_api.js.map +1 -1
- package/lib/engine/webcomponents/buttons.d.ts +15 -3
- package/lib/engine/webcomponents/buttons.js +32 -6
- package/lib/engine/webcomponents/buttons.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.d.ts +21 -0
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +167 -0
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.attributes.d.ts +72 -0
- package/lib/engine/webcomponents/needle-engine.attributes.js +2 -0
- package/lib/engine/webcomponents/needle-engine.attributes.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.d.ts +113 -0
- package/lib/engine/webcomponents/needle-engine.extras.d.ts +6 -0
- package/lib/engine/webcomponents/needle-engine.extras.js +14 -0
- package/lib/engine/webcomponents/needle-engine.extras.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.js +832 -0
- package/lib/engine/webcomponents/needle-engine.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +44 -0
- package/lib/engine/webcomponents/needle-engine.loading.js +350 -0
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -0
- package/lib/engine/xr/NeedleXRSession.js +21 -0
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +1 -1
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/Skybox.js +1 -1
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +1 -0
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/needle-engine.d.ts +1 -1
- package/lib/needle-engine.js +1 -1
- package/lib/needle-engine.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/api.ts +4 -4
- package/src/engine/engine_application.ts +11 -11
- package/src/engine/engine_context.ts +11 -2
- package/src/engine/engine_lifecycle_api.ts +2 -1
- package/src/engine/webcomponents/buttons.ts +37 -8
- package/src/engine/{engine_element_overlay.ts → webcomponents/needle-engine.ar-overlay.ts} +2 -2
- package/src/engine/{engine_element_extras.ts → webcomponents/needle-engine.extras.ts} +1 -1
- package/src/engine/{engine_element_loading.ts → webcomponents/needle-engine.loading.ts} +6 -6
- package/src/engine/{engine_element.ts → webcomponents/needle-engine.ts} +15 -16
- package/src/engine/xr/NeedleXRSession.ts +26 -2
- package/src/engine-components/CameraUtils.ts +1 -1
- package/src/engine-components/SceneSwitcher.ts +1 -1
- package/src/engine-components/Skybox.ts +1 -1
- package/src/engine-components/ui/EventSystem.ts +1 -0
- package/src/needle-engine.ts +1 -1
- /package/src/engine/{engine_element_attributes.ts → webcomponents/needle-engine.attributes.ts} +0 -0
package/lib/needle-engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"needle-engine.js","sourceRoot":"","sources":["../src/needle-engine.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"needle-engine.js","sourceRoot":"","sources":["../src/needle-engine.ts"],"names":[],"mappings":"AAAA,OAAO,yCAAyC,CAAC;AACjD,OAAO,0BAA0B,CAAC;AAClC,OAAO,0BAA0B,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,yBAAyB,CAAC;AAExC,0CAA0C;AAC1C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACpK,MAAM,MAAM,GAAG;IACX,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAChB,eAAe,EAAE,eAAe;IAChC,MAAM,EAAE;QACJ,WAAW,EAAE,SAAS;KACzB;IACD,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,QAAQ;IAClB,cAAc,EAAE,cAAc;IAC9B,aAAa,EAAE,aAAa;IAC5B,oBAAoB,EAAE,aAAa;IACnC,gBAAgB,EAAE,SAAS;IAC3B,cAAc,EAAE,OAAO;CAC1B,CAAC;AACF,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,SAAS,EAAE;IAC7C,OAAO,CAAC,IAAI,CAAC,sCAAsC,UAAU,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;CACtF;AACD,SAAS,cAAc,CAAC,GAAW;IAC/B,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;QACnB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;KAC1B;AACL,CAAC;AACD,OAAO,KAAK,SAAS,MAAM,kCAAkC,CAAC;AAC9D,cAAc,CAAC,SAAS,CAAC,CAAC;AAE1B,OAAO,KAAK,UAAU,MAAM,2CAA2C,CAAC;AACxE,cAAc,CAAC,UAAU,CAAC,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE;IACzD,QAAQ,MAAM,EAAE;QACZ,KAAK,WAAW,CAAC;QACjB,KAAK,aAAa,CAAC;QACnB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM;YACP,SAAS;QACb;YACI,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM;KACb;CACJ;AAED,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;IACvB,UAAU,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;CACjC;KACI;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;QACtB,UAAU,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;KAC3C;CACJ;AAGD,wBAAwB;AACxB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;IACtB,UAAU,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;CAC/B;;IACI,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0-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.min.js",
|
|
6
6
|
"exports": {
|
package/src/engine/api.ts
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
export * from "./debug/index.js";
|
|
23
23
|
export * from "./engine_addressables.js";
|
|
24
24
|
export { AnimationUtils } from "./engine_animation.js";
|
|
25
|
-
export
|
|
25
|
+
export { Application } from "./engine_application.js";
|
|
26
26
|
export * from "./engine_assetdatabase.js";
|
|
27
27
|
export { getCameraController, setAutoFitEnabled, setCameraController, useForAutoFit } from "./engine_camera.js"
|
|
28
28
|
export * from "./engine_components.js";
|
|
@@ -33,9 +33,6 @@ export * from "./engine_context.js";
|
|
|
33
33
|
export * from "./engine_context_registry.js";
|
|
34
34
|
export * from "./engine_coroutine.js"
|
|
35
35
|
export * from "./engine_create_objects.js";
|
|
36
|
-
export * from "./engine_element.js";
|
|
37
|
-
export * from "./engine_element_attributes.js";
|
|
38
|
-
export * from "./engine_element_loading.js";
|
|
39
36
|
export * from "./engine_gameobject.js";
|
|
40
37
|
export { Gizmos } from "./engine_gizmos.js"
|
|
41
38
|
export * from "./engine_gltf.js";
|
|
@@ -79,4 +76,7 @@ export * from "./export/index.js";
|
|
|
79
76
|
export * from "./extensions/index.js";
|
|
80
77
|
export * from "./js-extensions/index.js";
|
|
81
78
|
export * from "./webcomponents/api.js"
|
|
79
|
+
export * from "./webcomponents/needle-engine.attributes.js";
|
|
80
|
+
export * from "./webcomponents/needle-engine.js";
|
|
81
|
+
export * from "./webcomponents/needle-engine.loading.js";
|
|
82
82
|
export * from "./xr/api.js"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isDevEnvironment } from "./debug/index.js";
|
|
2
2
|
import { Context } from "./engine_setup.js";
|
|
3
|
-
import { NeedleXRSession } from "./engine_xr.js";
|
|
4
3
|
|
|
5
4
|
export enum ApplicationEvents {
|
|
6
5
|
Visible = "application-visible",
|
|
@@ -10,7 +9,11 @@ export enum ApplicationEvents {
|
|
|
10
9
|
|
|
11
10
|
let userInteractionRegistered = false;
|
|
12
11
|
const userInteractionCallbacks: Function[] = [];
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Invoked when the user interacts with the page (click, touch, keypress, etc) allowing to play media / audio / start XR
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function internalOnUserInputRegistered() {
|
|
14
17
|
if (userInteractionRegistered) return;
|
|
15
18
|
if (isDevEnvironment()) console.debug("User interaction registered: audio can now be played");
|
|
16
19
|
userInteractionRegistered = true;
|
|
@@ -18,15 +21,12 @@ function onUserInteraction() {
|
|
|
18
21
|
userInteractionCallbacks.length = 0;
|
|
19
22
|
copy.forEach(cb => cb());
|
|
20
23
|
}
|
|
21
|
-
document.addEventListener('mousedown',
|
|
22
|
-
document.addEventListener('pointerup',
|
|
23
|
-
document.addEventListener('click',
|
|
24
|
-
document.addEventListener('dragstart',
|
|
25
|
-
document.addEventListener('touchend',
|
|
26
|
-
document.addEventListener('keydown',
|
|
27
|
-
NeedleXRSession.onXRSessionStart(() => {
|
|
28
|
-
onUserInteraction();
|
|
29
|
-
})
|
|
24
|
+
document.addEventListener('mousedown', internalOnUserInputRegistered);
|
|
25
|
+
document.addEventListener('pointerup', internalOnUserInputRegistered);
|
|
26
|
+
document.addEventListener('click', internalOnUserInputRegistered);
|
|
27
|
+
document.addEventListener('dragstart', internalOnUserInputRegistered);
|
|
28
|
+
document.addEventListener('touchend', internalOnUserInputRegistered);
|
|
29
|
+
document.addEventListener('keydown', internalOnUserInputRegistered);
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* The Application class can be used to mute audio globally, and to check if the application (canvas) is currently visible (it's tab is active and not minimized).
|
|
@@ -1019,12 +1019,21 @@ export class Context implements IContext {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
|
|
1021
1021
|
this.clear();
|
|
1022
|
+
|
|
1023
|
+
const oldRenderer = this.renderer;
|
|
1024
|
+
// We only need to create a new renderer if we don't have one yet
|
|
1025
|
+
// We do prevent creating a new renderer here to avoid flickering when the context is created while the content is still being loaded. This can be the case where CSS transformations update the layout (e.g. scale() while loading + old canvas disposed but in the DOM layout.)
|
|
1026
|
+
const needsNewRenderer = !oldRenderer || oldRenderer["isDisposed"] === true;
|
|
1027
|
+
|
|
1022
1028
|
// stop the animation loop if its running during creation
|
|
1023
1029
|
// since we do not want to start enabling scripts etc before they are deserialized
|
|
1024
|
-
if (this.isManagedExternally === false) {
|
|
1030
|
+
if (this.isManagedExternally === false && (needsNewRenderer)) {
|
|
1025
1031
|
this.createNewRenderer();
|
|
1026
|
-
this.renderer?.setAnimationLoop(null);
|
|
1027
1032
|
}
|
|
1033
|
+
else {
|
|
1034
|
+
this.lodsManager.setRenderer(this.renderer);
|
|
1035
|
+
}
|
|
1036
|
+
this.renderer?.setAnimationLoop(null);
|
|
1028
1037
|
|
|
1029
1038
|
await delay(1);
|
|
1030
1039
|
|
|
@@ -38,7 +38,8 @@ export function onDestroy(cb: LifecycleMethod, opts?: LifecycleMethodOptions): (
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/** Register a callback in the engine start event.
|
|
41
|
-
* This happens at the beginning of
|
|
41
|
+
* This happens once at the beginning of a frame
|
|
42
|
+
* (e.g. once when the method is registered, after <needle-engine> is created or the src has changed)
|
|
42
43
|
* @param cb The callback to be called. Optionally return a function that will be called when the onStart callback is removed again
|
|
43
44
|
* @returns A function that can be called to unregister the callback
|
|
44
45
|
* @example
|
|
@@ -4,14 +4,26 @@ import { generateQRCode, isMobileDevice } from "../engine_utils.js";
|
|
|
4
4
|
import { onXRSessionEnd, onXRSessionStart } from "../xr/events.js";
|
|
5
5
|
import { getIconElement } from "./icons.js";
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
*
|
|
7
|
+
/**
|
|
8
|
+
* Use the ButtonsFactory to create buttons with icons and functionality
|
|
9
|
+
* Get access to the default buttons by using `ButtonsFactory.instance`
|
|
9
10
|
* The factory will create the buttons if they don't exist yet, and return the existing ones if they do (this allows you to reparent or modify created buttons)
|
|
10
11
|
*/
|
|
11
12
|
export class ButtonsFactory {
|
|
12
13
|
|
|
13
14
|
private static _instance?: ButtonsFactory;
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get access to the default HTML button factory.
|
|
18
|
+
* Use this to get or create default Needle Engine buttons that can be added to your HTML UI
|
|
19
|
+
* If you want to create a new factory and create new button instances instead of shared buttons, use `ButtonsFactory.create()` instead
|
|
20
|
+
*/
|
|
21
|
+
static get instance() {
|
|
22
|
+
return this.getOrCreate();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get access to the default HTML button factory.
|
|
15
27
|
* Use this to get or create default Needle Engine buttons that can be added to your HTML UI
|
|
16
28
|
* If you want to create a new factory and create new button instances instead of shared buttons, use `ButtonsFactory.create()` instead
|
|
17
29
|
*/
|
|
@@ -37,7 +49,7 @@ export class ButtonsFactory {
|
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
/** Create a fullscreen button (or return the existing one if it already exists) */
|
|
40
|
-
createFullscreenButton(ctx: IContext)
|
|
52
|
+
createFullscreenButton(ctx: IContext): HTMLButtonElement | null {
|
|
41
53
|
if (this._fullscreenButton) {
|
|
42
54
|
return this._fullscreenButton;
|
|
43
55
|
}
|
|
@@ -59,7 +71,7 @@ export class ButtonsFactory {
|
|
|
59
71
|
if (document.fullscreenElement) {
|
|
60
72
|
document.exitFullscreen();
|
|
61
73
|
} else {
|
|
62
|
-
if("webkitRequestFullscreen" in ctx.domElement && typeof ctx.domElement["webkitRequestFullscreen"] === "function")
|
|
74
|
+
if ("webkitRequestFullscreen" in ctx.domElement && typeof ctx.domElement["webkitRequestFullscreen"] === "function")
|
|
63
75
|
ctx.domElement["webkitRequestFullscreen"]();
|
|
64
76
|
else if ("requestFullscreen" in ctx.domElement)
|
|
65
77
|
ctx.domElement.requestFullscreen();
|
|
@@ -141,6 +153,22 @@ export class ButtonsFactory {
|
|
|
141
153
|
*/
|
|
142
154
|
get qrButton() { return this._qrButton; }
|
|
143
155
|
|
|
156
|
+
private _customQRButtonUrl: string | undefined;
|
|
157
|
+
|
|
158
|
+
/** Get or set the QR code button URL - this URL will open when scanning the QR code */
|
|
159
|
+
set qrButtonUrl(url: string) {
|
|
160
|
+
// make sure it's a URL
|
|
161
|
+
try {
|
|
162
|
+
new URL(url);
|
|
163
|
+
this._customQRButtonUrl = url;
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.warn(`[Needle] QR code button URL is not a valid URL '${url}'`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
get qrButtonUrl() {
|
|
169
|
+
return this._customQRButtonUrl || window.location.href;
|
|
170
|
+
}
|
|
171
|
+
|
|
144
172
|
/** Create a QR code button (or return the existing one if it already exists)
|
|
145
173
|
* The QR code button will show a QR code that can be scanned to open the current page on a phone
|
|
146
174
|
* The QR code will be generated with the current URL when the button is clicked
|
|
@@ -150,6 +178,7 @@ export class ButtonsFactory {
|
|
|
150
178
|
|
|
151
179
|
if (this._qrButton) return this._qrButton;
|
|
152
180
|
|
|
181
|
+
const instance = this;
|
|
153
182
|
const qrCodeButton = document.createElement("button");
|
|
154
183
|
this._qrButton = qrCodeButton;
|
|
155
184
|
qrCodeButton.innerText = "QR Code";
|
|
@@ -175,8 +204,8 @@ export class ButtonsFactory {
|
|
|
175
204
|
|
|
176
205
|
qrCodeButton.addEventListener("click", () => {
|
|
177
206
|
if (qrCodeContainer.parentNode) return hideQRCode();
|
|
178
|
-
if (window.location.href.includes("://localhost")) {
|
|
179
|
-
showBalloonWarning("To access your website from another device in the same local network you have to use the IP address instead of localhost.");
|
|
207
|
+
if (isDevEnvironment() && window.location.href.includes("://localhost")) {
|
|
208
|
+
showBalloonWarning("To access your website from another device in the same local network you have to use the IP address instead of localhost. The IP address is logged in your development server console when you start the server.");
|
|
180
209
|
}
|
|
181
210
|
showQRCode();
|
|
182
211
|
});
|
|
@@ -233,7 +262,7 @@ export class ButtonsFactory {
|
|
|
233
262
|
async function generateAndInsertQRCode() {
|
|
234
263
|
const size = 200;
|
|
235
264
|
const code = await generateQRCode({
|
|
236
|
-
text:
|
|
265
|
+
text: instance.qrButtonUrl,
|
|
237
266
|
width: size,
|
|
238
267
|
height: size,
|
|
239
268
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Context } from "
|
|
2
|
-
import { DeviceUtilities,getParam } from "
|
|
1
|
+
import { Context } from "../engine_setup.js";
|
|
2
|
+
import { DeviceUtilities,getParam } from "../engine_utils.js";
|
|
3
3
|
|
|
4
4
|
const debug = getParam("debugoverlay");
|
|
5
5
|
export const arContainerClassName = "ar";
|
|
@@ -10,7 +10,7 @@ DO NOT IMPORT ENGINE_ELEMENT FROM HERE
|
|
|
10
10
|
* Use the addAttributeChangeCallback utility methods to register callback events
|
|
11
11
|
*/
|
|
12
12
|
export async function registerObservableAttribute(name: string) {
|
|
13
|
-
const { NeedleEngineHTMLElement } = await import("./
|
|
13
|
+
const { NeedleEngineHTMLElement } = await import("./needle-engine.js");
|
|
14
14
|
if (!NeedleEngineHTMLElement.observedAttributes.includes(name))
|
|
15
15
|
NeedleEngineHTMLElement.observedAttributes.push(name);
|
|
16
16
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { needleLogoOnlySVG } from "
|
|
2
|
-
import { isDevEnvironment, showBalloonWarning } from "
|
|
3
|
-
import { hasCommercialLicense, hasProLicense, runtimeLicenseCheckPromise } from "
|
|
4
|
-
import { Mathf } from "
|
|
5
|
-
import { LoadingProgressArgs } from "
|
|
6
|
-
import { getParam } from "
|
|
1
|
+
import { needleLogoOnlySVG } from "../assets/index.js"
|
|
2
|
+
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
3
|
+
import { hasCommercialLicense, hasProLicense, runtimeLicenseCheckPromise } from "../engine_license.js";
|
|
4
|
+
import { Mathf } from "../engine_math.js";
|
|
5
|
+
import { LoadingProgressArgs } from "../engine_setup.js";
|
|
6
|
+
import { getParam } from "../engine_utils.js";
|
|
7
7
|
|
|
8
8
|
const debug = getParam("debugloading");
|
|
9
9
|
const debugRendering = getParam("debugloadingrendering");
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { AgXToneMapping, Color, LinearToneMapping, NeutralToneMapping, NoToneMapping } from "three";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
//
|
|
3
|
+
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
4
|
+
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
5
|
+
import { registerLoader } from "../engine_gltf.js";
|
|
6
|
+
import { hasCommercialLicense } from "../engine_license.js";
|
|
7
|
+
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.js";
|
|
8
|
+
import { NeedleLoader } from "../engine_scenetools.js";
|
|
9
|
+
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
10
|
+
import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
|
|
11
|
+
import { getParam } from "../engine_utils.js";
|
|
12
|
+
import { RGBAColor } from "../js-extensions/RGBAColor.js";
|
|
13
|
+
import { ensureFonts } from "./fonts.js";
|
|
14
|
+
import { arContainerClassName, AROverlayHandler } from "./needle-engine.ar-overlay.js";
|
|
15
|
+
import { NeedleEngineAttributes, TonemappingAttributeOptions } from "./needle-engine.attributes.js";
|
|
16
|
+
import { calculateProgress01, EngineLoadingView, type ILoadingViewHandler } from "./needle-engine.loading.js";
|
|
17
|
+
|
|
19
18
|
// registering loader here too to make sure it's imported when using engine via vanilla js
|
|
20
19
|
registerLoader(NeedleLoader);
|
|
21
20
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Camera, Object3D, PerspectiveCamera, Quaternion, Vector3 } from "three";
|
|
2
2
|
|
|
3
3
|
import { enableSpatialConsole, isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../debug/index.js";
|
|
4
|
+
import { Application, internalOnUserInputRegistered } from "../engine_application.js";
|
|
4
5
|
import { Context, FrameEvent } from "../engine_context.js";
|
|
5
6
|
import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
|
|
6
7
|
import { isDestroyed } from "../engine_gameobject.js";
|
|
@@ -161,8 +162,11 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, async cb =>
|
|
|
161
162
|
});
|
|
162
163
|
ContextRegistry.registerCallback(ContextEvent.ContextCreated, async cb => {
|
|
163
164
|
contexts_loading.delete(cb.context);
|
|
165
|
+
const autostart = cb.context?.domElement.getAttribute("autostart") || null;
|
|
166
|
+
handleAutoStart(autostart);
|
|
164
167
|
});
|
|
165
168
|
|
|
169
|
+
|
|
166
170
|
function contextIsLoading() { return contexts_loading.size > 0; }
|
|
167
171
|
function waitForContextLoadingFinished(): Promise<void> {
|
|
168
172
|
return new Promise(res => {
|
|
@@ -187,6 +191,18 @@ if (DeviceUtilities.isDesktop() && isDevEnvironment()) {
|
|
|
187
191
|
});
|
|
188
192
|
}
|
|
189
193
|
|
|
194
|
+
function handleAutoStart(value: string | null) {
|
|
195
|
+
if (!value) return;
|
|
196
|
+
switch (value?.toLowerCase()) {
|
|
197
|
+
case "ar":
|
|
198
|
+
Application.registerWaitForInteraction(() => {
|
|
199
|
+
// TODO: move WebARSessionRoot to core
|
|
200
|
+
NeedleXRSession.start("ar");
|
|
201
|
+
})
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
190
206
|
// if (getParam("simulatewebxrloading")) {
|
|
191
207
|
// ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, async _cb => {
|
|
192
208
|
// await delay(3000);
|
|
@@ -375,7 +391,7 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
375
391
|
case "immersive-ar":
|
|
376
392
|
const arFeatures = ['anchors', 'local-floor', 'layers', 'dom-overlay', 'hit-test', 'unbounded'];
|
|
377
393
|
// Don't request handtracking by default on VisionOS
|
|
378
|
-
if (!DeviceUtilities.isVisionOS())
|
|
394
|
+
if (!DeviceUtilities.isVisionOS())
|
|
379
395
|
arFeatures.push('hand-tracking');
|
|
380
396
|
return {
|
|
381
397
|
optionalFeatures: arFeatures,
|
|
@@ -701,6 +717,11 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
701
717
|
*
|
|
702
718
|
*/
|
|
703
719
|
get rigScale() {
|
|
720
|
+
// const ar_scaleValue = this.context.domElement.getAttribute("ar-scale");
|
|
721
|
+
// if (ar_scaleValue) {
|
|
722
|
+
// const scale = parseFloat(ar_scaleValue);
|
|
723
|
+
// if (!isNaN(scale)) return scale;
|
|
724
|
+
// }
|
|
704
725
|
if (!this._rigs[0]) return 1;
|
|
705
726
|
if (this._lastRigScaleUpdate !== this.context.time.frame) {
|
|
706
727
|
this._lastRigScaleUpdate = this.context.time.frame;
|
|
@@ -708,6 +729,7 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
708
729
|
}
|
|
709
730
|
return this._rigScale;
|
|
710
731
|
}
|
|
732
|
+
|
|
711
733
|
/** add a rig to the available XR rigs - if it's priority is higher than the currently active rig it will be enabled */
|
|
712
734
|
addRig(rig: IXRRig) {
|
|
713
735
|
const i = this._rigs.indexOf(rig);
|
|
@@ -1004,7 +1026,7 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1004
1026
|
console.debug("Controller already exists for input source", index);
|
|
1005
1027
|
return;
|
|
1006
1028
|
}
|
|
1007
|
-
else if(this._newControllers.find(c => c.inputSource === newInputSource)) {
|
|
1029
|
+
else if (this._newControllers.find(c => c.inputSource === newInputSource)) {
|
|
1008
1030
|
console.debug("Controller already registered for input source", index);
|
|
1009
1031
|
return;
|
|
1010
1032
|
}
|
|
@@ -1197,6 +1219,8 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1197
1219
|
|
|
1198
1220
|
invokeXRSessionStart({ session: this });
|
|
1199
1221
|
|
|
1222
|
+
internalOnUserInputRegistered();
|
|
1223
|
+
|
|
1200
1224
|
for (const listener of NeedleXRSession._xrStartListeners) {
|
|
1201
1225
|
listener(args);
|
|
1202
1226
|
}
|
|
@@ -4,9 +4,9 @@ import { getCameraController } from "../engine/engine_camera.js";
|
|
|
4
4
|
import { addNewComponent, getOrAddComponent } from "../engine/engine_components.js";
|
|
5
5
|
import { Context } from "../engine/engine_context.js";
|
|
6
6
|
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
|
|
7
|
-
import { NeedleEngineHTMLElement } from "../engine/engine_element.js";
|
|
8
7
|
import type { ICamera, IContext } from "../engine/engine_types.js";
|
|
9
8
|
import { getParam } from "../engine/engine_utils.js";
|
|
9
|
+
import { NeedleEngineHTMLElement } from "../engine/webcomponents/needle-engine.js";
|
|
10
10
|
import { Camera, ClearFlags } from "./Camera.js";
|
|
11
11
|
import { OrbitControls } from "./OrbitControls.js";
|
|
12
12
|
import { EnvironmentScene } from "./utils/EnvironmentScene.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { EquirectangularReflectionMapping, Object3D, Scene, Texture } from "three";
|
|
2
2
|
|
|
3
3
|
import { AssetReference } from "../engine/engine_addressables.js";
|
|
4
|
-
import { registerObservableAttribute } from "../engine/engine_element_extras.js";
|
|
5
4
|
import { destroy } from "../engine/engine_gameobject.js";
|
|
6
5
|
import { InputEvents } from "../engine/engine_input.js";
|
|
7
6
|
import { isLocalNetwork } from "../engine/engine_networking_utils.js";
|
|
8
7
|
import { serializable } from "../engine/engine_serialization.js";
|
|
9
8
|
import { getParam, setParamWithoutReload } from "../engine/engine_utils.js";
|
|
9
|
+
import { registerObservableAttribute } from "../engine/webcomponents/needle-engine.extras.js";
|
|
10
10
|
import { Behaviour, GameObject } from "./Component.js";
|
|
11
11
|
import { EventList } from "./EventList.js";
|
|
12
12
|
|
|
@@ -6,11 +6,11 @@ import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
|
|
|
6
6
|
|
|
7
7
|
import { disposeObjectResources, setDisposable } from "../engine/engine_assetdatabase.js";
|
|
8
8
|
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
|
|
9
|
-
import { registerObservableAttribute } from "../engine/engine_element_extras.js";
|
|
10
9
|
import { syncField } from "../engine/engine_networking_auto.js";
|
|
11
10
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
|
12
11
|
import { type IContext } from "../engine/engine_types.js";
|
|
13
12
|
import { addAttributeChangeCallback, getParam, PromiseAllWithErrors, removeAttributeChangeCallback } from "../engine/engine_utils.js";
|
|
13
|
+
import { registerObservableAttribute } from "../engine/webcomponents/needle-engine.extras.js";
|
|
14
14
|
import { Camera, ClearFlags } from "./Camera.js";
|
|
15
15
|
import { Behaviour, GameObject } from "./Component.js";
|
|
16
16
|
|
|
@@ -86,6 +86,7 @@ export class EventSystem extends Behaviour {
|
|
|
86
86
|
// We only want ONE eventsystem on the root scene
|
|
87
87
|
// as long as this component is not implemented in core we need to check this here
|
|
88
88
|
if (this.gameObject as Object3D !== this.context.scene) {
|
|
89
|
+
console.debug(`[Needle Engine] EventSystem is only allowed on the scene root. Disabling EventSystem on '${this.gameObject.name}'`);
|
|
89
90
|
this.enabled = false;
|
|
90
91
|
}
|
|
91
92
|
}
|
package/src/needle-engine.ts
CHANGED
/package/src/engine/{engine_element_attributes.ts → webcomponents/needle-engine.attributes.ts}
RENAMED
|
File without changes
|