@needle-tools/engine 3.0.0-alpha → 3.0.1-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 +3 -0
- package/dist/needle-engine.js +9552 -9570
- package/dist/needle-engine.min.js +4812 -0
- package/dist/needle-engine.umd.cjs +279 -279
- package/lib/engine/engine_addressables.js +1 -1
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_assetdatabase.js +24 -17
- package/lib/engine/engine_assetdatabase.js.map +1 -1
- package/lib/engine/engine_context.d.ts +0 -1
- package/lib/engine/engine_context.js +15 -17
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.d.ts +2 -1
- package/lib/engine/engine_context_registry.js +6 -1
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_element.js +1 -1
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_gltf.d.ts +2 -2
- package/lib/engine/engine_mainloop_utils.js +13 -11
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking_files.js +4 -3
- package/lib/engine/engine_networking_files.js.map +1 -1
- package/lib/engine/engine_patcher.d.ts +4 -3
- package/lib/engine/engine_patcher.js +61 -44
- package/lib/engine/engine_patcher.js.map +1 -1
- package/lib/engine/engine_scenetools.d.ts +4 -4
- package/lib/engine/engine_scenetools.js +5 -5
- package/lib/engine/engine_scenetools.js.map +1 -1
- package/lib/engine/engine_time.d.ts +2 -1
- package/lib/engine/engine_time.js.map +1 -1
- package/lib/engine/engine_types.d.ts +5 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +1 -1
- package/lib/engine-components/Animation.js +3 -3
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -1
- package/lib/engine-components/Renderer.js +15 -4
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -0
- package/lib/engine-components/api.js +2 -0
- package/lib/engine-components/api.js.map +1 -0
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.d.ts +2 -0
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js +18 -1
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +3 -0
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -1
- package/lib/engine-components/ui/Text.js +42 -17
- package/lib/engine-components/ui/Text.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/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/plugins/vite/copyfiles.js +37 -10
- package/plugins/vite/reload.js +2 -1
- package/src/engine/engine_addressables.ts +1 -1
- package/src/engine/engine_assetdatabase.ts +29 -18
- package/src/engine/engine_context.ts +15 -18
- package/src/engine/engine_context_registry.ts +7 -1
- package/src/engine/engine_element.ts +1 -1
- package/src/engine/engine_gltf.ts +2 -2
- package/src/engine/engine_mainloop_utils.ts +12 -10
- package/src/engine/engine_networking_files.ts +5 -4
- package/src/engine/engine_patcher.ts +104 -47
- package/src/engine/engine_scenetools.ts +7 -7
- package/src/engine/engine_time.ts +2 -1
- package/src/engine/engine_types.ts +6 -0
- package/src/engine-components/Animation.ts +3 -3
- package/src/engine-components/Renderer.ts +19 -5
- package/src/engine-components/api.ts +1 -0
- package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusion.ts +15 -1
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +1 -1
- package/src/engine-components/ui/Text.ts +41 -17
- package/src/needle-engine.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1-alpha",
|
|
4
4
|
"description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally.",
|
|
5
5
|
"main": "dist/needle-engine.umd.cjs",
|
|
6
6
|
"module": "lib/needle-engine.js",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"flatbuffers": "2.0.4",
|
|
58
58
|
"md5": "^2.3.0",
|
|
59
59
|
"peerjs": "1.3.2",
|
|
60
|
-
"simplex-noise": "^4.0.1",
|
|
61
60
|
"postprocessing": "^6.30.1",
|
|
61
|
+
"simplex-noise": "^4.0.1",
|
|
62
62
|
"stats.js": "^0.17.0",
|
|
63
63
|
"three": "npm:@needle-tools/three@^0.146.6",
|
|
64
64
|
"three-mesh-ui": "^6.4.5",
|
|
@@ -72,10 +72,9 @@
|
|
|
72
72
|
"@needle-tools/helper": "^0.4.5",
|
|
73
73
|
"@needle-tools/needle-component-compiler": "1.9.3",
|
|
74
74
|
"@types/three": "0.146.0",
|
|
75
|
-
"copy-files-from-to": "^3.7.0",
|
|
76
75
|
"esbuild": "^0.15.10",
|
|
77
76
|
"esbuild-node-externals": "^1.5.0",
|
|
78
|
-
"fs-extra": "^11.1.
|
|
77
|
+
"fs-extra": "^11.1.1",
|
|
79
78
|
"jsdoc-babel": "^0.5.0",
|
|
80
79
|
"jsdoc-to-markdown": "^7.1.1",
|
|
81
80
|
"madge": "^5.0.1",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { existsSync } from 'fs';
|
|
2
|
+
import { resolve, join } from 'path'
|
|
3
|
+
import { existsSync, statSync, mkdirSync, readdirSync, copyFileSync, mkdir } from 'fs';
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
/** copy files on build from assets to dist */
|
|
@@ -11,32 +10,60 @@ export const needleCopyFiles = (command, config, userSettings) => {
|
|
|
11
10
|
return;
|
|
12
11
|
}
|
|
13
12
|
|
|
13
|
+
const copyIncludesFromEngine = config?.copyIncludesFromEngine ?? true;
|
|
14
|
+
|
|
14
15
|
return {
|
|
15
16
|
name: 'needle-copy-files',
|
|
16
17
|
apply: 'build',
|
|
17
18
|
async closeBundle() {
|
|
18
19
|
const baseDir = process.cwd();
|
|
20
|
+
const pluginName = "needle-copy-files";
|
|
19
21
|
|
|
20
22
|
const outdirName = "dist";
|
|
21
23
|
const outDir = resolve(baseDir, outdirName);
|
|
22
24
|
if (!existsSync(outDir)) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
mkdirSync(outDir);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (copyIncludesFromEngine !== false) {
|
|
29
|
+
// copy include from engine
|
|
30
|
+
const engineIncludeDir = resolve(baseDir, 'node_modules', '@needle-tools', 'engine', 'src', 'include');
|
|
31
|
+
if (existsSync(engineIncludeDir)) {
|
|
32
|
+
console.log(`[${pluginName}] - Copy engine include to ${baseDir}/include`)
|
|
33
|
+
const targetDir = resolve(baseDir, 'include');
|
|
34
|
+
copyRecursiveSync(engineIncludeDir, targetDir);
|
|
35
|
+
}
|
|
25
36
|
}
|
|
37
|
+
|
|
26
38
|
// copy assets dir
|
|
27
39
|
const assetsDir = resolve(baseDir, 'assets');
|
|
28
40
|
if (existsSync(assetsDir)) {
|
|
29
|
-
console.log(`Copy assets to ${outdirName}/assets`)
|
|
41
|
+
console.log(`[${pluginName}] - Copy assets to ${outdirName}/assets`)
|
|
30
42
|
const targetDir = resolve(outDir, 'assets');
|
|
31
|
-
|
|
43
|
+
copyRecursiveSync(assetsDir, targetDir);
|
|
32
44
|
}
|
|
33
45
|
// copy include dir
|
|
34
46
|
const includeDir = resolve(baseDir, 'include');
|
|
35
47
|
if (existsSync(includeDir)) {
|
|
36
|
-
console.log(`Copy include to ${outdirName}/include`)
|
|
48
|
+
console.log(`[${pluginName}] - Copy include to ${outdirName}/include`)
|
|
37
49
|
const targetDir = resolve(outDir, 'include');
|
|
38
|
-
|
|
50
|
+
copyRecursiveSync(includeDir, targetDir);
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
|
-
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function copyRecursiveSync(src, dest) {
|
|
57
|
+
var exists = existsSync(src);
|
|
58
|
+
var stats = exists && statSync(src);
|
|
59
|
+
var isDirectory = exists && stats.isDirectory();
|
|
60
|
+
if (isDirectory) {
|
|
61
|
+
if (!existsSync(dest))
|
|
62
|
+
mkdirSync(dest);
|
|
63
|
+
readdirSync(src).forEach(function (childItemName) {
|
|
64
|
+
copyRecursiveSync(join(src, childItemName), join(dest, childItemName));
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
copyFileSync(src, dest);
|
|
68
|
+
}
|
|
69
|
+
};
|
package/plugins/vite/reload.js
CHANGED
|
@@ -43,7 +43,8 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
43
43
|
else if (!config.server.watch.ignored) config.server.watch.ignored = [];
|
|
44
44
|
for (const pattern of ignorePatterns)
|
|
45
45
|
config.server.watch.ignored.push(pattern);
|
|
46
|
-
|
|
46
|
+
if(config?.debug === true || userSettings?.debug === true)
|
|
47
|
+
setTimeout(() => console.log("Updated server ignore patterns: ", config.server.watch.ignored), 100);
|
|
47
48
|
},
|
|
48
49
|
handleHotUpdate(args) {
|
|
49
50
|
args.buildDirectory = buildDirectory;
|
|
@@ -163,7 +163,7 @@ export class AssetReference {
|
|
|
163
163
|
}
|
|
164
164
|
else {
|
|
165
165
|
if (debug) console.log("Load async", this.uri);
|
|
166
|
-
this._loading = getLoader().loadSync(context, this._hashedUri,
|
|
166
|
+
this._loading = getLoader().loadSync(context, this._hashedUri, this.uri, null, prog => {
|
|
167
167
|
this.raiseProgressEvent(prog);
|
|
168
168
|
});
|
|
169
169
|
}
|
|
@@ -278,27 +278,21 @@ function updateUsers(symbol: symbol, user: object, object: object | object[], ad
|
|
|
278
278
|
|
|
279
279
|
// We dont want to update users during rendering
|
|
280
280
|
|
|
281
|
-
const $renderMethod = Symbol("render-method");
|
|
282
|
-
|
|
283
|
-
Object.defineProperty(WebGLRenderer.prototype, "render", {
|
|
284
|
-
set: function (this: WebGLRenderer, value: Function) {
|
|
285
|
-
this[$renderMethod] = wrapMethod(value);
|
|
286
|
-
},
|
|
287
|
-
get: function (this: WebGLRenderer) {
|
|
288
|
-
return this[$renderMethod];
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
281
|
|
|
282
|
+
try {
|
|
292
283
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
284
|
+
// addPatch(WebGLRenderer.prototype, "render",
|
|
285
|
+
// () => {
|
|
286
|
+
// noUpdateScope++;
|
|
287
|
+
// },
|
|
288
|
+
// () => {
|
|
289
|
+
// noUpdateScope--;
|
|
290
|
+
// }
|
|
291
|
+
// );
|
|
292
|
+
}
|
|
293
|
+
catch (e) {
|
|
294
|
+
console.warn("Could not wrap WebGLRenderer.render", e);
|
|
300
295
|
}
|
|
301
|
-
|
|
302
296
|
|
|
303
297
|
|
|
304
298
|
// addGltfLoadEventListener(GltfLoadEventType.BeforeLoad, (_) => {
|
|
@@ -320,3 +314,20 @@ function wrapMethod(fn: Function) {
|
|
|
320
314
|
// }
|
|
321
315
|
// });
|
|
322
316
|
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
// class MyObject {
|
|
322
|
+
// myNumber: number = 1;
|
|
323
|
+
// }
|
|
324
|
+
|
|
325
|
+
// addPatch(MyObject.prototype, "myNumber", (obj, oldValue, newValue) => {
|
|
326
|
+
// console.log("myNumber changed", oldValue, newValue);
|
|
327
|
+
// });
|
|
328
|
+
|
|
329
|
+
// const i = new MyObject();
|
|
330
|
+
// setInterval(() => {
|
|
331
|
+
// console.log("RUN");
|
|
332
|
+
// i.myNumber += 1;
|
|
333
|
+
// }, 1000);
|
|
@@ -87,15 +87,12 @@ export function registerComponent(script: IComponent, context?: Context) {
|
|
|
87
87
|
|
|
88
88
|
export class Context implements IContext {
|
|
89
89
|
|
|
90
|
-
private static _current: Context;
|
|
91
|
-
|
|
92
90
|
static get Current(): Context {
|
|
93
|
-
return
|
|
91
|
+
return ContextRegistry.Current as Context;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
static set Current(context: Context) {
|
|
97
95
|
ContextRegistry.Current = context;
|
|
98
|
-
this._current = context;
|
|
99
96
|
}
|
|
100
97
|
|
|
101
98
|
name: string;
|
|
@@ -307,7 +304,7 @@ export class Context implements IContext {
|
|
|
307
304
|
// private _requestSizeUpdate : boolean = false;
|
|
308
305
|
|
|
309
306
|
updateSize() {
|
|
310
|
-
if (!this.isManagedExternally &&
|
|
307
|
+
if (!this.isManagedExternally && this.renderer.xr?.isPresenting === false) {
|
|
311
308
|
this._sizeChanged = false;
|
|
312
309
|
const scaleFactor = this.resolutionScaleFactor;
|
|
313
310
|
const width = this.domWidth * scaleFactor;
|
|
@@ -516,10 +513,10 @@ export class Context implements IContext {
|
|
|
516
513
|
if (!this.isManagedExternally)
|
|
517
514
|
this.domElement.prepend(this.renderer.domElement);
|
|
518
515
|
|
|
519
|
-
Context.
|
|
516
|
+
Context.Current = this;
|
|
520
517
|
|
|
521
518
|
// Setup
|
|
522
|
-
Context.
|
|
519
|
+
Context.Current = this;
|
|
523
520
|
for (let i = 0; i < this.new_scripts.length; i++) {
|
|
524
521
|
const script = this.new_scripts[i];
|
|
525
522
|
if (script.gameObject !== undefined && script.gameObject !== null) {
|
|
@@ -546,13 +543,13 @@ export class Context implements IContext {
|
|
|
546
543
|
// resolve post setup callbacks (things that rely on threejs objects having references to components)
|
|
547
544
|
if (this.post_setup_callbacks) {
|
|
548
545
|
for (let i = 0; i < this.post_setup_callbacks.length; i++) {
|
|
549
|
-
Context.
|
|
546
|
+
Context.Current = this;
|
|
550
547
|
await this.post_setup_callbacks[i](this);
|
|
551
548
|
}
|
|
552
549
|
}
|
|
553
550
|
|
|
554
551
|
if (!this.mainCamera) {
|
|
555
|
-
Context.
|
|
552
|
+
Context.Current = this;
|
|
556
553
|
let camera: ICamera | null = null;
|
|
557
554
|
foreachComponent(this.scene, comp => {
|
|
558
555
|
const cam = comp as ICamera;
|
|
@@ -577,7 +574,7 @@ export class Context implements IContext {
|
|
|
577
574
|
}
|
|
578
575
|
}
|
|
579
576
|
|
|
580
|
-
Context.
|
|
577
|
+
Context.Current = this;
|
|
581
578
|
looputils.processNewScripts(this);
|
|
582
579
|
|
|
583
580
|
// const mainCam = this.mainCameraComponent as Camera;
|
|
@@ -624,10 +621,10 @@ export class Context implements IContext {
|
|
|
624
621
|
|
|
625
622
|
this._stats?.begin();
|
|
626
623
|
|
|
627
|
-
Context.
|
|
624
|
+
Context.Current = this;
|
|
628
625
|
if (this.onHandlePaused()) return;
|
|
629
626
|
|
|
630
|
-
Context.
|
|
627
|
+
Context.Current = this;
|
|
631
628
|
this.time.update();
|
|
632
629
|
if (debugframerate)
|
|
633
630
|
console.log("FPS", (this.time.smoothedFps).toFixed(0));
|
|
@@ -655,7 +652,7 @@ export class Context implements IContext {
|
|
|
655
652
|
const script = this.scripts_earlyUpdate[i];
|
|
656
653
|
if (!script.activeAndEnabled) continue;
|
|
657
654
|
if (script.earlyUpdate !== undefined) {
|
|
658
|
-
Context.
|
|
655
|
+
Context.Current = this;
|
|
659
656
|
script.earlyUpdate();
|
|
660
657
|
}
|
|
661
658
|
}
|
|
@@ -668,7 +665,7 @@ export class Context implements IContext {
|
|
|
668
665
|
const script = this.scripts_update[i];
|
|
669
666
|
if (!script.activeAndEnabled) continue;
|
|
670
667
|
if (script.update !== undefined) {
|
|
671
|
-
Context.
|
|
668
|
+
Context.Current = this;
|
|
672
669
|
script.update();
|
|
673
670
|
}
|
|
674
671
|
}
|
|
@@ -681,7 +678,7 @@ export class Context implements IContext {
|
|
|
681
678
|
const script = this.scripts_lateUpdate[i];
|
|
682
679
|
if (!script.activeAndEnabled) continue;
|
|
683
680
|
if (script.lateUpdate !== undefined) {
|
|
684
|
-
Context.
|
|
681
|
+
Context.Current = this;
|
|
685
682
|
script.lateUpdate();
|
|
686
683
|
}
|
|
687
684
|
}
|
|
@@ -712,7 +709,7 @@ export class Context implements IContext {
|
|
|
712
709
|
if (!script.activeAndEnabled) continue;
|
|
713
710
|
// if(script.isActiveAndEnabled === false) continue;
|
|
714
711
|
if (script.onBeforeRender !== undefined) {
|
|
715
|
-
Context.
|
|
712
|
+
Context.Current = this;
|
|
716
713
|
script.onBeforeRender(frame);
|
|
717
714
|
}
|
|
718
715
|
}
|
|
@@ -741,7 +738,7 @@ export class Context implements IContext {
|
|
|
741
738
|
const script = this.scripts_onAfterRender[i];
|
|
742
739
|
if (!script.activeAndEnabled) continue;
|
|
743
740
|
if (script.onAfterRender !== undefined) {
|
|
744
|
-
Context.
|
|
741
|
+
Context.Current = this;
|
|
745
742
|
script.onAfterRender();
|
|
746
743
|
}
|
|
747
744
|
}
|
|
@@ -798,7 +795,7 @@ export class Context implements IContext {
|
|
|
798
795
|
const script = this.scripts_pausedChanged[i];
|
|
799
796
|
if (!script.activeAndEnabled) continue;
|
|
800
797
|
if (script.onPausedChanged !== undefined) {
|
|
801
|
-
Context.
|
|
798
|
+
Context.Current = this;
|
|
802
799
|
script.onPausedChanged(paused, this._wasPaused);
|
|
803
800
|
}
|
|
804
801
|
}
|
|
@@ -14,7 +14,13 @@ export type ContextEventArgs = {
|
|
|
14
14
|
export type ContextCallback = (evt: ContextEventArgs) => void;
|
|
15
15
|
|
|
16
16
|
export class ContextRegistry {
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
static get Current(): IContext{
|
|
19
|
+
return globalThis["NeedleEngine.Context.Current"]
|
|
20
|
+
}
|
|
21
|
+
static set Current(ctx: IContext) {
|
|
22
|
+
globalThis["NeedleEngine.Context.Current"] = ctx;
|
|
23
|
+
}
|
|
18
24
|
|
|
19
25
|
static Registered: IContext[] = [];
|
|
20
26
|
|
|
@@ -240,7 +240,7 @@ export class EngineElement extends HTMLElement implements INeedleEngineComponent
|
|
|
240
240
|
totalProgress01: this._loadingProgress01
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
-
const res = await loader.loadSync(ctx, url,
|
|
243
|
+
const res = await loader.loadSync(ctx, url, url, hash, prog => {
|
|
244
244
|
// Calc progress
|
|
245
245
|
progress.progress = prog;
|
|
246
246
|
this._loadingProgress01 = calculateProgress01(progress);
|
|
@@ -8,8 +8,8 @@ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'
|
|
|
8
8
|
export interface INeedleGltfLoader {
|
|
9
9
|
createBuiltinComponents(context: Context, gltfId: SourceIdentifier, gltf, seed: number | null | UIDProvider, extension?: NEEDLE_components): Promise<void>
|
|
10
10
|
writeBuiltinComponentData(comp: object, context: SerializationContext);
|
|
11
|
-
parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined>;
|
|
12
|
-
loadSync(context: Context, url: string, seed: number | UIDProvider | null,
|
|
11
|
+
parseSync(context: Context, data : string | ArrayBuffer, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined>;
|
|
12
|
+
loadSync(context: Context, url: string, sourceId:string, seed: number | UIDProvider | null, prog?: (prog : ProgressEvent) => void): Promise<GLTF | undefined>
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
let gltfLoader: INeedleGltfLoader;
|
|
@@ -370,17 +370,19 @@ export function runPrewarm(context: IContext) {
|
|
|
370
370
|
if (cam) {
|
|
371
371
|
if (debugPrewarm) console.log("prewarm", list.length, "objects", [...list]);
|
|
372
372
|
const renderer = context.renderer;
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
obj
|
|
380
|
-
|
|
373
|
+
if (renderer.compile) {
|
|
374
|
+
const scene = context.scene;
|
|
375
|
+
renderer.compile(scene, cam!)
|
|
376
|
+
prewarmTarget ??= new WebGLCubeRenderTarget(64)
|
|
377
|
+
prewarmCamera ??= new CubeCamera(0.001, 9999999, prewarmTarget);
|
|
378
|
+
prewarmCamera.update(renderer, scene);
|
|
379
|
+
for (const obj of list) {
|
|
380
|
+
obj[$prewarmedFlag] = true;
|
|
381
|
+
obj[$waitingForPrewarm] = false;
|
|
382
|
+
}
|
|
383
|
+
list.length = 0;
|
|
384
|
+
if (debugPrewarm) console.log("prewarm done");
|
|
381
385
|
}
|
|
382
|
-
list.length = 0;
|
|
383
|
-
if (debugPrewarm) console.log("prewarm done");
|
|
384
386
|
}
|
|
385
387
|
}
|
|
386
388
|
|
|
@@ -48,13 +48,13 @@ export async function addFile(file: File, context: Context, backendUrl?: string)
|
|
|
48
48
|
if (name.endsWith(".gltf") || name.endsWith(".glb")) {
|
|
49
49
|
return new Promise((resolve, _reject) => {
|
|
50
50
|
const reader = new FileReader()
|
|
51
|
-
reader.
|
|
51
|
+
reader.readAsArrayBuffer(file);
|
|
52
52
|
reader.onloadend = async (_ev: ProgressEvent<FileReader>) => {
|
|
53
|
-
const content = reader.result as
|
|
53
|
+
const content = reader.result as ArrayBuffer;
|
|
54
54
|
// first load it locally
|
|
55
55
|
const seed = generateSeed();
|
|
56
56
|
const prov = new InstantiateIdProvider(seed);
|
|
57
|
-
const gltf: GLTF = await getLoader().
|
|
57
|
+
const gltf: GLTF = await getLoader().parseSync(context, content, file.name, prov) as GLTF;
|
|
58
58
|
if (gltf && gltf.scene) {
|
|
59
59
|
const obj = gltf.scene as unknown as IGameObject;
|
|
60
60
|
// if we dont have a guid yet (because components guids are actually created in a callback a bit later)
|
|
@@ -85,7 +85,8 @@ export async function addFileFromUrl(url: URL, context: Context): Promise<GLTF |
|
|
|
85
85
|
return new Promise(async (resolve, _reject) => {
|
|
86
86
|
const seed = generateSeed();
|
|
87
87
|
const prov = new InstantiateIdProvider(seed);
|
|
88
|
-
const
|
|
88
|
+
const urlStr = url.toString();
|
|
89
|
+
const gltf: GLTF = await getLoader().loadSync(context, urlStr, urlStr, prov) as GLTF;
|
|
89
90
|
if (gltf && gltf.scene) {
|
|
90
91
|
const obj = gltf.scene as unknown as IGameObject;
|
|
91
92
|
// handleUpload(context.connection, file, seed, obj); // TODO needs to upload the URL only and store that
|
|
@@ -3,67 +3,102 @@
|
|
|
3
3
|
|
|
4
4
|
const _wrappedMethods = new WeakSet();
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
export
|
|
6
|
+
|
|
7
|
+
// export function wrap<T>(prototype: object, methodName: string, before: (t: T) => void, after: (t: T) => void) {
|
|
8
|
+
|
|
9
|
+
// const $key = Symbol(methodName + "-patched");
|
|
10
|
+
|
|
11
|
+
// const alreadyDefined = Object.getOwnPropertyDescriptor(prototype, methodName);
|
|
12
|
+
// if (alreadyDefined) {
|
|
13
|
+
// const originalRender = alreadyDefined.get;
|
|
14
|
+
// if (originalRender) {
|
|
15
|
+
// // Object.defineProperty(prototype, "render", {
|
|
16
|
+
// // set: function (this: any, value: Function) {
|
|
17
|
+
// // originalRender.call(this);
|
|
18
|
+
// // },
|
|
19
|
+
// // get: function (this: ) {
|
|
20
|
+
// // return originalRender.call(this);
|
|
21
|
+
// // }
|
|
22
|
+
// // });
|
|
23
|
+
// }
|
|
24
|
+
// }
|
|
25
|
+
// else {
|
|
26
|
+
// Object.defineProperty(prototype, methodName, {
|
|
27
|
+
// set: function (this: any, value: Function) {
|
|
28
|
+
// this[$key] = value;
|
|
29
|
+
// },
|
|
30
|
+
// get: function (this: any) {
|
|
31
|
+
// return this[$key];
|
|
32
|
+
// }
|
|
33
|
+
// });
|
|
34
|
+
// }
|
|
35
|
+
// }
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// export declare type FieldPatch = (instance: object, oldValue: any, newValue: any) => any;
|
|
39
|
+
|
|
40
|
+
export type Prefix = (...args) => any;
|
|
41
|
+
export type Postfix = (...args) => any;
|
|
8
42
|
|
|
9
43
|
/**
|
|
10
44
|
* Use patcher for patching properties insteadof calling Object.defineProperty individually
|
|
11
45
|
* since this will cause conflicts if multiple patches need to be applied to the same property
|
|
12
46
|
*/
|
|
13
|
-
export function addPatch<
|
|
47
|
+
export function addPatch<T extends object>(prototype: T, fieldName: string, beforeCallback?: Prefix, afterCallback?: Postfix) {
|
|
48
|
+
|
|
49
|
+
// TODO
|
|
50
|
+
return;
|
|
14
51
|
|
|
15
52
|
// TODO: we probably want to turn this into a symbol to prevent anyone from overriding it
|
|
16
53
|
// But when we need to store the symbol per prototype to allow e.g. material disposing to iterate those and dispose all
|
|
17
|
-
const backingField = fieldName + "__needle";// Symbol(fieldName);// + " (patched)";
|
|
54
|
+
const backingField = Symbol(fieldName + "__needle");// Symbol(fieldName);// + " (patched)";
|
|
18
55
|
|
|
19
|
-
internalAddPatch(prototype, fieldName,
|
|
56
|
+
internalAddPatch(prototype, fieldName, afterCallback, beforeCallback);
|
|
20
57
|
|
|
21
58
|
const desc = Object.getOwnPropertyDescriptor(prototype, fieldName);
|
|
59
|
+
|
|
60
|
+
const existing = prototype[fieldName];
|
|
61
|
+
console.log(prototype);
|
|
22
62
|
|
|
23
63
|
if (desc) {
|
|
24
|
-
// TODO: check if the property is writable
|
|
25
|
-
// the property might be a method in which case we want to wrap it
|
|
26
|
-
if (typeof desc.value === "function") {
|
|
27
|
-
const method = desc.value;
|
|
28
|
-
if (method) {
|
|
29
|
-
if (_wrappedMethods.has(method)) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
_wrappedMethods.add(method);
|
|
33
|
-
prototype[fieldName] = function (this: object, ...args: any[]) {
|
|
34
|
-
// call the original method
|
|
35
|
-
const result = method.apply(this, args);
|
|
36
|
-
// call the patches
|
|
37
|
-
const patches = getPatches(prototype, fieldName);
|
|
38
|
-
if (patches) {
|
|
39
|
-
for (const patch of patches) {
|
|
40
|
-
patch(this, result, ...args);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
// TODO: declare method?
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else if (prototype.hasOwnProperty(backingField)) {
|
|
52
64
|
}
|
|
53
65
|
else {
|
|
54
66
|
Object.defineProperty(prototype, fieldName, {
|
|
55
67
|
set: function (this: object, value: any) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
console.log("setting", fieldName, value);
|
|
69
|
+
if (typeof value === "function") {
|
|
70
|
+
this[backingField] = addWrapper(value, prototype, fieldName);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const prev = this[backingField];
|
|
74
|
+
executePrefixes(prototype, fieldName, this, prev, value);
|
|
75
|
+
this[backingField] = value;
|
|
76
|
+
executePostFixes(prototype, fieldName, this, prev, value);
|
|
77
|
+
}
|
|
59
78
|
},
|
|
60
79
|
get: function (this: any) {
|
|
61
|
-
|
|
80
|
+
console.log("GET", fieldName);
|
|
81
|
+
const value = this[backingField];
|
|
82
|
+
if (typeof value === "function") {
|
|
83
|
+
if (value[backingField]) {
|
|
84
|
+
return value[backingField];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
62
88
|
}
|
|
63
89
|
});
|
|
64
90
|
}
|
|
65
91
|
}
|
|
66
92
|
|
|
93
|
+
function addWrapper(originalFunction: Function, prototype, fieldname) {
|
|
94
|
+
return function (this: object, ...args: any[]) {
|
|
95
|
+
executePrefixes(prototype, fieldname, this, ...args);
|
|
96
|
+
const result = originalFunction.apply(this, args);
|
|
97
|
+
executePostFixes(prototype, fieldname, this, result, ...args);
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
67
102
|
export function removePatch(prototype: object, fieldName: string, cb: Function) {
|
|
68
103
|
const patches = getPatches(prototype, fieldName);
|
|
69
104
|
if (patches) {
|
|
@@ -76,38 +111,60 @@ export function removePatch(prototype: object, fieldName: string, cb: Function)
|
|
|
76
111
|
}
|
|
77
112
|
|
|
78
113
|
|
|
114
|
+
export const NeedlePatchesKey = "Needle:Patches";
|
|
79
115
|
|
|
80
|
-
|
|
81
|
-
|
|
116
|
+
declare type PatchInfo = {
|
|
117
|
+
prefix?: Prefix;
|
|
118
|
+
postfix?: Postfix;
|
|
119
|
+
}
|
|
120
|
+
function patches(): WeakMap<object, Map<string, PatchInfo[]>> {
|
|
121
|
+
if (!globalThis[NeedlePatchesKey]) {
|
|
122
|
+
globalThis[NeedlePatchesKey] = new WeakMap<object, Map<string, PatchInfo[]>>();
|
|
123
|
+
}
|
|
124
|
+
return globalThis[NeedlePatchesKey];
|
|
125
|
+
}
|
|
82
126
|
|
|
83
127
|
function getPatches(prototype, fieldName: string) {
|
|
84
|
-
let patchesMap = patches.get(prototype);
|
|
128
|
+
let patchesMap = patches().get(prototype);
|
|
85
129
|
if (!patchesMap) {
|
|
86
130
|
return null;
|
|
87
131
|
}
|
|
88
132
|
return patchesMap.get(fieldName);;
|
|
89
133
|
}
|
|
90
134
|
|
|
91
|
-
function internalAddPatch(prototype, fieldName: string,
|
|
92
|
-
let patchesMap = patches.get(prototype);
|
|
135
|
+
function internalAddPatch(prototype, fieldName: string, postfix?: Postfix, prefix?: Prefix) {
|
|
136
|
+
let patchesMap = patches().get(prototype);
|
|
93
137
|
if (!patchesMap) {
|
|
94
138
|
patchesMap = new Map();
|
|
95
|
-
patches.set(prototype, patchesMap);
|
|
139
|
+
patches().set(prototype, patchesMap);
|
|
96
140
|
}
|
|
97
141
|
let patchList = patchesMap.get(fieldName);
|
|
98
142
|
if (!patchList) {
|
|
99
143
|
patchList = [];
|
|
100
144
|
patchesMap.set(fieldName, patchList);
|
|
101
145
|
}
|
|
102
|
-
patchList.push(
|
|
146
|
+
patchList.push({
|
|
147
|
+
prefix: prefix,
|
|
148
|
+
postfix: postfix
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function executePrefixes(prototype, fieldName: string, instance: object, ...args) {
|
|
153
|
+
if (!instance) return;
|
|
154
|
+
const patches = getPatches(prototype, fieldName);
|
|
155
|
+
if (patches) {
|
|
156
|
+
for (const patchInfo of patches) {
|
|
157
|
+
patchInfo.prefix?.call(instance, ...args);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
103
160
|
}
|
|
104
161
|
|
|
105
|
-
function
|
|
162
|
+
function executePostFixes(prototype, fieldName: string, instance: object, result: any, ...args) {
|
|
106
163
|
if (!instance) return;
|
|
107
164
|
const patches = getPatches(prototype, fieldName);
|
|
108
165
|
if (patches) {
|
|
109
|
-
for (const
|
|
110
|
-
|
|
166
|
+
for (const patchInfo of patches) {
|
|
167
|
+
patchInfo.postfix?.call(instance, result, ...args);
|
|
111
168
|
}
|
|
112
169
|
}
|
|
113
170
|
}
|