@eva/plugin-renderer-scene-capture 2.1.0-beta.14
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/README.md +30 -0
- package/dist/EVA.plugin.renderer.scene.capture.js +518 -0
- package/dist/EVA.plugin.renderer.scene.capture.min.js +1 -0
- package/dist/plugin-renderer-scene-capture.cjs.js +550 -0
- package/dist/plugin-renderer-scene-capture.cjs.prod.js +1 -0
- package/dist/plugin-renderer-scene-capture.d.ts +152 -0
- package/dist/plugin-renderer-scene-capture.esm.js +542 -0
- package/index.js +7 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @eva/plugin-renderer-scene-capture
|
|
2
|
+
|
|
3
|
+
Renders explicitly named, live Eva.js GameObject containers into a transparent
|
|
4
|
+
Pixi `RenderTexture`. It is intended for effects such as the rain-demo's
|
|
5
|
+
reflection layer: create reflection proxy entities, name them, then capture
|
|
6
|
+
those names before the root application renders its main stage.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { SceneCapture, SceneCaptureSystem, getSceneCaptureTexture } from '@eva/plugin-renderer-scene-capture';
|
|
10
|
+
|
|
11
|
+
// Register SceneCaptureSystem alongside RendererSystem, then attach this to
|
|
12
|
+
// any non-rendering owner GameObject.
|
|
13
|
+
const capture = new SceneCapture({
|
|
14
|
+
sourceNames: ['building-reflection', 'player-reflection'],
|
|
15
|
+
output: 'rain-reflection',
|
|
16
|
+
width: 750,
|
|
17
|
+
height: 420,
|
|
18
|
+
resolutionScale: 0.5,
|
|
19
|
+
updateMode: 'always',
|
|
20
|
+
clearAlpha: 0,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const texture = getSceneCaptureTexture('rain-reflection');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`always` writes for every presentation, `onDirty` writes once then waits for a
|
|
27
|
+
component change or `requestCapture()`, and `manual` writes only after
|
|
28
|
+
`requestCapture()`. Source names may appear after the capture component is
|
|
29
|
+
created. Missing sources clear the target transparently. The main Pixi stage is
|
|
30
|
+
never accepted as a source, and source containers are never reparented.
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
globalThis.EVA = globalThis.EVA || {};
|
|
3
|
+
globalThis.EVA.plugin = globalThis.EVA.plugin || {};
|
|
4
|
+
globalThis.EVA.plugin.renderer = globalThis.EVA.plugin.renderer || {};
|
|
5
|
+
globalThis.EVA.plugin.renderer.scene = globalThis.EVA.plugin.renderer.scene || {};
|
|
6
|
+
var _EVA_IIFE_capture = function (exports, eva_js, pluginRenderer, pixi_js) {
|
|
7
|
+
'use strict';
|
|
8
|
+
function __decorate(decorators, target, key, desc) {
|
|
9
|
+
var c = arguments.length,
|
|
10
|
+
r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
|
|
11
|
+
d;
|
|
12
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
13
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
+
}
|
|
15
|
+
function __metadata(metadataKey, metadataValue) {
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
17
|
+
}
|
|
18
|
+
function __rest(s, e) {
|
|
19
|
+
var t = {};
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
|
|
21
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
22
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
}
|
|
26
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
27
|
+
var e = new Error(message);
|
|
28
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
29
|
+
};
|
|
30
|
+
class SymbolKeysNotSupportedError extends Error {
|
|
31
|
+
constructor() {
|
|
32
|
+
super('Symbol keys are not supported yet!');
|
|
33
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const IDE_PROPERTY_METADATA = 'IDE_PROPERTY_METADATA';
|
|
37
|
+
function transformBasicType(type) {
|
|
38
|
+
if (type === String) {
|
|
39
|
+
return 'string';
|
|
40
|
+
}
|
|
41
|
+
if (type === Number) {
|
|
42
|
+
return 'number';
|
|
43
|
+
}
|
|
44
|
+
if (type === Boolean) {
|
|
45
|
+
return 'boolean';
|
|
46
|
+
}
|
|
47
|
+
return 'unknown';
|
|
48
|
+
}
|
|
49
|
+
function defineLegacyIDEProp(target, propertyKey, patch) {
|
|
50
|
+
const constructor = target.constructor;
|
|
51
|
+
const current = constructor.IDEProps || {};
|
|
52
|
+
current[propertyKey] = _extends(_extends({
|
|
53
|
+
key: propertyKey
|
|
54
|
+
}, current[propertyKey]), patch);
|
|
55
|
+
constructor.IDEProps = current;
|
|
56
|
+
}
|
|
57
|
+
function defineTypes(target, key, options, returnTypeFunction) {
|
|
58
|
+
let type = Reflect.getMetadata('design:type', target, key);
|
|
59
|
+
let isArray = type === Array;
|
|
60
|
+
const str = transformBasicType(type);
|
|
61
|
+
if (str !== 'unknown') {
|
|
62
|
+
type = str;
|
|
63
|
+
}
|
|
64
|
+
if (returnTypeFunction) {
|
|
65
|
+
const returnType = returnTypeFunction();
|
|
66
|
+
if (Array.isArray(returnType)) {
|
|
67
|
+
isArray = true;
|
|
68
|
+
type = returnType[0];
|
|
69
|
+
} else {
|
|
70
|
+
type = returnType;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const properties = Reflect.getMetadata(IDE_PROPERTY_METADATA, target.constructor) || {};
|
|
74
|
+
const current = properties[key] || {};
|
|
75
|
+
const property = _extends(_extends(_extends({}, current), {
|
|
76
|
+
type,
|
|
77
|
+
isArray: isArray
|
|
78
|
+
}), options);
|
|
79
|
+
properties[key] = property;
|
|
80
|
+
Reflect.defineMetadata(IDE_PROPERTY_METADATA, properties, target.constructor);
|
|
81
|
+
const legacyProperty = __rest(property, ["isArray"]);
|
|
82
|
+
defineLegacyIDEProp(target, key, legacyProperty);
|
|
83
|
+
}
|
|
84
|
+
function type(type) {
|
|
85
|
+
return Field({
|
|
86
|
+
type
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function getTypeDecoratorParams(returnTypeFuncOrOptions, maybeOptions) {
|
|
90
|
+
if (typeof returnTypeFuncOrOptions === 'function') {
|
|
91
|
+
return {
|
|
92
|
+
returnTypeFunc: returnTypeFuncOrOptions,
|
|
93
|
+
options: maybeOptions || {}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
options: returnTypeFuncOrOptions || {}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function Field(returnTypeFunction, maybeOptions) {
|
|
101
|
+
return (target, propertyKey) => {
|
|
102
|
+
if (typeof propertyKey === 'symbol') {
|
|
103
|
+
throw new SymbolKeysNotSupportedError();
|
|
104
|
+
}
|
|
105
|
+
const {
|
|
106
|
+
options,
|
|
107
|
+
returnTypeFunc
|
|
108
|
+
} = getTypeDecoratorParams(returnTypeFunction, maybeOptions);
|
|
109
|
+
defineTypes(target, propertyKey, options, returnTypeFunc);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
var ExecuteMode;
|
|
113
|
+
(function (ExecuteMode) {
|
|
114
|
+
ExecuteMode[ExecuteMode["Edit"] = 2] = "Edit";
|
|
115
|
+
ExecuteMode[ExecuteMode["Game"] = 4] = "Game";
|
|
116
|
+
ExecuteMode[ExecuteMode["All"] = 6] = "All";
|
|
117
|
+
})(ExecuteMode || (ExecuteMode = {}));
|
|
118
|
+
const finitePositive$1 = (value, fallback) => {
|
|
119
|
+
const numberValue = Number(value);
|
|
120
|
+
return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : fallback;
|
|
121
|
+
};
|
|
122
|
+
const clamp = (value, min, max, fallback) => {
|
|
123
|
+
const numberValue = Number(value);
|
|
124
|
+
if (!Number.isFinite(numberValue)) return fallback;
|
|
125
|
+
return Math.min(max, Math.max(min, numberValue));
|
|
126
|
+
};
|
|
127
|
+
class SceneCapture extends eva_js.Component {
|
|
128
|
+
constructor() {
|
|
129
|
+
super(...arguments);
|
|
130
|
+
this.sourceNames = [];
|
|
131
|
+
this.output = '';
|
|
132
|
+
this.width = 256;
|
|
133
|
+
this.height = 256;
|
|
134
|
+
this.resolutionScale = 1;
|
|
135
|
+
this.updateMode = 'always';
|
|
136
|
+
this.clearColor = 0x000000;
|
|
137
|
+
this.clearAlpha = 0;
|
|
138
|
+
this.enabled = true;
|
|
139
|
+
this.captureRevision = 0;
|
|
140
|
+
}
|
|
141
|
+
init(params) {
|
|
142
|
+
if (params) _extends(this, params);
|
|
143
|
+
this.sourceNames = Array.isArray(this.sourceNames) ? this.sourceNames.filter(name => typeof name === 'string' && name.trim().length > 0) : [];
|
|
144
|
+
this.output = typeof this.output === 'string' ? this.output.trim() : '';
|
|
145
|
+
this.width = finitePositive$1(this.width, 256);
|
|
146
|
+
this.height = finitePositive$1(this.height, 256);
|
|
147
|
+
this.resolutionScale = finitePositive$1(this.resolutionScale, 1);
|
|
148
|
+
this.updateMode = this.normalizeUpdateMode(this.updateMode);
|
|
149
|
+
this.clearColor = Math.max(0, Math.min(0xffffff, Number(this.clearColor) || 0)) >>> 0;
|
|
150
|
+
this.clearAlpha = clamp(this.clearAlpha, 0, 1, 0);
|
|
151
|
+
this.enabled = this.enabled !== false;
|
|
152
|
+
}
|
|
153
|
+
requestCapture() {
|
|
154
|
+
this.captureRevision++;
|
|
155
|
+
this.emit('captureRequested', {
|
|
156
|
+
revision: this.captureRevision
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
normalizeUpdateMode(value) {
|
|
160
|
+
return value === 'onDirty' || value === 'manual' ? value : 'always';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
SceneCapture.componentName = 'SceneCapture';
|
|
164
|
+
__decorate([type('array'), __metadata("design:type", Array)], SceneCapture.prototype, "sourceNames", void 0);
|
|
165
|
+
__decorate([type('string'), __metadata("design:type", String)], SceneCapture.prototype, "output", void 0);
|
|
166
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "width", void 0);
|
|
167
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "height", void 0);
|
|
168
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "resolutionScale", void 0);
|
|
169
|
+
__decorate([type('string'), __metadata("design:type", String)], SceneCapture.prototype, "updateMode", void 0);
|
|
170
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "clearColor", void 0);
|
|
171
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "clearAlpha", void 0);
|
|
172
|
+
__decorate([type('boolean'), __metadata("design:type", Boolean)], SceneCapture.prototype, "enabled", void 0);
|
|
173
|
+
__decorate([type('number'), __metadata("design:type", Number)], SceneCapture.prototype, "captureRevision", void 0);
|
|
174
|
+
class SceneCaptureTextureRegistry {
|
|
175
|
+
constructor() {
|
|
176
|
+
this.entries = new Map();
|
|
177
|
+
}
|
|
178
|
+
get(output) {
|
|
179
|
+
var _a;
|
|
180
|
+
return (_a = this.entries.get(this.normalize(output))) === null || _a === void 0 ? void 0 : _a.texture;
|
|
181
|
+
}
|
|
182
|
+
getEntry(output) {
|
|
183
|
+
return this.entries.get(this.normalize(output));
|
|
184
|
+
}
|
|
185
|
+
has(output) {
|
|
186
|
+
return this.entries.has(this.normalize(output));
|
|
187
|
+
}
|
|
188
|
+
set(output, owner, texture) {
|
|
189
|
+
const key = this.normalize(output);
|
|
190
|
+
if (!key || !owner || !texture) return;
|
|
191
|
+
this.entries.set(key, Object.freeze({
|
|
192
|
+
output: key,
|
|
193
|
+
owner,
|
|
194
|
+
texture
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
delete(output, owner) {
|
|
198
|
+
const key = this.normalize(output);
|
|
199
|
+
const entry = this.entries.get(key);
|
|
200
|
+
if (!entry || owner && entry.owner !== owner) return false;
|
|
201
|
+
return this.entries.delete(key);
|
|
202
|
+
}
|
|
203
|
+
normalize(output) {
|
|
204
|
+
return typeof output === 'string' ? output.trim() : '';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const sceneCaptureTextureRegistry = new SceneCaptureTextureRegistry();
|
|
208
|
+
function getSceneCaptureTexture(output) {
|
|
209
|
+
return sceneCaptureTextureRegistry.get(output);
|
|
210
|
+
}
|
|
211
|
+
let nextSystemId = 0;
|
|
212
|
+
const finitePositive = (value, fallback) => {
|
|
213
|
+
const numberValue = Number(value);
|
|
214
|
+
return Number.isFinite(numberValue) && numberValue > 0 ? numberValue : fallback;
|
|
215
|
+
};
|
|
216
|
+
const clampAlpha = value => {
|
|
217
|
+
const numberValue = Number(value);
|
|
218
|
+
if (!Number.isFinite(numberValue)) return 0;
|
|
219
|
+
return Math.max(0, Math.min(1, numberValue));
|
|
220
|
+
};
|
|
221
|
+
const normalizedOutput = value => typeof value === 'string' ? value.trim() : '';
|
|
222
|
+
let SceneCaptureSystem = class SceneCaptureSystem extends pluginRenderer.Renderer {
|
|
223
|
+
constructor() {
|
|
224
|
+
super(...arguments);
|
|
225
|
+
this.name = 'SceneCapture';
|
|
226
|
+
this.presentationAddFlushEnabled = true;
|
|
227
|
+
this.records = new Map();
|
|
228
|
+
this.outputs = new Map();
|
|
229
|
+
this.emptyCaptureRoot = new pixi_js.Container();
|
|
230
|
+
this.participantId = `scene-capture:${++nextSystemId}`;
|
|
231
|
+
this.destroyed = false;
|
|
232
|
+
}
|
|
233
|
+
init() {
|
|
234
|
+
this.renderSystem = this.game.getSystem(pluginRenderer.RendererSystem);
|
|
235
|
+
if (!this.renderSystem) {
|
|
236
|
+
throw new Error('[SceneCapture] RendererSystem must be registered before SceneCaptureSystem.');
|
|
237
|
+
}
|
|
238
|
+
this.renderSystem.rendererManager.register(this);
|
|
239
|
+
this.ensurePresentationParticipant();
|
|
240
|
+
}
|
|
241
|
+
update(time) {
|
|
242
|
+
super.update(time);
|
|
243
|
+
this.ensurePresentationParticipant();
|
|
244
|
+
}
|
|
245
|
+
lateUpdate() {
|
|
246
|
+
var _a;
|
|
247
|
+
if (this.hasLivePresentationParticipant()) return;
|
|
248
|
+
const application = (_a = this.renderSystem) === null || _a === void 0 ? void 0 : _a.application;
|
|
249
|
+
if (application) this.captureForApplication(application);
|
|
250
|
+
}
|
|
251
|
+
componentChanged(changed) {
|
|
252
|
+
if (changed.componentName !== 'SceneCapture') return;
|
|
253
|
+
const component = changed.component;
|
|
254
|
+
const gameObjectId = changed.gameObject.id;
|
|
255
|
+
if (changed.type === eva_js.OBSERVER_TYPE.ADD) {
|
|
256
|
+
this.addRecord(gameObjectId, component);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (changed.type === eva_js.OBSERVER_TYPE.REMOVE) {
|
|
260
|
+
const record = this.records.get(gameObjectId);
|
|
261
|
+
if (record) this.disposeRecord(record);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const record = this.records.get(gameObjectId);
|
|
265
|
+
if (!record) return;
|
|
266
|
+
record.component = component;
|
|
267
|
+
this.resizeRecord(record);
|
|
268
|
+
this.updateOutput(record);
|
|
269
|
+
if (component.updateMode !== 'manual') record.dirty = true;
|
|
270
|
+
if (component.captureRevision !== record.lastCaptureRevision) record.dirty = true;
|
|
271
|
+
}
|
|
272
|
+
getTexture(output) {
|
|
273
|
+
var _a;
|
|
274
|
+
return (_a = this.outputs.get(normalizedOutput(output))) === null || _a === void 0 ? void 0 : _a.texture;
|
|
275
|
+
}
|
|
276
|
+
onDestroy() {
|
|
277
|
+
var _a;
|
|
278
|
+
this.destroyed = true;
|
|
279
|
+
(_a = this.presentationHandle) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
280
|
+
this.presentationHandle = undefined;
|
|
281
|
+
for (const record of Array.from(this.records.values())) this.disposeRecord(record);
|
|
282
|
+
try {
|
|
283
|
+
this.emptyCaptureRoot.destroy({
|
|
284
|
+
children: false
|
|
285
|
+
});
|
|
286
|
+
} catch (_b) {}
|
|
287
|
+
}
|
|
288
|
+
addRecord(gameObjectId, component) {
|
|
289
|
+
const existing = this.records.get(gameObjectId);
|
|
290
|
+
if (existing) this.disposeRecord(existing);
|
|
291
|
+
const record = {};
|
|
292
|
+
const owner = record;
|
|
293
|
+
_extends(record, {
|
|
294
|
+
owner,
|
|
295
|
+
gameObjectId,
|
|
296
|
+
component,
|
|
297
|
+
texture: this.createTexture(component),
|
|
298
|
+
output: normalizedOutput(component.output),
|
|
299
|
+
width: this.widthOf(component),
|
|
300
|
+
height: this.heightOf(component),
|
|
301
|
+
resolutionScale: this.resolutionOf(component),
|
|
302
|
+
dirty: component.updateMode !== 'manual' || component.captureRevision > 0,
|
|
303
|
+
lastCaptureRevision: 0,
|
|
304
|
+
disposed: false,
|
|
305
|
+
onCaptureRequested: () => {
|
|
306
|
+
if (!record.disposed) record.dirty = true;
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
component.on('captureRequested', record.onCaptureRequested);
|
|
310
|
+
this.records.set(gameObjectId, record);
|
|
311
|
+
this.bindOutput(record);
|
|
312
|
+
}
|
|
313
|
+
createTexture(component) {
|
|
314
|
+
return pixi_js.RenderTexture.create({
|
|
315
|
+
width: this.widthOf(component),
|
|
316
|
+
height: this.heightOf(component),
|
|
317
|
+
resolution: this.resolutionOf(component)
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
widthOf(component) {
|
|
321
|
+
return finitePositive(component.width, 256);
|
|
322
|
+
}
|
|
323
|
+
heightOf(component) {
|
|
324
|
+
return finitePositive(component.height, 256);
|
|
325
|
+
}
|
|
326
|
+
resolutionOf(component) {
|
|
327
|
+
return finitePositive(component.resolutionScale, 1);
|
|
328
|
+
}
|
|
329
|
+
resizeRecord(record) {
|
|
330
|
+
const width = this.widthOf(record.component);
|
|
331
|
+
const height = this.heightOf(record.component);
|
|
332
|
+
const resolutionScale = this.resolutionOf(record.component);
|
|
333
|
+
if (record.width === width && record.height === height && record.resolutionScale === resolutionScale) return;
|
|
334
|
+
record.width = width;
|
|
335
|
+
record.height = height;
|
|
336
|
+
record.resolutionScale = resolutionScale;
|
|
337
|
+
const texture = record.texture;
|
|
338
|
+
if (typeof texture.resize === 'function') {
|
|
339
|
+
texture.resize(width, height, resolutionScale);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const previous = record.texture;
|
|
343
|
+
record.texture = this.createTexture(record.component);
|
|
344
|
+
this.bindOutput(record);
|
|
345
|
+
try {
|
|
346
|
+
previous.destroy(true);
|
|
347
|
+
} catch (_a) {}
|
|
348
|
+
}
|
|
349
|
+
updateOutput(record) {
|
|
350
|
+
const nextOutput = normalizedOutput(record.component.output);
|
|
351
|
+
if (record.output === nextOutput) return;
|
|
352
|
+
this.unbindOutput(record);
|
|
353
|
+
record.output = nextOutput;
|
|
354
|
+
this.bindOutput(record);
|
|
355
|
+
}
|
|
356
|
+
bindOutput(record) {
|
|
357
|
+
if (!record.output) return;
|
|
358
|
+
this.outputs.set(record.output, record);
|
|
359
|
+
sceneCaptureTextureRegistry.set(record.output, record.owner, record.texture);
|
|
360
|
+
}
|
|
361
|
+
unbindOutput(record) {
|
|
362
|
+
if (!record.output) return;
|
|
363
|
+
if (this.outputs.get(record.output) === record) this.outputs.delete(record.output);
|
|
364
|
+
sceneCaptureTextureRegistry.delete(record.output, record.owner);
|
|
365
|
+
}
|
|
366
|
+
disposeRecord(record) {
|
|
367
|
+
if (record.disposed) return;
|
|
368
|
+
record.disposed = true;
|
|
369
|
+
this.records.delete(record.gameObjectId);
|
|
370
|
+
this.unbindOutput(record);
|
|
371
|
+
try {
|
|
372
|
+
record.component.off('captureRequested', record.onCaptureRequested);
|
|
373
|
+
} catch (_a) {}
|
|
374
|
+
try {
|
|
375
|
+
record.texture.destroy(true);
|
|
376
|
+
} catch (_b) {}
|
|
377
|
+
}
|
|
378
|
+
ensurePresentationParticipant() {
|
|
379
|
+
var _a;
|
|
380
|
+
if (this.destroyed || this.hasLivePresentationParticipant()) return;
|
|
381
|
+
const renderer = this.renderSystem;
|
|
382
|
+
if (!(renderer === null || renderer === void 0 ? void 0 : renderer.application) || typeof renderer.registerPresentationParticipant !== 'function') return;
|
|
383
|
+
const applicationId = (_a = renderer.getPresentationApplicationId) === null || _a === void 0 ? void 0 : _a.call(renderer, renderer.application);
|
|
384
|
+
let handle;
|
|
385
|
+
handle = renderer.registerPresentationParticipant({
|
|
386
|
+
id: this.participantId,
|
|
387
|
+
applicationId,
|
|
388
|
+
build: () => ({
|
|
389
|
+
writes: Array.from(this.outputs.keys(), output => `scene-capture:${output}`)
|
|
390
|
+
}),
|
|
391
|
+
submit: context => {
|
|
392
|
+
this.captureForApplication(context.application);
|
|
393
|
+
},
|
|
394
|
+
dispose: () => {
|
|
395
|
+
if (this.presentationHandle === handle) this.presentationHandle = undefined;
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
this.presentationHandle = handle;
|
|
399
|
+
}
|
|
400
|
+
hasLivePresentationParticipant() {
|
|
401
|
+
return Boolean(this.presentationHandle && !this.presentationHandle.disposed);
|
|
402
|
+
}
|
|
403
|
+
captureForApplication(application) {
|
|
404
|
+
const renderer = application === null || application === void 0 ? void 0 : application.renderer;
|
|
405
|
+
if (!(renderer === null || renderer === void 0 ? void 0 : renderer.render)) return;
|
|
406
|
+
for (const record of this.records.values()) {
|
|
407
|
+
if (!this.shouldCapture(record)) continue;
|
|
408
|
+
if (!this.captureRecord(renderer, application, record)) continue;
|
|
409
|
+
record.dirty = false;
|
|
410
|
+
record.lastCaptureRevision = record.component.captureRevision;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
shouldCapture(record) {
|
|
414
|
+
const component = record.component;
|
|
415
|
+
if (record.disposed || component.enabled === false) return false;
|
|
416
|
+
if (component.updateMode === 'always') return true;
|
|
417
|
+
if (component.captureRevision !== record.lastCaptureRevision) record.dirty = true;
|
|
418
|
+
return record.dirty;
|
|
419
|
+
}
|
|
420
|
+
captureRecord(renderer, application, record) {
|
|
421
|
+
const sources = this.resolveSourceContainers(record.component, application);
|
|
422
|
+
const clearColor = this.toClearColor(record.component);
|
|
423
|
+
try {
|
|
424
|
+
if (sources.length === 0) {
|
|
425
|
+
renderer.render({
|
|
426
|
+
container: this.emptyCaptureRoot,
|
|
427
|
+
target: record.texture,
|
|
428
|
+
clear: true,
|
|
429
|
+
clearColor
|
|
430
|
+
});
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
for (let index = 0; index < sources.length; index++) {
|
|
434
|
+
const source = sources[index];
|
|
435
|
+
const options = {
|
|
436
|
+
container: source,
|
|
437
|
+
target: record.texture,
|
|
438
|
+
clear: index === 0
|
|
439
|
+
};
|
|
440
|
+
if (index === 0) options.clearColor = clearColor;
|
|
441
|
+
if (source.worldTransform) options.transform = source.worldTransform;
|
|
442
|
+
renderer.render(options);
|
|
443
|
+
}
|
|
444
|
+
return true;
|
|
445
|
+
} catch (_a) {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
resolveSourceContainers(component, application) {
|
|
450
|
+
var _a;
|
|
451
|
+
const sources = [];
|
|
452
|
+
const sourceNames = Array.isArray(component.sourceNames) ? component.sourceNames : [];
|
|
453
|
+
const game = this.game;
|
|
454
|
+
for (const sourceName of sourceNames) {
|
|
455
|
+
if (!sourceName || typeof (game === null || game === void 0 ? void 0 : game.findAllByName) !== 'function') continue;
|
|
456
|
+
const gameObjects = game.findAllByName(sourceName);
|
|
457
|
+
for (const gameObject of gameObjects || []) {
|
|
458
|
+
if (!gameObject || gameObject.destroyed) continue;
|
|
459
|
+
const container = (_a = this.containerManager) === null || _a === void 0 ? void 0 : _a.getContainer(gameObject.id);
|
|
460
|
+
if (!container || container.destroyed || container === application.stage || container === this.emptyCaptureRoot) {
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
if (!sources.includes(container)) sources.push(container);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return sources;
|
|
467
|
+
}
|
|
468
|
+
toClearColor(component) {
|
|
469
|
+
const color = (Number(component.clearColor) || 0) >>> 0;
|
|
470
|
+
return [(color >>> 16 & 0xff) / 255, (color >>> 8 & 0xff) / 255, (color & 0xff) / 255, clampAlpha(component.clearAlpha)];
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
SceneCaptureSystem.systemName = 'SceneCapture';
|
|
474
|
+
SceneCaptureSystem = __decorate([eva_js.decorators.componentObserver({
|
|
475
|
+
SceneCapture: [{
|
|
476
|
+
prop: ['sourceNames'],
|
|
477
|
+
deep: true
|
|
478
|
+
}, {
|
|
479
|
+
prop: ['output'],
|
|
480
|
+
deep: false
|
|
481
|
+
}, {
|
|
482
|
+
prop: ['width'],
|
|
483
|
+
deep: false
|
|
484
|
+
}, {
|
|
485
|
+
prop: ['height'],
|
|
486
|
+
deep: false
|
|
487
|
+
}, {
|
|
488
|
+
prop: ['resolutionScale'],
|
|
489
|
+
deep: false
|
|
490
|
+
}, {
|
|
491
|
+
prop: ['updateMode'],
|
|
492
|
+
deep: false
|
|
493
|
+
}, {
|
|
494
|
+
prop: ['clearColor'],
|
|
495
|
+
deep: false
|
|
496
|
+
}, {
|
|
497
|
+
prop: ['clearAlpha'],
|
|
498
|
+
deep: false
|
|
499
|
+
}, {
|
|
500
|
+
prop: ['enabled'],
|
|
501
|
+
deep: false
|
|
502
|
+
}, {
|
|
503
|
+
prop: ['captureRevision'],
|
|
504
|
+
deep: false
|
|
505
|
+
}]
|
|
506
|
+
})], SceneCaptureSystem);
|
|
507
|
+
var SceneCaptureSystem$1 = SceneCaptureSystem;
|
|
508
|
+
exports.SceneCapture = SceneCapture;
|
|
509
|
+
exports.SceneCaptureSystem = SceneCaptureSystem$1;
|
|
510
|
+
exports.SceneCaptureTextureRegistry = SceneCaptureTextureRegistry;
|
|
511
|
+
exports.getSceneCaptureTexture = getSceneCaptureTexture;
|
|
512
|
+
exports.sceneCaptureTextureRegistry = sceneCaptureTextureRegistry;
|
|
513
|
+
Object.defineProperty(exports, '__esModule', {
|
|
514
|
+
value: true
|
|
515
|
+
});
|
|
516
|
+
return exports;
|
|
517
|
+
}({}, EVA, EVA.plugin.renderer, PIXI);
|
|
518
|
+
globalThis.EVA.plugin.renderer.scene.capture = globalThis.EVA.plugin.renderer.scene.capture || _EVA_IIFE_capture;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function _extends(){return _extends=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},_extends.apply(null,arguments)}globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{},globalThis.EVA.plugin.renderer.scene=globalThis.EVA.plugin.renderer.scene||{};var _EVA_IIFE_capture=function(e,t,r,n){"use strict";function o(e,t,r,n){var o,i=arguments.length,s=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,r,n);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(s=(i<3?o(s):i>3?o(t,r,s):o(t,r))||s);return i>3&&s&&Object.defineProperty(t,r,s),s}function i(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}"function"==typeof SuppressedError&&SuppressedError;class s extends Error{constructor(){super("Symbol keys are not supported yet!"),Object.setPrototypeOf(this,new.target.prototype)}}const a="IDE_PROPERTY_METADATA";function u(e,t,r,n){let o=Reflect.getMetadata("design:type",e,t),i=o===Array;const s=function(e){return e===String?"string":e===Number?"number":e===Boolean?"boolean":"unknown"}(o);if("unknown"!==s&&(o=s),n){const e=n();Array.isArray(e)?(i=!0,o=e[0]):o=e}const u=Reflect.getMetadata(a,e.constructor)||{},p=_extends(_extends(_extends({},u[t]||{}),{type:o,isArray:i}),r);u[t]=p,Reflect.defineMetadata(a,u,e.constructor);!function(e,t,r){const n=e.constructor,o=n.IDEProps||{};o[t]=_extends(_extends({key:t},o[t]),r),n.IDEProps=o}(e,t,function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]])}return r}(p,["isArray"]))}function p(e){return t={type:e},(e,n)=>{if("symbol"==typeof n)throw new s;const{options:o,returnTypeFunc:i}=function(e,t){return"function"==typeof e?{returnTypeFunc:e,options:t||{}}:{options:e||{}}}(t,r);u(e,n,o,i)};var t,r}var c;!function(e){e[e.Edit=2]="Edit",e[e.Game=4]="Game",e[e.All=6]="All"}(c||(c={}));const d=(e,t)=>{const r=Number(e);return Number.isFinite(r)&&r>0?r:t};class l extends t.Component{constructor(){super(...arguments),this.sourceNames=[],this.output="",this.width=256,this.height=256,this.resolutionScale=1,this.updateMode="always",this.clearColor=0,this.clearAlpha=0,this.enabled=!0,this.captureRevision=0}init(e){e&&_extends(this,e),this.sourceNames=Array.isArray(this.sourceNames)?this.sourceNames.filter(e=>"string"==typeof e&&e.trim().length>0):[],this.output="string"==typeof this.output?this.output.trim():"",this.width=d(this.width,256),this.height=d(this.height,256),this.resolutionScale=d(this.resolutionScale,1),this.updateMode=this.normalizeUpdateMode(this.updateMode),this.clearColor=Math.max(0,Math.min(16777215,Number(this.clearColor)||0))>>>0,this.clearAlpha=((e,t,r,n)=>{const o=Number(e);return Number.isFinite(o)?Math.min(r,Math.max(t,o)):n})(this.clearAlpha,0,1,0),this.enabled=!1!==this.enabled}requestCapture(){this.captureRevision++,this.emit("captureRequested",{revision:this.captureRevision})}normalizeUpdateMode(e){return"onDirty"===e||"manual"===e?e:"always"}}l.componentName="SceneCapture",o([p("array"),i("design:type",Array)],l.prototype,"sourceNames",void 0),o([p("string"),i("design:type",String)],l.prototype,"output",void 0),o([p("number"),i("design:type",Number)],l.prototype,"width",void 0),o([p("number"),i("design:type",Number)],l.prototype,"height",void 0),o([p("number"),i("design:type",Number)],l.prototype,"resolutionScale",void 0),o([p("string"),i("design:type",String)],l.prototype,"updateMode",void 0),o([p("number"),i("design:type",Number)],l.prototype,"clearColor",void 0),o([p("number"),i("design:type",Number)],l.prototype,"clearAlpha",void 0),o([p("boolean"),i("design:type",Boolean)],l.prototype,"enabled",void 0),o([p("number"),i("design:type",Number)],l.prototype,"captureRevision",void 0);class h{constructor(){this.entries=new Map}get(e){var t;return null===(t=this.entries.get(this.normalize(e)))||void 0===t?void 0:t.texture}getEntry(e){return this.entries.get(this.normalize(e))}has(e){return this.entries.has(this.normalize(e))}set(e,t,r){const n=this.normalize(e);n&&t&&r&&this.entries.set(n,Object.freeze({output:n,owner:t,texture:r}))}delete(e,t){const r=this.normalize(e),n=this.entries.get(r);return!(!n||t&&n.owner!==t)&&this.entries.delete(r)}normalize(e){return"string"==typeof e?e.trim():""}}const y=new h;let m=0;const f=(e,t)=>{const r=Number(e);return Number.isFinite(r)&&r>0?r:t},g=e=>{const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(1,t)):0},b=e=>"string"==typeof e?e.trim():"";let v=class extends r.Renderer{constructor(){super(...arguments),this.name="SceneCapture",this.presentationAddFlushEnabled=!0,this.records=new Map,this.outputs=new Map,this.emptyCaptureRoot=new n.Container,this.participantId="scene-capture:"+ ++m,this.destroyed=!1}init(){if(this.renderSystem=this.game.getSystem(r.RendererSystem),!this.renderSystem)throw new Error("[SceneCapture] RendererSystem must be registered before SceneCaptureSystem.");this.renderSystem.rendererManager.register(this),this.ensurePresentationParticipant()}update(e){super.update(e),this.ensurePresentationParticipant()}lateUpdate(){var e;if(this.hasLivePresentationParticipant())return;const t=null===(e=this.renderSystem)||void 0===e?void 0:e.application;t&&this.captureForApplication(t)}componentChanged(e){if("SceneCapture"!==e.componentName)return;const r=e.component,n=e.gameObject.id;if(e.type===t.OBSERVER_TYPE.ADD)return void this.addRecord(n,r);if(e.type===t.OBSERVER_TYPE.REMOVE){const e=this.records.get(n);return void(e&&this.disposeRecord(e))}const o=this.records.get(n);o&&(o.component=r,this.resizeRecord(o),this.updateOutput(o),"manual"!==r.updateMode&&(o.dirty=!0),r.captureRevision!==o.lastCaptureRevision&&(o.dirty=!0))}getTexture(e){var t;return null===(t=this.outputs.get(b(e)))||void 0===t?void 0:t.texture}onDestroy(){var e;this.destroyed=!0,null===(e=this.presentationHandle)||void 0===e||e.dispose(),this.presentationHandle=void 0;for(const e of Array.from(this.records.values()))this.disposeRecord(e);try{this.emptyCaptureRoot.destroy({children:!1})}catch(e){}}addRecord(e,t){const r=this.records.get(e);r&&this.disposeRecord(r);const n={};_extends(n,{owner:n,gameObjectId:e,component:t,texture:this.createTexture(t),output:b(t.output),width:this.widthOf(t),height:this.heightOf(t),resolutionScale:this.resolutionOf(t),dirty:"manual"!==t.updateMode||t.captureRevision>0,lastCaptureRevision:0,disposed:!1,onCaptureRequested:()=>{n.disposed||(n.dirty=!0)}}),t.on("captureRequested",n.onCaptureRequested),this.records.set(e,n),this.bindOutput(n)}createTexture(e){return n.RenderTexture.create({width:this.widthOf(e),height:this.heightOf(e),resolution:this.resolutionOf(e)})}widthOf(e){return f(e.width,256)}heightOf(e){return f(e.height,256)}resolutionOf(e){return f(e.resolutionScale,1)}resizeRecord(e){const t=this.widthOf(e.component),r=this.heightOf(e.component),n=this.resolutionOf(e.component);if(e.width===t&&e.height===r&&e.resolutionScale===n)return;e.width=t,e.height=r,e.resolutionScale=n;const o=e.texture;if("function"==typeof o.resize)return void o.resize(t,r,n);const i=e.texture;e.texture=this.createTexture(e.component),this.bindOutput(e);try{i.destroy(!0)}catch(e){}}updateOutput(e){const t=b(e.component.output);e.output!==t&&(this.unbindOutput(e),e.output=t,this.bindOutput(e))}bindOutput(e){e.output&&(this.outputs.set(e.output,e),y.set(e.output,e.owner,e.texture))}unbindOutput(e){e.output&&(this.outputs.get(e.output)===e&&this.outputs.delete(e.output),y.delete(e.output,e.owner))}disposeRecord(e){if(!e.disposed){e.disposed=!0,this.records.delete(e.gameObjectId),this.unbindOutput(e);try{e.component.off("captureRequested",e.onCaptureRequested)}catch(e){}try{e.texture.destroy(!0)}catch(e){}}}ensurePresentationParticipant(){var e;if(this.destroyed||this.hasLivePresentationParticipant())return;const t=this.renderSystem;if(!(null==t?void 0:t.application)||"function"!=typeof t.registerPresentationParticipant)return;const r=null===(e=t.getPresentationApplicationId)||void 0===e?void 0:e.call(t,t.application);let n;n=t.registerPresentationParticipant({id:this.participantId,applicationId:r,build:()=>({writes:Array.from(this.outputs.keys(),e=>`scene-capture:${e}`)}),submit:e=>{this.captureForApplication(e.application)},dispose:()=>{this.presentationHandle===n&&(this.presentationHandle=void 0)}}),this.presentationHandle=n}hasLivePresentationParticipant(){return Boolean(this.presentationHandle&&!this.presentationHandle.disposed)}captureForApplication(e){const t=null==e?void 0:e.renderer;if(null==t?void 0:t.render)for(const r of this.records.values())this.shouldCapture(r)&&this.captureRecord(t,e,r)&&(r.dirty=!1,r.lastCaptureRevision=r.component.captureRevision)}shouldCapture(e){const t=e.component;return!e.disposed&&!1!==t.enabled&&("always"===t.updateMode||(t.captureRevision!==e.lastCaptureRevision&&(e.dirty=!0),e.dirty))}captureRecord(e,t,r){const n=this.resolveSourceContainers(r.component,t),o=this.toClearColor(r.component);try{if(0===n.length)return e.render({container:this.emptyCaptureRoot,target:r.texture,clear:!0,clearColor:o}),!0;for(let t=0;t<n.length;t++){const i=n[t],s={container:i,target:r.texture,clear:0===t};0===t&&(s.clearColor=o),i.worldTransform&&(s.transform=i.worldTransform),e.render(s)}return!0}catch(e){return!1}}resolveSourceContainers(e,t){var r;const n=[],o=Array.isArray(e.sourceNames)?e.sourceNames:[],i=this.game;for(const e of o){if(!e||"function"!=typeof(null==i?void 0:i.findAllByName))continue;const o=i.findAllByName(e);for(const e of o||[]){if(!e||e.destroyed)continue;const o=null===(r=this.containerManager)||void 0===r?void 0:r.getContainer(e.id);o&&!o.destroyed&&o!==t.stage&&o!==this.emptyCaptureRoot&&(n.includes(o)||n.push(o))}}return n}toClearColor(e){const t=(Number(e.clearColor)||0)>>>0;return[(t>>>16&255)/255,(t>>>8&255)/255,(255&t)/255,g(e.clearAlpha)]}};v.systemName="SceneCapture",v=o([t.decorators.componentObserver({SceneCapture:[{prop:["sourceNames"],deep:!0},{prop:["output"],deep:!1},{prop:["width"],deep:!1},{prop:["height"],deep:!1},{prop:["resolutionScale"],deep:!1},{prop:["updateMode"],deep:!1},{prop:["clearColor"],deep:!1},{prop:["clearAlpha"],deep:!1},{prop:["enabled"],deep:!1},{prop:["captureRevision"],deep:!1}]})],v);var R=v;return e.SceneCapture=l,e.SceneCaptureSystem=R,e.SceneCaptureTextureRegistry=h,e.getSceneCaptureTexture=function(e){return y.get(e)},e.sceneCaptureTextureRegistry=y,Object.defineProperty(e,"__esModule",{value:!0}),e}({},EVA,EVA.plugin.renderer,PIXI);globalThis.EVA.plugin.renderer.scene.capture=globalThis.EVA.plugin.renderer.scene.capture||_EVA_IIFE_capture;
|