@needle-tools/engine 2.67.15-pre → 2.67.16
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 +9 -0
- package/dist/needle-engine.js +3605 -3574
- package/dist/needle-engine.min.js +76 -76
- package/dist/needle-engine.umd.cjs +74 -74
- package/lib/engine-components/postprocessing/Effects/DepthOfField.d.ts +1 -0
- package/lib/engine-components/postprocessing/Effects/DepthOfField.js +15 -1
- package/lib/engine-components/postprocessing/Effects/DepthOfField.js.map +1 -1
- package/lib/engine-components/postprocessing/VolumeParameter.d.ts +1 -0
- package/lib/engine-components/postprocessing/VolumeParameter.js +4 -0
- package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +3 -1
- package/lib/engine-components/timeline/PlayableDirector.js +21 -2
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +1 -0
- package/lib/engine-components/timeline/TimelineTracks.js +9 -1
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/ui/Text.js +0 -1
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/generate-font.js +1 -1
- package/src/engine/codegen/register_types.js +2 -2
- package/src/engine-components/postprocessing/Effects/DepthOfField.ts +18 -6
- package/src/engine-components/postprocessing/VolumeParameter.ts +5 -0
- package/src/engine-components/timeline/PlayableDirector.ts +19 -2
- package/src/engine-components/timeline/TimelineTracks.ts +9 -2
- package/src/engine-components/ui/Text.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "2.67.
|
|
3
|
+
"version": "2.67.16",
|
|
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",
|
package/plugins/generate-font.js
CHANGED
|
@@ -60,7 +60,7 @@ generateBMFont(fontPath, opts,
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
const fileName = path.parse(font.filename).name;
|
|
63
|
-
const name = outputDir + "/" + fileName
|
|
63
|
+
const name = outputDir + "/" + fileName + "-msdf.json";
|
|
64
64
|
fs.writeFile(name, font.data, (err) => {
|
|
65
65
|
if (err) throw err;
|
|
66
66
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TypeStore } from "./../engine_typestore"
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
// Import types
|
|
4
4
|
import { __Ignore } from "../../engine-components/codegen/components";
|
|
5
5
|
import { AlignmentConstraint } from "../../engine-components/AlignmentConstraint";
|
|
@@ -179,7 +179,7 @@ import { XRGrabModel } from "../../engine-components/WebXRGrabRendering";
|
|
|
179
179
|
import { XRGrabRendering } from "../../engine-components/WebXRGrabRendering";
|
|
180
180
|
import { XRRig } from "../../engine-components/WebXRRig";
|
|
181
181
|
import { XRState } from "../../engine-components/XRFlag";
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
// Register types
|
|
184
184
|
TypeStore.add("__Ignore", __Ignore);
|
|
185
185
|
TypeStore.add("AlignmentConstraint", AlignmentConstraint);
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { DepthOfFieldEffect } from "postprocessing";
|
|
2
|
-
import { PerspectiveCamera, Vector3 } from "three";
|
|
3
|
-
import { getWorldPosition } from "../../../engine/engine_three_utils";
|
|
4
2
|
import { serializable } from "../../../engine/engine_serialization";
|
|
5
3
|
import { Mathf } from "../../../engine/engine_math";
|
|
6
4
|
import { PostProcessingEffect } from "../PostProcessingEffect";
|
|
7
5
|
import { VolumeParameter } from "../VolumeParameter";
|
|
8
6
|
import { registerCustomEffectType } from "../VolumeProfile";
|
|
7
|
+
import { isMobileDevice } from "../../../engine/engine_utils";
|
|
9
8
|
|
|
10
9
|
export enum DepthOfFieldMode {
|
|
11
10
|
Off = 0,
|
|
@@ -20,7 +19,7 @@ export class DepthOfField extends PostProcessingEffect {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
@serializable()
|
|
23
|
-
mode
|
|
22
|
+
mode!: DepthOfFieldMode;
|
|
24
23
|
|
|
25
24
|
@serializable(VolumeParameter)
|
|
26
25
|
focusDistance!: VolumeParameter;
|
|
@@ -34,13 +33,16 @@ export class DepthOfField extends PostProcessingEffect {
|
|
|
34
33
|
@serializable(VolumeParameter)
|
|
35
34
|
gaussianMaxRadius!: VolumeParameter;
|
|
36
35
|
|
|
36
|
+
@serializable(VolumeParameter)
|
|
37
|
+
resolutionScale?: VolumeParameter;
|
|
38
|
+
|
|
37
39
|
init() {
|
|
38
40
|
this.focalLength.valueProcessor = v => {
|
|
39
41
|
const t = v / 300;
|
|
40
42
|
const max = 2;// this.context.mainCameraComponent?.farClipPlane ?? 10;
|
|
41
43
|
return Mathf.lerp(max, .01, t);
|
|
42
44
|
};
|
|
43
|
-
|
|
45
|
+
|
|
44
46
|
const maxBokehScale = 20;
|
|
45
47
|
this.aperture.valueProcessor = v => {
|
|
46
48
|
const t = 1 - v / 32;
|
|
@@ -49,7 +51,16 @@ export class DepthOfField extends PostProcessingEffect {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
onCreateEffect() {
|
|
52
|
-
if(this.mode === DepthOfFieldMode.Off) return undefined;
|
|
54
|
+
if (this.mode === DepthOfFieldMode.Off) return undefined;
|
|
55
|
+
|
|
56
|
+
const factor = 1 / window.devicePixelRatio;
|
|
57
|
+
|
|
58
|
+
if (this.resolutionScale === undefined) {
|
|
59
|
+
let defaultValue = 1;
|
|
60
|
+
if(isMobileDevice()) defaultValue = .6;
|
|
61
|
+
this.resolutionScale = new VolumeParameter(defaultValue * factor);
|
|
62
|
+
}
|
|
63
|
+
|
|
53
64
|
// console.log(this.focusDistance.overrideState, this.focusDistance.value);
|
|
54
65
|
// const depth = new DepthEffect({
|
|
55
66
|
// inverted: true,
|
|
@@ -59,7 +70,7 @@ export class DepthOfField extends PostProcessingEffect {
|
|
|
59
70
|
worldFocusRange: .2,
|
|
60
71
|
focalLength: 1,
|
|
61
72
|
bokehScale: 20,
|
|
62
|
-
resolutionScale:
|
|
73
|
+
resolutionScale: this.resolutionScale.value,
|
|
63
74
|
});
|
|
64
75
|
|
|
65
76
|
this.focusDistance.onValueChanged = v => {
|
|
@@ -68,6 +79,7 @@ export class DepthOfField extends PostProcessingEffect {
|
|
|
68
79
|
this.focalLength.onValueChanged = v => dof.circleOfConfusionMaterial.worldFocusRange = v;
|
|
69
80
|
this.aperture.onValueChanged = v => dof.bokehScale = v;
|
|
70
81
|
|
|
82
|
+
if (this.resolutionScale) this.resolutionScale.onValueChanged = v => dof.resolution.scale = v;
|
|
71
83
|
|
|
72
84
|
return [dof];
|
|
73
85
|
}
|
|
@@ -5,6 +5,11 @@ export declare type VolumeParameterValueProcessor = (value: any) => any;
|
|
|
5
5
|
|
|
6
6
|
export class VolumeParameter {
|
|
7
7
|
|
|
8
|
+
constructor(value?: any) {
|
|
9
|
+
this._value = value;
|
|
10
|
+
this._defaultValue = value;
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
@serializable()
|
|
9
14
|
get overrideState(): boolean {
|
|
10
15
|
return this._active;
|
|
@@ -6,7 +6,7 @@ import { AudioSource } from '../AudioSource';
|
|
|
6
6
|
import { SignalReceiver } from './SignalAsset';
|
|
7
7
|
import * as Models from "./TimelineModels";
|
|
8
8
|
import * as Tracks from "./TimelineTracks";
|
|
9
|
-
import { deepClone, getParam } from '../../engine/engine_utils';
|
|
9
|
+
import { deepClone, delay, getParam } from '../../engine/engine_utils';
|
|
10
10
|
import { GuidsMap } from '../../engine/engine_types';
|
|
11
11
|
import { Object3D } from 'three';
|
|
12
12
|
import { isLocalNetwork } from '../../engine/engine_networking_utils';
|
|
@@ -87,6 +87,8 @@ export class PlayableDirector extends Behaviour {
|
|
|
87
87
|
get speed(): number { return this._speed; }
|
|
88
88
|
set speed(value: number) { this._speed = value; }
|
|
89
89
|
|
|
90
|
+
/** When enabled the timeline will wait for audio tracks to load at the current time before starting to play */
|
|
91
|
+
waitForAudio: boolean = true;
|
|
90
92
|
|
|
91
93
|
private _visibilityChangeEvt?: any;
|
|
92
94
|
private _clonedPlayableAsset: boolean = false;
|
|
@@ -151,13 +153,28 @@ export class PlayableDirector extends Behaviour {
|
|
|
151
153
|
this.setupAndCreateTrackHandlers();
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
play() {
|
|
156
|
+
async play() {
|
|
155
157
|
if (!this.isValid()) return;
|
|
156
158
|
const pauseChanged = this._isPaused == true;
|
|
157
159
|
this._isPaused = false;
|
|
158
160
|
if (pauseChanged) this.invokePauseChangedMethodsOnTracks();
|
|
159
161
|
if (this._isPlaying) return;
|
|
160
162
|
this._isPlaying = true;
|
|
163
|
+
if (this.waitForAudio) {
|
|
164
|
+
// Make sure audio tracks have loaded at the current time
|
|
165
|
+
const promises: Array<Promise<any>> = [];
|
|
166
|
+
for (const track of this._audioTracks) {
|
|
167
|
+
const promise = track.loadAudio(this._time, 1, 0);
|
|
168
|
+
if (promise)
|
|
169
|
+
promises.push(promise);
|
|
170
|
+
}
|
|
171
|
+
if (promises.length > 0) {
|
|
172
|
+
await Promise.all(promises);
|
|
173
|
+
if (!this._isPlaying) return;
|
|
174
|
+
}
|
|
175
|
+
while(this._audioTracks.length > 0 && this._isPlaying && !AudioSource.userInteractionRegistered && this.waitForAudio)
|
|
176
|
+
await delay(200);
|
|
177
|
+
}
|
|
161
178
|
this._internalUpdateRoutine = this.startCoroutine(this.internalUpdate());
|
|
162
179
|
}
|
|
163
180
|
|
|
@@ -657,6 +657,9 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
private static _currentlyLoading: Map<string, Promise<AudioBuffer | null>> = new Map();
|
|
660
|
+
public static dispose() {
|
|
661
|
+
AudioTrackHandler._currentlyLoading.clear();
|
|
662
|
+
}
|
|
660
663
|
|
|
661
664
|
private handleAudioLoading(model: Models.ClipModel, audio: THREE.Audio): Promise<AudioBuffer | null> | null {
|
|
662
665
|
if (!this._audioLoader) {
|
|
@@ -665,8 +668,12 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
665
668
|
// TODO: maybe we should cache the loaders / buffers here by path
|
|
666
669
|
const path = this.getAudioFilePath(model.asset.clip);
|
|
667
670
|
|
|
668
|
-
if(AudioTrackHandler._currentlyLoading.get(path)) {
|
|
669
|
-
|
|
671
|
+
if (AudioTrackHandler._currentlyLoading.get(path)) {
|
|
672
|
+
const promise = AudioTrackHandler._currentlyLoading.get(path)!
|
|
673
|
+
promise.then((buffer) => {
|
|
674
|
+
if (buffer) audio.setBuffer(buffer);
|
|
675
|
+
});
|
|
676
|
+
return promise;
|
|
670
677
|
}
|
|
671
678
|
|
|
672
679
|
if (debug) console.warn("LOAD audio track", path, this.director.sourceId);
|