@needle-tools/engine 3.0.0-alpha.1 → 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 +9914 -9823
- package/dist/needle-engine.min.js +4812 -0
- package/dist/needle-engine.umd.cjs +283 -283
- package/lib/engine/engine_addressables.js +1 -1
- package/lib/engine/engine_addressables.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_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_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_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
|
}
|
|
@@ -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
|
|
@@ -24,11 +24,11 @@ export class NeedleGltfLoader implements INeedleGltfLoader {
|
|
|
24
24
|
return writeBuiltinComponentData(comp, context);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
|
|
27
|
+
parseSync(context: Context, data : string | ArrayBuffer, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
|
|
28
28
|
return parseSync(context, data, path, seed);
|
|
29
29
|
}
|
|
30
|
-
loadSync(context: Context, url: string, seed: number | UIDProvider | null,
|
|
31
|
-
return loadSync(context, url,
|
|
30
|
+
loadSync(context: Context, url: string, sourceId:string, seed: number | UIDProvider | null, prog?: ((ProgressEvent: any) => void) | undefined): Promise<GLTF | undefined> {
|
|
31
|
+
return loadSync(context, url, sourceId, seed, prog);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -87,7 +87,7 @@ function invokeEvents(type: GltfLoadEventType, event: GltfLoadEvent) {
|
|
|
87
87
|
|
|
88
88
|
async function handleLoadedGltf(context: Context, gltfId: string, gltf, seed: number | null | UIDProvider, componentsExtension) {
|
|
89
89
|
if (printGltf)
|
|
90
|
-
console.
|
|
90
|
+
console.warn("glTF", gltfId, gltf);
|
|
91
91
|
await getLoader().createBuiltinComponents(context, gltfId, gltf, seed, componentsExtension);
|
|
92
92
|
|
|
93
93
|
// load and assign animation
|
|
@@ -102,7 +102,7 @@ export function createGLTFLoader(url: string, context: Context) {
|
|
|
102
102
|
return loader;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
export function parseSync(context: Context, data, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
|
|
105
|
+
export function parseSync(context: Context, data : string | ArrayBuffer, path: string, seed: number | UIDProvider | null): Promise<GLTF | undefined> {
|
|
106
106
|
if (typeof path !== "string") {
|
|
107
107
|
console.warn("Parse gltf binary without path, this might lead to errors in resolving extensions. Please provide the source path of the gltf/glb file", path, typeof path);
|
|
108
108
|
}
|
|
@@ -131,7 +131,7 @@ export function parseSync(context: Context, data, path: string, seed: number | U
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
export function loadSync(context: Context, url: string, seed: number | UIDProvider | null,
|
|
134
|
+
export function loadSync(context: Context, url: string, sourceId:string, seed: number | UIDProvider | null, prog?: (ProgressEvent) => void): Promise<GLTF | undefined> {
|
|
135
135
|
// better to create new loaders every time
|
|
136
136
|
// (maybe we can cache them...)
|
|
137
137
|
// but due to the async nature and potentially triggering multiple loads at the same time
|
|
@@ -145,7 +145,7 @@ export function loadSync(context: Context, url: string, seed: number | UIDProvid
|
|
|
145
145
|
invokeEvents(GltfLoadEventType.BeforeLoad, new GltfLoadEvent(context, url, loader));
|
|
146
146
|
loader.load(url, async data => {
|
|
147
147
|
invokeEvents(GltfLoadEventType.AfterLoaded, new GltfLoadEvent(context, url, loader, data));
|
|
148
|
-
await handleLoadedGltf(context,
|
|
148
|
+
await handleLoadedGltf(context, sourceId, data, seed, componentsExtension);
|
|
149
149
|
invokeEvents(GltfLoadEventType.FinishedSetup, new GltfLoadEvent(context, url, loader, data));
|
|
150
150
|
registerPrewarmObject(data.scene, context);
|
|
151
151
|
resolve(data);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Clock } from 'three'
|
|
2
2
|
import { getParam } from './engine_utils';
|
|
3
|
+
import { ITime } from './engine_types';
|
|
3
4
|
|
|
4
5
|
const timescaleUrl = getParam("timescale");
|
|
5
6
|
let timeScale = 1;
|
|
6
7
|
if (typeof timescaleUrl === "number") timeScale = timescaleUrl;
|
|
7
8
|
|
|
8
|
-
export class Time {
|
|
9
|
+
export class Time implements ITime {
|
|
9
10
|
|
|
10
11
|
deltaTime = 0;
|
|
11
12
|
time = 0;
|
|
@@ -27,9 +27,13 @@ export declare type CoroutineData = {
|
|
|
27
27
|
chained?: Array<Generator>
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export interface ITime {
|
|
31
|
+
get time(): number;
|
|
32
|
+
}
|
|
30
33
|
|
|
31
34
|
export interface IContext {
|
|
32
35
|
alias?: string | null;
|
|
36
|
+
hash?:string;
|
|
33
37
|
|
|
34
38
|
scene: Scene;
|
|
35
39
|
renderer: WebGLRenderer;
|
|
@@ -37,6 +41,8 @@ export interface IContext {
|
|
|
37
41
|
mainCameraComponent: ICamera | undefined;
|
|
38
42
|
domElement: HTMLElement;
|
|
39
43
|
|
|
44
|
+
time: ITime;
|
|
45
|
+
|
|
40
46
|
scripts: IComponent[];
|
|
41
47
|
scripts_pausedChanged: IComponent[];
|
|
42
48
|
// scripts with update event
|
|
@@ -145,7 +145,7 @@ export class Animation extends Behaviour {
|
|
|
145
145
|
return false;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
play(clipOrNumber: AnimationClip | number | string | undefined, options?: PlayOptions): Promise<AnimationAction> | void {
|
|
148
|
+
play(clipOrNumber: AnimationClip | number | string | undefined = 0, options?: PlayOptions): Promise<AnimationAction> | void {
|
|
149
149
|
if (debug) console.log("PLAY", clipOrNumber)
|
|
150
150
|
this.init();
|
|
151
151
|
if (!this.mixer) {
|
|
@@ -171,8 +171,8 @@ export class Animation extends Behaviour {
|
|
|
171
171
|
if (!options) options = {};
|
|
172
172
|
if (!options.minMaxOffsetNormalized) options.minMaxOffsetNormalized = this.minMaxOffsetNormalized;
|
|
173
173
|
if (!options.minMaxSpeed) options.minMaxSpeed = this.minMaxSpeed;
|
|
174
|
-
if (
|
|
175
|
-
if (
|
|
174
|
+
if (options.loop === undefined) options.loop = this.loop;
|
|
175
|
+
if (options.clampWhenFinished === undefined) options.clampWhenFinished = this.clampWhenFinished;
|
|
176
176
|
for (const act of this.actions) {
|
|
177
177
|
if (act.getClip() === clip) {
|
|
178
178
|
return this.internalOnPlay(act, options);
|
|
@@ -639,7 +639,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
|
|
642
|
-
|
|
642
|
+
applySettings(go: THREE.Object3D) {
|
|
643
643
|
go.receiveShadow = this.receiveShadows;
|
|
644
644
|
if (this.shadowCastingMode == ShadowCastingMode.On) {
|
|
645
645
|
go.castShadow = true;
|
|
@@ -734,15 +734,16 @@ class InstancingHandler {
|
|
|
734
734
|
public setup(renderer: Renderer, obj: THREE.Object3D, context: Context, handlesArray: InstanceHandle[] | null, args: InstancingSetupArgs, level: number = 0)
|
|
735
735
|
: InstanceHandle[] | null {
|
|
736
736
|
|
|
737
|
+
// make sure setting casting settings are applied so when we add the mesh to the InstancedMesh we can ask for the correct cast shadow setting
|
|
738
|
+
renderer.applySettings(obj);
|
|
737
739
|
const res = this.tryCreateOrAddInstance(obj, context, args);
|
|
738
740
|
if (res) {
|
|
739
741
|
renderer.loadProgressiveTextures(res.instancer.material);
|
|
740
742
|
if (handlesArray === null) handlesArray = [];
|
|
741
743
|
handlesArray.push(res);
|
|
742
|
-
return handlesArray;
|
|
743
744
|
}
|
|
744
745
|
|
|
745
|
-
if (level <= 0 && obj.type !== "Mesh") {
|
|
746
|
+
else if (level <= 0 && obj.type !== "Mesh") {
|
|
746
747
|
const nextLevel = level + 1;
|
|
747
748
|
for (const ch of obj.children) {
|
|
748
749
|
handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
|
|
@@ -799,10 +800,8 @@ class InstancingHandler {
|
|
|
799
800
|
let previousMatrix: THREE.Matrix4 = obj.matrixWorld.clone();
|
|
800
801
|
const matrixChangeWrapper = (a: Matrix4, b: Matrix4) => {
|
|
801
802
|
const newMatrixWorld = original(a, b);
|
|
802
|
-
// console.warn("MULT", obj.matrixWorldNeedsUpdate);
|
|
803
803
|
if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
|
|
804
804
|
previousMatrix.copy(newMatrixWorld)
|
|
805
|
-
// handle.setMatrix(newMatrixWorld);
|
|
806
805
|
obj[NEED_UPDATE_INSTANCE_KEY] = true;
|
|
807
806
|
}
|
|
808
807
|
return newMatrixWorld;
|
|
@@ -865,6 +864,13 @@ class InstanceHandle {
|
|
|
865
864
|
|
|
866
865
|
class InstancedMeshRenderer {
|
|
867
866
|
|
|
867
|
+
set castShadow(val: boolean) {
|
|
868
|
+
this.inst.castShadow = val;
|
|
869
|
+
}
|
|
870
|
+
set receiveShadow(val: boolean) {
|
|
871
|
+
this.inst.receiveShadow = val;
|
|
872
|
+
}
|
|
873
|
+
|
|
868
874
|
public name: string = "";
|
|
869
875
|
public geo: THREE.BufferGeometry;
|
|
870
876
|
public material: THREE.Material;
|
|
@@ -915,6 +921,14 @@ class InstancedMeshRenderer {
|
|
|
915
921
|
return null;
|
|
916
922
|
}
|
|
917
923
|
const handle = new InstanceHandle(-1, obj, this);
|
|
924
|
+
|
|
925
|
+
if (obj.castShadow === true && this.inst.castShadow === false) {
|
|
926
|
+
this.inst.castShadow = true;
|
|
927
|
+
}
|
|
928
|
+
if (obj.receiveShadow === true && this.inst.receiveShadow === false) {
|
|
929
|
+
this.inst.receiveShadow = true;
|
|
930
|
+
}
|
|
931
|
+
|
|
918
932
|
this.add(handle);
|
|
919
933
|
return handle;
|
|
920
934
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ui/PointerEvents"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BlendFunction, DepthDownsamplingPass, Effect, NormalPass, SSAOEffect } from "postprocessing";
|
|
2
|
-
import { NeverDepth, PerspectiveCamera } from "three";
|
|
2
|
+
import { Color, NeverDepth, PerspectiveCamera } from "three";
|
|
3
3
|
import { serializable } from "../../../engine/engine_serialization";
|
|
4
4
|
import { EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect";
|
|
5
5
|
import { VolumeParameter } from "../VolumeParameter";
|
|
@@ -21,6 +21,12 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
|
|
|
21
21
|
@serializable(VolumeParameter)
|
|
22
22
|
samples!: VolumeParameter;
|
|
23
23
|
|
|
24
|
+
@serializable(VolumeParameter)
|
|
25
|
+
color!: VolumeParameter;
|
|
26
|
+
|
|
27
|
+
@serializable(VolumeParameter)
|
|
28
|
+
luminanceInfluence!: VolumeParameter;
|
|
29
|
+
|
|
24
30
|
onBeforeRender() {
|
|
25
31
|
if (this._ssao && this.context.mainCamera instanceof PerspectiveCamera) {
|
|
26
32
|
const fadeDistance = this.context.mainCamera.far - this.context.mainCamera.near;
|
|
@@ -48,6 +54,7 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
|
|
|
48
54
|
worldProximityFalloff: 2,
|
|
49
55
|
intensity: 1,
|
|
50
56
|
blendFunction: BlendFunction.MULTIPLY,
|
|
57
|
+
luminanceInfluence: .5,
|
|
51
58
|
});
|
|
52
59
|
|
|
53
60
|
this.intensity.onValueChanged = newValue => {
|
|
@@ -59,6 +66,13 @@ export class ScreenSpaceAmbientOcclusion extends PostProcessingEffect {
|
|
|
59
66
|
this.samples.onValueChanged = newValue => {
|
|
60
67
|
ssao.samples = newValue;
|
|
61
68
|
}
|
|
69
|
+
this.color.onValueChanged = newValue => {
|
|
70
|
+
if (!ssao.color) ssao.color = new Color();
|
|
71
|
+
ssao.color.copy(newValue);
|
|
72
|
+
}
|
|
73
|
+
this.luminanceInfluence.onValueChanged = newValue => {
|
|
74
|
+
ssao.luminanceInfluence = newValue;
|
|
75
|
+
}
|
|
62
76
|
|
|
63
77
|
const arr = new Array();
|
|
64
78
|
arr.push(normalPass);
|