@needle-tools/engine 4.15.0-next.cecd8e7 → 4.15.0-next.f391a30
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/components.needle.json +1 -1
- package/dist/{gltf-progressive-BttGBXw6.umd.cjs → gltf-progressive-CMwJPwEt.umd.cjs} +1 -1
- package/dist/{gltf-progressive-Bm_6aEi4.js → gltf-progressive-CTlvpS3A.js} +1 -1
- package/dist/{gltf-progressive-T5WKTux5.min.js → gltf-progressive-DYL3SLVb.min.js} +1 -1
- package/dist/materialx-4jJLLe9Q.js +4174 -0
- package/dist/materialx-Bt9FHwco.min.js +158 -0
- package/dist/materialx-NDD0y4JY.umd.cjs +158 -0
- package/dist/{needle-engine.bundle-JQGIFVRm.umd.cjs → needle-engine.bundle-C1BFRZDF.umd.cjs} +103 -101
- package/dist/{needle-engine.bundle-VZVrVbc3.js → needle-engine.bundle-DB4kLWO_.js} +2829 -2823
- package/dist/{needle-engine.bundle-CuAiLb-d.min.js → needle-engine.bundle-DsTdfmeb.min.js} +115 -113
- package/dist/needle-engine.d.ts +27 -46
- package/dist/needle-engine.js +287 -288
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-06AXuvdv.min.js → postprocessing-BN-f4viE.min.js} +1 -1
- package/dist/{postprocessing-CPDcA21P.umd.cjs → postprocessing-DYmYOVm4.umd.cjs} +1 -1
- package/dist/{postprocessing-CI2x8Cln.js → postprocessing-De9ZpJrk.js} +1 -1
- package/dist/{three-examples-BMmNgNCN.umd.cjs → three-examples-BHqRVpO_.umd.cjs} +12 -12
- package/dist/{three-examples-CMYCd5nH.js → three-examples-C0ZCCA_K.js} +182 -192
- package/dist/{three-examples-CQl1fFZp.min.js → three-examples-DmTY8tGr.min.js} +14 -14
- package/lib/engine/api.d.ts +0 -2
- package/lib/engine/api.js +0 -2
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug.js +1 -1
- package/lib/engine/debug/debug.js.map +1 -1
- package/lib/engine/debug/debug_spatial_console.js +1 -1
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_context.js +1 -1
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_create_objects.js +1 -1
- package/lib/engine/engine_create_objects.js.map +1 -1
- package/lib/engine/engine_gizmos.js +1 -1
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_license.js +7 -2
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_utils.js +2 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/export/gltf/EXT_mesh_gpu_instancing_exporter.js.map +1 -0
- package/lib/engine/export/gltf/index.js +1 -1
- package/lib/engine/export/gltf/index.js.map +1 -1
- package/lib/engine/webcomponents/logo-element.d.ts +6 -3
- package/lib/engine/webcomponents/logo-element.js +18 -0
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
- package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +10 -7
- package/lib/engine/webcomponents/needle menu/needle-menu.js +14 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +10 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +3 -0
- package/lib/engine/webcomponents/needle-engine.js +10 -0
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/Component.js +0 -1
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +24 -2
- package/lib/engine-components/ReflectionProbe.js +27 -1
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/Skybox.js +4 -2
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js +1 -1
- package/lib/engine-components/export/gltf/GltfExport.js.map +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +2 -2
- package/lib/engine-components/export/usdz/USDZExporter.js +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js +2 -2
- package/lib/engine-components/export/usdz/extensions/behavior/PhysicsExtension.js.map +1 -1
- package/package.json +17 -13
- package/plugins/common/buildinfo.js +46 -10
- package/plugins/common/files.js +2 -1
- package/plugins/common/license.js +144 -69
- package/plugins/common/logger.js +172 -11
- package/plugins/common/needle-engine-skill.md +175 -0
- package/plugins/common/worker.js +5 -4
- package/plugins/types/userconfig.d.ts +40 -2
- package/plugins/vite/ai.js +71 -0
- package/plugins/vite/alias.js +6 -5
- package/plugins/vite/asap.js +6 -5
- package/plugins/vite/build-pipeline.js +224 -41
- package/plugins/vite/buildinfo.js +66 -6
- package/plugins/vite/copyfiles.js +41 -12
- package/plugins/vite/custom-element-data.js +26 -16
- package/plugins/vite/defines.js +8 -5
- package/plugins/vite/dependencies.js +16 -10
- package/plugins/vite/dependency-watcher.js +35 -7
- package/plugins/vite/drop-client.js +7 -5
- package/plugins/vite/drop.js +16 -14
- package/plugins/vite/editor-connection.js +18 -16
- package/plugins/vite/imports-logger.js +12 -2
- package/plugins/vite/index.js +8 -3
- package/plugins/vite/local-files-analysis.js +789 -0
- package/plugins/vite/local-files-core.js +992 -0
- package/plugins/vite/local-files-internals.js +28 -0
- package/plugins/vite/local-files-types.d.ts +111 -0
- package/plugins/vite/local-files-utils.js +359 -0
- package/plugins/vite/local-files.js +2 -441
- package/plugins/vite/logger.client.js +45 -35
- package/plugins/vite/logger.js +6 -3
- package/plugins/vite/logging.js +129 -0
- package/plugins/vite/meta.js +18 -4
- package/plugins/vite/needle-app.js +4 -3
- package/plugins/vite/peer.js +2 -1
- package/plugins/vite/pwa.js +33 -17
- package/plugins/vite/reload.js +24 -2
- package/src/engine/api.ts +0 -3
- package/src/engine/debug/debug.ts +1 -1
- package/src/engine/debug/debug_spatial_console.ts +5 -1
- package/src/engine/engine_context.ts +1 -1
- package/src/engine/engine_create_objects.ts +1 -1
- package/src/engine/engine_gizmos.ts +9 -5
- package/src/engine/engine_license.ts +7 -2
- package/src/engine/engine_utils.ts +2 -2
- package/src/engine/export/gltf/index.ts +1 -1
- package/src/engine/webcomponents/logo-element.ts +20 -3
- package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +6 -2
- package/src/engine/webcomponents/needle menu/needle-menu.ts +23 -11
- package/src/engine/webcomponents/needle-engine.ar-overlay.ts +13 -2
- package/src/engine/webcomponents/needle-engine.ts +13 -1
- package/src/engine-components/Component.ts +1 -2
- package/src/engine-components/ReflectionProbe.ts +32 -8
- package/src/engine-components/Skybox.ts +4 -2
- package/src/engine-components/export/gltf/GltfExport.ts +1 -1
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +2 -2
- package/src/engine-components/export/usdz/USDZExporter.ts +1 -1
- package/src/engine-components/export/usdz/extensions/behavior/PhysicsExtension.ts +2 -2
- package/dist/materialx-CJyQZtjt.min.js +0 -90
- package/dist/materialx-DMs1E08Z.js +0 -4636
- package/dist/materialx-DaKKOoVk.umd.cjs +0 -90
- package/lib/engine/engine_test_utils.d.ts +0 -39
- package/lib/engine/engine_test_utils.js +0 -84
- package/lib/engine/engine_test_utils.js.map +0 -1
- package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +0 -1
- package/src/engine/engine_test_utils.ts +0 -109
- package/src/include/draco/draco_decoder.js +0 -34
- package/src/include/draco/draco_decoder.wasm +0 -0
- package/src/include/draco/draco_wasm_wrapper.js +0 -117
- package/src/include/ktx2/basis_transcoder.js +0 -19
- package/src/include/ktx2/basis_transcoder.wasm +0 -0
- package/src/include/needle/arial-msdf.json +0 -1472
- package/src/include/needle/arial.png +0 -0
- package/src/include/needle/poweredbyneedle.webp +0 -0
- /package/lib/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.d.ts +0 -0
- /package/lib/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.js +0 -0
- /package/src/{include/three → engine/export/gltf}/EXT_mesh_gpu_instancing_exporter.js +0 -0
|
@@ -607,7 +607,7 @@ export namespace DeviceUtilities {
|
|
|
607
607
|
/** @returns `true` if it's a phone or tablet */
|
|
608
608
|
export function isMobileDevice() {
|
|
609
609
|
if (_ismobile !== undefined) return _ismobile;
|
|
610
|
-
// eslint-disable-next-line
|
|
610
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
611
611
|
if ((typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1)) {
|
|
612
612
|
return _ismobile = true;
|
|
613
613
|
}
|
|
@@ -677,7 +677,7 @@ export namespace DeviceUtilities {
|
|
|
677
677
|
/** @returns `true` for mobile Apple devices like iPad, iPhone, iPod, Vision Pro, ... */
|
|
678
678
|
export function isiOS() {
|
|
679
679
|
if (__isiOS !== undefined) return __isiOS;
|
|
680
|
-
// eslint-disable-next-line
|
|
680
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
681
681
|
return __isiOS = iosDevices.includes(navigator.platform)
|
|
682
682
|
// iPad on iOS 13 detection
|
|
683
683
|
|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AnimationClip, Object3D } from "three";
|
|
2
2
|
import { GLTFExporter, GLTFExporterOptions } from "three/examples/jsm/exporters/GLTFExporter.js";
|
|
3
3
|
|
|
4
|
-
import GLTFMeshGPUInstancingExtension from "../../../include/three/EXT_mesh_gpu_instancing_exporter.js";
|
|
5
4
|
import { AnimationUtils } from "../../engine_animation.js";
|
|
6
5
|
import type { Context } from "../../engine_setup.js";
|
|
7
6
|
import { registerExportExtensions } from "../../extensions/index.js";
|
|
8
7
|
import { __isExporting } from "../state.js";
|
|
9
8
|
import { shouldExport_HideFlags } from "../utils.js";
|
|
9
|
+
import GLTFMeshGPUInstancingExtension from "./EXT_mesh_gpu_instancing_exporter.js";
|
|
10
10
|
import { GizmoWriter as GLTFGizmoWriter, RenderTextureWriter as GLTFRenderTextureWriter } from "./Writers.js";
|
|
11
11
|
|
|
12
12
|
declare type ExportOptions = {
|
|
@@ -20,8 +20,13 @@ export class NeedleLogoElement extends HTMLElement {
|
|
|
20
20
|
return document.createElement(elementName) as NeedleLogoElement;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
private _didInitialize = false;
|
|
24
|
+
|
|
23
25
|
constructor() {
|
|
24
26
|
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private initializeDom() {
|
|
25
30
|
this._root = this.attachShadow({ mode: 'closed' });
|
|
26
31
|
const template = document.createElement('template');
|
|
27
32
|
template.innerHTML = `<style>
|
|
@@ -83,25 +88,37 @@ export class NeedleLogoElement extends HTMLElement {
|
|
|
83
88
|
this.addEventListener("click", () => {
|
|
84
89
|
globalThis.open("https://needle.tools", "_blank");
|
|
85
90
|
});
|
|
91
|
+
}
|
|
86
92
|
|
|
93
|
+
ensureInitialized() {
|
|
94
|
+
if (!this._didInitialize) {
|
|
95
|
+
this._didInitialize = true;
|
|
96
|
+
this.initializeDom();
|
|
97
|
+
}
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
connectedCallback() {
|
|
101
|
+
this.ensureInitialized();
|
|
102
|
+
if (!this.wrapper) return;
|
|
90
103
|
this.wrapper.setAttribute("title", "Made with Needle Engine");
|
|
91
104
|
this.setAttribute("aria-label", "Needle Engine logo. Click to open the Needle Engine website.");
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
private
|
|
95
|
-
private
|
|
96
|
-
private
|
|
107
|
+
private _root!: ShadowRoot;
|
|
108
|
+
private wrapper!: HTMLDivElement;
|
|
109
|
+
private logoElement!: HTMLImageElement;
|
|
97
110
|
|
|
98
111
|
/** Show or hide the logo element (used by the menu) */
|
|
99
112
|
setLogoVisible(val: boolean) {
|
|
113
|
+
this.ensureInitialized();
|
|
114
|
+
if (!this.logoElement) return;
|
|
100
115
|
this.logoElement.style.display = val ? "block" : "none";
|
|
101
116
|
}
|
|
102
117
|
|
|
103
118
|
/** Switch the logo between full and compact versions */
|
|
104
119
|
setType(type: "full" | "compact") {
|
|
120
|
+
this.ensureInitialized();
|
|
121
|
+
if (!this.logoElement) return;
|
|
105
122
|
if (type === "full") {
|
|
106
123
|
this.logoElement.src = needleLogoSVG;
|
|
107
124
|
this.logoElement.classList.remove("with-text");
|
|
@@ -302,7 +302,7 @@ export class NeedleSpatialMenu {
|
|
|
302
302
|
// logoObject.position.y = 1;
|
|
303
303
|
// this._context.scene.add(logoObject);
|
|
304
304
|
const textureLoader = new TextureLoader();
|
|
305
|
-
textureLoader.load("
|
|
305
|
+
textureLoader.load("https://cdn.needle.tools/static/branding/poweredbyneedle.webp", (texture) => {
|
|
306
306
|
if (texture) {
|
|
307
307
|
onClick.allowModifyUI = false;
|
|
308
308
|
firstLabel.removeFromParent();
|
|
@@ -343,7 +343,11 @@ export class NeedleSpatialMenu {
|
|
|
343
343
|
|
|
344
344
|
if (!fontFamily) {
|
|
345
345
|
fontFamily = ThreeMeshUI.FontLibrary.addFontFamily(this.familyName);
|
|
346
|
-
const normal = fontFamily.addVariant(
|
|
346
|
+
const normal = fontFamily.addVariant(
|
|
347
|
+
"normal",
|
|
348
|
+
"normal",
|
|
349
|
+
"https://cdn.needle.tools/static/fonts/msdf/arial/arial-msdf.json",
|
|
350
|
+
"https://cdn.needle.tools/static/fonts/msdf/arial/arial.png") as any as ThreeMeshUI.FontVariant;
|
|
347
351
|
/** @ts-ignore */
|
|
348
352
|
normal?.addEventListener('ready', () => {
|
|
349
353
|
this.markDirty();
|
|
@@ -129,6 +129,7 @@ export class NeedleMenu {
|
|
|
129
129
|
|
|
130
130
|
constructor(context: Context) {
|
|
131
131
|
this._menu = NeedleMenuElement.getOrCreate(context.domElement, context);
|
|
132
|
+
this._menu.ensureInitialized();
|
|
132
133
|
this._context = context;
|
|
133
134
|
this._spatialMenu = new NeedleSpatialMenu(context, this._menu);
|
|
134
135
|
window.addEventListener("message", this.onPostMessage);
|
|
@@ -309,8 +310,7 @@ export class NeedleMenu {
|
|
|
309
310
|
export class NeedleMenuElement extends HTMLElement {
|
|
310
311
|
|
|
311
312
|
static create() {
|
|
312
|
-
|
|
313
|
-
return document.createElement(elementName, { is: elementName });
|
|
313
|
+
return document.createElement(elementName);
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
static getOrCreate(domElement: HTMLElement, context: Context) {
|
|
@@ -337,9 +337,13 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
337
337
|
|
|
338
338
|
private _domElement: HTMLElement | null = null;
|
|
339
339
|
private _context: Context | null = null;
|
|
340
|
+
private _didInitialize = false;
|
|
340
341
|
|
|
341
342
|
constructor() {
|
|
342
343
|
super();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
private initializeDom() {
|
|
343
347
|
|
|
344
348
|
const template = document.createElement('template');
|
|
345
349
|
// TODO: make host full size again and move the buttons to a wrapper so that we can later easily open e.g. foldouts/dropdowns / use the whole canvas space
|
|
@@ -795,7 +799,7 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
795
799
|
|
|
796
800
|
|
|
797
801
|
let context = this._context;
|
|
798
|
-
// we need to assign it in the timeout because the reference is set *after* the
|
|
802
|
+
// we need to assign it in the timeout because the reference is set *after* the element is initialized
|
|
799
803
|
setTimeout(() => context = this._context);
|
|
800
804
|
|
|
801
805
|
// watch changes
|
|
@@ -864,13 +868,21 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
864
868
|
}
|
|
865
869
|
}
|
|
866
870
|
|
|
871
|
+
ensureInitialized() {
|
|
872
|
+
if (!this._didInitialize) {
|
|
873
|
+
this._didInitialize = true;
|
|
874
|
+
this.initializeDom();
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
867
878
|
private _sizeChangeInterval;
|
|
868
879
|
|
|
869
880
|
connectedCallback() {
|
|
881
|
+
this.ensureInitialized();
|
|
870
882
|
window.addEventListener("resize", this.handleSizeChange);
|
|
871
883
|
this.handleMenuVisible();
|
|
872
884
|
this._sizeChangeInterval = setInterval(() => this.handleSizeChange(undefined, false), 5000);
|
|
873
|
-
// the dom element is set after
|
|
885
|
+
// the dom element is set after initialization runs
|
|
874
886
|
setTimeout(() => {
|
|
875
887
|
this._domElement?.addEventListener("resize", this.handleSizeChange);
|
|
876
888
|
this._domElement?.addEventListener("click", this.#onClick);
|
|
@@ -958,19 +970,19 @@ export class NeedleMenuElement extends HTMLElement {
|
|
|
958
970
|
|
|
959
971
|
// private _root: ShadowRoot | null = null;
|
|
960
972
|
/** @private root container element inside shadow DOM */
|
|
961
|
-
private
|
|
973
|
+
private root!: HTMLDivElement;
|
|
962
974
|
/** @private wraps the whole content (internal layout) */
|
|
963
|
-
private
|
|
975
|
+
private wrapper!: HTMLDivElement;
|
|
964
976
|
/** @private contains the buttons and dynamic elements */
|
|
965
|
-
private
|
|
977
|
+
private options!: HTMLDivElement;
|
|
966
978
|
/** @private contains options visible when in compact mode */
|
|
967
|
-
private
|
|
979
|
+
private optionsCompactMode!: HTMLDivElement;
|
|
968
980
|
/** @private contains the needle-logo html element */
|
|
969
|
-
private
|
|
981
|
+
private logoContainer!: HTMLDivElement;
|
|
970
982
|
/** @private compact menu button element */
|
|
971
|
-
private
|
|
983
|
+
private compactMenuButton!: HTMLButtonElement;
|
|
972
984
|
/** @private foldout container used in compact mode */
|
|
973
|
-
private
|
|
985
|
+
private foldout!: HTMLDivElement;
|
|
974
986
|
|
|
975
987
|
|
|
976
988
|
private readonly trackedElements: WeakSet<Node> = new WeakSet();
|
|
@@ -121,7 +121,7 @@ export class AROverlayHandler {
|
|
|
121
121
|
|
|
122
122
|
const quitARSlot = document.createElement("slot");
|
|
123
123
|
quitARSlot.style.display = "contents";
|
|
124
|
-
quitARSlot.style.padding = "10px";
|
|
124
|
+
quitARSlot.style.padding = "10px";
|
|
125
125
|
quitARSlot.setAttribute("name", "quit-ar");
|
|
126
126
|
this.appendElement(quitARSlot, element);
|
|
127
127
|
this._createdAROnlyElements.push(quitARSlot);
|
|
@@ -131,7 +131,16 @@ export class AROverlayHandler {
|
|
|
131
131
|
// No default quit button in the top right corner in app clips
|
|
132
132
|
// we provide one via the native UI
|
|
133
133
|
if (DeviceUtilities.isNeedleAppClip()) {
|
|
134
|
-
|
|
134
|
+
|
|
135
|
+
// quitARSlot.style.display = "none";
|
|
136
|
+
globalThis["NEEDLE_ENGINE_APPCLIP_DISABLE_MENU"] = true;
|
|
137
|
+
|
|
138
|
+
// respect the UI bar at the top of the screen and add some padding to the quit button container
|
|
139
|
+
// @TODO: this should be done in CSS in one place and not here and in debug overlay
|
|
140
|
+
const meta = document.querySelector('meta[name="viewport"]');
|
|
141
|
+
if (meta && !meta.getAttribute("content")?.includes("viewport-fit=")) {
|
|
142
|
+
meta.setAttribute("content", meta.getAttribute("content") + ",viewport-fit=cover");
|
|
143
|
+
}
|
|
135
144
|
}
|
|
136
145
|
|
|
137
146
|
// We want to search the document if there's a quit-ar button
|
|
@@ -155,6 +164,8 @@ export class AROverlayHandler {
|
|
|
155
164
|
right: 0;
|
|
156
165
|
z-index: 600;
|
|
157
166
|
pointer-events: all;
|
|
167
|
+
padding-top: env(safe-area-inset-top, 0px);
|
|
168
|
+
padding-right: calc(env(safe-area-inset-right, 0px) + 10px);
|
|
158
169
|
`;
|
|
159
170
|
this.appendElement(fixedButtonContainer, quitARSlot);
|
|
160
171
|
|
|
@@ -168,19 +168,30 @@ export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngi
|
|
|
168
168
|
*/
|
|
169
169
|
public get context() { return this._context; }
|
|
170
170
|
|
|
171
|
-
private _context
|
|
171
|
+
private _context!: Context;
|
|
172
172
|
private _overlay_ar: AROverlayHandler;
|
|
173
173
|
private _loadingProgress01: number = 0;
|
|
174
174
|
private _loadingView?: ILoadingViewHandler;
|
|
175
175
|
private _previousSrc: string | null | string[] = null;
|
|
176
176
|
/** @private set to true after <needle-engine> did load completely at least once. Set to false when < to false when <needle-engine> is removed from the document removed from the document */
|
|
177
177
|
private _didFullyLoad: boolean = false;
|
|
178
|
+
private _didInitialize = false;
|
|
178
179
|
|
|
179
180
|
constructor() {
|
|
180
181
|
super();
|
|
181
182
|
this._overlay_ar = new AROverlayHandler();
|
|
182
183
|
// TODO: do we want to rename this event?
|
|
183
184
|
this.addEventListener("ready", this.onReady);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private ensureInitialized() {
|
|
188
|
+
if (!this._didInitialize) {
|
|
189
|
+
this._didInitialize = true;
|
|
190
|
+
this.initializeDom();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private initializeDom() {
|
|
184
195
|
|
|
185
196
|
ensureFonts();
|
|
186
197
|
|
|
@@ -281,6 +292,7 @@ export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngi
|
|
|
281
292
|
* @internal
|
|
282
293
|
*/
|
|
283
294
|
async connectedCallback() {
|
|
295
|
+
this.ensureInitialized();
|
|
284
296
|
if (debug) {
|
|
285
297
|
console.log("<needle-engine> connected");
|
|
286
298
|
}
|
|
@@ -49,7 +49,7 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
|
|
|
49
49
|
abstract activeSelf: boolean;
|
|
50
50
|
|
|
51
51
|
/** @deprecated Use {@link addComponent} instead */
|
|
52
|
-
// eslint-disable-next-line
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
53
53
|
abstract addNewComponent<T extends IComponent>(type: ConstructorConcrete<T>, init?: ComponentInit<T>): T;
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -364,7 +364,6 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
/** @deprecated use `addComponent` */
|
|
367
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
368
367
|
public static addNewComponent<T extends IComponent>(go: IGameObject | Object3D, type: T | ConstructorConcrete<T>, init?: ComponentInit<T>, callAwake: boolean = true): T {
|
|
369
368
|
return addComponent(go, type, init, { callAwake });
|
|
370
369
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CubeTexture, EquirectangularReflectionMapping, LinearSRGBColorSpace, Material, Object3D, Texture, Vector3 } from "three";
|
|
2
2
|
|
|
3
|
-
import { isDevEnvironment, showBalloonWarning } from "../engine/debug/index.js";
|
|
4
3
|
import { MaterialPropertyBlock } from "../engine/engine_materialpropertyblock.js";
|
|
5
4
|
import { loadPMREM } from "../engine/engine_pmrem.js";
|
|
6
5
|
import { serializable } from "../engine/engine_serialization.js";
|
|
7
6
|
import { Context } from "../engine/engine_setup.js";
|
|
8
|
-
import type { IRenderer } from "../engine/engine_types.js";
|
|
9
7
|
import { getParam, resolveUrl } from "../engine/engine_utils.js";
|
|
10
8
|
import { BoxHelperComponent } from "./BoxHelperComponent.js";
|
|
11
9
|
import { Behaviour } from "./Component.js";
|
|
@@ -42,7 +40,11 @@ const $reflectionProbeKey = Symbol("reflectionProbeKey");
|
|
|
42
40
|
export class ReflectionProbe extends Behaviour {
|
|
43
41
|
|
|
44
42
|
private static _probes: Map<Context, ReflectionProbe[]> = new Map();
|
|
45
|
-
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Checks if the given material is currently using a reflection probe. This is determined by checking for an override on the material's "envMap" property, which is set by the Renderer component when applying a reflection probe.
|
|
47
|
+
*/
|
|
46
48
|
static isUsingReflectionProbe(material: Material) {
|
|
47
49
|
return !!(material as any)[$reflectionProbeKey];
|
|
48
50
|
}
|
|
@@ -50,8 +52,13 @@ export class ReflectionProbe extends Behaviour {
|
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* Event invoked when a reflection probe is enabled. Used internally by Renderer components to update probes when they become active. Not recommended to call this directly in most cases.
|
|
55
|
+
* @see {@link onDisabled} for the corresponding disable event.
|
|
53
56
|
*/
|
|
54
57
|
static readonly onEnabled: EventList<ReflectionProbe> = new EventList();
|
|
58
|
+
/**
|
|
59
|
+
* Event invoked when a reflection probe is disabled. Used internally by Renderer components to update probes when they become inactive. Not recommended to call this directly in most cases.
|
|
60
|
+
* @see {@link onEnabled} for the corresponding enable event.
|
|
61
|
+
*/
|
|
55
62
|
static readonly onDisabled: EventList<ReflectionProbe> = new EventList();
|
|
56
63
|
|
|
57
64
|
/**
|
|
@@ -90,11 +97,14 @@ export class ReflectionProbe extends Behaviour {
|
|
|
90
97
|
return null;
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
private _texture!: Texture;
|
|
100
|
+
private _texture!: Texture | null;
|
|
94
101
|
private _textureUrlInFlight?: string;
|
|
95
102
|
|
|
103
|
+
/**
|
|
104
|
+
* The cubemap or HDR texture used for reflections. Can be assigned directly or via a URL string. When assigning via URL, the texture will be loaded asynchronously and applied once ready.
|
|
105
|
+
*/
|
|
96
106
|
@serializable([Texture, String])
|
|
97
|
-
set texture(tex: Texture) {
|
|
107
|
+
set texture(tex: Texture | null) {
|
|
98
108
|
if (this._texture === tex) return;
|
|
99
109
|
|
|
100
110
|
if (typeof tex === "string") {
|
|
@@ -111,7 +121,10 @@ export class ReflectionProbe extends Behaviour {
|
|
|
111
121
|
return;
|
|
112
122
|
}
|
|
113
123
|
|
|
114
|
-
|
|
124
|
+
// During deserialization / loading of the GLB the deserializer sets an empty DataTexture
|
|
125
|
+
// But if the texture is serialized as a string (via Blender Reflection Probes) then the async loading above
|
|
126
|
+
// Will abort IF textureInFlight is reset (here). That's why we do NOT reset textureInFlight during initialization (when __didAwake is false). Only after awake, when we are sure that the async loading is done, we reset the in-flight URL to allow new assignments.
|
|
127
|
+
if(this.__didAwake) this._textureUrlInFlight = undefined;
|
|
115
128
|
|
|
116
129
|
this._texture = tex;
|
|
117
130
|
|
|
@@ -127,7 +140,7 @@ export class ReflectionProbe extends Behaviour {
|
|
|
127
140
|
tex.needsUpdate = true;
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
|
-
get texture(): Texture {
|
|
143
|
+
get texture(): Texture | null {
|
|
131
144
|
return this._texture;
|
|
132
145
|
}
|
|
133
146
|
|
|
@@ -165,6 +178,7 @@ export class ReflectionProbe extends Behaviour {
|
|
|
165
178
|
ReflectionProbe._probes.get(this.context)?.push(this);
|
|
166
179
|
}
|
|
167
180
|
|
|
181
|
+
/** @internal */
|
|
168
182
|
awake() {
|
|
169
183
|
this._boxHelper = this.gameObject.addComponent(BoxHelperComponent) as BoxHelperComponent;
|
|
170
184
|
this._boxHelper.updateBox(true);
|
|
@@ -178,20 +192,24 @@ export class ReflectionProbe extends Behaviour {
|
|
|
178
192
|
}
|
|
179
193
|
}
|
|
180
194
|
|
|
195
|
+
/** @internal */
|
|
181
196
|
onEnable(): void {
|
|
182
197
|
ReflectionProbe.onEnabled?.invoke(this);
|
|
183
198
|
}
|
|
184
199
|
|
|
200
|
+
/** @internal */
|
|
185
201
|
onDisable(): void {
|
|
186
202
|
ReflectionProbe.onDisabled?.invoke(this);
|
|
187
203
|
}
|
|
188
204
|
|
|
205
|
+
/** @internal */
|
|
189
206
|
start(): void {
|
|
190
207
|
if (!this._texture) {
|
|
191
208
|
console.warn(`[ReflectionProbe] Missing texture. Please assign a custom cubemap texture. To use reflection probes assign them to your renderer's "anchor" property.`);
|
|
192
209
|
}
|
|
193
210
|
}
|
|
194
211
|
|
|
212
|
+
/** @internal */
|
|
195
213
|
onDestroy() {
|
|
196
214
|
const probes = ReflectionProbe._probes.get(this.context);
|
|
197
215
|
if (probes) {
|
|
@@ -202,6 +220,9 @@ export class ReflectionProbe extends Behaviour {
|
|
|
202
220
|
}
|
|
203
221
|
}
|
|
204
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Applies this reflection probe to the given object by setting material property overrides for "envMap", "envMapRotation", and "envMapIntensity". This is typically called by the Renderer component when determining which reflection probe to use for a given object.
|
|
225
|
+
*/
|
|
205
226
|
apply(object: Object3D) {
|
|
206
227
|
if (disable) return;
|
|
207
228
|
if (!this.enabled) return;
|
|
@@ -218,6 +239,9 @@ export class ReflectionProbe extends Behaviour {
|
|
|
218
239
|
propertyBlock.setOverride("envMapIntensity", intensity);
|
|
219
240
|
}
|
|
220
241
|
|
|
242
|
+
/**
|
|
243
|
+
* Removes the reflection probe overrides from the given object. This is typically called by the Renderer component when an object is no longer influenced by this probe or when the probe is disabled.
|
|
244
|
+
*/
|
|
221
245
|
unapply(obj: Object3D) {
|
|
222
246
|
const block = MaterialPropertyBlock.get(obj);
|
|
223
247
|
if (block) {
|
|
@@ -479,8 +479,10 @@ function tryParseMagicSkyboxName(str: string | null | undefined, environment: bo
|
|
|
479
479
|
return useLowRes ? value.url_low : value.url;
|
|
480
480
|
}
|
|
481
481
|
else if (typeof str === "string" && str?.length && (isDevEnvironment() || debug)) {
|
|
482
|
-
|
|
483
|
-
|
|
482
|
+
// Only warn if the string looks like it was meant to be a magic skybox name.
|
|
483
|
+
// Strings that contain "/" or "." are paths or URLs, not magic names.
|
|
484
|
+
const looksLikePath = str.includes("/") || str.includes(".");
|
|
485
|
+
if(!looksLikePath) {
|
|
484
486
|
console.warn(`RemoteSkybox: Unknown magic skybox name "${str}". Valid names are: ${Object.keys(MagicSkyboxNames).map(n => `"${n}"`).join(", ")}`);
|
|
485
487
|
}
|
|
486
488
|
}
|
|
@@ -6,11 +6,11 @@ import { SerializationContext } from "../../../engine/engine_serialization_core.
|
|
|
6
6
|
import { serializable } from "../../../engine/engine_serialization_decorator.js";
|
|
7
7
|
import { getWorldPosition } from "../../../engine/engine_three_utils.js";
|
|
8
8
|
import { getParam } from "../../../engine/engine_utils.js";
|
|
9
|
+
import GLTFMeshGPUInstancingExtension from '../../../engine/export/gltf/EXT_mesh_gpu_instancing_exporter.js';
|
|
9
10
|
import { RenderTextureWriter } from "../../../engine/export/gltf/Writers.js";
|
|
10
11
|
import { shouldExport_HideFlags } from "../../../engine/export/utils.js";
|
|
11
12
|
import { registerExportExtensions } from "../../../engine/extensions/index.js";
|
|
12
13
|
import { NEEDLE_components } from "../../../engine/extensions/NEEDLE_components.js";
|
|
13
|
-
import GLTFMeshGPUInstancingExtension from '../../../include/three/EXT_mesh_gpu_instancing_exporter.js';
|
|
14
14
|
import { BoxHelperComponent } from "../../BoxHelperComponent.js";
|
|
15
15
|
import { Behaviour, GameObject } from "../../Component.js";
|
|
16
16
|
import { Renderer } from "../../Renderer.js";
|
|
@@ -2457,7 +2457,7 @@ ${usedUVChannels.has(0) ? `
|
|
|
2457
2457
|
def Shader "uvReader_st"
|
|
2458
2458
|
{
|
|
2459
2459
|
uniform token info:id = "UsdPrimvarReader_float2"
|
|
2460
|
-
|
|
2460
|
+
string inputs:varname = "st"
|
|
2461
2461
|
float2 inputs:fallback = (0.0, 0.0)
|
|
2462
2462
|
float2 outputs:result
|
|
2463
2463
|
}
|
|
@@ -2466,7 +2466,7 @@ ${usedUVChannels.has(1) ? `
|
|
|
2466
2466
|
def Shader "uvReader_st1"
|
|
2467
2467
|
{
|
|
2468
2468
|
uniform token info:id = "UsdPrimvarReader_float2"
|
|
2469
|
-
|
|
2469
|
+
string inputs:varname = "st1"
|
|
2470
2470
|
float2 inputs:fallback = (0.0, 0.0)
|
|
2471
2471
|
float2 outputs:result
|
|
2472
2472
|
}
|
|
@@ -740,7 +740,7 @@ export class USDZExporter extends Behaviour {
|
|
|
740
740
|
}
|
|
741
741
|
else if (sessionRoot) {
|
|
742
742
|
arScale = sessionRoot.arScale;
|
|
743
|
-
// eslint-disable-next-line
|
|
743
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
744
744
|
_invertForward = sessionRoot.invertForward;
|
|
745
745
|
}
|
|
746
746
|
|
|
@@ -62,9 +62,9 @@ export class PhysicsExtension implements IUSDExporterExtension {
|
|
|
62
62
|
writer.appendLine(`double dynamicFriction = ${colliderSource.sharedMaterial?.dynamicFriction}`);
|
|
63
63
|
if (mat && mat.bounciness !== undefined)
|
|
64
64
|
writer.appendLine(`double restitution = ${colliderSource.sharedMaterial?.bounciness}`);
|
|
65
|
-
// eslint-disable-next-line
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
66
66
|
if (mat && mat.staticFriction !== undefined)
|
|
67
|
-
// eslint-disable-next-line
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
68
68
|
writer.appendLine(`double staticFriction = ${colliderSource.sharedMaterial?.staticFriction}`);
|
|
69
69
|
writer.closeBlock( "}" );
|
|
70
70
|
}
|