@needle-tools/engine 4.8.6 → 4.8.7
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 +4 -0
- package/dist/{gltf-progressive-DXRy9EQz.js → gltf-progressive-BcHT3Nyo.js} +1 -1
- package/dist/{gltf-progressive-C-U_onhf.umd.cjs → gltf-progressive-CH3Q4H06.umd.cjs} +1 -1
- package/dist/{gltf-progressive-DViD_J_l.min.js → gltf-progressive-DR6HqF_h.min.js} +1 -1
- package/dist/{needle-engine.bundle-BTJDRZkJ.js → needle-engine.bundle-B0qaChJt.js} +3481 -3468
- package/dist/{needle-engine.bundle-CQIq7Zg-.min.js → needle-engine.bundle-CZBThBDy.min.js} +117 -117
- package/dist/{needle-engine.bundle-CaNItSG7.umd.cjs → needle-engine.bundle-lBmpWgFp.umd.cjs} +120 -120
- package/dist/needle-engine.js +402 -400
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-61aXdqNz.umd.cjs → postprocessing-CVb_x9YY.umd.cjs} +1 -1
- package/dist/{postprocessing-D9jDHD0U.js → postprocessing-ORx-0eCx.js} +1 -1
- package/dist/{postprocessing-Be9Ds4NK.min.js → postprocessing-Ywv5oKkX.min.js} +1 -1
- package/dist/three-examples-BX_Sktc9.min.js +501 -0
- package/dist/{three-examples-BihZ_R96.js → three-examples-CNexix3E.js} +2436 -2781
- package/dist/{three-examples-Ce6Th3bv.umd.cjs → three-examples-DWxXVnws.umd.cjs} +21 -21
- package/dist/{vendor-BRpzuoJE.min.js → vendor-C43vobGc.min.js} +37 -37
- package/dist/{vendor-p_xp9KuJ.js → vendor-Z4SPrTcP.js} +2402 -2047
- package/dist/vendor-xfQ8tKF3.umd.cjs +1121 -0
- package/lib/engine/api.d.ts +2 -0
- package/lib/engine/api.js +2 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_feature_flags.d.ts +3 -0
- package/lib/engine/engine_feature_flags.js +6 -0
- package/lib/engine/engine_feature_flags.js.map +1 -0
- package/lib/engine/engine_gameobject.js +0 -4
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.d.ts +2 -1
- package/lib/engine/engine_mainloop_utils.js +18 -6
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_pmrem.d.ts +6 -0
- package/lib/engine/engine_pmrem.js +9 -40
- package/lib/engine/engine_pmrem.js.map +1 -1
- package/lib/engine/extensions/extensions.js +2 -2
- package/lib/engine/extensions/extensions.js.map +1 -1
- package/lib/engine/js-extensions/Object3D.js +19 -0
- package/lib/engine/js-extensions/Object3D.js.map +1 -1
- package/lib/engine-components/Skybox.js +9 -3
- package/lib/engine-components/Skybox.js.map +1 -1
- package/package.json +3 -2
- package/src/engine/api.ts +3 -1
- package/src/engine/engine_feature_flags.ts +8 -0
- package/src/engine/engine_gameobject.ts +0 -4
- package/src/engine/engine_mainloop_utils.ts +24 -8
- package/src/engine/engine_pmrem.ts +9 -45
- package/src/engine/extensions/extensions.ts +2 -2
- package/src/engine/js-extensions/Object3D.ts +25 -2
- package/src/engine-components/Skybox.ts +8 -4
- package/dist/three-examples-DKY9Nfge.min.js +0 -501
- package/dist/vendor-Ja-vKV-a.umd.cjs +0 -1121
package/src/engine/api.ts
CHANGED
|
@@ -33,6 +33,7 @@ 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_feature_flags.js"
|
|
36
37
|
export * from "./engine_gameobject.js";
|
|
37
38
|
export { Gizmos } from "./engine_gizmos.js"
|
|
38
39
|
export * from "./engine_gltf.js";
|
|
@@ -42,7 +43,7 @@ export { InstancingUtil } from "./engine_instancing.js";
|
|
|
42
43
|
export { hasCommercialLicense, hasIndieLicense, hasProLicense } from "./engine_license.js";
|
|
43
44
|
export * from "./engine_lifecycle_api.js";
|
|
44
45
|
export { NeedleEngineModelLoader } from "./engine_loaders.callbacks.js";
|
|
45
|
-
export { loadAsset, loadSync,parseSync } from "./engine_loaders.js";
|
|
46
|
+
export { loadAsset, loadSync, parseSync } from "./engine_loaders.js";
|
|
46
47
|
export * from "./engine_math.js";
|
|
47
48
|
export { MODULES as NEEDLE_ENGINE_MODULES } from "./engine_modules.js";
|
|
48
49
|
export * from "./engine_networking.js";
|
|
@@ -59,6 +60,7 @@ export * from "./engine_physics.js";
|
|
|
59
60
|
export * from "./engine_physics.types.js";
|
|
60
61
|
export * from "./engine_physics_rapier.js";
|
|
61
62
|
export * from "./engine_playerview.js";
|
|
63
|
+
export { loadPMREM } from "./engine_pmrem.js";
|
|
62
64
|
export * from "./engine_scenelighting.js";
|
|
63
65
|
export * from "./engine_serialization.js";
|
|
64
66
|
export { type ISerializable } from "./engine_serialization_core.js";
|
|
@@ -105,11 +105,7 @@ export class InstantiateOptions implements IInstantiateOptions {
|
|
|
105
105
|
// });
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
const $isActive = Symbol("isActive");
|
|
109
108
|
export function isActiveSelf(go: Object3D): boolean {
|
|
110
|
-
// if (go[$isActive] === undefined) {
|
|
111
|
-
// go[$isActive] = true;
|
|
112
|
-
// }
|
|
113
109
|
return go.visible;
|
|
114
110
|
}
|
|
115
111
|
|
|
@@ -3,6 +3,7 @@ import { CubeCamera, Object3D, Scene, WebGLCubeRenderTarget } from 'three';
|
|
|
3
3
|
import { isDevEnvironment } from "./debug/index.js";
|
|
4
4
|
import * as constants from "./engine_constants.js";
|
|
5
5
|
import { ContextRegistry } from "./engine_context_registry.js";
|
|
6
|
+
import { NEEDLE_ENGINE_FEATURE_FLAGS } from './engine_feature_flags.js';
|
|
6
7
|
import { isActiveSelf } from './engine_gameobject.js';
|
|
7
8
|
import { safeInvoke } from "./engine_generic_utils.js";
|
|
8
9
|
import type { IComponent, IContext } from './engine_types.js';
|
|
@@ -31,7 +32,7 @@ export function processNewScripts(context: IContext) {
|
|
|
31
32
|
if (debug)
|
|
32
33
|
console.log("Register new components", context.new_scripts.length, [...context.new_scripts], context.alias ? ("element: " + context.alias) : context["hash"], context);
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
if (context.new_scripts_pre_setup_callbacks.length > 0) {
|
|
36
37
|
for (const cb of context.new_scripts_pre_setup_callbacks) {
|
|
37
38
|
if (!cb) continue;
|
|
@@ -39,7 +40,7 @@ export function processNewScripts(context: IContext) {
|
|
|
39
40
|
}
|
|
40
41
|
context.new_scripts_pre_setup_callbacks.length = 0;
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
|
|
43
44
|
if (context.new_scripts.length <= 0) return;
|
|
44
45
|
|
|
45
46
|
// TODO: update all the code from above to use this logic
|
|
@@ -269,8 +270,22 @@ export function isNeedleXRSessionEventReceiver(script: any, mode: XRSessionMode
|
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
|
|
273
|
+
let needsUpdate = true;
|
|
274
|
+
export function markHierarchyDirty() {
|
|
275
|
+
needsUpdate = true;
|
|
276
|
+
}
|
|
277
|
+
|
|
272
278
|
/** @internal */
|
|
273
|
-
export function updateIsActive(obj?: Object3D) {
|
|
279
|
+
export function updateIsActive(obj?: Object3D, force: boolean = false) {
|
|
280
|
+
|
|
281
|
+
if (NEEDLE_ENGINE_FEATURE_FLAGS.experimentalSmartHierarchyUpdate) {
|
|
282
|
+
|
|
283
|
+
if (!force) {
|
|
284
|
+
if (!needsUpdate) return;
|
|
285
|
+
}
|
|
286
|
+
needsUpdate = false;
|
|
287
|
+
}
|
|
288
|
+
|
|
274
289
|
if (!obj) obj = ContextRegistry.Current.scene;
|
|
275
290
|
if (!obj) {
|
|
276
291
|
console.trace("Invalid call - no current context.");
|
|
@@ -295,11 +310,11 @@ function updateIsActiveInHierarchyRecursiveRuntime(go: Object3D, activeInHierarc
|
|
|
295
310
|
return false;
|
|
296
311
|
}
|
|
297
312
|
|
|
298
|
-
const
|
|
313
|
+
const activeSelf = isActiveSelf(go);
|
|
299
314
|
if (activeInHierarchy) {
|
|
300
|
-
activeInHierarchy =
|
|
315
|
+
activeInHierarchy = activeSelf;
|
|
301
316
|
// IF we update activeInHierarchy within a disabled hierarchy we need to check the parent
|
|
302
|
-
if (activeInHierarchy && go.parent) {
|
|
317
|
+
if (activeInHierarchy && go.parent && level === 0) {
|
|
303
318
|
const parent = go.parent;
|
|
304
319
|
activeInHierarchy = parent[constants.activeInHierarchyFieldName];
|
|
305
320
|
if (activeInHierarchy === undefined) {
|
|
@@ -315,12 +330,13 @@ function updateIsActiveInHierarchyRecursiveRuntime(go: Object3D, activeInHierarc
|
|
|
315
330
|
|
|
316
331
|
const prevActive = go[constants.activeInHierarchyFieldName];
|
|
317
332
|
const changed = prevActive !== activeInHierarchy;
|
|
318
|
-
go[constants.activeInHierarchyFieldName] = activeInHierarchy;
|
|
319
333
|
|
|
320
334
|
// only raise events here if we didnt call enable etc already
|
|
321
335
|
if (changed) {
|
|
336
|
+
go[constants.activeInHierarchyFieldName] = activeInHierarchy;
|
|
337
|
+
|
|
322
338
|
if (debugHierarchy)
|
|
323
|
-
console.warn("ACTIVE CHANGE", go.name,
|
|
339
|
+
console.warn("ACTIVE CHANGE", go.name, activeSelf, go.visible, activeInHierarchy, "changed?" + changed, go);
|
|
324
340
|
if (allowEventCall) {
|
|
325
341
|
perComponent(go, comp => {
|
|
326
342
|
if (activeInHierarchy) {
|
|
@@ -4,12 +4,16 @@ import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader";
|
|
|
4
4
|
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
|
|
5
5
|
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
|
|
6
6
|
|
|
7
|
-
import { disposeObjectResources, setDisposable } from "./engine_assetdatabase.js";
|
|
8
|
-
|
|
9
7
|
const running: Map<string, Promise<Texture | null>> = new Map();
|
|
10
8
|
|
|
11
9
|
// #region api
|
|
12
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Loads a PMREM texture from the given URL. This also supports the ultra-fast preprocessed environment maps (PMREM) format.
|
|
13
|
+
* @param url The URL of the PMREM texture to load.
|
|
14
|
+
* @param renderer The WebGLRenderer to use for loading the texture.
|
|
15
|
+
* @returns A promise that resolves to the loaded texture or null if loading failed.
|
|
16
|
+
*/
|
|
13
17
|
export function loadPMREM(url: string, renderer: WebGLRenderer): Promise<Texture | null> {
|
|
14
18
|
if (running.has(url)) {
|
|
15
19
|
return running.get(url)!;
|
|
@@ -17,47 +21,13 @@ export function loadPMREM(url: string, renderer: WebGLRenderer): Promise<Texture
|
|
|
17
21
|
const actualUrl = new URL(url, window.location.href);
|
|
18
22
|
const promise = internalLoadPMREM(actualUrl, renderer);
|
|
19
23
|
running.set(url, promise);
|
|
24
|
+
promise.finally(() => {
|
|
25
|
+
running.delete(url);
|
|
26
|
+
});
|
|
20
27
|
return promise;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
// #region Cache
|
|
26
|
-
|
|
27
|
-
declare type SkyboxCacheEntry = { src: string, texture: Promise<Texture | null> };
|
|
28
|
-
function ensureGlobalCache() {
|
|
29
|
-
if (!globalThis["NEEDLE_ENGINE_SKYBOX_TEXTURES"])
|
|
30
|
-
globalThis["NEEDLE_ENGINE_SKYBOX_TEXTURES"] = new Array<SkyboxCacheEntry>();
|
|
31
|
-
return globalThis["NEEDLE_ENGINE_SKYBOX_TEXTURES"] as Array<SkyboxCacheEntry>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function tryGetPreviouslyLoadedTexture(src: string) {
|
|
35
|
-
const cache = ensureGlobalCache();
|
|
36
|
-
const found = cache.find(x => x.src === src);
|
|
37
|
-
if (found) {
|
|
38
|
-
return found.texture;
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
async function disposeCachedTexture(tex: Promise<Texture | null>) {
|
|
43
|
-
const texture = await tex;
|
|
44
|
-
if (!texture) return;
|
|
45
|
-
setDisposable(texture, true);
|
|
46
|
-
disposeObjectResources(texture);
|
|
47
|
-
}
|
|
48
|
-
function registerPromise(src: string, texture: Promise<Texture | null>) {
|
|
49
|
-
const cache = ensureGlobalCache();
|
|
50
|
-
// Make sure the cache doesnt get too big
|
|
51
|
-
while (cache.length > 5) {
|
|
52
|
-
const entry = cache.shift();
|
|
53
|
-
if (entry) { disposeCachedTexture(entry.texture); }
|
|
54
|
-
}
|
|
55
|
-
texture.then(t => { return setDisposable(t, false) });
|
|
56
|
-
cache.push({ src, texture });
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
31
|
// #region loading
|
|
62
32
|
|
|
63
33
|
|
|
@@ -67,11 +37,6 @@ async function internalLoadPMREM(url: URL, renderer: WebGLRenderer) {
|
|
|
67
37
|
const pathname = url.pathname;
|
|
68
38
|
const isPMREM_URL: boolean = url.toString().toLowerCase().includes("pmrem") || url.searchParams.get("pmrem") != null;
|
|
69
39
|
|
|
70
|
-
const cached = tryGetPreviouslyLoadedTexture(pathname);
|
|
71
|
-
if (cached) {
|
|
72
|
-
const res = await cached;
|
|
73
|
-
if (res?.source?.data?.length > 0 || res?.source?.data?.data?.length) return res;
|
|
74
|
-
}
|
|
75
40
|
const isEXR = pathname.endsWith(".exr");
|
|
76
41
|
const isHdr = pathname.endsWith(".hdr");
|
|
77
42
|
const isKtx2 = pathname.endsWith(".ktx2");
|
|
@@ -110,7 +75,6 @@ async function internalLoadPMREM(url: URL, renderer: WebGLRenderer) {
|
|
|
110
75
|
return tex;
|
|
111
76
|
});
|
|
112
77
|
|
|
113
|
-
registerPromise(str, promise);
|
|
114
78
|
const texture = await promise.catch(_err => {
|
|
115
79
|
console.warn("Failed to load texture from url:", url);
|
|
116
80
|
return null;
|
|
@@ -22,11 +22,11 @@ const debug = getParam("debugextensions");
|
|
|
22
22
|
|
|
23
23
|
// lazily import the GLTFAnimationPointerExtension in case it doesnt exist (e.g. using vanilla three)
|
|
24
24
|
let GLTFAnimationPointerExtension: any;
|
|
25
|
-
const KHR_ANIMATIONPOINTER_IMPORT = import("three
|
|
25
|
+
const KHR_ANIMATIONPOINTER_IMPORT = import("@needle-tools/three-animation-pointer").then(async mod => {
|
|
26
26
|
GLTFAnimationPointerExtension = mod.GLTFAnimationPointerExtension;
|
|
27
27
|
return GLTFAnimationPointerExtension;
|
|
28
28
|
}).catch(e => {
|
|
29
|
-
console.warn("Failed to import GLTFLoaderAnimationPointer. Please use @needle-tools/three for full KHR_animation support", e);
|
|
29
|
+
console.warn("Failed to import GLTFLoaderAnimationPointer. Please use @needle-tools/three-animationpointer for full KHR_animation support", e);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Object3D, Quaternion, Vector3 } from "three";
|
|
2
2
|
import { TransformControlsGizmo } from "three/examples/jsm/controls/TransformControls.js";
|
|
3
3
|
|
|
4
|
-
import { addComponent,
|
|
4
|
+
import { addComponent, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, removeComponent } from "../../engine/engine_components.js";
|
|
5
5
|
import { destroy, isActiveSelf, setActive } from "../../engine/engine_gameobject.js";
|
|
6
6
|
import {
|
|
7
7
|
getTempVector,
|
|
@@ -15,7 +15,9 @@ import {
|
|
|
15
15
|
setWorldScale
|
|
16
16
|
}
|
|
17
17
|
from "../../engine/engine_three_utils.js";
|
|
18
|
-
import type { ComponentInit, Constructor, ConstructorConcrete, HideFlags,IComponent as Component, IComponent } from "../../engine/engine_types.js";
|
|
18
|
+
import type { ComponentInit, Constructor, ConstructorConcrete, HideFlags, IComponent as Component, IComponent } from "../../engine/engine_types.js";
|
|
19
|
+
import { NEEDLE_ENGINE_FEATURE_FLAGS } from "../engine_feature_flags.js";
|
|
20
|
+
import { markHierarchyDirty } from "../engine_mainloop_utils.js";
|
|
19
21
|
import { applyPrototypeExtensions, registerPrototypeExtensions } from "./ExtensionUtils.js";
|
|
20
22
|
|
|
21
23
|
|
|
@@ -150,6 +152,27 @@ export function apply(object: Object3D) {
|
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
|
|
155
|
+
if (NEEDLE_ENGINE_FEATURE_FLAGS.experimentalSmartHierarchyUpdate) {
|
|
156
|
+
|
|
157
|
+
const addFn = Object3D.prototype.add;
|
|
158
|
+
Object3D.prototype.add = function (...args: any) {
|
|
159
|
+
markHierarchyDirty();
|
|
160
|
+
return addFn.apply(this, args);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const attachFn = Object3D.prototype.attach;
|
|
164
|
+
Object3D.prototype.attach = function (...args: any) {
|
|
165
|
+
markHierarchyDirty();
|
|
166
|
+
return attachFn.apply(this, args);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const removeFn = Object3D.prototype.remove;
|
|
170
|
+
Object3D.prototype.remove = function (...args: any) {
|
|
171
|
+
markHierarchyDirty();
|
|
172
|
+
return removeFn.apply(this, args);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
153
176
|
|
|
154
177
|
Object3D.prototype["SetActive"] = function (active: boolean) {
|
|
155
178
|
this.visible = active;
|
|
@@ -217,9 +217,9 @@ export class RemoteSkybox extends Behaviour {
|
|
|
217
217
|
if (debug) console.warn("RemoteSkybox: Failed to load texture from url", url);
|
|
218
218
|
return false;
|
|
219
219
|
}
|
|
220
|
-
// Check if we're
|
|
221
|
-
if (!this.enabled) {
|
|
222
|
-
if (debug) console.warn("RemoteSkybox: Component is
|
|
220
|
+
// Check if we're not disabled or destroyed
|
|
221
|
+
if (!this.enabled || this.destroyed) {
|
|
222
|
+
if (debug) console.warn("RemoteSkybox: Component is disabled or destroyed");
|
|
223
223
|
return false;
|
|
224
224
|
}
|
|
225
225
|
// Check if the url has changed while loading
|
|
@@ -239,7 +239,6 @@ export class RemoteSkybox extends Behaviour {
|
|
|
239
239
|
const envMap = this._prevLoadedEnvironment;
|
|
240
240
|
if (!envMap) return;
|
|
241
241
|
|
|
242
|
-
|
|
243
242
|
if ((envMap instanceof CubeTexture || envMap instanceof CompressedCubeTexture) || envMap.mapping == CubeUVReflectionMapping) {
|
|
244
243
|
// Nothing to do
|
|
245
244
|
}
|
|
@@ -248,6 +247,11 @@ export class RemoteSkybox extends Behaviour {
|
|
|
248
247
|
envMap.needsUpdate = true;
|
|
249
248
|
}
|
|
250
249
|
|
|
250
|
+
if(this.destroyed) return;
|
|
251
|
+
if(!this.context) {
|
|
252
|
+
console.warn("RemoteSkybox: Context is not available - can not apply skybox.");
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
251
255
|
|
|
252
256
|
// capture state
|
|
253
257
|
if (this.context.scene.background !== envMap)
|