@zephyr3d/scene 0.9.3 → 0.9.5
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/animation/animationmask.js +224 -0
- package/dist/animation/animationmask.js.map +1 -0
- package/dist/animation/animationset.js +268 -67
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/animationtrack.js.map +1 -1
- package/dist/animation/eulerrotationtrack.js +3 -0
- package/dist/animation/eulerrotationtrack.js.map +1 -1
- package/dist/animation/fixed_geometry_cache_track.js +7 -0
- package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
- package/dist/animation/ik_modifier.js.map +1 -1
- package/dist/animation/joint_dynamics/collision.js +6 -4
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +390 -43
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +62 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +4 -3
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/joint_dynamics_modifier.js +2 -0
- package/dist/animation/joint_dynamics_modifier.js.map +1 -1
- package/dist/animation/morphtarget.js +3 -72
- package/dist/animation/morphtarget.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -0
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/pca_geometry_cache_track.js +3 -0
- package/dist/animation/pca_geometry_cache_track.js.map +1 -1
- package/dist/animation/proptrack.js +3 -0
- package/dist/animation/proptrack.js.map +1 -1
- package/dist/animation/rotationtrack.js +3 -0
- package/dist/animation/rotationtrack.js.map +1 -1
- package/dist/animation/scaletrack.js +3 -0
- package/dist/animation/scaletrack.js.map +1 -1
- package/dist/animation/skeleton.js +254 -79
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +4 -4
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/animation/translationtrack.js +3 -0
- package/dist/animation/translationtrack.js.map +1 -1
- package/dist/app/engine.js +129 -17
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptregistry.js +251 -80
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +133 -102
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/gltf/gltf_loader.js +18 -14
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/loader.js +1 -6
- package/dist/asset/loaders/loader.js.map +1 -1
- package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -1
- package/dist/asset/model.js +1052 -183
- package/dist/asset/model.js.map +1 -1
- package/dist/avatar/wardrobe.js +474 -0
- package/dist/avatar/wardrobe.js.map +1 -0
- package/dist/index.d.ts +1810 -233
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/material/material.js +1 -1
- package/dist/material/material.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +6 -3
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +72 -15
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/msdf_text.js +180 -0
- package/dist/material/msdf_text.js.map +1 -0
- package/dist/material/msdf_text_sprite.js +64 -0
- package/dist/material/msdf_text_sprite.js.map +1 -0
- package/dist/material/pbrblueprint.js +21 -6
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/shader/helper.js +277 -277
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/sprite_sdf.js +106 -0
- package/dist/material/sprite_sdf.js.map +1 -0
- package/dist/posteffect/ssr.js +1 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/render/abuffer_oit.js +1 -0
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +28 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/drawable_mixin.js +1 -0
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/envlight.js +54 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +1 -0
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +1 -0
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +1 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/render_queue.js +1 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/sky.js +9 -0
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/basesprite.js +1 -5
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +18 -8
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +16 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/mesh.js +164 -102
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +96 -0
- package/dist/scene/meshdrawable.js.map +1 -0
- package/dist/scene/msdftext.js +341 -0
- package/dist/scene/msdftext.js.map +1 -0
- package/dist/scene/msdftextsprite.js +349 -0
- package/dist/scene/msdftextsprite.js.map +1 -0
- package/dist/scene/particlesys.js +1 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +2 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +437 -230
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/sdftextsprite.js +322 -0
- package/dist/scene/sdftextsprite.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +1 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +1 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/textsprite.js +120 -0
- package/dist/scene/textsprite.js.map +1 -0
- package/dist/scene/water.js +1 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shadow/shader.js +1 -0
- package/dist/shadow/shader.js.map +1 -1
- package/dist/text/font/font_asset.js +884 -0
- package/dist/text/font/font_asset.js.map +1 -0
- package/dist/text/font/sfnt_reader.js +43 -0
- package/dist/text/font/sfnt_reader.js.map +1 -0
- package/dist/text/msdf/generator.js +417 -0
- package/dist/text/msdf/generator.js.map +1 -0
- package/dist/text/msdf/shape.js +146 -0
- package/dist/text/msdf/shape.js.map +1 -0
- package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
- package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
- package/dist/text/runtime/msdf_text_atlas_manager.js +50 -0
- package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
- package/dist/text/runtime/text_layout.js +96 -0
- package/dist/text/runtime/text_layout.js.map +1 -0
- package/dist/utility/blueprint/material/inputs.js +188 -1
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +16 -1
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +32 -0
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/bounding_volume.js.map +1 -1
- package/dist/utility/pmrem.js +34 -8
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/serialization/manager.js +340 -283
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +702 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +2 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +2 -0
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +2 -0
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1 -0
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +66 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +189 -8
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +2 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +1 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +2 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +2 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +516 -0
- package/dist/utility/serialization/scene/text.js.map +1 -0
- package/dist/utility/serialization/scene/water.js +2 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/textures/sheenlut.js +138 -0
- package/dist/utility/textures/sheenlut.js.map +1 -0
- package/dist/values.js +48 -48
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { DWeakRef, ASSERT, base64ToUint8Array, Vector3,
|
|
2
|
-
import { GLTFLoader } from './loaders/gltf/gltf_loader.js';
|
|
1
|
+
import { DWeakRef, DRef, ASSERT, base64ToUint8Array, Vector3, Vector4, guessMimeType, isPowerOf2, nextPowerOf2 } from '@zephyr3d/base';
|
|
3
2
|
import { WebImageLoader } from './loaders/image/webimage_loader.js';
|
|
4
3
|
import { DDSLoader } from './loaders/dds/dds_loader.js';
|
|
5
4
|
import { HDRLoader } from './loaders/hdr/hdr.js';
|
|
@@ -24,6 +23,7 @@ import '../material/pbrsg.js';
|
|
|
24
23
|
import { PBRBluePrintMaterial } from '../material/pbrblueprint.js';
|
|
25
24
|
import '../material/sprite.js';
|
|
26
25
|
import '../material/sprite_std.js';
|
|
26
|
+
import '../material/msdf_text.js';
|
|
27
27
|
import { SpriteBlueprintMaterial } from '../material/spriteblueprint.js';
|
|
28
28
|
import { BoundingBox } from '../utility/bounding_volume.js';
|
|
29
29
|
import { MaterialBlueprintIR } from '../utility/blueprint/material/ir.js';
|
|
@@ -32,6 +32,7 @@ import '../render/rendergraph/forward_plus_builder.js';
|
|
|
32
32
|
import '../render/sky.js';
|
|
33
33
|
import '../render/clipmap.js';
|
|
34
34
|
import '../shaders/atmosphere.js';
|
|
35
|
+
import { FontAsset } from '../text/font/font_asset.js';
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Centralized asset manager for loading and caching resources.
|
|
@@ -58,12 +59,11 @@ import '../shaders/atmosphere.js';
|
|
|
58
59
|
new HDRLoader(),
|
|
59
60
|
new TGALoader()
|
|
60
61
|
];
|
|
61
|
-
/** @internal */
|
|
62
|
-
new GLTFLoader()
|
|
63
|
-
];
|
|
62
|
+
/** @internal */ _modelLoaders = {};
|
|
64
63
|
/** @internal */ _textures;
|
|
65
64
|
/** @internal */ _models;
|
|
66
65
|
/** @internal */ _binaryDatas;
|
|
66
|
+
/** @internal */ _fontAssets;
|
|
67
67
|
/** @internal */ _textDatas;
|
|
68
68
|
/** @internal */ _bluePrints;
|
|
69
69
|
/** @internal */ _materials;
|
|
@@ -82,6 +82,7 @@ import '../shaders/atmosphere.js';
|
|
|
82
82
|
this._skeletons = {};
|
|
83
83
|
this._bluePrints = {};
|
|
84
84
|
this._binaryDatas = {};
|
|
85
|
+
this._fontAssets = {};
|
|
85
86
|
this._textDatas = {};
|
|
86
87
|
this._jsonDatas = {};
|
|
87
88
|
}
|
|
@@ -133,11 +134,26 @@ import '../shaders/atmosphere.js';
|
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
this._skeletons = {};
|
|
137
|
+
this._fontAssets = {};
|
|
136
138
|
this._binaryDatas = {};
|
|
137
139
|
this._textDatas = {};
|
|
138
140
|
this._jsonDatas = {};
|
|
139
141
|
}
|
|
140
142
|
/**
|
|
143
|
+
* Removes a cached font asset entry by URL.
|
|
144
|
+
*
|
|
145
|
+
* This only evicts the cache entry. It does not dispose any external references to the FontAsset.
|
|
146
|
+
*
|
|
147
|
+
* @param url - Resource URL or VFS path.
|
|
148
|
+
* @returns `true` if a cache entry existed and was removed.
|
|
149
|
+
*/ releaseFontAsset(url) {
|
|
150
|
+
if (url in this._fontAssets) {
|
|
151
|
+
delete this._fontAssets[url];
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
141
157
|
* Register a texture loader (highest priority first).
|
|
142
158
|
*
|
|
143
159
|
* Note: This is a static registry shared by all AssetManager instances.
|
|
@@ -150,13 +166,9 @@ import '../shaders/atmosphere.js';
|
|
|
150
166
|
}
|
|
151
167
|
/**
|
|
152
168
|
* Register a model loader (highest priority first).
|
|
153
|
-
|
|
154
|
-
* Note: This is a static registry shared by all AssetManager instances.
|
|
155
|
-
*
|
|
156
|
-
* @param loader - A concrete model loader implementation.
|
|
157
|
-
*/ static addModelLoader(loader) {
|
|
169
|
+
*/ setModelLoader(mimeType, loader) {
|
|
158
170
|
if (loader) {
|
|
159
|
-
this._modelLoaders
|
|
171
|
+
this._modelLoaders[mimeType] = loader;
|
|
160
172
|
}
|
|
161
173
|
}
|
|
162
174
|
/**
|
|
@@ -170,11 +182,11 @@ import '../shaders/atmosphere.js';
|
|
|
170
182
|
* @param postProcess - Optional transformation applied to the loaded text.
|
|
171
183
|
* @param httpRequest - Optional HttpRequest for custom URL resolution/headers.
|
|
172
184
|
* @returns A promise that resolves to the loaded (and optionally processed) text.
|
|
173
|
-
*/ async fetchTextData(url, postProcess, httpRequest,
|
|
185
|
+
*/ async fetchTextData(url, postProcess, httpRequest, options) {
|
|
174
186
|
const hash = httpRequest?.urlResolver?.(url) ?? url;
|
|
175
187
|
let P = this._textDatas[hash];
|
|
176
188
|
if (!P) {
|
|
177
|
-
P = this.loadTextData(url, postProcess,
|
|
189
|
+
P = this.loadTextData(url, postProcess, options?.overrideVFS);
|
|
178
190
|
this._textDatas[hash] = P;
|
|
179
191
|
}
|
|
180
192
|
return P;
|
|
@@ -189,11 +201,11 @@ import '../shaders/atmosphere.js';
|
|
|
189
201
|
* @param postProcess - Optional transformation applied to the parsed JSON object.
|
|
190
202
|
* @param httpRequest - Optional HttpRequest for custom URL resolution/headers.
|
|
191
203
|
* @returns A promise that resolves to the loaded (and optionally processed) JSON value.
|
|
192
|
-
*/ async fetchJsonData(url, postProcess, httpRequest,
|
|
204
|
+
*/ async fetchJsonData(url, postProcess, httpRequest, options) {
|
|
193
205
|
const hash = httpRequest?.urlResolver?.(url) ?? url;
|
|
194
206
|
let P = this._jsonDatas[hash];
|
|
195
207
|
if (!P) {
|
|
196
|
-
P = this.loadJsonData(url, postProcess,
|
|
208
|
+
P = this.loadJsonData(url, postProcess, options?.overrideVFS);
|
|
197
209
|
this._jsonDatas[hash] = P;
|
|
198
210
|
}
|
|
199
211
|
return P;
|
|
@@ -207,20 +219,53 @@ import '../shaders/atmosphere.js';
|
|
|
207
219
|
* @param postProcess - Optional transformation applied to the loaded ArrayBuffer.
|
|
208
220
|
* @param httpRequest - Optional HttpRequest for custom URL resolution/headers.
|
|
209
221
|
* @returns A promise that resolves to the loaded (and optionally processed) ArrayBuffer.
|
|
210
|
-
*/ async fetchBinaryData(url, postProcess, httpRequest,
|
|
222
|
+
*/ async fetchBinaryData(url, postProcess, httpRequest, options) {
|
|
211
223
|
const hash = httpRequest?.urlResolver?.(url) ?? url;
|
|
212
224
|
let P = this._binaryDatas[hash];
|
|
213
225
|
if (!P) {
|
|
214
|
-
P = this.loadBinaryData(url, postProcess,
|
|
226
|
+
P = this.loadBinaryData(url, postProcess, options?.overrideVFS);
|
|
215
227
|
this._binaryDatas[hash] = P;
|
|
216
228
|
}
|
|
217
229
|
return P;
|
|
218
230
|
}
|
|
219
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Fetch a font asset via VFS.
|
|
233
|
+
*
|
|
234
|
+
* - Cached per URL only.
|
|
235
|
+
* - `options` are applied only when the font is first loaded for that URL.
|
|
236
|
+
* - If the URL is already cached, later calls ignore `options` and reuse the cached FontAsset.
|
|
237
|
+
*
|
|
238
|
+
* @param url - Resource URL or VFS path.
|
|
239
|
+
* @param options - Optional MSDF atlas settings bound to the loaded FontAsset.
|
|
240
|
+
* @returns A promise that resolves to the loaded (and optionally processed) font asset.
|
|
241
|
+
*/ async fetchFontAsset(url, options) {
|
|
242
|
+
const hash = url;
|
|
243
|
+
let P = this._fontAssets[hash];
|
|
244
|
+
if (!P) {
|
|
245
|
+
P = new Promise((resolve, reject)=>{
|
|
246
|
+
this.loadBinaryData(url, null, options?.overrideVFS).then((data)=>{
|
|
247
|
+
resolve(data ? FontAsset.fromBuffer(data, options) : null);
|
|
248
|
+
}).catch((err)=>{
|
|
249
|
+
reject(new Error(`Failed to load font asset from ${url}: ${err instanceof Error ? err.message : err}`));
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
this._fontAssets[hash] = P;
|
|
253
|
+
}
|
|
254
|
+
return P;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Fetch a font asset via VFS if already cached.
|
|
258
|
+
* @param url - Resource URL or VFS path.
|
|
259
|
+
* @returns The cached FontAsset if it exists and is loaded, or null if not cached or still loading.
|
|
260
|
+
*/ getFontAsset(url) {
|
|
261
|
+
const hash = url;
|
|
262
|
+
return this._fontAssets[hash] instanceof Promise ? null : this._fontAssets[hash] ?? null;
|
|
263
|
+
}
|
|
264
|
+
async fetchBluePrint(url, options) {
|
|
220
265
|
const hash = url;
|
|
221
266
|
let P = this._bluePrints[hash];
|
|
222
267
|
if (!P) {
|
|
223
|
-
P = this.loadBluePrint(url,
|
|
268
|
+
P = this.loadBluePrint(url, options?.overrideVFS);
|
|
224
269
|
this._bluePrints[hash] = P;
|
|
225
270
|
}
|
|
226
271
|
return P;
|
|
@@ -231,13 +276,13 @@ import '../shaders/atmosphere.js';
|
|
|
231
276
|
* @typeParam T - Expected concrete material type.
|
|
232
277
|
* @param url - Resource URL or VFS path.
|
|
233
278
|
* @returns A promise that resolves to the loaded material.
|
|
234
|
-
*/ async fetchMaterial(url,
|
|
279
|
+
*/ async fetchMaterial(url, options) {
|
|
235
280
|
const hash = url;
|
|
236
281
|
let P = this._materials[hash];
|
|
237
282
|
if (P instanceof DWeakRef && P.get() && !P.get().disposed) {
|
|
238
283
|
return P.get();
|
|
239
284
|
} else if (!P || P instanceof DWeakRef) {
|
|
240
|
-
P = this.loadMaterial(url, false,
|
|
285
|
+
P = this.loadMaterial(url, false, options?.overrideVFS);
|
|
241
286
|
this._materials[hash] = P;
|
|
242
287
|
}
|
|
243
288
|
const material = await P;
|
|
@@ -252,13 +297,13 @@ import '../shaders/atmosphere.js';
|
|
|
252
297
|
* @typeParam T - Expected concrete primitive type.
|
|
253
298
|
* @param url - Resource URL or VFS path.
|
|
254
299
|
* @returns A promise that resolves to the loaded primitive.
|
|
255
|
-
*/ async fetchPrimitive(url,
|
|
300
|
+
*/ async fetchPrimitive(url, options) {
|
|
256
301
|
const hash = url;
|
|
257
302
|
let P = this._primitives[hash];
|
|
258
303
|
if (P instanceof DWeakRef && P.get() && !P.get().disposed) {
|
|
259
304
|
return P.get();
|
|
260
305
|
} else if (!P || P instanceof DWeakRef) {
|
|
261
|
-
P = this.loadPrimitive(url,
|
|
306
|
+
P = this.loadPrimitive(url, options?.overrideVFS);
|
|
262
307
|
this._primitives[hash] = P;
|
|
263
308
|
}
|
|
264
309
|
const primitive = await P;
|
|
@@ -280,16 +325,16 @@ import '../shaders/atmosphere.js';
|
|
|
280
325
|
* @param options - Texture fetching options (color space, sampler, target texture).
|
|
281
326
|
* @param httpRequest - Optional HttpRequest (not used for binary read but may supply URL resolver for hashing).
|
|
282
327
|
* @returns A promise that resolves to the loaded texture.
|
|
283
|
-
*/ async fetchTexture(url, options
|
|
328
|
+
*/ async fetchTexture(url, options) {
|
|
284
329
|
if (options?.texture) {
|
|
285
|
-
return this.loadTexture(url, options.mimeType ?? null, !options.linearColorSpace, options.samplerOptions, options.texture,
|
|
330
|
+
return this.loadTexture(url, options.mimeType ?? null, !options.linearColorSpace, options.samplerOptions, options.texture, options.overrideVFS);
|
|
286
331
|
} else {
|
|
287
332
|
const hash = this.getHash('2d', url, options);
|
|
288
333
|
let P = this._textures[hash];
|
|
289
334
|
if (P instanceof DWeakRef && P.get() && !P.get().disposed) {
|
|
290
335
|
return P.get();
|
|
291
336
|
} else if (!P || P instanceof DWeakRef) {
|
|
292
|
-
P = this.loadTexture(url, options?.mimeType ?? null, !options?.linearColorSpace, options?.samplerOptions, null,
|
|
337
|
+
P = this.loadTexture(url, options?.mimeType ?? null, !options?.linearColorSpace, options?.samplerOptions, null, options?.overrideVFS);
|
|
293
338
|
this._textures[hash] = P;
|
|
294
339
|
}
|
|
295
340
|
const tex = await P;
|
|
@@ -309,13 +354,13 @@ import '../shaders/atmosphere.js';
|
|
|
309
354
|
* @param options - Model loader options (MIME override, Draco, instancing hint, post-process).
|
|
310
355
|
* @returns A promise that resolves to the SharedModel.
|
|
311
356
|
* @internal
|
|
312
|
-
*/ async fetchModelData(url, options
|
|
357
|
+
*/ async fetchModelData(url, options) {
|
|
313
358
|
const hash = url;
|
|
314
359
|
let P = this._models[hash];
|
|
315
360
|
if (P instanceof DWeakRef && P.get() && !P.get().disposed) {
|
|
316
361
|
return P.get();
|
|
317
362
|
} else if (!P || P instanceof DWeakRef) {
|
|
318
|
-
P = this.loadModel(url, options,
|
|
363
|
+
P = this.loadModel(url, options, options?.overrideVFS);
|
|
319
364
|
this._models[hash] = P;
|
|
320
365
|
}
|
|
321
366
|
const sharedModel = await P;
|
|
@@ -335,13 +380,21 @@ import '../shaders/atmosphere.js';
|
|
|
335
380
|
* @param options - Model loader options and instancing hint.
|
|
336
381
|
* @param httpRequest - Optional HttpRequest (unused for binary read; present for API symmetry).
|
|
337
382
|
* @returns A promise with the created node group and animation set info.
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
383
|
+
*
|
|
384
|
+
* @internal
|
|
385
|
+
*/ async fetchModel(scene, url, options) {
|
|
386
|
+
const sharedModel = new DRef();
|
|
387
|
+
try {
|
|
388
|
+
sharedModel.set(await this.fetchModelData(url, options));
|
|
389
|
+
const node = await sharedModel.get().createSceneNode(getEngine().resourceManager, scene, options?.enableInstancing ?? false, options?.loadMeshes ?? true, options?.loadSkeletons ?? true, options?.loadAnimations ?? true, options?.loadJointDynamics ?? true, options?.overrideVFS ?? getEngine().resourceManager.VFS);
|
|
390
|
+
node.sharedModel = sharedModel.get();
|
|
391
|
+
node.animationSet.resetSkeletonModifiers();
|
|
392
|
+
return node;
|
|
393
|
+
} catch (err) {
|
|
394
|
+
console.error(`Load model failed: ${url}: ${err}`);
|
|
395
|
+
} finally{
|
|
396
|
+
sharedModel.dispose();
|
|
397
|
+
}
|
|
345
398
|
}
|
|
346
399
|
/**
|
|
347
400
|
* Load a text resource via VFS and optionally post-process it.
|
|
@@ -352,10 +405,10 @@ import '../shaders/atmosphere.js';
|
|
|
352
405
|
* @param postProcess - Optional transformation applied to the text.
|
|
353
406
|
* @returns A promise that resolves to the loaded (and optionally processed) text.
|
|
354
407
|
* @internal
|
|
355
|
-
*/ async loadTextData(url, postProcess,
|
|
356
|
-
let text = await this.
|
|
408
|
+
*/ async loadTextData(url, postProcess, vfs) {
|
|
409
|
+
let text = await this.readFileFromVFS(url, {
|
|
357
410
|
encoding: 'utf8'
|
|
358
|
-
},
|
|
411
|
+
}, vfs);
|
|
359
412
|
if (postProcess) {
|
|
360
413
|
try {
|
|
361
414
|
text = postProcess(text);
|
|
@@ -374,10 +427,10 @@ import '../shaders/atmosphere.js';
|
|
|
374
427
|
* @param postProcess - Optional transformation applied to the parsed JSON.
|
|
375
428
|
* @returns A promise that resolves to the loaded (and optionally processed) JSON.
|
|
376
429
|
* @internal
|
|
377
|
-
*/ async loadJsonData(url, postProcess,
|
|
378
|
-
let json = JSON.parse(await this.
|
|
430
|
+
*/ async loadJsonData(url, postProcess, vfs) {
|
|
431
|
+
let json = JSON.parse(await this.readFileFromVFS(url, {
|
|
379
432
|
encoding: 'utf8'
|
|
380
|
-
},
|
|
433
|
+
}, vfs));
|
|
381
434
|
if (postProcess) {
|
|
382
435
|
try {
|
|
383
436
|
json = postProcess(json);
|
|
@@ -396,11 +449,11 @@ import '../shaders/atmosphere.js';
|
|
|
396
449
|
* @param postProcess - Optional transformation applied to the ArrayBuffer.
|
|
397
450
|
* @returns A promise that resolves to the loaded (and optionally processed) ArrayBuffer.
|
|
398
451
|
* @internal
|
|
399
|
-
*/ async loadBinaryData(url, postProcess,
|
|
452
|
+
*/ async loadBinaryData(url, postProcess, vfs) {
|
|
400
453
|
try {
|
|
401
|
-
let data = await this.
|
|
454
|
+
let data = await this.readFileFromVFS(url, {
|
|
402
455
|
encoding: 'binary'
|
|
403
|
-
},
|
|
456
|
+
}, vfs);
|
|
404
457
|
if (postProcess) {
|
|
405
458
|
data = postProcess(data);
|
|
406
459
|
}
|
|
@@ -410,11 +463,11 @@ import '../shaders/atmosphere.js';
|
|
|
410
463
|
return null;
|
|
411
464
|
}
|
|
412
465
|
}
|
|
413
|
-
async loadPrimitive(url,
|
|
466
|
+
async loadPrimitive(url, vfs) {
|
|
414
467
|
try {
|
|
415
|
-
const data = await this.
|
|
468
|
+
const data = await this.readFileFromVFS(url, {
|
|
416
469
|
encoding: 'utf8'
|
|
417
|
-
},
|
|
470
|
+
}, vfs);
|
|
418
471
|
const content = JSON.parse(data);
|
|
419
472
|
ASSERT(content.type === 'Primitive' || content.type === 'Default', `Unsupported primitive type: ${content.type}`);
|
|
420
473
|
if (content.type === 'Primitive') {
|
|
@@ -480,20 +533,22 @@ import '../shaders/atmosphere.js';
|
|
|
480
533
|
}
|
|
481
534
|
}
|
|
482
535
|
}
|
|
483
|
-
async loadBluePrintMaterialData(url, reload,
|
|
536
|
+
async loadBluePrintMaterialData(url, reload, vfs) {
|
|
484
537
|
try {
|
|
485
538
|
let irData;
|
|
486
539
|
if (typeof url === 'string') {
|
|
487
|
-
const data = await this.
|
|
540
|
+
const data = await this.readFileFromVFS(url, {
|
|
488
541
|
encoding: 'utf8'
|
|
489
|
-
},
|
|
542
|
+
}, vfs);
|
|
490
543
|
const content = JSON.parse(data);
|
|
491
544
|
ASSERT(content.type === 'PBRBluePrintMaterial' || content.type === 'SpriteBluePrintMaterial', `Unsupported material type: ${content.type}`);
|
|
492
545
|
irData = content.data;
|
|
493
546
|
} else {
|
|
494
547
|
irData = url;
|
|
495
548
|
}
|
|
496
|
-
const ir = reload ? await this.loadBluePrint(irData.IR,
|
|
549
|
+
const ir = reload ? await this.loadBluePrint(irData.IR, vfs) : await this.fetchBluePrint(irData.IR, vfs ? {
|
|
550
|
+
overrideVFS: vfs
|
|
551
|
+
} : undefined);
|
|
497
552
|
const uniformValues = irData.uniformValues.map((v)=>({
|
|
498
553
|
...v,
|
|
499
554
|
finalValue: v.value.length === 1 ? v.value[0] : new Float32Array(v.value)
|
|
@@ -502,8 +557,9 @@ import '../shaders/atmosphere.js';
|
|
|
502
557
|
const textures = irData.uniformTextures;
|
|
503
558
|
for (const v of textures){
|
|
504
559
|
const tex = await this.fetchTexture(v.texture, {
|
|
505
|
-
linearColorSpace: !v.sRGB
|
|
506
|
-
|
|
560
|
+
linearColorSpace: !v.sRGB,
|
|
561
|
+
overrideVFS: vfs
|
|
562
|
+
});
|
|
507
563
|
uniformTextures.push({
|
|
508
564
|
...v,
|
|
509
565
|
finalTexture: new DRef(tex),
|
|
@@ -536,19 +592,19 @@ import '../shaders/atmosphere.js';
|
|
|
536
592
|
* @param url - Resource URL or VFS path.
|
|
537
593
|
* @returns A promise that resolves to the loaded material.
|
|
538
594
|
* @internal
|
|
539
|
-
*/ async loadMaterial(url, reload,
|
|
595
|
+
*/ async loadMaterial(url, reload, vfs) {
|
|
540
596
|
try {
|
|
541
|
-
const data = await this.
|
|
597
|
+
const data = await this.readFileFromVFS(url, {
|
|
542
598
|
encoding: 'utf8'
|
|
543
|
-
},
|
|
599
|
+
}, vfs);
|
|
544
600
|
const content = JSON.parse(data);
|
|
545
601
|
ASSERT(content.type === 'PBRBluePrintMaterial' || content.type === 'SpriteBluePrintMaterial' || content.type === 'Default', `Unsupported material type: ${content.type}`);
|
|
546
602
|
let mat;
|
|
547
603
|
if (content.type === 'PBRBluePrintMaterial') {
|
|
548
|
-
const data = await this.loadBluePrintMaterialData(content.data, reload,
|
|
604
|
+
const data = await this.loadBluePrintMaterialData(content.data, reload, vfs);
|
|
549
605
|
mat = new PBRBluePrintMaterial(data.irFragment, data.irVertex, data.uniformValues, data.uniformTextures);
|
|
550
606
|
} else if (content.type === 'SpriteBluePrintMaterial') {
|
|
551
|
-
const data = await this.loadBluePrintMaterialData(content.data, reload,
|
|
607
|
+
const data = await this.loadBluePrintMaterialData(content.data, reload, vfs);
|
|
552
608
|
mat = new SpriteBlueprintMaterial(data.irFragment, data.uniformValues, data.uniformTextures);
|
|
553
609
|
} else {
|
|
554
610
|
const obj = await this._resourceManager.deserializeObject(null, content.data);
|
|
@@ -691,11 +747,11 @@ import '../shaders/atmosphere.js';
|
|
|
691
747
|
invalidateBluePrint(path) {
|
|
692
748
|
delete this._bluePrints[path];
|
|
693
749
|
}
|
|
694
|
-
async loadBluePrint(path,
|
|
750
|
+
async loadBluePrint(path, vfs) {
|
|
695
751
|
try {
|
|
696
|
-
const content = await this.
|
|
752
|
+
const content = await this.readFileFromVFS(path, {
|
|
697
753
|
encoding: 'utf8'
|
|
698
|
-
},
|
|
754
|
+
}, vfs);
|
|
699
755
|
const bp = JSON.parse(content);
|
|
700
756
|
ASSERT(bp.type === 'PBRMaterial' || bp.type === 'SpriteMaterial' || bp.type === 'MaterialFunction', `Unsupported blueprint type: ${bp.type}`);
|
|
701
757
|
const states = bp.state;
|
|
@@ -758,10 +814,10 @@ import '../shaders/atmosphere.js';
|
|
|
758
814
|
* @param texture - Optional destination texture to populate.
|
|
759
815
|
* @returns A promise that resolves to the created or populated texture.
|
|
760
816
|
* @internal
|
|
761
|
-
*/ async loadTexture(url, mimeType, srgb, samplerOptions, texture,
|
|
762
|
-
const data = await this.
|
|
817
|
+
*/ async loadTexture(url, mimeType, srgb, samplerOptions, texture, vfs) {
|
|
818
|
+
const data = await this.readFileFromVFS(url, {
|
|
763
819
|
encoding: 'binary'
|
|
764
|
-
},
|
|
820
|
+
}, vfs);
|
|
765
821
|
mimeType = mimeType ?? this.vfs.guessMIMEType(url);
|
|
766
822
|
for (const loader of AssetManager._textureLoaders){
|
|
767
823
|
if (!loader.supportMIMEType(mimeType)) {
|
|
@@ -848,22 +904,11 @@ import '../shaders/atmosphere.js';
|
|
|
848
904
|
* @param options - Model load options (MIME override, Draco module, post-process hook).
|
|
849
905
|
* @returns A promise that resolves to the loaded SharedModel.
|
|
850
906
|
* @internal
|
|
851
|
-
*/ async loadModel(url, options,
|
|
852
|
-
const
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
const data = new Blob([
|
|
857
|
-
arrayBuffer
|
|
858
|
-
], {
|
|
859
|
-
type: mimeType
|
|
860
|
-
});
|
|
861
|
-
const filename = this.vfs.basename(url);
|
|
862
|
-
for (const loader of AssetManager._modelLoaders){
|
|
863
|
-
if (!loader.supportMIMEType(mimeType)) {
|
|
864
|
-
continue;
|
|
865
|
-
}
|
|
866
|
-
let model = await loader.load(this, url, options?.mimeType || data.type, data, options?.dracoDecoderModule, VFSs);
|
|
907
|
+
*/ async loadModel(url, options, vfs) {
|
|
908
|
+
const mimeType = options?.mimeType || guessMimeType(url);
|
|
909
|
+
const importer = this._modelLoaders[mimeType];
|
|
910
|
+
if (importer) {
|
|
911
|
+
let model = await importer.loadModel(url, vfs);
|
|
867
912
|
if (!model) {
|
|
868
913
|
throw new Error(`Load asset failed: ${url}`);
|
|
869
914
|
}
|
|
@@ -874,7 +919,6 @@ import '../shaders/atmosphere.js';
|
|
|
874
919
|
throw new Error(`Model loader post process failed: ${err}`);
|
|
875
920
|
}
|
|
876
921
|
}
|
|
877
|
-
model.name = filename;
|
|
878
922
|
return model;
|
|
879
923
|
}
|
|
880
924
|
throw new Error(`Can not find loader for asset ${url}`);
|
|
@@ -939,39 +983,26 @@ import '../shaders/atmosphere.js';
|
|
|
939
983
|
return `${type}:${url}:${!options?.linearColorSpace}`;
|
|
940
984
|
}
|
|
941
985
|
/**
|
|
942
|
-
* Try reading from file from a
|
|
986
|
+
* Try reading from file from a VFS
|
|
943
987
|
*
|
|
944
988
|
* @param path - File path
|
|
945
989
|
* @param options - Read options
|
|
946
|
-
* @param
|
|
990
|
+
* @param vfs - VFS to read from
|
|
947
991
|
* @returns File content
|
|
948
992
|
*
|
|
949
993
|
* @internal
|
|
950
|
-
*/ async
|
|
951
|
-
|
|
952
|
-
this.vfs
|
|
953
|
-
];
|
|
954
|
-
for (const vfs of vfsList){
|
|
955
|
-
try {
|
|
956
|
-
return await vfs.readFile(path, options);
|
|
957
|
-
} catch {}
|
|
958
|
-
}
|
|
959
|
-
throw new VFSError(`File does not exist: ${path}`, 'ENOENT', path);
|
|
994
|
+
*/ async readFileFromVFS(path, options, vfs) {
|
|
995
|
+
return await (vfs ?? this.vfs).readFile(path, options);
|
|
960
996
|
}
|
|
961
997
|
/**
|
|
962
|
-
* Write file to a
|
|
998
|
+
* Write file to a VFS
|
|
963
999
|
*
|
|
964
1000
|
* @param path - File path
|
|
965
1001
|
* @param data - Data to write
|
|
966
1002
|
* @param options - Write options
|
|
967
|
-
* @param
|
|
968
|
-
*/ async writeFileToVFSs(path, data, options,
|
|
969
|
-
|
|
970
|
-
this.vfs
|
|
971
|
-
];
|
|
972
|
-
for (const vfs of vfsList){
|
|
973
|
-
await vfs.writeFile(path, data, options);
|
|
974
|
-
}
|
|
1003
|
+
* @param vfs - VFS to write to
|
|
1004
|
+
*/ async writeFileToVFSs(path, data, options, vfs) {
|
|
1005
|
+
await (vfs ?? this.vfs).writeFile(path, data, options);
|
|
975
1006
|
}
|
|
976
1007
|
}
|
|
977
1008
|
|