@needle-tools/engine 5.1.0-alpha.1 → 5.1.0-canary.0d9f44e
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/.needle/generated/needle-bindings.gen.d.ts +5 -0
- package/components.needle.json +1 -1
- package/dist/{gltf-progressive-DJBMx-zB.umd.cjs → gltf-progressive-BmblPzFj.umd.cjs} +4 -4
- package/dist/{gltf-progressive-BryRjllq.min.js → gltf-progressive-CN_mbb66.min.js} +2 -2
- package/dist/{gltf-progressive-Cl167Vjx.js → gltf-progressive-DUlhxdv4.js} +5 -2
- package/dist/{needle-engine.bundle-BGyKqxBH.js → needle-engine.bundle-B35n_IHX.js} +8736 -8500
- package/dist/{needle-engine.bundle-DzVx9Z8D.umd.cjs → needle-engine.bundle-CDj15wRB.umd.cjs} +164 -164
- package/dist/{needle-engine.bundle-CiYtOO2O.min.js → needle-engine.bundle-D5zzggEG.min.js} +164 -164
- package/dist/needle-engine.d.ts +140 -22
- package/dist/needle-engine.js +172 -170
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-B_9sKVU7.min.js → postprocessing-B571qGWR.min.js} +34 -34
- package/dist/{postprocessing-WDc9WwI3.js → postprocessing-CfrLAbLX.js} +0 -1
- package/dist/{postprocessing-B2wb6pzI.umd.cjs → postprocessing-CiGkAeM9.umd.cjs} +17 -17
- package/dist/three-examples.js +4289 -3778
- package/dist/three-examples.min.js +301 -14
- package/dist/three-examples.umd.cjs +301 -14
- package/dist/{vendor-CAcsI0eU.js → vendor-BFrMaK9q.js} +8983 -9136
- package/dist/vendor-CJmyOrCq.min.js +1116 -0
- package/dist/vendor-DkMW3WY4.umd.cjs +1116 -0
- package/lib/engine/api.d.ts +12 -0
- package/lib/engine/api.js +2 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug_environment.js +1 -1
- package/lib/engine/debug/debug_environment.js.map +1 -1
- package/lib/engine/engine_application.js +8 -6
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_constants.js +6 -0
- package/lib/engine/engine_constants.js.map +1 -1
- package/lib/engine/engine_context.d.ts +31 -2
- package/lib/engine/engine_context.js +43 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.js +1 -1
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_init.js +5 -0
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +3 -2
- package/lib/engine/engine_input.js +3 -2
- 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 -15
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lifecycle_functions_internal.js +5 -0
- package/lib/engine/engine_lifecycle_functions_internal.js.map +1 -1
- package/lib/engine/engine_networking_blob.d.ts +1 -1
- package/lib/engine/engine_networking_blob.js +5 -11
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_physics_rapier.js +0 -1
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_pmrem.js +2 -2
- package/lib/engine/engine_pmrem.js.map +1 -1
- package/lib/engine/engine_scenedata.d.ts +34 -0
- package/lib/engine/engine_scenedata.js +135 -0
- package/lib/engine/engine_scenedata.js.map +1 -0
- package/lib/engine/engine_ssr.d.ts +18 -0
- package/lib/engine/engine_ssr.js +40 -0
- package/lib/engine/engine_ssr.js.map +1 -0
- package/lib/engine/engine_three_utils.d.ts +14 -7
- package/lib/engine/engine_three_utils.js +14 -7
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.js +2 -0
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/engine_utils_hash.d.ts +9 -0
- package/lib/engine/engine_utils_hash.js +112 -0
- package/lib/engine/engine_utils_hash.js.map +1 -0
- package/lib/engine/webcomponents/logo-element.d.ts +10 -1
- package/lib/engine/webcomponents/logo-element.js +2 -1
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +12 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js +2 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-button.d.ts +15 -1
- package/lib/engine/webcomponents/needle-button.js +2 -1
- package/lib/engine/webcomponents/needle-button.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +7 -1
- package/lib/engine/webcomponents/needle-engine.js +2 -1
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.js +1 -1
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine-components/Light.d.ts +25 -8
- package/lib/engine-components/Light.js +132 -27
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/RigidBody.js +3 -3
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +2 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/BloomEffect.d.ts +1 -1
- package/lib/engine-components/postprocessing/Effects/Sharpening.js +1 -2
- package/lib/engine-components/postprocessing/Effects/Sharpening.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +5 -6
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.d.ts +0 -1
- package/lib/engine-components/web/ScrollFollow.js +3 -2
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/needle-engine.d.ts +1 -0
- package/lib/needle-engine.js +1 -0
- package/lib/needle-engine.js.map +1 -1
- package/package.json +7 -5
- package/plugins/dts-generator/dts.codegen.js +334 -0
- package/plugins/dts-generator/dts.scan.js +99 -0
- package/plugins/dts-generator/dts.writer.js +59 -0
- package/plugins/dts-generator/glb.discovery.js +279 -0
- package/plugins/dts-generator/glb.extractor.js +215 -0
- package/plugins/dts-generator/glb.reader.js +167 -0
- package/plugins/dts-generator/index.js +36 -0
- package/plugins/dts-generator/manifest.types.js +174 -0
- package/plugins/types/index.d.ts +2 -1
- package/plugins/types/needle-bindings.d.ts +30 -0
- package/plugins/types/userconfig.d.ts +21 -2
- package/plugins/vite/asap.js +1 -1
- package/plugins/vite/dependency-watcher.d.ts +2 -2
- package/plugins/vite/dependency-watcher.js +3 -4
- package/plugins/vite/drop.d.ts +2 -2
- package/plugins/vite/drop.js +3 -4
- package/plugins/vite/dts-generator.d.ts +7 -0
- package/plugins/vite/dts-generator.js +191 -0
- package/plugins/vite/index.d.ts +10 -3
- package/plugins/vite/index.js +27 -10
- package/plugins/vite/logging.js +2 -2
- package/plugins/vite/meta.js +4 -2
- package/plugins/vite/poster.d.ts +2 -2
- package/plugins/vite/poster.js +3 -5
- package/plugins/vite/reload.d.ts +2 -2
- package/plugins/vite/reload.js +5 -5
- package/src/engine/api.ts +15 -1
- package/src/engine/debug/debug_environment.ts +1 -1
- package/src/engine/engine_application.ts +8 -6
- package/src/engine/engine_constants.ts +11 -6
- package/src/engine/engine_context.ts +47 -2
- package/src/engine/engine_context_registry.ts +1 -1
- package/src/engine/engine_init.ts +4 -0
- package/src/engine/engine_input.ts +3 -2
- package/src/engine/engine_license.ts +23 -19
- package/src/engine/engine_lifecycle_functions_internal.ts +7 -0
- package/src/engine/engine_networking_blob.ts +5 -11
- package/src/engine/engine_physics_rapier.ts +0 -3
- package/src/engine/engine_pmrem.ts +3 -3
- package/src/engine/engine_scenedata.ts +133 -0
- package/src/engine/engine_ssr.ts +48 -0
- package/src/engine/engine_three_utils.ts +15 -7
- package/src/engine/engine_types.ts +2 -0
- package/src/engine/engine_utils.ts +1 -0
- package/src/engine/engine_utils_hash.ts +65 -0
- package/src/engine/webcomponents/logo-element.ts +10 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +11 -2
- package/src/engine/webcomponents/needle-button.ts +15 -1
- package/src/engine/webcomponents/needle-engine.ts +8 -1
- package/src/engine/xr/NeedleXRSession.ts +1 -1
- package/src/engine-components/Light.ts +132 -27
- package/src/engine-components/RigidBody.ts +3 -3
- package/src/engine-components/SceneSwitcher.ts +1 -0
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +1 -1
- package/src/engine-components/postprocessing/Effects/Sharpening.ts +1 -2
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +4 -8
- package/src/engine-components/web/ScrollFollow.ts +2 -2
- package/src/needle-engine.ts +2 -0
- package/src/vite-env.d.ts +16 -0
- package/dist/vendor-CEM38hLE.umd.cjs +0 -1116
- package/dist/vendor-HRlxIBga.min.js +0 -1116
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR-safe base classes for browser globals that are not available in Node/SSR environments.
|
|
3
|
+
*
|
|
4
|
+
* Use these instead of extending browser globals directly so that class definitions
|
|
5
|
+
* do not throw a ReferenceError at module evaluation time in SSR/Node contexts
|
|
6
|
+
* (SvelteKit, Next.js, etc.).
|
|
7
|
+
*
|
|
8
|
+
* In browser environments each constant is the real global; in SSR it falls back
|
|
9
|
+
* to a plain empty class so that `class Foo extends HTMLElementBase` is valid.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/** True when running in an SSR/Node environment (no browser globals). */
|
|
14
|
+
export const SSR: boolean = typeof window === "undefined";
|
|
15
|
+
|
|
16
|
+
/** SSR-safe base class for web components. */
|
|
17
|
+
export const HTMLElementBase: typeof HTMLElement =
|
|
18
|
+
typeof HTMLElement !== "undefined" ? HTMLElement : (class { } as unknown as typeof HTMLElement);
|
|
19
|
+
|
|
20
|
+
/** SSR-safe base class for pointer events. */
|
|
21
|
+
export const PointerEventBase: typeof PointerEvent =
|
|
22
|
+
typeof PointerEvent !== "undefined" ? PointerEvent : (class { } as unknown as typeof PointerEvent);
|
|
23
|
+
|
|
24
|
+
/** SSR-safe base class for keyboard events. */
|
|
25
|
+
export const KeyboardEventBase: typeof KeyboardEvent =
|
|
26
|
+
typeof KeyboardEvent !== "undefined" ? KeyboardEvent : (class { } as unknown as typeof KeyboardEvent);
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// #region minimal polyfills
|
|
32
|
+
// Three.js FileLoader uses ProgressEvent in fetch stream callbacks.
|
|
33
|
+
// It doesn't exist in Node — install a minimal stub so SSR doesn't crash.
|
|
34
|
+
if (typeof globalThis.ProgressEvent === "undefined") {
|
|
35
|
+
(globalThis as any).ProgressEvent = class ProgressEvent {
|
|
36
|
+
readonly type: string;
|
|
37
|
+
readonly lengthComputable: boolean;
|
|
38
|
+
readonly loaded: number;
|
|
39
|
+
readonly total: number;
|
|
40
|
+
constructor(type: string, init?: { lengthComputable?: boolean; loaded?: number; total?: number }) {
|
|
41
|
+
this.type = type;
|
|
42
|
+
this.lengthComputable = init?.lengthComputable ?? false;
|
|
43
|
+
this.loaded = init?.loaded ?? 0;
|
|
44
|
+
this.total = init?.total ?? 0;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// #endregion
|
|
@@ -493,13 +493,21 @@ void main(){
|
|
|
493
493
|
* Utility class to perform various graphics operations like copying textures to canvas
|
|
494
494
|
*/
|
|
495
495
|
export class Graphics {
|
|
496
|
-
private static
|
|
497
|
-
private static
|
|
498
|
-
private static
|
|
499
|
-
private static
|
|
500
|
-
private static
|
|
501
|
-
private static
|
|
502
|
-
private static
|
|
496
|
+
private static _planeGeometry: PlaneGeometry | undefined;
|
|
497
|
+
private static _renderer: WebGLRenderer | undefined;
|
|
498
|
+
private static _perspectiveCam: PerspectiveCamera | undefined;
|
|
499
|
+
private static _orthographicCam: OrthographicCamera | undefined;
|
|
500
|
+
private static _scene: Scene | undefined;
|
|
501
|
+
private static _blitMaterial: BlitMaterial | undefined;
|
|
502
|
+
private static _mesh: Mesh | undefined;
|
|
503
|
+
|
|
504
|
+
private static get planeGeometry() { return this._planeGeometry ??= new PlaneGeometry(2, 2, 1, 1); }
|
|
505
|
+
private static get renderer() { return this._renderer ??= new WebGLRenderer({ antialias: false, alpha: true }); }
|
|
506
|
+
private static get perspectiveCam() { return this._perspectiveCam ??= new PerspectiveCamera(); }
|
|
507
|
+
private static get orthographicCam() { return this._orthographicCam ??= new OrthographicCamera(); }
|
|
508
|
+
private static get scene() { return this._scene ??= new Scene(); }
|
|
509
|
+
private static get blitMaterial() { return this._blitMaterial ??= new BlitMaterial(); }
|
|
510
|
+
private static get mesh() { return this._mesh ??= new Mesh(Graphics.planeGeometry, Graphics.blitMaterial); }
|
|
503
511
|
|
|
504
512
|
|
|
505
513
|
/**
|
|
@@ -258,6 +258,8 @@ export declare interface ICameraController {
|
|
|
258
258
|
export declare interface ILight extends IComponent {
|
|
259
259
|
intensity: number;
|
|
260
260
|
color: Color;
|
|
261
|
+
/** The type of light as a lowercase string: `"directional"`, `"point"`, `"spot"` */
|
|
262
|
+
readonly type: "directional" | "point" | "spot";
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
export declare interface ISharedMaterials {
|
|
@@ -597,6 +597,7 @@ export namespace DeviceUtilities {
|
|
|
597
597
|
/** @returns `true` for MacOS or Windows devices. `false` for Hololens and other headsets. */
|
|
598
598
|
export function isDesktop() {
|
|
599
599
|
if (_isDesktop !== undefined) return _isDesktop;
|
|
600
|
+
if (typeof window === "undefined") return _isDesktop = false;
|
|
600
601
|
const ua = window.navigator.userAgent;
|
|
601
602
|
const standalone = /Windows|MacOS|Mac OS/.test(ua);
|
|
602
603
|
const isHololens = /Windows NT/.test(ua) && /Edg/.test(ua) && !/Win64/.test(ua);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-JS hashing utilities — no external dependencies, works in browser and Node/SSR.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// MD5 based on the public-domain RSA Data Security MD5 algorithm.
|
|
6
|
+
function md5Bytes(input: Uint8Array): number[] {
|
|
7
|
+
function safeAdd(x: number, y: number) { const lsw = (x & 0xffff) + (y & 0xffff); return ((x >> 16) + (y >> 16) + (lsw >> 16)) << 16 | lsw & 0xffff; }
|
|
8
|
+
function bitRotateLeft(num: number, cnt: number) { return num << cnt | num >>> 32 - cnt; }
|
|
9
|
+
function md5cmn(q: number, a: number, b: number, x: number, s: number, t: number) { return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); }
|
|
10
|
+
function md5ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return md5cmn(b & c | ~b & d, a, b, x, s, t); }
|
|
11
|
+
function md5gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return md5cmn(b & d | c & ~d, a, b, x, s, t); }
|
|
12
|
+
function md5hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return md5cmn(b ^ c ^ d, a, b, x, s, t); }
|
|
13
|
+
function md5ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return md5cmn(c ^ (b | ~d), a, b, x, s, t); }
|
|
14
|
+
|
|
15
|
+
const len8 = input.length;
|
|
16
|
+
const padded = new Uint8Array((Math.ceil((len8 + 9) / 64) * 64));
|
|
17
|
+
padded.set(input);
|
|
18
|
+
padded[len8] = 0x80;
|
|
19
|
+
const view = new DataView(padded.buffer);
|
|
20
|
+
view.setUint32(padded.length - 8, len8 << 3, true);
|
|
21
|
+
view.setUint32(padded.length - 4, (len8 / 0x20000000) | 0, true);
|
|
22
|
+
|
|
23
|
+
let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476;
|
|
24
|
+
for (let i = 0; i < padded.length >> 2; i += 16) {
|
|
25
|
+
const M = (j: number) => view.getInt32((i + j) * 4, true);
|
|
26
|
+
const [oa, ob, oc, od] = [a, b, c, d];
|
|
27
|
+
a = md5ff(a,b,c,d,M(0),7,-680876936); d=md5ff(d,a,b,c,M(1),12,-389564586); c=md5ff(c,d,a,b,M(2),17,606105819); b=md5ff(b,c,d,a,M(3),22,-1044525330);
|
|
28
|
+
a=md5ff(a,b,c,d,M(4),7,-176418897); d=md5ff(d,a,b,c,M(5),12,1200080426); c=md5ff(c,d,a,b,M(6),17,-1473231341); b=md5ff(b,c,d,a,M(7),22,-45705983);
|
|
29
|
+
a=md5ff(a,b,c,d,M(8),7,1770035416); d=md5ff(d,a,b,c,M(9),12,-1958414417); c=md5ff(c,d,a,b,M(10),17,-42063); b=md5ff(b,c,d,a,M(11),22,-1990404162);
|
|
30
|
+
a=md5ff(a,b,c,d,M(12),7,1804603682); d=md5ff(d,a,b,c,M(13),12,-40341101); c=md5ff(c,d,a,b,M(14),17,-1502002290); b=md5ff(b,c,d,a,M(15),22,1236535329);
|
|
31
|
+
a=md5gg(a,b,c,d,M(1),5,-165796510); d=md5gg(d,a,b,c,M(6),9,-1069501632); c=md5gg(c,d,a,b,M(11),14,643717713); b=md5gg(b,c,d,a,M(0),20,-373897302);
|
|
32
|
+
a=md5gg(a,b,c,d,M(5),5,-701558691); d=md5gg(d,a,b,c,M(10),9,38016083); c=md5gg(c,d,a,b,M(15),14,-660478335); b=md5gg(b,c,d,a,M(4),20,-405537848);
|
|
33
|
+
a=md5gg(a,b,c,d,M(9),5,568446438); d=md5gg(d,a,b,c,M(14),9,-1019803690); c=md5gg(c,d,a,b,M(3),14,-187363961); b=md5gg(b,c,d,a,M(8),20,1163531501);
|
|
34
|
+
a=md5gg(a,b,c,d,M(13),5,-1444681467); d=md5gg(d,a,b,c,M(2),9,-51403784); c=md5gg(c,d,a,b,M(7),14,1735328473); b=md5gg(b,c,d,a,M(12),20,-1926607734);
|
|
35
|
+
a=md5hh(a,b,c,d,M(5),4,-378558); d=md5hh(d,a,b,c,M(8),11,-2022574463); c=md5hh(c,d,a,b,M(11),16,1839030562); b=md5hh(b,c,d,a,M(14),23,-35309556);
|
|
36
|
+
a=md5hh(a,b,c,d,M(1),4,-1530992060); d=md5hh(d,a,b,c,M(4),11,1272893353); c=md5hh(c,d,a,b,M(7),16,-155497632); b=md5hh(b,c,d,a,M(10),23,-1094730640);
|
|
37
|
+
a=md5hh(a,b,c,d,M(13),4,681279174); d=md5hh(d,a,b,c,M(0),11,-358537222); c=md5hh(c,d,a,b,M(3),16,-722521979); b=md5hh(b,c,d,a,M(6),23,76029189);
|
|
38
|
+
a=md5hh(a,b,c,d,M(9),4,-640364487); d=md5hh(d,a,b,c,M(12),11,-421815835); c=md5hh(c,d,a,b,M(15),16,530742520); b=md5hh(b,c,d,a,M(2),23,-995338651);
|
|
39
|
+
a=md5ii(a,b,c,d,M(0),6,-198630844); d=md5ii(d,a,b,c,M(7),10,1126891415); c=md5ii(c,d,a,b,M(14),15,-1416354905); b=md5ii(b,c,d,a,M(5),21,-57434055);
|
|
40
|
+
a=md5ii(a,b,c,d,M(12),6,1700485571); d=md5ii(d,a,b,c,M(3),10,-1894986606); c=md5ii(c,d,a,b,M(10),15,-1051523); b=md5ii(b,c,d,a,M(1),21,-2054922799);
|
|
41
|
+
a=md5ii(a,b,c,d,M(8),6,1873313359); d=md5ii(d,a,b,c,M(15),10,-30611744); c=md5ii(c,d,a,b,M(6),15,-1560198380); b=md5ii(b,c,d,a,M(13),21,1309151649);
|
|
42
|
+
a=md5ii(a,b,c,d,M(4),6,-145523070); d=md5ii(d,a,b,c,M(11),10,-1120210379); c=md5ii(c,d,a,b,M(2),15,718787259); b=md5ii(b,c,d,a,M(9),21,-343485551);
|
|
43
|
+
a=safeAdd(a,oa); b=safeAdd(b,ob); c=safeAdd(c,oc); d=safeAdd(d,od);
|
|
44
|
+
}
|
|
45
|
+
const result = new DataView(new ArrayBuffer(16));
|
|
46
|
+
result.setUint32(0, a, true); result.setUint32(4, b, true); result.setUint32(8, c, true); result.setUint32(12, d, true);
|
|
47
|
+
return Array.from(new Uint8Array(result.buffer));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Returns the MD5 hash of the given bytes as a lowercase hex string. */
|
|
51
|
+
export function md5Hex(input: Uint8Array): string {
|
|
52
|
+
return md5Bytes(input).map(b => b.toString(16).padStart(2, "0")).join("");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Returns the MD5 hash of the given bytes as a raw byte array. */
|
|
56
|
+
export function md5AsBytes(input: Uint8Array): number[] {
|
|
57
|
+
return md5Bytes(input);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Returns the SHA-256 hash of the given buffer as a base64 string. */
|
|
61
|
+
export function sha256Base64(buffer: ArrayBuffer): Promise<string> {
|
|
62
|
+
return crypto.subtle.digest("SHA-256", new Uint8Array(buffer)).then(res =>
|
|
63
|
+
btoa(String.fromCharCode(...new Uint8Array(res)))
|
|
64
|
+
);
|
|
65
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { madeWithNeedleSVG, needleLogoOnlySVG, needleLogoSVG } from "../assets/index.js";
|
|
2
|
+
import { HTMLElementBase } from "../engine_ssr.js";
|
|
2
3
|
|
|
3
4
|
const elementName = "needle-logo-element";
|
|
4
5
|
|
|
@@ -6,13 +7,21 @@ declare global {
|
|
|
6
7
|
interface HTMLElementTagNameMap {
|
|
7
8
|
"needle-logo-element": NeedleLogoElement;
|
|
8
9
|
}
|
|
10
|
+
namespace JSX {
|
|
11
|
+
interface IntrinsicElements {
|
|
12
|
+
"needle-logo-element": NeedleLogoElementJSXAttributes;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
interface NeedleLogoElementJSXAttributes extends Partial<Omit<HTMLElement, "style" | "children">> {
|
|
16
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
17
|
+
}
|
|
9
18
|
}
|
|
10
19
|
|
|
11
20
|
/**
|
|
12
21
|
* Needle logo web component used in the hosting UI (small, compact logo or full)
|
|
13
22
|
* @element needle-logo-element
|
|
14
23
|
*/
|
|
15
|
-
export class NeedleLogoElement extends
|
|
24
|
+
export class NeedleLogoElement extends HTMLElementBase {
|
|
16
25
|
|
|
17
26
|
static get elementName() { return elementName; }
|
|
18
27
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { showBalloonMessage } from "../../debug/debug.js";
|
|
2
|
+
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
2
3
|
import type { Context } from "../../engine_context.js";
|
|
3
4
|
import { hasCommercialLicense, onLicenseCheckResultChanged, Telemetry } from "../../engine_license.js";
|
|
4
5
|
import { isLocalNetwork } from "../../engine_networking_utils.js";
|
|
@@ -13,7 +14,15 @@ import { NeedleSpatialMenu } from "./needle-menu-spatial.js";
|
|
|
13
14
|
|
|
14
15
|
declare global {
|
|
15
16
|
interface HTMLElementTagNameMap {
|
|
16
|
-
"needle-
|
|
17
|
+
"needle-menu": NeedleMenuElement;
|
|
18
|
+
}
|
|
19
|
+
namespace JSX {
|
|
20
|
+
interface IntrinsicElements {
|
|
21
|
+
"needle-menu": NeedleMenuJSXAttributes;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
interface NeedleMenuJSXAttributes extends Partial<Omit<HTMLElement, "style" | "children">> {
|
|
25
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
17
26
|
}
|
|
18
27
|
}
|
|
19
28
|
|
|
@@ -303,7 +312,7 @@ export class NeedleMenu {
|
|
|
303
312
|
*
|
|
304
313
|
* @element needle-menu
|
|
305
314
|
*/
|
|
306
|
-
export class NeedleMenuElement extends
|
|
315
|
+
export class NeedleMenuElement extends HTMLElementBase {
|
|
307
316
|
|
|
308
317
|
static create() {
|
|
309
318
|
// Ensure the element is registered before creating — guards against
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isDevEnvironment } from "../debug/index.js";
|
|
2
|
+
import { HTMLElementBase } from "../engine_ssr.js";
|
|
2
3
|
import { ButtonsFactory } from "./buttons.js";
|
|
3
4
|
import { iconFontUrl, loadFont } from "./fonts.js";
|
|
4
5
|
import { WebXRButtonFactory } from "./WebXRButtons.js";
|
|
@@ -7,6 +8,19 @@ declare global {
|
|
|
7
8
|
interface HTMLElementTagNameMap {
|
|
8
9
|
"needle-button": NeedleButtonElement;
|
|
9
10
|
}
|
|
11
|
+
namespace JSX {
|
|
12
|
+
interface IntrinsicElements {
|
|
13
|
+
"needle-button": NeedleButtonJSXAttributes;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
interface NeedleButtonJSXAttributes extends Partial<Omit<HTMLElement, "style" | "children">> {
|
|
17
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
18
|
+
ar?: boolean | string;
|
|
19
|
+
vr?: boolean | string;
|
|
20
|
+
quicklook?: boolean | string;
|
|
21
|
+
qrcode?: boolean | string;
|
|
22
|
+
unstyled?: boolean | string;
|
|
23
|
+
}
|
|
10
24
|
}
|
|
11
25
|
|
|
12
26
|
const isDev = isDevEnvironment();
|
|
@@ -65,7 +79,7 @@ const isDev = isDevEnvironment();
|
|
|
65
79
|
* @see {@link NeedleEngineWebComponent} for the main <needle-engine> element
|
|
66
80
|
* @see {@link NeedleMenu} for the built-in menu component that can display similar buttons
|
|
67
81
|
*/
|
|
68
|
-
export class NeedleButtonElement extends
|
|
82
|
+
export class NeedleButtonElement extends HTMLElementBase {
|
|
69
83
|
|
|
70
84
|
static observedAttributes = ["ar", "vr", "quicklook", "qrcode"];
|
|
71
85
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
2
|
+
import { HTMLElementBase } from "../engine_ssr.js";
|
|
2
3
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
3
4
|
import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
|
|
4
5
|
import { hasCommercialLicense } from "../engine_license.js";
|
|
@@ -20,6 +21,12 @@ declare global {
|
|
|
20
21
|
interface HTMLElementTagNameMap {
|
|
21
22
|
"needle-engine": NeedleEngineWebComponent;
|
|
22
23
|
}
|
|
24
|
+
// JSX support — allows <needle-engine> in React, Preact, SolidJS and any other JSX-based framework.
|
|
25
|
+
namespace JSX {
|
|
26
|
+
interface IntrinsicElements {
|
|
27
|
+
"needle-engine": NeedleEngineAttributes;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
const debug = getParam("debugwebcomponent");
|
|
@@ -153,7 +160,7 @@ const observedAttributes = [
|
|
|
153
160
|
* @see {@link NeedleButtonElement} for adding AR/VR/Quicklook buttons via <needle-button>
|
|
154
161
|
* @see {@link NeedleMenu} for the built-in menu configuration component
|
|
155
162
|
*/
|
|
156
|
-
export class NeedleEngineWebComponent extends
|
|
163
|
+
export class NeedleEngineWebComponent extends HTMLElementBase implements INeedleEngineComponent {
|
|
157
164
|
|
|
158
165
|
static get observedAttributes() {
|
|
159
166
|
return observedAttributes;
|
|
@@ -207,7 +207,7 @@ function waitForContextLoadingFinished(): Promise<void> {
|
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
|
|
210
|
-
if (DeviceUtilities.isDesktop() && isDevEnvironment()) {
|
|
210
|
+
if (typeof window !== "undefined" && DeviceUtilities.isDesktop() && isDevEnvironment()) {
|
|
211
211
|
window.addEventListener("keydown", (evt) => {
|
|
212
212
|
if (evt.key === "x" || evt.key === "Escape") {
|
|
213
213
|
if (NeedleXRSession.active) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { CameraHelper, Color, DirectionalLight, DirectionalLightHelper, Light as ThreeLight, OrthographicCamera, PointLight, SpotLight, Vector3 } from "three";
|
|
2
|
+
import { CSM } from "three/examples/jsm/csm/CSM.js";
|
|
3
|
+
import { CSMHelper } from "three/examples/jsm/csm/CSMHelper.js";
|
|
2
4
|
|
|
3
5
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
|
4
|
-
|
|
6
|
+
|
|
5
7
|
import { setWorldPositionXYZ } from "../engine/engine_three_utils.js";
|
|
6
8
|
import type { ILight } from "../engine/engine_types.js";
|
|
7
9
|
import { getParam } from "../engine/engine_utils.js";
|
|
@@ -106,11 +108,40 @@ enum LightShadows {
|
|
|
106
108
|
export class Light extends Behaviour implements ILight {
|
|
107
109
|
|
|
108
110
|
/**
|
|
109
|
-
* The type of light
|
|
110
|
-
* Can not be changed at runtime.
|
|
111
|
+
* The type of light as a lowercase string: `"directional"`, `"point"`, `"spot"`.
|
|
112
|
+
* Implements {@link ILight.type}. Can not be changed at runtime.
|
|
111
113
|
*/
|
|
114
|
+
get type(): ILight["type"] {
|
|
115
|
+
return this._type;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Numeric LightType serialized from Unity/Blender — converts to string on write */
|
|
112
119
|
@serializable()
|
|
113
|
-
|
|
120
|
+
set type(value: LightType | ILight["type"]) {
|
|
121
|
+
if (this.light && this.__didAwake) {
|
|
122
|
+
throw new Error("Changing the light type at runtime is not supported");
|
|
123
|
+
}
|
|
124
|
+
switch (value) {
|
|
125
|
+
case LightType.Directional:
|
|
126
|
+
this._type = "directional";
|
|
127
|
+
break;
|
|
128
|
+
case LightType.Point:
|
|
129
|
+
this._type = "point";
|
|
130
|
+
break;
|
|
131
|
+
case LightType.Spot:
|
|
132
|
+
this._type = "spot";
|
|
133
|
+
break;
|
|
134
|
+
case "directional":
|
|
135
|
+
case "point":
|
|
136
|
+
case "spot":
|
|
137
|
+
this._type = value;
|
|
138
|
+
break;
|
|
139
|
+
default:
|
|
140
|
+
throw new Error("Invalid light type: " + value);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
private _type: ILight["type"] = "point";
|
|
144
|
+
|
|
114
145
|
|
|
115
146
|
/**
|
|
116
147
|
* The maximum distance the light affects.
|
|
@@ -174,6 +205,9 @@ export class Light extends Behaviour implements ILight {
|
|
|
174
205
|
if (this.light !== undefined) {
|
|
175
206
|
this.light.color = val;
|
|
176
207
|
}
|
|
208
|
+
if (this._csm) {
|
|
209
|
+
for (const l of this._csm.lights) l.color.copy(val);
|
|
210
|
+
}
|
|
177
211
|
}
|
|
178
212
|
get color(): Color {
|
|
179
213
|
if (this.light) return this.light.color;
|
|
@@ -259,6 +293,9 @@ export class Light extends Behaviour implements ILight {
|
|
|
259
293
|
if (this.light) {
|
|
260
294
|
this.light.intensity = val;
|
|
261
295
|
}
|
|
296
|
+
if (this._csm) {
|
|
297
|
+
for (const l of this._csm.lights) l.intensity = val;
|
|
298
|
+
}
|
|
262
299
|
if (debug) console.log("Set light intensity to " + this._intensity, val, this)
|
|
263
300
|
}
|
|
264
301
|
get intensity(): number { return this._intensity; }
|
|
@@ -312,6 +349,24 @@ export class Light extends Behaviour implements ILight {
|
|
|
312
349
|
}
|
|
313
350
|
private _shadowResolution?: number = undefined;
|
|
314
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Number of shadow cascade levels (only used when `useCascades` is true)
|
|
354
|
+
*/
|
|
355
|
+
@serializable()
|
|
356
|
+
cascades: number = 3;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Cascade split mode (only used when `useCascades` is true):
|
|
360
|
+
* - `practical` — balanced (default, recommended)
|
|
361
|
+
* - `logarithmic` — more resolution close up
|
|
362
|
+
* - `uniform` — equal splits
|
|
363
|
+
*/
|
|
364
|
+
@serializable()
|
|
365
|
+
cascadeMode: "practical" | "logarithmic" | "uniform" = "practical";
|
|
366
|
+
|
|
367
|
+
private _csm?: CSM;
|
|
368
|
+
private _csmHelper?: CSMHelper;
|
|
369
|
+
|
|
315
370
|
/**
|
|
316
371
|
* Whether this light's illumination is entirely baked into lightmaps
|
|
317
372
|
*/
|
|
@@ -345,7 +400,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
345
400
|
*/
|
|
346
401
|
public getWorldPosition(vec: Vector3): Vector3 {
|
|
347
402
|
if (this.light) {
|
|
348
|
-
if (this.type ===
|
|
403
|
+
if (this.type === "directional") {
|
|
349
404
|
return this.light.getWorldPosition(vec).multiplyScalar(1);
|
|
350
405
|
}
|
|
351
406
|
return this.light.getWorldPosition(vec);
|
|
@@ -372,12 +427,21 @@ export class Light extends Behaviour implements ILight {
|
|
|
372
427
|
else if (this.light.parent !== this.gameObject)
|
|
373
428
|
this.gameObject.add(this.light);
|
|
374
429
|
}
|
|
375
|
-
|
|
376
|
-
this.startCoroutine(this.updateMainLightRoutine(), FrameEvent.LateUpdate);
|
|
430
|
+
this.context.lights.add(this);
|
|
377
431
|
}
|
|
378
432
|
|
|
379
433
|
onDisable() {
|
|
380
434
|
if (debug) console.log("DISABLE LIGHT", this.name);
|
|
435
|
+
this.context.lights.delete(this);
|
|
436
|
+
if (this._csm) {
|
|
437
|
+
this._csm.remove();
|
|
438
|
+
this._csm.dispose();
|
|
439
|
+
this._csm = undefined;
|
|
440
|
+
if (this._csmHelper) {
|
|
441
|
+
this._csmHelper.removeFromParent();
|
|
442
|
+
this._csmHelper = undefined;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
381
445
|
if (this.light) {
|
|
382
446
|
if (this.selfIsLight)
|
|
383
447
|
this.light.intensity = 0;
|
|
@@ -386,6 +450,27 @@ export class Light extends Behaviour implements ILight {
|
|
|
386
450
|
}
|
|
387
451
|
}
|
|
388
452
|
|
|
453
|
+
onBeforeRender() {
|
|
454
|
+
if (this.type === "directional" && this.shadows !== LightShadows.None) {
|
|
455
|
+
// context.mainLight is computed — always returns the brightest registered directional light
|
|
456
|
+
const isMain = this.context.mainLight === this;
|
|
457
|
+
if (isMain) {
|
|
458
|
+
if (!this._csm) this.createCSM();
|
|
459
|
+
} else if (this._csm) {
|
|
460
|
+
// this light is no longer the main light (a brighter one took over) — tear down CSM
|
|
461
|
+
this._csm.remove();
|
|
462
|
+
this._csm.dispose();
|
|
463
|
+
this._csm = undefined;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (this._csm) {
|
|
467
|
+
// keep lightDirection in sync with the gameObject's world orientation
|
|
468
|
+
this._csm.lightDirection.copy(this.gameObject.worldForward);
|
|
469
|
+
this._csm.update();
|
|
470
|
+
if (this._csmHelper) this._csmHelper.update();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
389
474
|
/**
|
|
390
475
|
* Creates the appropriate three.js light based on the configured light type
|
|
391
476
|
* and applies all settings like shadows, intensity, and color.
|
|
@@ -399,14 +484,14 @@ export class Light extends Behaviour implements ILight {
|
|
|
399
484
|
this._intensity = this.light.intensity;
|
|
400
485
|
|
|
401
486
|
switch (this.type) {
|
|
402
|
-
case
|
|
487
|
+
case "directional":
|
|
403
488
|
this.setDirectionalLight(this.light as DirectionalLight);
|
|
404
489
|
break;
|
|
405
490
|
}
|
|
406
491
|
}
|
|
407
492
|
else if (!this.light) {
|
|
408
493
|
switch (this.type) {
|
|
409
|
-
case
|
|
494
|
+
case "directional":
|
|
410
495
|
// console.log(this);
|
|
411
496
|
const dirLight = new DirectionalLight(this.color, this.intensity * Math.PI);
|
|
412
497
|
// directional light target is at 0 0 0 by default
|
|
@@ -425,7 +510,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
425
510
|
}
|
|
426
511
|
break;
|
|
427
512
|
|
|
428
|
-
case
|
|
513
|
+
case "spot":
|
|
429
514
|
const spotLight = new SpotLight(this.color, this.intensity * Math.PI, this.range, toRadians(this.spotAngle / 2), 1 - toRadians(this.innerSpotAngle / 2) / toRadians(this.spotAngle / 2), 2);
|
|
430
515
|
spotLight.position.set(0, 0, 0);
|
|
431
516
|
spotLight.rotation.set(0, 0, 0);
|
|
@@ -437,7 +522,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
437
522
|
spotLightTarget.rotation.set(0, 0, 0);
|
|
438
523
|
break;
|
|
439
524
|
|
|
440
|
-
case
|
|
525
|
+
case "point":
|
|
441
526
|
const pointLight = new PointLight(this.color, this.intensity * Math.PI, this.range);
|
|
442
527
|
this.light = pointLight;
|
|
443
528
|
|
|
@@ -526,22 +611,6 @@ export class Light extends Behaviour implements ILight {
|
|
|
526
611
|
|
|
527
612
|
}
|
|
528
613
|
|
|
529
|
-
/**
|
|
530
|
-
* Coroutine that updates the main light reference in the context
|
|
531
|
-
* if this directional light should be the main light
|
|
532
|
-
*/
|
|
533
|
-
*updateMainLightRoutine() {
|
|
534
|
-
while (true) {
|
|
535
|
-
if (this.type === LightType.Directional) {
|
|
536
|
-
if (!this.context.mainLight || this.intensity > this.context.mainLight.intensity) {
|
|
537
|
-
this.context.mainLight = this;
|
|
538
|
-
}
|
|
539
|
-
yield;
|
|
540
|
-
}
|
|
541
|
-
break;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
614
|
/**
|
|
546
615
|
* Controls whether the renderer's shadow map type can be changed when soft shadows are used
|
|
547
616
|
*/
|
|
@@ -598,6 +667,41 @@ export class Light extends Behaviour implements ILight {
|
|
|
598
667
|
}
|
|
599
668
|
}
|
|
600
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Creates and initializes a CSM instance for this directional light.
|
|
672
|
+
* CSM manages its own cascade DirectionalLights internally.
|
|
673
|
+
*/
|
|
674
|
+
private createCSM() {
|
|
675
|
+
const camera = this.context.mainCamera;
|
|
676
|
+
if (!camera) {
|
|
677
|
+
if (debug) console.warn("CSM: no main camera found, deferring");
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
this._csm = new CSM({
|
|
682
|
+
camera,
|
|
683
|
+
parent: this.context.scene,
|
|
684
|
+
cascades: this.cascades,
|
|
685
|
+
mode: this.cascadeMode,
|
|
686
|
+
maxFar: this._shadowDistance ?? shadowMaxDistance,
|
|
687
|
+
shadowMapSize: this._shadowResolution ?? 2048,
|
|
688
|
+
shadowBias: this._shadowBias,
|
|
689
|
+
lightDirection: this.gameObject.worldForward.clone(),
|
|
690
|
+
lightIntensity: this._intensity >= 0 ? this._intensity : 1,
|
|
691
|
+
});
|
|
692
|
+
this._csm.fade = true;
|
|
693
|
+
|
|
694
|
+
// apply color to all cascade lights
|
|
695
|
+
for (const l of this._csm.lights) {
|
|
696
|
+
l.color.copy(this._color);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
if (debug) {
|
|
700
|
+
this._csmHelper = new CSMHelper(this._csm);
|
|
701
|
+
this.context.scene.add(this._csmHelper);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
601
705
|
/**
|
|
602
706
|
* Configures a directional light by adding and positioning its target
|
|
603
707
|
* @param dirLight The directional light to set up
|
|
@@ -610,4 +714,5 @@ export class Light extends Behaviour implements ILight {
|
|
|
610
714
|
}
|
|
611
715
|
|
|
612
716
|
const vec = new Vector3(0, 0, 0);
|
|
717
|
+
const _csmLightDir = new Vector3();
|
|
613
718
|
|
|
@@ -382,12 +382,12 @@ export class Rigidbody extends Behaviour implements IRigidbody {
|
|
|
382
382
|
this._watch.start(true, true);
|
|
383
383
|
this.startCoroutine(this.beforePhysics(), FrameEvent.LateUpdate);
|
|
384
384
|
if (isDevEnvironment()) {
|
|
385
|
-
if (
|
|
386
|
-
console.warn(`
|
|
385
|
+
if (globalThis["NEEDLE_USE_RAPIER"] === false)
|
|
386
|
+
console.warn(`RAPIER physics are disabled in your build. Enable them by setting NEEDLE_USE_RAPIER to true in your build config: Rigidbody could not be created.`);
|
|
387
387
|
else {
|
|
388
388
|
MODULES.RAPIER_PHYSICS.ready().then(async () => {
|
|
389
389
|
await delayForFrames(3);
|
|
390
|
-
if (!this.context.physics.engine?.getBody(this))
|
|
390
|
+
if (this.activeAndEnabled && !this.context.physics.engine?.getBody(this))
|
|
391
391
|
console.warn(`Rigidbody could not be created. Ensure \"${this.name}\" has a Collider component.`);
|
|
392
392
|
})
|
|
393
393
|
}
|
|
@@ -723,6 +723,7 @@ export class SceneSwitcher extends Behaviour {
|
|
|
723
723
|
// unless the user defines that he wants to use the scene name
|
|
724
724
|
if (this.useSceneName) {
|
|
725
725
|
if (scene instanceof Object3D) queryParameterValue = scene.name;
|
|
726
|
+
else if (scene instanceof AssetReference && scene.asset?.name) queryParameterValue = scene.asset.name;
|
|
726
727
|
else if (scene.url) queryParameterValue = sceneUriToName(scene.url);
|
|
727
728
|
}
|
|
728
729
|
// save the loaded scene as an url parameter
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { EffectAttribute } from "postprocessing";
|
|
2
1
|
import { Uniform } from "three";
|
|
3
2
|
|
|
4
3
|
import { MODULES } from "../../../engine/engine_modules.js";
|
|
@@ -138,7 +137,7 @@ function createSharpeningEffectType() {
|
|
|
138
137
|
["radius", new Uniform(1)],
|
|
139
138
|
// ["threshold", new Uniform(0)],
|
|
140
139
|
]),
|
|
141
|
-
attributes: EffectAttribute.CONVOLUTION
|
|
140
|
+
attributes: MODULES.POSTPROCESSING.MODULE.EffectAttribute.CONVOLUTION
|
|
142
141
|
});
|
|
143
142
|
}
|
|
144
143
|
}
|
|
@@ -14,10 +14,6 @@ import { threeToneMappingToEffectMode } from "./Effects/Tonemapping.utils.js";
|
|
|
14
14
|
import { PostProcessingEffect, PostProcessingEffectContext } from "./PostProcessingEffect.js";
|
|
15
15
|
import { orderEffects, PostprocessingEffectData, PostProcessingEffectOrder } from "./utils.js";
|
|
16
16
|
|
|
17
|
-
declare const NEEDLE_USE_POSTPROCESSING: boolean;
|
|
18
|
-
globalThis["NEEDLE_USE_POSTPROCESSING"] = globalThis["NEEDLE_USE_POSTPROCESSING"] !== undefined ? globalThis["NEEDLE_USE_POSTPROCESSING"] : true;
|
|
19
|
-
|
|
20
|
-
|
|
21
17
|
const debug = getParam("debugpost");
|
|
22
18
|
|
|
23
19
|
const activeKey = Symbol("needle:postprocessing-handler");
|
|
@@ -58,13 +54,13 @@ export class PostProcessingHandler implements IPostProcessingHandler {
|
|
|
58
54
|
|
|
59
55
|
apply(components: PostProcessingEffect[]): Promise<void> {
|
|
60
56
|
if ("env" in import.meta && (import.meta as any /* webpack support */ ).env.VITE_NEEDLE_USE_POSTPROCESSING === "false") {
|
|
61
|
-
if (debug) console.warn("
|
|
62
|
-
else console.debug("
|
|
57
|
+
if (debug) console.warn("POSTPROCESSING is disabled via vite env setting");
|
|
58
|
+
else console.debug("POSTPROCESSING is disabled via vite env setting");
|
|
63
59
|
return Promise.resolve();
|
|
64
60
|
}
|
|
65
61
|
if (!NEEDLE_USE_POSTPROCESSING) {
|
|
66
|
-
if (debug) console.warn("
|
|
67
|
-
else console.debug("
|
|
62
|
+
if (debug || isDevEnvironment()) console.warn("POSTPROCESSING is disabled via global vite define setting");
|
|
63
|
+
else console.debug("POSTPROCESSING is disabled via vite define");
|
|
68
64
|
return Promise.resolve();
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// For firefox ViewTimeline support
|
|
2
|
-
|
|
1
|
+
// For firefox ViewTimeline support — dynamic import to avoid SSR crashes (polyfill accesses window at module level)
|
|
2
|
+
if (typeof window !== "undefined") import("scroll-timeline-polyfill/dist/scroll-timeline.js");
|
|
3
3
|
|
|
4
4
|
import { Box3, Object3D } from "three";
|
|
5
5
|
|