@needle-tools/engine 2.67.4-pre → 2.67.5-pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/needle-engine.js +1171 -1164
- package/dist/needle-engine.umd.cjs +62 -62
- package/lib/engine/engine_setup.js +4 -2
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +1 -0
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/postprocessing/Volume.js +19 -9
- package/lib/engine-components/postprocessing/Volume.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/engine_setup.ts +4 -2
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +1 -0
- package/src/engine-components/postprocessing/Volume.ts +213 -201
|
@@ -1,201 +1,213 @@
|
|
|
1
|
-
import { Behaviour, GameObject } from "../Component";
|
|
2
|
-
import { serializeable } from "../../engine/engine_serialization_decorator";
|
|
3
|
-
import { getParam } from "../../engine/engine_utils";
|
|
4
|
-
import { VolumeProfile } from "./VolumeProfile";
|
|
5
|
-
import { EditorModification, IEditorModification as IEditorModificationReceiver } from "../../engine/engine_editor-sync";
|
|
6
|
-
import { PostProcessingHandler } from "./PostProcessingHandler";
|
|
7
|
-
import { PostProcessingEffect } from "./PostProcessingEffect";
|
|
8
|
-
import { VolumeParameter } from "./VolumeParameter";
|
|
9
|
-
import { getEditorModificationCache } from "../../engine/engine_editor-sync";
|
|
10
|
-
import { isDevEnvironment } from "../../engine/debug";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (this.context.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
this.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (effectVolumeProperties.has(componentName)) {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
1
|
+
import { Behaviour, GameObject } from "../Component";
|
|
2
|
+
import { serializeable } from "../../engine/engine_serialization_decorator";
|
|
3
|
+
import { getParam } from "../../engine/engine_utils";
|
|
4
|
+
import { VolumeProfile } from "./VolumeProfile";
|
|
5
|
+
import { EditorModification, IEditorModification as IEditorModificationReceiver } from "../../engine/engine_editor-sync";
|
|
6
|
+
import { PostProcessingHandler } from "./PostProcessingHandler";
|
|
7
|
+
import { PostProcessingEffect } from "./PostProcessingEffect";
|
|
8
|
+
import { VolumeParameter } from "./VolumeParameter";
|
|
9
|
+
import { getEditorModificationCache } from "../../engine/engine_editor-sync";
|
|
10
|
+
import { isDevEnvironment } from "../../engine/debug";
|
|
11
|
+
import { EffectComposer } from "postprocessing";
|
|
12
|
+
|
|
13
|
+
const debug = getParam("debugpost");
|
|
14
|
+
|
|
15
|
+
export class Volume extends Behaviour implements IEditorModificationReceiver {
|
|
16
|
+
|
|
17
|
+
@serializeable(VolumeProfile)
|
|
18
|
+
sharedProfile?: VolumeProfile;
|
|
19
|
+
|
|
20
|
+
private _postprocessing?: PostProcessingHandler;
|
|
21
|
+
private _effects: PostProcessingEffect[] = [];
|
|
22
|
+
|
|
23
|
+
awake() {
|
|
24
|
+
// ensure the profile is initialized
|
|
25
|
+
this.sharedProfile?.init();
|
|
26
|
+
|
|
27
|
+
if (debug) {
|
|
28
|
+
console.log(this);
|
|
29
|
+
console.log("Press P to toggle post processing");
|
|
30
|
+
window.addEventListener("keydown", (e) => {
|
|
31
|
+
if (e.key === "p") {
|
|
32
|
+
console.log("Toggle volume: " + this.name, !this.enabled);
|
|
33
|
+
this.enabled = !this.enabled;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
onDisable() {
|
|
40
|
+
this._postprocessing?.unapply();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
onBeforeRender(): void {
|
|
44
|
+
if (!this.context.isInXR) {
|
|
45
|
+
|
|
46
|
+
if (this.context.composer && (this.context.composer instanceof EffectComposer) === false) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Wait for the first frame to be rendered before creating because then we know we have a camera (issue 135)
|
|
51
|
+
if (this.context.mainCamera) {
|
|
52
|
+
if (!this._postprocessing || !this._postprocessing.isActive)
|
|
53
|
+
this.apply();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (this.context.composer) {
|
|
57
|
+
this.context.composer.setRenderer(this.context.renderer);
|
|
58
|
+
this.context.composer.setMainScene(this.context.scene);
|
|
59
|
+
if (this.context.mainCamera)
|
|
60
|
+
this.context.composer.setMainCamera(this.context.mainCamera);
|
|
61
|
+
}
|
|
62
|
+
if (this.context.renderer) {
|
|
63
|
+
this.context.renderer.autoClear = false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
onDestroy(): void {
|
|
69
|
+
this._postprocessing?.dispose();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private _lastApplyTime?: number;
|
|
73
|
+
private _rapidApplyCount = 0;
|
|
74
|
+
|
|
75
|
+
private apply() {
|
|
76
|
+
if (debug) console.log("Apply PostProcessing", this, this.context.mainCamera?.name);
|
|
77
|
+
|
|
78
|
+
if (isDevEnvironment()) {
|
|
79
|
+
if (this._lastApplyTime !== undefined && Date.now() - this._lastApplyTime < 100) {
|
|
80
|
+
this._rapidApplyCount++;
|
|
81
|
+
if (this._rapidApplyCount === 5)
|
|
82
|
+
console.warn("Detected rapid post processing modifications - this might be a bug", this);
|
|
83
|
+
}
|
|
84
|
+
this._lastApplyTime = Date.now();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
this.unapply();
|
|
89
|
+
|
|
90
|
+
this._effects.length = 0;
|
|
91
|
+
// get from profile
|
|
92
|
+
if (this.sharedProfile?.components) {
|
|
93
|
+
this._effects.push(...this.sharedProfile.components);
|
|
94
|
+
}
|
|
95
|
+
// get additional effects
|
|
96
|
+
const additionalComponents = this.gameObject.getComponentsInChildren(PostProcessingEffect);
|
|
97
|
+
if (debug && additionalComponents?.length)
|
|
98
|
+
console.log("Additional", additionalComponents);
|
|
99
|
+
if (additionalComponents) {
|
|
100
|
+
for (const comp of additionalComponents) {
|
|
101
|
+
if (comp.active) this._effects.push(comp);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this._effects.length > 0) {
|
|
106
|
+
if (!this._postprocessing)
|
|
107
|
+
this._postprocessing = new PostProcessingHandler(this.context);
|
|
108
|
+
this._postprocessing.apply(this._effects);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this._applyPostQueue();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private unapply() {
|
|
115
|
+
this._postprocessing?.unapply();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
private _applyPostQueue() {
|
|
120
|
+
if (this._modificationQueue) {
|
|
121
|
+
for (const entry of this._modificationQueue.values()) this.onEditorModification(entry);
|
|
122
|
+
this._modificationQueue.clear();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** called from needle editor sync package if its active */
|
|
127
|
+
onEditorModification(modification: EditorModification): void | boolean | undefined {
|
|
128
|
+
|
|
129
|
+
if (modification.propertyName.startsWith("postprocessing.")) {
|
|
130
|
+
|
|
131
|
+
if (!this._postprocessing) {
|
|
132
|
+
if (!this._modificationQueue) this._modificationQueue = new Map<string, EditorModification>();
|
|
133
|
+
this._modificationQueue.set(modification.propertyName, modification);
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!this._effects?.length) return;
|
|
138
|
+
const path = modification.propertyName.split(".");
|
|
139
|
+
if (path.length === 3 || path.length === 4) {
|
|
140
|
+
const componentName = path[1];
|
|
141
|
+
const propertyName = path[2];
|
|
142
|
+
for (const comp of this._effects) {
|
|
143
|
+
if (comp.typeName?.toLowerCase() === componentName.toLowerCase()) {
|
|
144
|
+
|
|
145
|
+
if (propertyName === "active") {
|
|
146
|
+
comp.active = modification.value;
|
|
147
|
+
this.scheduleRecreate();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// cache the volume parameters
|
|
152
|
+
if (!effectVolumeProperties.has(componentName)) {
|
|
153
|
+
const volumeParameterKeys = new Array<string>();
|
|
154
|
+
effectVolumeProperties.set(componentName, volumeParameterKeys);
|
|
155
|
+
const keys = Object.keys(comp);
|
|
156
|
+
for (const key of keys) {
|
|
157
|
+
const prop = comp[key];
|
|
158
|
+
if (prop instanceof VolumeParameter) {
|
|
159
|
+
volumeParameterKeys.push(key);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (effectVolumeProperties.has(componentName)) {
|
|
165
|
+
const paramName = propertyName.toLowerCase();
|
|
166
|
+
const volumeParameterKeys = effectVolumeProperties.get(componentName)!;
|
|
167
|
+
for (const key of volumeParameterKeys) {
|
|
168
|
+
if (key.toLowerCase() === paramName) {
|
|
169
|
+
const prop = comp[key] as VolumeParameter;
|
|
170
|
+
if (prop instanceof VolumeParameter) {
|
|
171
|
+
const isActiveStateChange = path.length === 4 && path[3] === "active";
|
|
172
|
+
if (isActiveStateChange) {
|
|
173
|
+
prop.overrideState = modification.value;
|
|
174
|
+
this.scheduleRecreate();
|
|
175
|
+
}
|
|
176
|
+
else if (prop && prop.value !== undefined) {
|
|
177
|
+
prop.value = modification.value;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
console.warn("Unknown modification", propertyName);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private _modificationQueue?: Map<string, EditorModification>;
|
|
197
|
+
|
|
198
|
+
private _recreateId: number = -1;
|
|
199
|
+
private scheduleRecreate() {
|
|
200
|
+
// When the editor modifications come in with changed active effects we want/need to re-create the effects
|
|
201
|
+
// We defer it slightly because multiple active changes could be made and we dont want to recreate the full effect stack multiple times
|
|
202
|
+
const id = ++this._recreateId;
|
|
203
|
+
setTimeout(() => {
|
|
204
|
+
if (id !== this._recreateId) return;
|
|
205
|
+
this.onDisable();
|
|
206
|
+
this.onEnable();
|
|
207
|
+
}, 200);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** cached VolumeParameter keys per object */
|
|
213
|
+
const effectVolumeProperties: Map<string, string[]> = new Map<string, string[]>();
|