@fps-games/editor 0.2.1-beta.2 → 0.2.1-beta.3
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/dist/build-info.json +41 -41
- package/dist/local-editor-harness.d.ts.map +1 -1
- package/dist/local-editor-harness.js +16 -7
- package/dist/local-editor-harness.js.map +1 -1
- package/dist/playable-babylon-rendering.d.ts +8 -7
- package/dist/playable-babylon-rendering.d.ts.map +1 -1
- package/dist/playable-babylon-rendering.js +77 -32
- package/dist/playable-babylon-rendering.js.map +1 -1
- package/dist/playable-product-projection-preview.d.ts +2 -0
- package/dist/playable-product-projection-preview.d.ts.map +1 -1
- package/dist/playable-product-projection-preview.js +7 -4
- package/dist/playable-product-projection-preview.js.map +1 -1
- package/dist/playable-sdk.d.ts +1 -1
- package/dist/playable-sdk.d.ts.map +1 -1
- package/dist/playable-sdk.js +1 -1
- package/dist/playable-sdk.js.map +1 -1
- package/dist/playable-standard-project.d.ts +0 -1
- package/dist/playable-standard-project.d.ts.map +1 -1
- package/dist/playable-standard-project.js +13 -4
- package/dist/playable-standard-project.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/environment-texture-controller.d.ts +4 -2
- package/node_modules/@fps-games/babylon-renderer/dist/environment/environment-texture-controller.d.ts.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/environment-texture-controller.js +301 -121
- package/node_modules/@fps-games/babylon-renderer/dist/environment/environment-texture-controller.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/profile.js +5 -4
- package/node_modules/@fps-games/babylon-renderer/dist/environment/profile.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/types.d.ts +4 -4
- package/node_modules/@fps-games/babylon-renderer/dist/environment/types.d.ts.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/types.js +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/environment/types.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.d.ts +2 -0
- package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.d.ts.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.js +12 -1
- package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/plugin.d.ts +6 -3
- package/node_modules/@fps-games/babylon-renderer/dist/plugin.d.ts.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/plugin.js +100 -39
- package/node_modules/@fps-games/babylon-renderer/dist/plugin.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/reference.d.ts +1 -3
- package/node_modules/@fps-games/babylon-renderer/dist/reference.d.ts.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/dist/reference.js.map +1 -1
- package/node_modules/@fps-games/babylon-renderer/package.json +11 -8
- package/node_modules/@fps-games/editor-babylon/package.json +6 -6
- package/node_modules/@fps-games/editor-browser/package.json +7 -7
- package/node_modules/@fps-games/editor-core/package.json +6 -6
- package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js +10 -3
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/generated-module.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/index.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.d.ts +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.js +4 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +4 -4
- package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts +2 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js +1 -5
- package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/assets.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/inspectors.js +53 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/inspectors.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/types.d.ts +2 -0
- package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/types.d.ts.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/types.js.map +1 -1
- package/node_modules/@fps-games/editor-playable-sdk/package.json +6 -6
- package/node_modules/@fps-games/editor-protocol/package.json +2 -2
- package/node_modules/@fps-games/editor-tooling/package.json +3 -3
- package/node_modules/@fps-games/editor-ui/package.json +1 -1
- package/node_modules/@fps-games/playable-assets/dist/identity.d.ts +1 -0
- package/node_modules/@fps-games/playable-assets/dist/identity.d.ts.map +1 -1
- package/node_modules/@fps-games/playable-assets/dist/identity.js +1 -1
- package/node_modules/@fps-games/playable-assets/dist/identity.js.map +1 -1
- package/node_modules/@fps-games/playable-assets/dist/index.d.ts +1 -0
- package/node_modules/@fps-games/playable-assets/dist/index.d.ts.map +1 -1
- package/node_modules/@fps-games/playable-assets/dist/index.js +1 -0
- package/node_modules/@fps-games/playable-assets/dist/index.js.map +1 -1
- package/node_modules/@fps-games/playable-assets/dist/resource-resolver.d.ts +46 -0
- package/node_modules/@fps-games/playable-assets/dist/resource-resolver.d.ts.map +1 -0
- package/node_modules/@fps-games/playable-assets/dist/resource-resolver.js +109 -0
- package/node_modules/@fps-games/playable-assets/dist/resource-resolver.js.map +1 -0
- package/node_modules/@fps-games/playable-assets/package.json +1 -1
- package/node_modules/@fps-games/playable-contracts/package.json +1 -1
- package/node_modules/@fps-games/playable-rendering/package.json +2 -2
- package/node_modules/@fps-games/playable-runtime/dist/runtime.d.ts.map +1 -1
- package/node_modules/@fps-games/playable-runtime/dist/runtime.js +5 -0
- package/node_modules/@fps-games/playable-runtime/dist/runtime.js.map +1 -1
- package/node_modules/@fps-games/playable-runtime/dist/types.d.ts +2 -0
- package/node_modules/@fps-games/playable-runtime/dist/types.d.ts.map +1 -1
- package/node_modules/@fps-games/playable-runtime/dist/types.js.map +1 -1
- package/node_modules/@fps-games/playable-runtime/package.json +12 -12
- package/node_modules/@fps-games/playable-runtime-data/package.json +4 -4
- package/node_modules/@fps-games/playable-scene/package.json +2 -2
- package/node_modules/@fps-games/plugin-api/package.json +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/reference.d.ts.map +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/reference.js +11 -4
- package/node_modules/@fps-games/plugin-assets/dist/reference.js.map +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/renderer.d.ts +8 -0
- package/node_modules/@fps-games/plugin-assets/dist/renderer.d.ts.map +1 -0
- package/node_modules/@fps-games/plugin-assets/dist/renderer.js +13 -0
- package/node_modules/@fps-games/plugin-assets/dist/renderer.js.map +1 -0
- package/node_modules/@fps-games/plugin-assets/dist/resources.d.ts +12 -0
- package/node_modules/@fps-games/plugin-assets/dist/resources.d.ts.map +1 -0
- package/node_modules/@fps-games/plugin-assets/dist/resources.js +8 -0
- package/node_modules/@fps-games/plugin-assets/dist/resources.js.map +1 -0
- package/node_modules/@fps-games/plugin-assets/dist/runtime.d.ts +2 -1
- package/node_modules/@fps-games/plugin-assets/dist/runtime.d.ts.map +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/runtime.js +3 -0
- package/node_modules/@fps-games/plugin-assets/dist/runtime.js.map +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-assets/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-assets/package.json +32 -8
- package/node_modules/@fps-games/plugin-hierarchy/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-hierarchy/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-hierarchy/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-hierarchy/package.json +5 -5
- package/node_modules/@fps-games/plugin-host/package.json +2 -2
- package/node_modules/@fps-games/plugin-markers/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-markers/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-markers/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-markers/package.json +5 -5
- package/node_modules/@fps-games/plugin-materials/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-materials/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-materials/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-materials/package.json +5 -5
- package/node_modules/@fps-games/plugin-rendering/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-rendering/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-rendering/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-rendering/package.json +5 -5
- package/node_modules/@fps-games/plugin-scene/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-scene/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-scene/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-scene/package.json +5 -5
- package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-shadow-map-experiment/package.json +5 -5
- package/node_modules/@fps-games/plugin-shadows/dist/version.d.ts +1 -1
- package/node_modules/@fps-games/plugin-shadows/dist/version.js +1 -1
- package/node_modules/@fps-games/plugin-shadows/dist/version.js.map +1 -1
- package/node_modules/@fps-games/plugin-shadows/package.json +7 -7
- package/package.json +24 -22
package/node_modules/@fps-games/babylon-renderer/dist/environment/environment-texture-controller.js
CHANGED
|
@@ -1,79 +1,150 @@
|
|
|
1
1
|
import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture.js';
|
|
2
|
+
import { _ENVTextureLoader } from '@babylonjs/core/Materials/Textures/Loaders/envTextureLoader.js';
|
|
3
|
+
import { registerTextureLoader } from '@babylonjs/core/Materials/Textures/Loaders/textureLoaderManager.js';
|
|
2
4
|
import {} from './types.js';
|
|
3
5
|
import { normalizeBabylonEnvironmentTextureProfile } from './profile.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
+
// Register the framework default during module initialization so single-file
|
|
7
|
+
// bundlers cannot remove Babylon's dynamic .env loader discovery. Applications
|
|
8
|
+
// remain free to register their own .env loader after importing the renderer.
|
|
9
|
+
registerTextureLoader('.env', async () => new _ENVTextureLoader());
|
|
10
|
+
export function readBabylonEnvironmentTextureControllerCleanup(error) {
|
|
11
|
+
if (!error || (typeof error !== 'object' && typeof error !== 'function'))
|
|
12
|
+
return null;
|
|
13
|
+
const cleanup = error
|
|
14
|
+
.babylonEnvironmentTextureControllerCleanup;
|
|
15
|
+
return typeof cleanup === 'function'
|
|
16
|
+
? cleanup
|
|
17
|
+
: null;
|
|
18
|
+
}
|
|
19
|
+
export function createBabylonEnvironmentTextureController(scene, options = {}) {
|
|
20
|
+
return new BabylonEnvironmentTextureControllerImpl(scene, options.createTexture ?? createDefaultEnvironmentTexture);
|
|
6
21
|
}
|
|
7
22
|
class BabylonEnvironmentTextureControllerImpl {
|
|
8
|
-
constructor(scene,
|
|
23
|
+
constructor(scene, createTexture) {
|
|
9
24
|
this.scene = scene;
|
|
10
25
|
this.createTexture = createTexture;
|
|
11
26
|
this.profile = null;
|
|
12
27
|
this.texture = null;
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.textureUrl = nextProfile.textureUrl;
|
|
34
|
-
this.scene.environmentTexture = nextTexture;
|
|
35
|
-
previousTexture?.dispose();
|
|
36
|
-
}
|
|
37
|
-
this.profile = nextProfile;
|
|
38
|
-
this.scene.environmentIntensity = nextProfile.intensity;
|
|
39
|
-
if (this.texture) {
|
|
40
|
-
this.texture.level = nextProfile.intensity;
|
|
41
|
-
this.texture.rotationY = nextProfile.rotationY;
|
|
42
|
-
if (this.scene.environmentTexture !== this.texture) {
|
|
43
|
-
this.scene.environmentTexture = this.texture;
|
|
28
|
+
this.resource = null;
|
|
29
|
+
this.generation = 0;
|
|
30
|
+
this.pendingAbort = null;
|
|
31
|
+
this.retainedCleanupTextures = new Set();
|
|
32
|
+
this.pendingSceneClearTexture = null;
|
|
33
|
+
this.disposeRequested = false;
|
|
34
|
+
this.disposed = false;
|
|
35
|
+
this.retryCleanup = () => {
|
|
36
|
+
const cleanupErrors = [];
|
|
37
|
+
const pendingSceneTexture = this.pendingSceneClearTexture;
|
|
38
|
+
if (pendingSceneTexture) {
|
|
39
|
+
try {
|
|
40
|
+
if (this.scene.environmentTexture === pendingSceneTexture) {
|
|
41
|
+
this.scene.environmentTexture = null;
|
|
42
|
+
}
|
|
43
|
+
this.pendingSceneClearTexture = null;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
cleanupErrors.push(sanitizeCause(error));
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
|
-
|
|
49
|
+
for (const texture of [...this.retainedCleanupTextures]) {
|
|
50
|
+
try {
|
|
51
|
+
texture.dispose();
|
|
52
|
+
this.retainedCleanupTextures.delete(texture);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
cleanupErrors.push(sanitizeCause(error));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return Object.freeze(cleanupErrors);
|
|
59
|
+
};
|
|
46
60
|
}
|
|
47
|
-
async
|
|
61
|
+
async applyProfile(profile, signal) {
|
|
62
|
+
this.assertNotDisposed();
|
|
48
63
|
if (signal?.aborted)
|
|
49
64
|
throw createEnvironmentTextureAbortError();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
const nextProfile = normalizeBabylonEnvironmentTextureProfile(profile);
|
|
55
|
-
if (!nextProfile.textureUrl || (this.texture && this.textureUrl === nextProfile.textureUrl)) {
|
|
56
|
-
this.setProfile(nextProfile);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const nextTexture = await this.createEnvironmentTextureAsync(nextProfile.textureUrl, signal);
|
|
60
|
-
if (signal?.aborted) {
|
|
61
|
-
throwCandidateTextureFailure(nextTexture, createEnvironmentTextureAbortError());
|
|
65
|
+
const retainedCleanupErrors = this.retryCleanup();
|
|
66
|
+
if (retainedCleanupErrors.length > 0) {
|
|
67
|
+
throw createEnvironmentTextureCleanupFailure(retainedCleanupErrors, this.retryCleanup);
|
|
62
68
|
}
|
|
69
|
+
const generation = ++this.generation;
|
|
70
|
+
this.pendingAbort?.abort();
|
|
71
|
+
const candidateAbort = new AbortController();
|
|
72
|
+
this.pendingAbort = candidateAbort;
|
|
73
|
+
const removeSignalListener = forwardAbort(signal, candidateAbort);
|
|
74
|
+
const isCurrent = () => !this.disposed && this.generation === generation && !candidateAbort.signal.aborted;
|
|
63
75
|
try {
|
|
64
|
-
|
|
65
|
-
|
|
76
|
+
const nextProfile = profile ? normalizeBabylonEnvironmentTextureProfile(profile) : null;
|
|
77
|
+
if (!nextProfile?.texture) {
|
|
78
|
+
if (!isCurrent())
|
|
79
|
+
throw createEnvironmentTextureAbortError();
|
|
80
|
+
const previousTexture = this.texture;
|
|
81
|
+
const previousSceneTexture = this.scene.environmentTexture;
|
|
82
|
+
const sceneWithIntensity = this.scene;
|
|
83
|
+
const previousIntensity = sceneWithIntensity.environmentIntensity;
|
|
84
|
+
try {
|
|
85
|
+
if (previousTexture && previousSceneTexture === previousTexture) {
|
|
86
|
+
this.scene.environmentTexture = null;
|
|
87
|
+
}
|
|
88
|
+
if (nextProfile)
|
|
89
|
+
sceneWithIntensity.environmentIntensity = nextProfile.intensity;
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
restoreSceneState(this.scene, previousSceneTexture, previousIntensity);
|
|
93
|
+
throw createSafeEnvironmentTextureError('babylon.environment-texture.profile-failed', 'Failed to apply Babylon environment texture profile.', error);
|
|
94
|
+
}
|
|
95
|
+
this.texture = null;
|
|
96
|
+
this.resource = null;
|
|
97
|
+
this.profile = nextProfile;
|
|
98
|
+
const cleanupError = this.disposeTextureOrRetain(previousTexture);
|
|
99
|
+
if (cleanupError) {
|
|
100
|
+
throw createEnvironmentTextureCleanupFailure([cleanupError], this.retryCleanup);
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (this.texture && sameResource(this.resource, nextProfile.texture)) {
|
|
105
|
+
if (!isCurrent())
|
|
106
|
+
throw createEnvironmentTextureAbortError();
|
|
107
|
+
this.applyCommittedTextureProfile(this.texture, nextProfile);
|
|
108
|
+
this.profile = nextProfile;
|
|
109
|
+
this.resource = nextProfile.texture;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const candidate = await this.createEnvironmentTextureAsync(nextProfile.texture, candidateAbort.signal);
|
|
113
|
+
if (!isCurrent())
|
|
114
|
+
this.throwCandidateTextureFailure(candidate, createEnvironmentTextureAbortError());
|
|
115
|
+
try {
|
|
116
|
+
applyCandidateTextureProperties(candidate, nextProfile);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.throwCandidateTextureFailure(candidate, createSafeEnvironmentTextureError('babylon.environment-texture.profile-failed', 'Failed to apply Babylon environment texture profile.', error));
|
|
120
|
+
}
|
|
121
|
+
if (!isCurrent())
|
|
122
|
+
this.throwCandidateTextureFailure(candidate, createEnvironmentTextureAbortError());
|
|
123
|
+
const previousTexture = this.texture;
|
|
124
|
+
const previousSceneTexture = this.scene.environmentTexture;
|
|
125
|
+
const sceneWithIntensity = this.scene;
|
|
126
|
+
const previousIntensity = sceneWithIntensity.environmentIntensity;
|
|
127
|
+
try {
|
|
128
|
+
this.scene.environmentTexture = candidate;
|
|
129
|
+
sceneWithIntensity.environmentIntensity = nextProfile.intensity;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
restoreSceneState(this.scene, previousSceneTexture, previousIntensity);
|
|
133
|
+
this.throwCandidateTextureFailure(candidate, createSafeEnvironmentTextureError('babylon.environment-texture.profile-failed', 'Failed to apply Babylon environment texture profile.', error));
|
|
134
|
+
}
|
|
135
|
+
this.texture = candidate;
|
|
136
|
+
this.resource = nextProfile.texture;
|
|
137
|
+
this.profile = nextProfile;
|
|
138
|
+
const cleanupError = this.disposeTextureOrRetain(previousTexture);
|
|
139
|
+
if (cleanupError) {
|
|
140
|
+
throw createEnvironmentTextureCleanupFailure([cleanupError], this.retryCleanup);
|
|
141
|
+
}
|
|
66
142
|
}
|
|
67
|
-
|
|
68
|
-
|
|
143
|
+
finally {
|
|
144
|
+
removeSignalListener();
|
|
145
|
+
if (this.pendingAbort === candidateAbort)
|
|
146
|
+
this.pendingAbort = null;
|
|
69
147
|
}
|
|
70
|
-
const previousTexture = this.texture;
|
|
71
|
-
this.texture = nextTexture;
|
|
72
|
-
this.textureUrl = nextProfile.textureUrl;
|
|
73
|
-
this.profile = nextProfile;
|
|
74
|
-
this.scene.environmentTexture = nextTexture;
|
|
75
|
-
this.scene.environmentIntensity = nextProfile.intensity;
|
|
76
|
-
previousTexture?.dispose();
|
|
77
148
|
}
|
|
78
149
|
getProfile() {
|
|
79
150
|
return this.profile ? { ...this.profile } : null;
|
|
@@ -82,107 +153,216 @@ class BabylonEnvironmentTextureControllerImpl {
|
|
|
82
153
|
return this.texture;
|
|
83
154
|
}
|
|
84
155
|
dispose() {
|
|
85
|
-
this.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
156
|
+
if (this.disposed)
|
|
157
|
+
return;
|
|
158
|
+
if (!this.disposeRequested) {
|
|
159
|
+
this.disposeRequested = true;
|
|
160
|
+
this.generation += 1;
|
|
161
|
+
this.pendingAbort?.abort();
|
|
162
|
+
this.pendingAbort = null;
|
|
163
|
+
const texture = this.texture;
|
|
164
|
+
if (texture) {
|
|
165
|
+
this.retainedCleanupTextures.add(texture);
|
|
166
|
+
if (this.scene.environmentTexture === texture) {
|
|
167
|
+
this.pendingSceneClearTexture = texture;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
this.texture = null;
|
|
171
|
+
this.resource = null;
|
|
172
|
+
this.profile = null;
|
|
91
173
|
}
|
|
92
|
-
this.
|
|
93
|
-
|
|
94
|
-
|
|
174
|
+
const cleanupErrors = this.retryCleanup();
|
|
175
|
+
if (cleanupErrors.length > 0) {
|
|
176
|
+
throw createEnvironmentTextureCleanupFailure(cleanupErrors, this.retryCleanup);
|
|
177
|
+
}
|
|
178
|
+
this.disposed = true;
|
|
95
179
|
}
|
|
96
|
-
|
|
180
|
+
applyCommittedTextureProfile(texture, profile) {
|
|
181
|
+
const textureWithRotation = texture;
|
|
182
|
+
const sceneWithIntensity = this.scene;
|
|
183
|
+
const previousLevel = texture.level;
|
|
184
|
+
const previousRotation = textureWithRotation.rotationY;
|
|
185
|
+
const previousSceneTexture = this.scene.environmentTexture;
|
|
186
|
+
const previousIntensity = sceneWithIntensity.environmentIntensity;
|
|
97
187
|
try {
|
|
98
|
-
|
|
99
|
-
|
|
188
|
+
applyCandidateTextureProperties(texture, profile);
|
|
189
|
+
if (previousSceneTexture !== texture)
|
|
190
|
+
this.scene.environmentTexture = texture;
|
|
191
|
+
sceneWithIntensity.environmentIntensity = profile.intensity;
|
|
100
192
|
}
|
|
101
|
-
catch (
|
|
102
|
-
|
|
193
|
+
catch (error) {
|
|
194
|
+
restoreTextureProperties(texture, previousLevel, previousRotation);
|
|
195
|
+
restoreSceneState(this.scene, previousSceneTexture, previousIntensity);
|
|
196
|
+
throw createSafeEnvironmentTextureError('babylon.environment-texture.profile-failed', 'Failed to apply Babylon environment texture profile.', error);
|
|
103
197
|
}
|
|
104
198
|
}
|
|
105
|
-
|
|
199
|
+
createEnvironmentTextureAsync(resource, signal) {
|
|
106
200
|
return new Promise((resolve, reject) => {
|
|
201
|
+
if (signal.aborted) {
|
|
202
|
+
reject(createEnvironmentTextureAbortError());
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
107
205
|
let settled = false;
|
|
108
206
|
let texture = null;
|
|
109
207
|
let loaded = false;
|
|
110
|
-
let
|
|
111
|
-
const
|
|
112
|
-
const fail = (message, exception) => {
|
|
208
|
+
let pendingFailure = null;
|
|
209
|
+
const settleFailure = (failure) => {
|
|
113
210
|
if (settled)
|
|
114
211
|
return;
|
|
115
212
|
if (!texture) {
|
|
116
|
-
|
|
213
|
+
pendingFailure = failure;
|
|
117
214
|
return;
|
|
118
215
|
}
|
|
119
216
|
settled = true;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
texture.dispose();
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
cleanupError = error;
|
|
127
|
-
}
|
|
128
|
-
reject(Object.assign(new Error(message || `Failed to load Babylon environment texture: ${textureUrl}`), { cause: exception, ...(cleanupError === undefined ? {} : { cleanupError }) }));
|
|
217
|
+
signal.removeEventListener('abort', abort);
|
|
218
|
+
const cleanupError = this.disposeTextureOrRetain(texture);
|
|
219
|
+
reject(withCleanupError(failure, cleanupError, this.retryCleanup));
|
|
129
220
|
};
|
|
130
221
|
const complete = () => {
|
|
131
|
-
if (settled)
|
|
132
|
-
|
|
133
|
-
loaded = true;
|
|
134
|
-
if (!texture)
|
|
222
|
+
if (settled || !texture) {
|
|
223
|
+
loaded = true;
|
|
135
224
|
return;
|
|
225
|
+
}
|
|
136
226
|
settled = true;
|
|
137
|
-
|
|
227
|
+
signal.removeEventListener('abort', abort);
|
|
138
228
|
resolve(texture);
|
|
139
229
|
};
|
|
140
|
-
const abort = () =>
|
|
141
|
-
|
|
230
|
+
const abort = () => settleFailure(createEnvironmentTextureAbortError());
|
|
231
|
+
const fail = (_message, exception) => {
|
|
232
|
+
settleFailure(createSafeEnvironmentTextureError('babylon.environment-texture.load-failed', 'Failed to load Babylon environment texture.', exception));
|
|
233
|
+
};
|
|
234
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
142
235
|
try {
|
|
143
|
-
texture = this.createTexture(
|
|
144
|
-
onLoad: complete,
|
|
145
|
-
onError: fail,
|
|
146
|
-
});
|
|
236
|
+
texture = this.createTexture(resource, this.scene, { onLoad: complete, onError: fail });
|
|
147
237
|
}
|
|
148
|
-
catch (
|
|
238
|
+
catch (error) {
|
|
149
239
|
settled = true;
|
|
150
|
-
|
|
151
|
-
reject(
|
|
240
|
+
signal.removeEventListener('abort', abort);
|
|
241
|
+
reject(createSafeEnvironmentTextureError('babylon.environment-texture.create-failed', 'Failed to create Babylon environment texture.', error));
|
|
152
242
|
return;
|
|
153
243
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
else if (loaded || texture.isReady()) {
|
|
244
|
+
if (pendingFailure)
|
|
245
|
+
settleFailure(pendingFailure);
|
|
246
|
+
else if (loaded || texture.isReady())
|
|
159
247
|
complete();
|
|
160
|
-
}
|
|
161
248
|
});
|
|
162
249
|
}
|
|
250
|
+
assertNotDisposed() {
|
|
251
|
+
if (this.disposed || this.disposeRequested) {
|
|
252
|
+
throw new Error('Babylon environment texture controller is disposed.');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
disposeTextureOrRetain(texture) {
|
|
256
|
+
if (!texture)
|
|
257
|
+
return null;
|
|
258
|
+
this.retainedCleanupTextures.add(texture);
|
|
259
|
+
try {
|
|
260
|
+
texture.dispose();
|
|
261
|
+
this.retainedCleanupTextures.delete(texture);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
return sanitizeCause(error);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
throwCandidateTextureFailure(texture, failure) {
|
|
269
|
+
const cleanupError = this.disposeTextureOrRetain(texture);
|
|
270
|
+
throw withCleanupError(failure, cleanupError, this.retryCleanup);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function applyCandidateTextureProperties(texture, profile) {
|
|
274
|
+
texture.level = profile.intensity;
|
|
275
|
+
texture.rotationY = profile.rotationY;
|
|
276
|
+
}
|
|
277
|
+
function restoreTextureProperties(texture, level, rotationY) {
|
|
278
|
+
try {
|
|
279
|
+
texture.level = level;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// Best-effort rollback keeps the original operation error as the public diagnostic.
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
texture.rotationY = rotationY;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
// Best-effort rollback keeps the original operation error as the public diagnostic.
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function restoreSceneState(scene, environmentTexture, environmentIntensity) {
|
|
292
|
+
try {
|
|
293
|
+
scene.environmentTexture = environmentTexture;
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// Best-effort rollback keeps the original operation error as the public diagnostic.
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
scene.environmentIntensity = environmentIntensity;
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Best-effort rollback keeps the original operation error as the public diagnostic.
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function forwardAbort(signal, controller) {
|
|
306
|
+
if (!signal)
|
|
307
|
+
return () => undefined;
|
|
308
|
+
const onAbort = () => controller.abort();
|
|
309
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
310
|
+
if (signal.aborted)
|
|
311
|
+
controller.abort();
|
|
312
|
+
return () => signal.removeEventListener('abort', onAbort);
|
|
313
|
+
}
|
|
314
|
+
function sameResource(left, right) {
|
|
315
|
+
return left?.assetId === right.assetId
|
|
316
|
+
&& left?.url === right.url
|
|
317
|
+
&& left?.format === right.format;
|
|
163
318
|
}
|
|
164
319
|
function createEnvironmentTextureAbortError() {
|
|
165
|
-
return Object.assign(new Error('Babylon environment texture
|
|
320
|
+
return Object.assign(new Error('Babylon environment texture update aborted.'), { name: 'AbortError' });
|
|
321
|
+
}
|
|
322
|
+
function createSafeEnvironmentTextureError(code, message, cause) {
|
|
323
|
+
const error = Object.assign(new Error(message), { code });
|
|
324
|
+
if (cause !== undefined) {
|
|
325
|
+
Object.assign(error, { cause: sanitizeCause(cause) });
|
|
326
|
+
}
|
|
327
|
+
return error;
|
|
328
|
+
}
|
|
329
|
+
function sanitizeCause(cause) {
|
|
330
|
+
const message = cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');
|
|
331
|
+
return new Error(message.replace(/(?:data|blob):[^\s)]+/giu, '[redacted-resource-url]'));
|
|
332
|
+
}
|
|
333
|
+
function withCleanupError(failure, cleanupError, retryCleanup) {
|
|
334
|
+
const result = failure instanceof Error ? failure : new Error('Babylon environment texture operation failed.');
|
|
335
|
+
if (cleanupError) {
|
|
336
|
+
attachEnvironmentTextureCleanup(result, [cleanupError], retryCleanup);
|
|
337
|
+
}
|
|
338
|
+
return result;
|
|
339
|
+
}
|
|
340
|
+
function createEnvironmentTextureCleanupFailure(cleanupErrors, retryCleanup) {
|
|
341
|
+
return attachEnvironmentTextureCleanup(Object.assign(new Error('Failed to dispose Babylon environment texture resources.'), { code: 'babylon.environment-texture.dispose-failed' }), cleanupErrors, retryCleanup);
|
|
166
342
|
}
|
|
167
|
-
function
|
|
168
|
-
|
|
343
|
+
function attachEnvironmentTextureCleanup(failure, cleanupErrors, retryCleanup) {
|
|
344
|
+
const safeErrors = Object.freeze(cleanupErrors.map(sanitizeCause));
|
|
345
|
+
const metadata = {
|
|
346
|
+
cleanupError: safeErrors[0],
|
|
347
|
+
cleanupErrors: safeErrors,
|
|
348
|
+
babylonEnvironmentTextureControllerCleanup: retryCleanup,
|
|
349
|
+
retryCleanup,
|
|
350
|
+
};
|
|
169
351
|
try {
|
|
170
|
-
|
|
352
|
+
Object.assign(failure, metadata);
|
|
353
|
+
if (readBabylonEnvironmentTextureControllerCleanup(failure) === retryCleanup)
|
|
354
|
+
return failure;
|
|
171
355
|
}
|
|
172
|
-
catch
|
|
173
|
-
|
|
356
|
+
catch {
|
|
357
|
+
// Wrap non-extensible primary failures so the owning cleanup remains reachable.
|
|
174
358
|
}
|
|
175
|
-
|
|
176
|
-
? failure
|
|
177
|
-
: Object.assign(new Error(String(failure)), { cause: failure });
|
|
178
|
-
if (cleanupError !== undefined)
|
|
179
|
-
Object.assign(result, { cleanupError });
|
|
180
|
-
throw result;
|
|
359
|
+
return Object.assign(new Error(failure.message), { cause: failure, ...metadata });
|
|
181
360
|
}
|
|
182
|
-
function createDefaultEnvironmentTexture(
|
|
183
|
-
return new CubeTexture(
|
|
361
|
+
function createDefaultEnvironmentTexture(resource, scene, callbacks = {}) {
|
|
362
|
+
return new CubeTexture(resource.url, scene, {
|
|
184
363
|
prefiltered: true,
|
|
185
364
|
createPolynomials: true,
|
|
365
|
+
forcedExtension: resource.format,
|
|
186
366
|
onLoad: callbacks.onLoad,
|
|
187
367
|
onError: callbacks.onError,
|
|
188
368
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-texture-controller.js","sourceRoot":"","sources":["../../src/environment/environment-texture-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture.js';\nimport type { Scene } from '@babylonjs/core/scene.js';\nimport {\n type BabylonEnvironmentTextureController,\n type BabylonEnvironmentTextureControllerOptions,\n type BabylonEnvironmentTextureFactory,\n type BabylonEnvironmentTextureProfile,\n} from './types.js';\nimport { normalizeBabylonEnvironmentTextureProfile } from './profile.js';\n\nexport function createBabylonEnvironmentTextureController(\n scene: Scene,\n initialProfile?: BabylonEnvironmentTextureProfile | null,\n options: BabylonEnvironmentTextureControllerOptions = {},\n): BabylonEnvironmentTextureController {\n return new BabylonEnvironmentTextureControllerImpl(\n scene,\n initialProfile ?? null,\n options.createTexture ?? createDefaultEnvironmentTexture,\n );\n}\n\nclass BabylonEnvironmentTextureControllerImpl implements BabylonEnvironmentTextureController {\n private profile: BabylonEnvironmentTextureProfile | null = null;\n private texture: CubeTexture | null = null;\n private textureUrl = '';\n\n constructor(\n private readonly scene: Scene,\n initialProfile: BabylonEnvironmentTextureProfile | null,\n private readonly createTexture: BabylonEnvironmentTextureFactory,\n ) {\n this.setProfile(initialProfile);\n }\n\n setProfile(profile: BabylonEnvironmentTextureProfile | null | undefined): void {\n if (!profile) {\n this.clearEnvironmentTexture();\n this.profile = null;\n return;\n }\n\n const nextProfile = normalizeBabylonEnvironmentTextureProfile(profile);\n if (!nextProfile.textureUrl) {\n this.clearEnvironmentTexture();\n this.profile = nextProfile;\n (this.scene as unknown as { environmentIntensity?: number }).environmentIntensity = nextProfile.intensity;\n return;\n }\n\n if (!this.texture || this.textureUrl !== nextProfile.textureUrl) {\n const previousTexture = this.texture;\n const nextTexture = this.createEnvironmentTexture(nextProfile.textureUrl);\n this.texture = nextTexture;\n this.textureUrl = nextProfile.textureUrl;\n this.scene.environmentTexture = nextTexture;\n previousTexture?.dispose();\n }\n\n this.profile = nextProfile;\n (this.scene as unknown as { environmentIntensity?: number }).environmentIntensity = nextProfile.intensity;\n if (this.texture) {\n this.texture.level = nextProfile.intensity;\n (this.texture as unknown as { rotationY?: number }).rotationY = nextProfile.rotationY;\n if (this.scene.environmentTexture !== this.texture) {\n this.scene.environmentTexture = this.texture;\n }\n }\n }\n\n async setProfileAsync(\n profile: BabylonEnvironmentTextureProfile | null | undefined,\n signal?: AbortSignal,\n ): Promise<void> {\n if (signal?.aborted) throw createEnvironmentTextureAbortError();\n if (!profile) {\n this.setProfile(profile);\n return;\n }\n const nextProfile = normalizeBabylonEnvironmentTextureProfile(profile);\n if (!nextProfile.textureUrl || (this.texture && this.textureUrl === nextProfile.textureUrl)) {\n this.setProfile(nextProfile);\n return;\n }\n\n const nextTexture = await this.createEnvironmentTextureAsync(nextProfile.textureUrl, signal);\n if (signal?.aborted) {\n throwCandidateTextureFailure(nextTexture, createEnvironmentTextureAbortError());\n }\n try {\n nextTexture.level = nextProfile.intensity;\n (nextTexture as unknown as { rotationY?: number }).rotationY = nextProfile.rotationY;\n } catch (cause) {\n throwCandidateTextureFailure(nextTexture, cause);\n }\n const previousTexture = this.texture;\n this.texture = nextTexture;\n this.textureUrl = nextProfile.textureUrl;\n this.profile = nextProfile;\n this.scene.environmentTexture = nextTexture;\n (this.scene as unknown as { environmentIntensity?: number }).environmentIntensity = nextProfile.intensity;\n previousTexture?.dispose();\n }\n\n getProfile(): BabylonEnvironmentTextureProfile | null {\n return this.profile ? { ...this.profile } : null;\n }\n\n getTexture(): CubeTexture | null {\n return this.texture;\n }\n\n dispose(): void {\n this.clearEnvironmentTexture();\n this.profile = null;\n }\n\n private clearEnvironmentTexture(): void {\n if (this.texture && this.scene.environmentTexture === this.texture) {\n this.scene.environmentTexture = null;\n }\n this.texture?.dispose();\n this.texture = null;\n this.textureUrl = '';\n }\n\n private createEnvironmentTexture(textureUrl: string): CubeTexture {\n try {\n const texture = this.createTexture(textureUrl, this.scene);\n return texture;\n } catch (cause) {\n throw Object.assign(\n new Error(`Failed to create Babylon environment texture: ${textureUrl}`),\n { cause },\n );\n }\n }\n\n private async createEnvironmentTextureAsync(\n textureUrl: string,\n signal?: AbortSignal,\n ): Promise<CubeTexture> {\n return new Promise<CubeTexture>((resolve, reject) => {\n let settled = false;\n let texture: CubeTexture | null = null;\n let loaded = false;\n let pendingError: { message?: string; exception?: unknown } | null = null;\n const removeAbortListener = (): void => signal?.removeEventListener('abort', abort);\n const fail = (message?: string, exception?: unknown): void => {\n if (settled) return;\n if (!texture) {\n pendingError = { message, exception };\n return;\n }\n settled = true;\n removeAbortListener();\n let cleanupError: unknown;\n try { texture.dispose(); } catch (error) { cleanupError = error; }\n reject(Object.assign(\n new Error(message || `Failed to load Babylon environment texture: ${textureUrl}`),\n { cause: exception, ...(cleanupError === undefined ? {} : { cleanupError }) },\n ));\n };\n const complete = (): void => {\n if (settled) return;\n loaded = true;\n if (!texture) return;\n settled = true;\n removeAbortListener();\n resolve(texture);\n };\n const abort = (): void => fail('Babylon environment texture load aborted.', createEnvironmentTextureAbortError());\n signal?.addEventListener('abort', abort, { once: true });\n try {\n texture = this.createTexture(textureUrl, this.scene, {\n onLoad: complete,\n onError: fail,\n });\n } catch (cause) {\n settled = true;\n removeAbortListener();\n reject(Object.assign(\n new Error(`Failed to create Babylon environment texture: ${textureUrl}`),\n { cause },\n ));\n return;\n }\n const synchronousError = pendingError as { message?: string; exception?: unknown } | null;\n if (synchronousError) {\n fail(synchronousError.message, synchronousError.exception);\n } else if (loaded || texture.isReady()) {\n complete();\n }\n });\n }\n}\n\nfunction createEnvironmentTextureAbortError(): Error {\n return Object.assign(new Error('Babylon environment texture load aborted.'), { name: 'AbortError' });\n}\n\nfunction throwCandidateTextureFailure(texture: CubeTexture, failure: unknown): never {\n let cleanupError: unknown;\n try { texture.dispose(); } catch (error) { cleanupError = error; }\n const result = failure && typeof failure === 'object'\n ? failure\n : Object.assign(new Error(String(failure)), { cause: failure });\n if (cleanupError !== undefined) Object.assign(result, { cleanupError });\n throw result;\n}\n\nfunction createDefaultEnvironmentTexture(\n textureUrl: string,\n scene: Scene,\n callbacks: Parameters<BabylonEnvironmentTextureFactory>[2] = {},\n): CubeTexture {\n return new CubeTexture(textureUrl, scene, {\n prefiltered: true,\n createPolynomials: true,\n onLoad: callbacks.onLoad,\n onError: callbacks.onError,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"environment-texture-controller.js","sourceRoot":"","sources":["../../src/environment/environment-texture-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture.js';\nimport { _ENVTextureLoader } from '@babylonjs/core/Materials/Textures/Loaders/envTextureLoader.js';\nimport { registerTextureLoader } from '@babylonjs/core/Materials/Textures/Loaders/textureLoaderManager.js';\nimport type { Scene } from '@babylonjs/core/scene.js';\nimport type { PlayableResolvedAssetResource } from '@fps-games/playable-assets';\nimport {\n type BabylonEnvironmentTextureController,\n type BabylonEnvironmentTextureControllerOptions,\n type BabylonEnvironmentTextureFactory,\n type BabylonEnvironmentTextureLoadCallbacks,\n type BabylonEnvironmentTextureProfile,\n} from './types.js';\nimport { normalizeBabylonEnvironmentTextureProfile } from './profile.js';\n\n// Register the framework default during module initialization so single-file\n// bundlers cannot remove Babylon's dynamic .env loader discovery. Applications\n// remain free to register their own .env loader after importing the renderer.\nregisterTextureLoader('.env', async () => new _ENVTextureLoader());\n\nexport type BabylonEnvironmentTextureControllerCleanup = () => readonly unknown[];\n\nexport function readBabylonEnvironmentTextureControllerCleanup(\n error: unknown,\n): BabylonEnvironmentTextureControllerCleanup | null {\n if (!error || (typeof error !== 'object' && typeof error !== 'function')) return null;\n const cleanup = (error as { babylonEnvironmentTextureControllerCleanup?: unknown })\n .babylonEnvironmentTextureControllerCleanup;\n return typeof cleanup === 'function'\n ? cleanup as BabylonEnvironmentTextureControllerCleanup\n : null;\n}\n\nexport function createBabylonEnvironmentTextureController(\n scene: Scene,\n options: BabylonEnvironmentTextureControllerOptions = {},\n): BabylonEnvironmentTextureController {\n return new BabylonEnvironmentTextureControllerImpl(\n scene,\n options.createTexture ?? createDefaultEnvironmentTexture,\n );\n}\n\nclass BabylonEnvironmentTextureControllerImpl implements BabylonEnvironmentTextureController {\n private profile: BabylonEnvironmentTextureProfile | null = null;\n private texture: CubeTexture | null = null;\n private resource: PlayableResolvedAssetResource | null = null;\n private generation = 0;\n private pendingAbort: AbortController | null = null;\n private readonly retainedCleanupTextures = new Set<CubeTexture>();\n private pendingSceneClearTexture: CubeTexture | null = null;\n private disposeRequested = false;\n private disposed = false;\n private readonly retryCleanup: BabylonEnvironmentTextureControllerCleanup = () => {\n const cleanupErrors: unknown[] = [];\n const pendingSceneTexture = this.pendingSceneClearTexture;\n if (pendingSceneTexture) {\n try {\n if (this.scene.environmentTexture === pendingSceneTexture) {\n this.scene.environmentTexture = null;\n }\n this.pendingSceneClearTexture = null;\n } catch (error) {\n cleanupErrors.push(sanitizeCause(error));\n }\n }\n for (const texture of [...this.retainedCleanupTextures]) {\n try {\n texture.dispose();\n this.retainedCleanupTextures.delete(texture);\n } catch (error) {\n cleanupErrors.push(sanitizeCause(error));\n }\n }\n return Object.freeze(cleanupErrors);\n };\n\n constructor(\n private readonly scene: Scene,\n private readonly createTexture: BabylonEnvironmentTextureFactory,\n ) {}\n\n async applyProfile(\n profile: BabylonEnvironmentTextureProfile | null,\n signal?: AbortSignal,\n ): Promise<void> {\n this.assertNotDisposed();\n if (signal?.aborted) throw createEnvironmentTextureAbortError();\n const retainedCleanupErrors = this.retryCleanup();\n if (retainedCleanupErrors.length > 0) {\n throw createEnvironmentTextureCleanupFailure(retainedCleanupErrors, this.retryCleanup);\n }\n\n const generation = ++this.generation;\n this.pendingAbort?.abort();\n const candidateAbort = new AbortController();\n this.pendingAbort = candidateAbort;\n const removeSignalListener = forwardAbort(signal, candidateAbort);\n const isCurrent = (): boolean => !this.disposed && this.generation === generation && !candidateAbort.signal.aborted;\n\n try {\n const nextProfile = profile ? normalizeBabylonEnvironmentTextureProfile(profile) : null;\n if (!nextProfile?.texture) {\n if (!isCurrent()) throw createEnvironmentTextureAbortError();\n const previousTexture = this.texture;\n const previousSceneTexture = this.scene.environmentTexture;\n const sceneWithIntensity = this.scene as unknown as { environmentIntensity?: number };\n const previousIntensity = sceneWithIntensity.environmentIntensity;\n try {\n if (previousTexture && previousSceneTexture === previousTexture) {\n this.scene.environmentTexture = null;\n }\n if (nextProfile) sceneWithIntensity.environmentIntensity = nextProfile.intensity;\n } catch (error) {\n restoreSceneState(this.scene, previousSceneTexture, previousIntensity);\n throw createSafeEnvironmentTextureError(\n 'babylon.environment-texture.profile-failed',\n 'Failed to apply Babylon environment texture profile.',\n error,\n );\n }\n this.texture = null;\n this.resource = null;\n this.profile = nextProfile;\n const cleanupError = this.disposeTextureOrRetain(previousTexture);\n if (cleanupError) {\n throw createEnvironmentTextureCleanupFailure([cleanupError], this.retryCleanup);\n }\n return;\n }\n\n if (this.texture && sameResource(this.resource, nextProfile.texture)) {\n if (!isCurrent()) throw createEnvironmentTextureAbortError();\n this.applyCommittedTextureProfile(this.texture, nextProfile);\n this.profile = nextProfile;\n this.resource = nextProfile.texture;\n return;\n }\n\n const candidate = await this.createEnvironmentTextureAsync(nextProfile.texture, candidateAbort.signal);\n if (!isCurrent()) this.throwCandidateTextureFailure(candidate, createEnvironmentTextureAbortError());\n try {\n applyCandidateTextureProperties(candidate, nextProfile);\n } catch (error) {\n this.throwCandidateTextureFailure(candidate, createSafeEnvironmentTextureError('babylon.environment-texture.profile-failed', 'Failed to apply Babylon environment texture profile.', error));\n }\n if (!isCurrent()) this.throwCandidateTextureFailure(candidate, createEnvironmentTextureAbortError());\n\n const previousTexture = this.texture;\n const previousSceneTexture = this.scene.environmentTexture;\n const sceneWithIntensity = this.scene as unknown as { environmentIntensity?: number };\n const previousIntensity = sceneWithIntensity.environmentIntensity;\n try {\n this.scene.environmentTexture = candidate;\n sceneWithIntensity.environmentIntensity = nextProfile.intensity;\n } catch (error) {\n restoreSceneState(this.scene, previousSceneTexture, previousIntensity);\n this.throwCandidateTextureFailure(candidate, createSafeEnvironmentTextureError(\n 'babylon.environment-texture.profile-failed',\n 'Failed to apply Babylon environment texture profile.',\n error,\n ));\n }\n this.texture = candidate;\n this.resource = nextProfile.texture;\n this.profile = nextProfile;\n const cleanupError = this.disposeTextureOrRetain(previousTexture);\n if (cleanupError) {\n throw createEnvironmentTextureCleanupFailure([cleanupError], this.retryCleanup);\n }\n } finally {\n removeSignalListener();\n if (this.pendingAbort === candidateAbort) this.pendingAbort = null;\n }\n }\n\n getProfile(): BabylonEnvironmentTextureProfile | null {\n return this.profile ? { ...this.profile } : null;\n }\n\n getTexture(): CubeTexture | null {\n return this.texture;\n }\n\n dispose(): void {\n if (this.disposed) return;\n if (!this.disposeRequested) {\n this.disposeRequested = true;\n this.generation += 1;\n this.pendingAbort?.abort();\n this.pendingAbort = null;\n const texture = this.texture;\n if (texture) {\n this.retainedCleanupTextures.add(texture);\n if (this.scene.environmentTexture === texture) {\n this.pendingSceneClearTexture = texture;\n }\n }\n this.texture = null;\n this.resource = null;\n this.profile = null;\n }\n const cleanupErrors = this.retryCleanup();\n if (cleanupErrors.length > 0) {\n throw createEnvironmentTextureCleanupFailure(cleanupErrors, this.retryCleanup);\n }\n this.disposed = true;\n }\n\n private applyCommittedTextureProfile(texture: CubeTexture, profile: BabylonEnvironmentTextureProfile): void {\n const textureWithRotation = texture as unknown as { rotationY?: number };\n const sceneWithIntensity = this.scene as unknown as { environmentIntensity?: number };\n const previousLevel = texture.level;\n const previousRotation = textureWithRotation.rotationY;\n const previousSceneTexture = this.scene.environmentTexture;\n const previousIntensity = sceneWithIntensity.environmentIntensity;\n try {\n applyCandidateTextureProperties(texture, profile);\n if (previousSceneTexture !== texture) this.scene.environmentTexture = texture;\n sceneWithIntensity.environmentIntensity = profile.intensity;\n } catch (error) {\n restoreTextureProperties(texture, previousLevel, previousRotation);\n restoreSceneState(this.scene, previousSceneTexture, previousIntensity);\n throw createSafeEnvironmentTextureError(\n 'babylon.environment-texture.profile-failed',\n 'Failed to apply Babylon environment texture profile.',\n error,\n );\n }\n }\n\n private createEnvironmentTextureAsync(\n resource: PlayableResolvedAssetResource,\n signal: AbortSignal,\n ): Promise<CubeTexture> {\n return new Promise<CubeTexture>((resolve, reject) => {\n if (signal.aborted) {\n reject(createEnvironmentTextureAbortError());\n return;\n }\n let settled = false;\n let texture: CubeTexture | null = null;\n let loaded = false;\n let pendingFailure: unknown = null;\n\n const settleFailure = (failure: unknown): void => {\n if (settled) return;\n if (!texture) {\n pendingFailure = failure;\n return;\n }\n settled = true;\n signal.removeEventListener('abort', abort);\n const cleanupError = this.disposeTextureOrRetain(texture);\n reject(withCleanupError(failure, cleanupError, this.retryCleanup));\n };\n const complete = (): void => {\n if (settled || !texture) {\n loaded = true;\n return;\n }\n settled = true;\n signal.removeEventListener('abort', abort);\n resolve(texture);\n };\n const abort = (): void => settleFailure(createEnvironmentTextureAbortError());\n const fail = (_message?: string, exception?: unknown): void => {\n settleFailure(createSafeEnvironmentTextureError(\n 'babylon.environment-texture.load-failed',\n 'Failed to load Babylon environment texture.',\n exception,\n ));\n };\n\n signal.addEventListener('abort', abort, { once: true });\n try {\n texture = this.createTexture(resource, this.scene, { onLoad: complete, onError: fail });\n } catch (error) {\n settled = true;\n signal.removeEventListener('abort', abort);\n reject(createSafeEnvironmentTextureError(\n 'babylon.environment-texture.create-failed',\n 'Failed to create Babylon environment texture.',\n error,\n ));\n return;\n }\n\n if (pendingFailure) settleFailure(pendingFailure);\n else if (loaded || texture.isReady()) complete();\n });\n }\n\n private assertNotDisposed(): void {\n if (this.disposed || this.disposeRequested) {\n throw new Error('Babylon environment texture controller is disposed.');\n }\n }\n\n private disposeTextureOrRetain(texture: CubeTexture | null): Error | null {\n if (!texture) return null;\n this.retainedCleanupTextures.add(texture);\n try {\n texture.dispose();\n this.retainedCleanupTextures.delete(texture);\n return null;\n } catch (error) {\n return sanitizeCause(error);\n }\n }\n\n private throwCandidateTextureFailure(texture: CubeTexture, failure: unknown): never {\n const cleanupError = this.disposeTextureOrRetain(texture);\n throw withCleanupError(failure, cleanupError, this.retryCleanup);\n }\n}\n\nfunction applyCandidateTextureProperties(\n texture: CubeTexture,\n profile: BabylonEnvironmentTextureProfile,\n): void {\n texture.level = profile.intensity;\n (texture as unknown as { rotationY?: number }).rotationY = profile.rotationY;\n}\n\nfunction restoreTextureProperties(\n texture: CubeTexture,\n level: number,\n rotationY: number | undefined,\n): void {\n try {\n texture.level = level;\n } catch {\n // Best-effort rollback keeps the original operation error as the public diagnostic.\n }\n try {\n (texture as unknown as { rotationY?: number }).rotationY = rotationY;\n } catch {\n // Best-effort rollback keeps the original operation error as the public diagnostic.\n }\n}\n\nfunction restoreSceneState(\n scene: Scene,\n environmentTexture: Scene['environmentTexture'],\n environmentIntensity: number | undefined,\n): void {\n try {\n scene.environmentTexture = environmentTexture;\n } catch {\n // Best-effort rollback keeps the original operation error as the public diagnostic.\n }\n try {\n (scene as unknown as { environmentIntensity?: number }).environmentIntensity = environmentIntensity;\n } catch {\n // Best-effort rollback keeps the original operation error as the public diagnostic.\n }\n}\n\nfunction forwardAbort(signal: AbortSignal | undefined, controller: AbortController): () => void {\n if (!signal) return () => undefined;\n const onAbort = (): void => controller.abort();\n signal.addEventListener('abort', onAbort, { once: true });\n if (signal.aborted) controller.abort();\n return () => signal.removeEventListener('abort', onAbort);\n}\n\nfunction sameResource(\n left: PlayableResolvedAssetResource | null,\n right: PlayableResolvedAssetResource,\n): boolean {\n return left?.assetId === right.assetId\n && left?.url === right.url\n && left?.format === right.format;\n}\n\nfunction createEnvironmentTextureAbortError(): Error {\n return Object.assign(new Error('Babylon environment texture update aborted.'), { name: 'AbortError' });\n}\n\nfunction createSafeEnvironmentTextureError(code: string, message: string, cause: unknown): Error {\n const error = Object.assign(new Error(message), { code });\n if (cause !== undefined) {\n Object.assign(error, { cause: sanitizeCause(cause) });\n }\n return error;\n}\n\nfunction sanitizeCause(cause: unknown): Error {\n const message = cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n return new Error(message.replace(/(?:data|blob):[^\\s)]+/giu, '[redacted-resource-url]'));\n}\n\nfunction withCleanupError(\n failure: unknown,\n cleanupError: Error | null,\n retryCleanup: BabylonEnvironmentTextureControllerCleanup,\n): Error {\n const result = failure instanceof Error ? failure : new Error('Babylon environment texture operation failed.');\n if (cleanupError) {\n attachEnvironmentTextureCleanup(result, [cleanupError], retryCleanup);\n }\n return result;\n}\n\nfunction createEnvironmentTextureCleanupFailure(\n cleanupErrors: readonly unknown[],\n retryCleanup: BabylonEnvironmentTextureControllerCleanup,\n): Error {\n return attachEnvironmentTextureCleanup(\n Object.assign(\n new Error('Failed to dispose Babylon environment texture resources.'),\n { code: 'babylon.environment-texture.dispose-failed' },\n ),\n cleanupErrors,\n retryCleanup,\n );\n}\n\nfunction attachEnvironmentTextureCleanup(\n failure: Error,\n cleanupErrors: readonly unknown[],\n retryCleanup: BabylonEnvironmentTextureControllerCleanup,\n): Error {\n const safeErrors = Object.freeze(cleanupErrors.map(sanitizeCause));\n const metadata = {\n cleanupError: safeErrors[0],\n cleanupErrors: safeErrors,\n babylonEnvironmentTextureControllerCleanup: retryCleanup,\n retryCleanup,\n };\n try {\n Object.assign(failure, metadata);\n if (readBabylonEnvironmentTextureControllerCleanup(failure) === retryCleanup) return failure;\n } catch {\n // Wrap non-extensible primary failures so the owning cleanup remains reachable.\n }\n return Object.assign(new Error(failure.message), { cause: failure, ...metadata });\n}\n\nfunction createDefaultEnvironmentTexture(\n resource: PlayableResolvedAssetResource,\n scene: Scene,\n callbacks: BabylonEnvironmentTextureLoadCallbacks = {},\n): CubeTexture {\n return new CubeTexture(resource.url, scene, {\n prefiltered: true,\n createPolynomials: true,\n forcedExtension: resource.format,\n onLoad: callbacks.onLoad,\n onError: callbacks.onError,\n });\n}\n"]}
|
|
@@ -3,7 +3,7 @@ export function normalizeBabylonEnvironmentTextureProfile(value) {
|
|
|
3
3
|
const source = readRecord(value);
|
|
4
4
|
const fallback = DEFAULT_BABYLON_ENVIRONMENT_TEXTURE_PROFILE;
|
|
5
5
|
return {
|
|
6
|
-
|
|
6
|
+
texture: readResourceOrNull(source.texture),
|
|
7
7
|
intensity: readNonNegativeNumber(source.intensity, fallback.intensity),
|
|
8
8
|
rotationY: readFiniteNumber(source.rotationY, fallback.rotationY),
|
|
9
9
|
};
|
|
@@ -13,9 +13,10 @@ function readRecord(value) {
|
|
|
13
13
|
? value
|
|
14
14
|
: {};
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
function readResourceOrNull(value) {
|
|
17
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
18
|
+
return null;
|
|
19
|
+
return value;
|
|
19
20
|
}
|
|
20
21
|
function readFiniteNumber(value, fallback) {
|
|
21
22
|
return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/environment/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2CAA2C,GAE5C,MAAM,YAAY,CAAC;AAEpB,MAAM,UAAU,yCAAyC,CACvD,KAAc;IAEd,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,2CAA2C,CAAC;IAC7D,OAAO;QACL,
|
|
1
|
+
{"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/environment/profile.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2CAA2C,GAE5C,MAAM,YAAY,CAAC;AAEpB,MAAM,UAAU,yCAAyC,CACvD,KAAc;IAEd,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,2CAA2C,CAAC;IAC7D,OAAO;QACL,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC;QAC3C,SAAS,EAAE,qBAAqB,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;QACtE,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAC,KAAgC;QAClC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,KAAoD,CAAC;AAC9D,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,QAAgB;IACxD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChF,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,QAAgB;IAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxD,CAAC","sourcesContent":["import {\n DEFAULT_BABYLON_ENVIRONMENT_TEXTURE_PROFILE,\n type BabylonEnvironmentTextureProfile,\n} from './types.js';\n\nexport function normalizeBabylonEnvironmentTextureProfile(\n value: unknown,\n): BabylonEnvironmentTextureProfile {\n const source = readRecord(value);\n const fallback = DEFAULT_BABYLON_ENVIRONMENT_TEXTURE_PROFILE;\n return {\n texture: readResourceOrNull(source.texture),\n intensity: readNonNegativeNumber(source.intensity, fallback.intensity),\n rotationY: readFiniteNumber(source.rotationY, fallback.rotationY),\n };\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction readResourceOrNull(value: unknown): BabylonEnvironmentTextureProfile['texture'] {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n return value as BabylonEnvironmentTextureProfile['texture'];\n}\n\nfunction readFiniteNumber(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n}\n\nfunction readNonNegativeNumber(value: unknown, fallback: number): number {\n return Math.max(0, readFiniteNumber(value, fallback));\n}\n"]}
|