@zephyr3d/scene 0.9.3 → 0.9.4

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.
Files changed (129) hide show
  1. package/dist/animation/spring/spring_particle.js +4 -4
  2. package/dist/animation/spring/spring_particle.js.map +1 -1
  3. package/dist/app/engine.js +119 -71
  4. package/dist/app/engine.js.map +1 -1
  5. package/dist/asset/assetmanager.js +296 -244
  6. package/dist/asset/assetmanager.js.map +1 -1
  7. package/dist/asset/loaders/gltf/gltf_loader.js +1 -0
  8. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  9. package/dist/asset/model.js +57 -57
  10. package/dist/asset/model.js.map +1 -1
  11. package/dist/index.d.ts +684 -33
  12. package/dist/index.js +10 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/material/material.js +1 -1
  15. package/dist/material/material.js.map +1 -1
  16. package/dist/material/msdf_text.js +180 -0
  17. package/dist/material/msdf_text.js.map +1 -0
  18. package/dist/material/msdf_text_sprite.js +64 -0
  19. package/dist/material/msdf_text_sprite.js.map +1 -0
  20. package/dist/material/pbrblueprint.js +123 -108
  21. package/dist/material/pbrblueprint.js.map +1 -1
  22. package/dist/material/shader/helper.js +277 -277
  23. package/dist/material/shader/helper.js.map +1 -1
  24. package/dist/material/sprite_sdf.js +106 -0
  25. package/dist/material/sprite_sdf.js.map +1 -0
  26. package/dist/posteffect/ssr.js +1 -0
  27. package/dist/posteffect/ssr.js.map +1 -1
  28. package/dist/render/abuffer_oit.js +1 -0
  29. package/dist/render/abuffer_oit.js.map +1 -1
  30. package/dist/render/cluster_light.js.map +1 -1
  31. package/dist/render/cull_visitor.js +28 -0
  32. package/dist/render/cull_visitor.js.map +1 -1
  33. package/dist/render/drawable.js.map +1 -1
  34. package/dist/render/drawable_mixin.js +1 -0
  35. package/dist/render/drawable_mixin.js.map +1 -1
  36. package/dist/render/fbm_wavegenerator.js +1 -0
  37. package/dist/render/fbm_wavegenerator.js.map +1 -1
  38. package/dist/render/gerstner_wavegenerator.js +1 -0
  39. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  40. package/dist/render/globalbindgroup_allocator.js +1 -0
  41. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  42. package/dist/render/render_queue.js +1 -0
  43. package/dist/render/render_queue.js.map +1 -1
  44. package/dist/scene/basesprite.js +1 -5
  45. package/dist/scene/basesprite.js.map +1 -1
  46. package/dist/scene/batchgroup.js +29 -17
  47. package/dist/scene/batchgroup.js.map +1 -1
  48. package/dist/scene/environment.js +1 -0
  49. package/dist/scene/environment.js.map +1 -1
  50. package/dist/scene/mesh.js +86 -87
  51. package/dist/scene/mesh.js.map +1 -1
  52. package/dist/scene/meshdrawable.js +96 -0
  53. package/dist/scene/meshdrawable.js.map +1 -0
  54. package/dist/scene/msdftext.js +341 -0
  55. package/dist/scene/msdftext.js.map +1 -0
  56. package/dist/scene/msdftextsprite.js +349 -0
  57. package/dist/scene/msdftextsprite.js.map +1 -0
  58. package/dist/scene/particlesys.js +1 -0
  59. package/dist/scene/particlesys.js.map +1 -1
  60. package/dist/scene/scene.js +1 -0
  61. package/dist/scene/scene.js.map +1 -1
  62. package/dist/scene/scene_node.js +234 -228
  63. package/dist/scene/scene_node.js.map +1 -1
  64. package/dist/scene/sdftextsprite.js +322 -0
  65. package/dist/scene/sdftextsprite.js.map +1 -0
  66. package/dist/scene/terrain-cm/grass.js +1 -0
  67. package/dist/scene/terrain-cm/grass.js.map +1 -1
  68. package/dist/scene/terrain-cm/grassmaterial.js +1 -0
  69. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  70. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  71. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  72. package/dist/scene/textsprite.js +120 -0
  73. package/dist/scene/textsprite.js.map +1 -0
  74. package/dist/scene/water.js +1 -0
  75. package/dist/scene/water.js.map +1 -1
  76. package/dist/shadow/shader.js +1 -0
  77. package/dist/shadow/shader.js.map +1 -1
  78. package/dist/text/font/font_asset.js +884 -0
  79. package/dist/text/font/font_asset.js.map +1 -0
  80. package/dist/text/font/sfnt_reader.js +43 -0
  81. package/dist/text/font/sfnt_reader.js.map +1 -0
  82. package/dist/text/msdf/generator.js +417 -0
  83. package/dist/text/msdf/generator.js.map +1 -0
  84. package/dist/text/msdf/shape.js +143 -0
  85. package/dist/text/msdf/shape.js.map +1 -0
  86. package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
  87. package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
  88. package/dist/text/runtime/msdf_text_atlas_manager.js +47 -0
  89. package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
  90. package/dist/text/runtime/text_layout.js +96 -0
  91. package/dist/text/runtime/text_layout.js.map +1 -0
  92. package/dist/utility/blueprint/material/inputs.js +1275 -1091
  93. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  94. package/dist/utility/blueprint/material/ir.js +16 -1
  95. package/dist/utility/blueprint/material/ir.js.map +1 -1
  96. package/dist/utility/blueprint/material/pbr.js +32 -0
  97. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  98. package/dist/utility/serialization/manager.js +321 -277
  99. package/dist/utility/serialization/manager.js.map +1 -1
  100. package/dist/utility/serialization/scene/animation.js +2 -0
  101. package/dist/utility/serialization/scene/animation.js.map +1 -1
  102. package/dist/utility/serialization/scene/batch.js +2 -0
  103. package/dist/utility/serialization/scene/batch.js.map +1 -1
  104. package/dist/utility/serialization/scene/camera.js +2 -0
  105. package/dist/utility/serialization/scene/camera.js.map +1 -1
  106. package/dist/utility/serialization/scene/light.js +2 -0
  107. package/dist/utility/serialization/scene/light.js.map +1 -1
  108. package/dist/utility/serialization/scene/material.js +1 -0
  109. package/dist/utility/serialization/scene/material.js.map +1 -1
  110. package/dist/utility/serialization/scene/mesh.js +2 -0
  111. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  112. package/dist/utility/serialization/scene/node.js +2 -0
  113. package/dist/utility/serialization/scene/node.js.map +1 -1
  114. package/dist/utility/serialization/scene/particle.js +2 -0
  115. package/dist/utility/serialization/scene/particle.js.map +1 -1
  116. package/dist/utility/serialization/scene/primitive.js +1 -0
  117. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  118. package/dist/utility/serialization/scene/sprite.js +2 -0
  119. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  120. package/dist/utility/serialization/scene/terrain.js +2 -0
  121. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  122. package/dist/utility/serialization/scene/text.js +516 -0
  123. package/dist/utility/serialization/scene/text.js.map +1 -0
  124. package/dist/utility/serialization/scene/water.js +2 -0
  125. package/dist/utility/serialization/scene/water.js.map +1 -1
  126. package/dist/utility/serialization/types.js.map +1 -1
  127. package/dist/values.js +48 -48
  128. package/dist/values.js.map +1 -1
  129. package/package.json +3 -3
@@ -31,11 +31,12 @@ import '../../material/pbrsg.js';
31
31
  import '../../material/pbrblueprint.js';
32
32
  import '../../material/sprite.js';
33
33
  import '../../material/sprite_std.js';
34
+ import '../../material/msdf_text.js';
34
35
  import { PBRBlockNode, SpriteBlockNode, VertexBlockNode } from '../blueprint/material/pbr.js';
35
36
  import { ConstantScalarNode, ConstantVec2Node, ConstantVec3Node, ConstantVec4Node, ConstantBooleanNode, ConstantBVec2Node, ConstantBVec3Node, ConstantBVec4Node } from '../blueprint/common/constants.js';
36
37
  import { ConstantTexture2DNode, ConstantTexture2DArrayNode, ConstantTextureCubeNode, PannerNode, TextureSampleNode } from '../blueprint/material/texture.js';
37
38
  import { MakeVectorNode, SwizzleNode, EqualNode, NotEqualNode, LogicallyAndNode, LogicallyOrNode, CompComparisonNode, AnyConditionNode, AllConditionNode, SelectionNode, Degrees2RadiansNode, Radians2DegreesNode, SinNode, CosNode, TanNode, ArcSinNode, ArcCosNode, ArcTanNode, ArcTan2Node, SinHNode, CosHNode, TanHNode, ArcsineHNode, ArccosineHNode, ArctangentHNode, ExpNode, Exp2Node, LogNode, Log2Node, SqrtNode, InvSqrtNode, AbsNode, SignNode, FloorNode, CeilNode, FractNode, DDXNode, DDYNode, FWidthNode, CompAddNode, CompSubNode, CompMulNode, CompDivNode, ModNode, MinNode, MaxNode, PowNode, StepNode, SmoothStepNode, FmaNode, ClampNode, SaturateNode, MixNode, NormalizeNode, TransformNode, RotateAboutAxisNode, FaceForwardNode, ReflectNode, RefractNode, LengthNode, DistanceNode, DotProductNode, CrossProductNode, Hash1Node, Hash2Node, Hash3Node, SimplexNoise2DNode, PerlinNoise2DNode } from '../blueprint/common/math.js';
38
- import { VertexColorNode, VertexUVNode, VertexPositionNode, PixelWorldPositionNode, VertexNormalNode, PixelNormalNode, VertexTangentNode, VertexBinormalNode, ViewMatrixNode, ProjectionMatrixNode, ViewProjMatrixNode, InvProjMatrixNode, InvViewProjMatrixNode, BillboardMatrixNode, CameraPositionNode, CameraVectorNode, CameraNearFarNode, SkyEnvTextureNode, ElapsedTimeNode, ResolveVertexPositionNode, ResolveVertexTangentNode, ResolveVertexNormalNode } from '../blueprint/material/inputs.js';
39
+ import { VertexOutputNode, VertexIndexNode, InstanceIndexNode, VertexColorNode, VertexUVNode, VertexPositionNode, PixelWorldPositionNode, VertexNormalNode, PixelNormalNode, VertexTangentNode, VertexBinormalNode, ViewMatrixNode, ProjectionMatrixNode, ViewProjMatrixNode, InvProjMatrixNode, InvViewProjMatrixNode, BillboardMatrixNode, CameraPositionNode, CameraVectorNode, CameraNearFarNode, SkyEnvTextureNode, ElapsedTimeNode, ResolveVertexPositionNode, ResolveVertexTangentNode, ResolveVertexNormalNode } from '../blueprint/material/inputs.js';
39
40
  import { FunctionInputNode, FunctionOutputNode, FunctionCallNode } from '../blueprint/material/func.js';
40
41
  import '../../render/rendergraph/forward_plus_builder.js';
41
42
  import '../../render/sky.js';
@@ -45,6 +46,7 @@ import { SceneNode } from '../../scene/scene_node.js';
45
46
  import '../../shadow/shadowmapper.js';
46
47
  import '../../scene/mesh.js';
47
48
  import '../../scene/basesprite.js';
49
+ import '../../scene/meshdrawable.js';
48
50
  import '../../scene/water.js';
49
51
  import '../../scene/particlesys.js';
50
52
  import '../../scene/batchgroup.js';
@@ -59,6 +61,7 @@ import '../../animation/joint_dynamics/solver.js';
59
61
  import '../../animation/joint_dynamics/joint_dynamics_system.js';
60
62
  import { getJSONPropClass, getJSONNumberClass, getJSONStringClass, getJSONBoolClass, getJSONObjectClass, getJSONArrayClass } from './json.js';
61
63
  import { getSpriteClass } from './scene/sprite.js';
64
+ import { getTextSpriteClass, getMSDFTextSpriteClass, getMSDFTextClass } from './scene/text.js';
62
65
 
63
66
  const defaultValues = {
64
67
  bool: false,
@@ -111,29 +114,29 @@ const defaultValues = {
111
114
  ],
112
115
  command: null
113
116
  };
114
- /**
115
- * Manages serialization and deserialization of engine objects to/from JSON,
116
- * including asset resolution via a virtual file system (VFS) and asset manager.
117
- *
118
- * @remarks
119
- * - Keeps a registry of serializable classes and their properties.
120
- * - Converts object graphs to JSON using per-class metadata and property accessors.
121
- * - Supports async asset embedding/export and lazy deserialization via phases.
122
- * - Maps loaded assets/objects back to their source IDs for caching and deduplication.
123
- *
124
- * Typical workflow:
125
- * 1. Construct with a `VFS`.
126
- * 2. Optionally `registerClass` for custom types.
127
- * 3. Use `serializeObject` and `deserializeObject` to convert between runtime objects and JSON.
128
- * 4. Use `saveScene` / `loadScene` for scene I/O.
129
- *
130
- * Caching:
131
- * - `getAssetId` returns the known source ID for an allocated asset when available.
132
- *
133
- * Threading:
134
- * - Methods returning Promises perform async I/O using the provided `VFS`/AssetManager.
135
- *
136
- * @public
117
+ /**
118
+ * Manages serialization and deserialization of engine objects to/from JSON,
119
+ * including asset resolution via a virtual file system (VFS) and asset manager.
120
+ *
121
+ * @remarks
122
+ * - Keeps a registry of serializable classes and their properties.
123
+ * - Converts object graphs to JSON using per-class metadata and property accessors.
124
+ * - Supports async asset embedding/export and lazy deserialization via phases.
125
+ * - Maps loaded assets/objects back to their source IDs for caching and deduplication.
126
+ *
127
+ * Typical workflow:
128
+ * 1. Construct with a `VFS`.
129
+ * 2. Optionally `registerClass` for custom types.
130
+ * 3. Use `serializeObject` and `deserializeObject` to convert between runtime objects and JSON.
131
+ * 4. Use `saveScene` / `loadScene` for scene I/O.
132
+ *
133
+ * Caching:
134
+ * - `getAssetId` returns the known source ID for an allocated asset when available.
135
+ *
136
+ * Threading:
137
+ * - Methods returning Promises perform async I/O using the provided `VFS`/AssetManager.
138
+ *
139
+ * @public
137
140
  */ class ResourceManager {
138
141
  _classMap;
139
142
  _vfs;
@@ -143,10 +146,10 @@ const defaultValues = {
143
146
  _assetManager;
144
147
  _editorMode;
145
148
  _allocated;
146
- /**
147
- * Create a ResourceManager bound to a virtual file system.
148
- *
149
- * @param vfs - Virtual file system used for reading/writing assets and scenes.
149
+ /**
150
+ * Create a ResourceManager bound to a virtual file system.
151
+ *
152
+ * @param vfs - Virtual file system used for reading/writing assets and scenes.
150
153
  */ constructor(vfs, editorMode = false){
151
154
  this._vfs = vfs;
152
155
  this._editorMode = editorMode;
@@ -179,6 +182,9 @@ const defaultValues = {
179
182
  getGraphNodeClass(),
180
183
  getMeshClass(),
181
184
  getSpriteClass(),
185
+ getTextSpriteClass(),
186
+ getMSDFTextSpriteClass(),
187
+ getMSDFTextClass(),
182
188
  getWaterClass(this),
183
189
  getTerrainClass(this),
184
190
  getFFTWaveGeneratorClass(),
@@ -292,6 +298,9 @@ const defaultValues = {
292
298
  Hash3Node.getSerializationCls(),
293
299
  SimplexNoise2DNode.getSerializationCls(),
294
300
  PerlinNoise2DNode.getSerializationCls(),
301
+ VertexOutputNode.getSerializationCls(),
302
+ VertexIndexNode.getSerializationCls(),
303
+ InstanceIndexNode.getSerializationCls(),
295
304
  VertexColorNode.getSerializationCls(),
296
305
  VertexUVNode.getSerializationCls(),
297
306
  VertexPositionNode.getSerializationCls(),
@@ -330,49 +339,49 @@ const defaultValues = {
330
339
  this.registerProps(k[1]);
331
340
  }
332
341
  }
333
- /**
334
- * The virtual file system used by this manager.
335
- *
336
- * @remarks
337
- * Used by asset fetchers and scene save/load operations.
342
+ /**
343
+ * The virtual file system used by this manager.
344
+ *
345
+ * @remarks
346
+ * Used by asset fetchers and scene save/load operations.
338
347
  */ get VFS() {
339
348
  return this._vfs;
340
349
  }
341
350
  set VFS(vfs) {
342
351
  this._vfs = vfs;
343
352
  }
344
- /**
345
- * Wethether editor mode is enabled
346
- *
347
- * @remarks
348
- * In editor mode, some properties will be disabled
353
+ /**
354
+ * Wethether editor mode is enabled
355
+ *
356
+ * @remarks
357
+ * In editor mode, some properties will be disabled
349
358
  */ get editorMode() {
350
359
  return this._editorMode;
351
360
  }
352
- /**
353
- * AssetManager
361
+ /**
362
+ * AssetManager
354
363
  */ get assetManager() {
355
364
  return this._assetManager;
356
365
  }
357
- /**
358
- * Get the list of all registered serializable classes.
359
- *
360
- * @remarks
361
- * Includes built-in classes registered during construction and any custom classes
362
- * registered via `registerClass`.
363
- *
364
- * @returns An array of `SerializableClass` metadata.
366
+ /**
367
+ * Get the list of all registered serializable classes.
368
+ *
369
+ * @remarks
370
+ * Includes built-in classes registered during construction and any custom classes
371
+ * registered via `registerClass`.
372
+ *
373
+ * @returns An array of `SerializableClass` metadata.
365
374
  */ getClasses() {
366
375
  return [
367
376
  ...this._classMap.values()
368
377
  ];
369
378
  }
370
- /**
371
- * Get serialization metadata by a constructor function.
372
- *
373
- * @param ctor - The class constructor to look up.
374
- *
375
- * @returns The `SerializableClass` metadata, or `null` if not found.
379
+ /**
380
+ * Get serialization metadata by a constructor function.
381
+ *
382
+ * @param ctor - The class constructor to look up.
383
+ *
384
+ * @returns The `SerializableClass` metadata, or `null` if not found.
376
385
  */ getClassByConstructor(ctor) {
377
386
  let current = ctor;
378
387
  while(typeof current === 'function' && current !== Function.prototype){
@@ -384,21 +393,21 @@ const defaultValues = {
384
393
  }
385
394
  return null;
386
395
  }
387
- /**
388
- * Get serialization metadata by an object instance.
389
- *
390
- * @param obj - The object whose constructor will be used for the lookup.
391
- *
392
- * @returns The `SerializableClass` metadata, or `null` if not found.
396
+ /**
397
+ * Get serialization metadata by an object instance.
398
+ *
399
+ * @param obj - The object whose constructor will be used for the lookup.
400
+ *
401
+ * @returns The `SerializableClass` metadata, or `null` if not found.
393
402
  */ getClassByObject(obj) {
394
403
  return this.getClassByConstructor(obj.constructor);
395
404
  }
396
- /**
397
- * Get serialization metadata by class name.
398
- *
399
- * @param className - Fully qualified class name as stored in JSON.
400
- *
401
- * @returns The `SerializableClass` metadata, or `null` if not found.
405
+ /**
406
+ * Get serialization metadata by class name.
407
+ *
408
+ * @param className - Fully qualified class name as stored in JSON.
409
+ *
410
+ * @returns The `SerializableClass` metadata, or `null` if not found.
402
411
  */ getClassByName(className) {
403
412
  for (const val of this._classMap){
404
413
  if (val[0].name === className) {
@@ -407,12 +416,12 @@ const defaultValues = {
407
416
  }
408
417
  return null;
409
418
  }
410
- /**
411
- * Find the class that owns a given property accessor.
412
- *
413
- * @param prop - Property accessor to search for.
414
- *
415
- * @returns The `SerializableClass` that declares the property, or `null` if unknown.
419
+ /**
420
+ * Find the class that owns a given property accessor.
421
+ *
422
+ * @param prop - Property accessor to search for.
423
+ *
424
+ * @returns The `SerializableClass` that declares the property, or `null` if unknown.
416
425
  */ getClassByProperty(prop) {
417
426
  for (const k of this._clsPropMap){
418
427
  if (k[1].indexOf(prop) >= 0) {
@@ -421,21 +430,21 @@ const defaultValues = {
421
430
  }
422
431
  return null;
423
432
  }
424
- /**
425
- * Get the properties declared on a given class.
426
- *
427
- * @param cls - Serializable class metadata.
428
- *
429
- * @returns An array of `PropertyAccessor` entries, or `null` if none.
433
+ /**
434
+ * Get the properties declared on a given class.
435
+ *
436
+ * @param cls - Serializable class metadata.
437
+ *
438
+ * @returns An array of `PropertyAccessor` entries, or `null` if none.
430
439
  */ getPropertiesByClass(cls) {
431
440
  return this._clsPropMap.get(cls) ?? null;
432
441
  }
433
- /**
434
- * Get all properties declared on a given class and its ancestors.
435
- *
436
- * @param cls - Serializable class metadata.
437
- *
438
- * @returns An array of `PropertyAccessor` entries, or `null` if none.
442
+ /**
443
+ * Get all properties declared on a given class and its ancestors.
444
+ *
445
+ * @param cls - Serializable class metadata.
446
+ *
447
+ * @returns An array of `PropertyAccessor` entries, or `null` if none.
439
448
  */ getAllPropertiesByClass(cls) {
440
449
  const props = new Map();
441
450
  while(cls){
@@ -453,72 +462,72 @@ const defaultValues = {
453
462
  ...props.values()
454
463
  ];
455
464
  }
456
- /**
457
- * Get a property accessor by class and property name.
458
- *
459
- * @param cls - Serializable class metadata.
460
- * @param name - Property name to search for.
461
- *
462
- * @returns The `PropertyAccessor`, or `null` if not found.
465
+ /**
466
+ * Get a property accessor by class and property name.
467
+ *
468
+ * @param cls - Serializable class metadata.
469
+ * @param name - Property name to search for.
470
+ *
471
+ * @returns The `PropertyAccessor`, or `null` if not found.
463
472
  */ getPropertyByClass(cls, name) {
464
473
  return this.getPropertiesByClass(cls)?.find((value)=>value.name === name) ?? null;
465
474
  }
466
- /**
467
- * Get a property accessor by its canonical path.
468
- *
469
- * @remarks
470
- * The canonical path format is `/ClassName/propName`.
471
- *
472
- * @param name - Canonical property path.
473
- *
474
- * @returns The `PropertyAccessor`, or `null` if not found.
475
+ /**
476
+ * Get a property accessor by its canonical path.
477
+ *
478
+ * @remarks
479
+ * The canonical path format is `/ClassName/propName`.
480
+ *
481
+ * @param name - Canonical property path.
482
+ *
483
+ * @returns The `PropertyAccessor`, or `null` if not found.
475
484
  */ getPropertyByName(name) {
476
485
  return this._propMap[name] ?? null;
477
486
  }
478
- /**
479
- * Get the canonical path for a property accessor.
480
- *
481
- * @remarks
482
- * Returns a string like `/ClassName/propName` if the property is registered.
483
- *
484
- * @param prop - Property accessor.
485
- *
486
- * @returns The canonical path, or `null` if unknown.
487
+ /**
488
+ * Get the canonical path for a property accessor.
489
+ *
490
+ * @remarks
491
+ * Returns a string like `/ClassName/propName` if the property is registered.
492
+ *
493
+ * @param prop - Property accessor.
494
+ *
495
+ * @returns The canonical path, or `null` if unknown.
487
496
  */ getPropertyName(prop) {
488
497
  return this._propNameMap.get(prop) ?? null;
489
498
  }
490
- /**
491
- * Register a serializable class and its properties.
492
- *
493
- * @remarks
494
- * - No effect if the class is already registered.
495
- * - Also registers the class's properties with canonical paths.
496
- *
497
- * @param cls - Serializable class metadata to register.
499
+ /**
500
+ * Register a serializable class and its properties.
501
+ *
502
+ * @remarks
503
+ * - No effect if the class is already registered.
504
+ * - Also registers the class's properties with canonical paths.
505
+ *
506
+ * @param cls - Serializable class metadata to register.
498
507
  */ registerClass(cls) {
499
508
  if (!this._classMap.has(cls.ctor)) {
500
509
  this._classMap.set(cls.ctor, cls);
501
510
  this.registerProps(cls);
502
511
  }
503
512
  }
504
- /**
505
- * Get the known asset ID previously associated with a loaded/allocated asset.
506
- *
507
- * @remarks
508
- * Returns `null` if the asset was not loaded or tracked by this manager.
509
- *
510
- * @param asset - Asset instance (e.g., texture, model group) to look up.
511
- *
512
- * @returns The asset ID string, or `null` if unknown.
513
+ /**
514
+ * Get the known asset ID previously associated with a loaded/allocated asset.
515
+ *
516
+ * @remarks
517
+ * Returns `null` if the asset was not loaded or tracked by this manager.
518
+ *
519
+ * @param asset - Asset instance (e.g., texture, model group) to look up.
520
+ *
521
+ * @returns The asset ID string, or `null` if unknown.
513
522
  */ getAssetId(asset) {
514
523
  return this._allocated.get(asset) ?? null;
515
524
  }
516
- /**
517
- * Associate an asset ID to a loaded/allocated asset.
518
- *
519
- * @param asset - Asset instance (e.g., texture, model group) to set Id.
520
- * @param id - Asset ID to associated to this asset.
521
- *
525
+ /**
526
+ * Associate an asset ID to a loaded/allocated asset.
527
+ *
528
+ * @param asset - Asset instance (e.g., texture, model group) to set Id.
529
+ * @param id - Asset ID to associated to this asset.
530
+ *
522
531
  */ setAssetId(asset, id) {
523
532
  if (asset) {
524
533
  if (id) {
@@ -528,35 +537,66 @@ const defaultValues = {
528
537
  }
529
538
  }
530
539
  }
531
- /**
532
- * Fetch a binary asset by ID via the asset manager.
533
- *
534
- * @remarks
535
- * - Associates the returned data with the given ID for future reverse lookup.
536
- * - The ID is typically a VFS path or locator.
537
- *
538
- * @param id - Asset identifier or path.
539
- *
540
- * @returns A Promise that resolves to the binary content, or `null` if not found.
541
- */ async fetchBinary(id) {
540
+ /**
541
+ * Fetch a binary asset by ID via the asset manager.
542
+ *
543
+ * @remarks
544
+ * - Associates the returned data with the given ID for future reverse lookup.
545
+ * - The ID is typically a VFS path or locator.
546
+ *
547
+ * @param path - VFS path of the binary asset.
548
+ *
549
+ * @returns A Promise that resolves to the binary content, or `null` if not found.
550
+ */ async fetchBinary(path) {
551
+ const id = this.VFS.normalizePath(path);
542
552
  const data = await this._assetManager.fetchBinaryData(id);
543
553
  if (data) {
544
554
  this._allocated.set(data, id);
545
555
  }
546
556
  return data;
547
557
  }
548
- /**
549
- * Serialize an object to a JSON structure using registered class metadata.
550
- *
551
- * @remarks
552
- * - Throws if the object's class is not registered.
553
- * - Populates `asyncTasks` with pending I/O tasks for embedded resources.
554
- *
555
- * @param obj - The object to serialize.
556
- * @param json - Optional existing JSON object to fill.
557
- * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
558
- *
559
- * @returns The serialized JSON structure.
558
+ /**
559
+ * Fetch a text asset by ID via the asset manager.
560
+ *
561
+ * @param path - VFS path of TTF/OTF file.
562
+ * @returns A Promise that resolves to the font asset, or `null` if not found.
563
+ */ async fetchFontAsset(path, options) {
564
+ const id = this.VFS.normalizePath(path);
565
+ const fontAsset = await this._assetManager.fetchFontAsset(id, options);
566
+ if (fontAsset) {
567
+ this._allocated.set(fontAsset, id);
568
+ }
569
+ return fontAsset;
570
+ }
571
+ /**
572
+ * Get a cached font asset by ID if already loaded.
573
+ *
574
+ * @param path - VFS path of TTF/OTF file.
575
+ * @returns The cached FontAsset if it exists and is loaded, or null if not cached or still loading.
576
+ */ getFontAsset(path) {
577
+ return this._assetManager.getFontAsset(this.VFS.normalizePath(path));
578
+ }
579
+ /**
580
+ * Removes a cached font asset entry by asset instance or asset ID.
581
+ *
582
+ * @param asset - Loaded font asset instance or its asset ID/path.
583
+ * @returns `true` if a cache entry existed and was removed.
584
+ */ releaseFontAsset(asset) {
585
+ const path = typeof asset === 'string' ? asset : this.getAssetId(asset);
586
+ return path ? this._assetManager.releaseFontAsset(this.VFS.normalizePath(path)) : false;
587
+ }
588
+ /**
589
+ * Serialize an object to a JSON structure using registered class metadata.
590
+ *
591
+ * @remarks
592
+ * - Throws if the object's class is not registered.
593
+ * - Populates `asyncTasks` with pending I/O tasks for embedded resources.
594
+ *
595
+ * @param obj - The object to serialize.
596
+ * @param json - Optional existing JSON object to fill.
597
+ * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
598
+ *
599
+ * @returns The serialized JSON structure.
560
600
  */ async serializeObject(obj, json, asyncTasks) {
561
601
  if (obj === null || obj === undefined) {
562
602
  return obj;
@@ -582,14 +622,14 @@ const defaultValues = {
582
622
  }
583
623
  return json;
584
624
  }
585
- /**
586
- * Serialize object properties into a JSON structure.
587
- *
588
- * @param obj - The target object to serialize.
589
- * @param json - The JSON structure to populate.
590
- * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
591
- * @param info - Optional serialization metadata for the object's class.
592
- * @returns A Promise that resolves when serialization is complete.
625
+ /**
626
+ * Serialize object properties into a JSON structure.
627
+ *
628
+ * @param obj - The target object to serialize.
629
+ * @param json - The JSON structure to populate.
630
+ * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
631
+ * @param info - Optional serialization metadata for the object's class.
632
+ * @returns A Promise that resolves when serialization is complete.
593
633
  */ async serializeObjectProps(obj, json, asyncTasks, info) {
594
634
  if (!info) {
595
635
  const cls = this.getClasses();
@@ -606,17 +646,17 @@ const defaultValues = {
606
646
  }
607
647
  return json;
608
648
  }
609
- /**
610
- * Deserialize a JSON structure into an object instance.
611
- *
612
- * @remarks
613
- * - Uses the `ClassName` field to locate the registered class.
614
- * - Supports custom `createFunc` and phased property loading.
615
- *
616
- * @param ctx - Context object passed to custom constructors/resolvers.
617
- * @param json - The serialized JSON structure.
618
- *
619
- * @returns A Promise resolving to the reconstructed object instance, or `null` on failure.
649
+ /**
650
+ * Deserialize a JSON structure into an object instance.
651
+ *
652
+ * @remarks
653
+ * - Uses the `ClassName` field to locate the registered class.
654
+ * - Supports custom `createFunc` and phased property loading.
655
+ *
656
+ * @param ctx - Context object passed to custom constructors/resolvers.
657
+ * @param json - The serialized JSON structure.
658
+ *
659
+ * @returns A Promise resolving to the reconstructed object instance, or `null` on failure.
620
660
  */ async deserializeObject(ctx, json) {
621
661
  const cls = this.getClasses();
622
662
  const className = json['ClassName'];
@@ -649,12 +689,12 @@ const defaultValues = {
649
689
  }
650
690
  return obj;
651
691
  }
652
- /**
653
- * Deserialize object properties from JSON into an existing object instance.
654
- *
655
- * @param obj - The target object to populate.
656
- * @param json - The JSON structure containing serialized properties.
657
- * @param info - Optional serialization metadata for the object's class.
692
+ /**
693
+ * Deserialize object properties from JSON into an existing object instance.
694
+ *
695
+ * @param obj - The target object to populate.
696
+ * @param json - The JSON structure containing serialized properties.
697
+ * @param info - Optional serialization metadata for the object's class.
658
698
  */ async deserializeObjectProps(obj, json, info) {
659
699
  if (!info) {
660
700
  const cls = this.getClasses();
@@ -669,95 +709,99 @@ const defaultValues = {
669
709
  info = this.getClassByConstructor(info.parent);
670
710
  }
671
711
  }
672
- /**
673
- * Load a model by ID and track the allocation for reverse lookup.
674
- *
675
- * @param id - Model identifier or path.
676
- * @param scene - Scene into which the model is loaded.
677
- * @param options - Optional model fetch options.
678
- *
679
- * @returns A Promise resolving to the loaded model object, or `null` if failed.
680
- */ async fetchModel(id, scene, options) {
712
+ /**
713
+ * Load a model by ID and track the allocation for reverse lookup.
714
+ *
715
+ * @param path - VFS path of the model file.
716
+ * @param scene - Scene into which the model is loaded.
717
+ * @param options - Optional model fetch options.
718
+ *
719
+ * @returns A Promise resolving to the loaded model object, or `null` if failed.
720
+ */ async fetchModel(path, scene, options) {
721
+ const id = this.VFS.normalizePath(path);
681
722
  const model = await this._assetManager.fetchModel(scene, id, options);
682
723
  if (model) {
683
724
  this._allocated.set(model.group, id);
684
725
  }
685
726
  return model;
686
727
  }
687
- /**
688
- * Load a texture directly from an ArrayBuffer or typed array.
689
- *
690
- * - Chooses an appropriate loader based on the provided MIME type.
691
- * - Can upload into an existing texture if `texture` is specified.
692
- *
693
- * @typeParam T - Expected concrete texture type.
694
- * @param arrayBuffer - Raw texture data buffer.
695
- * @param mimeType - MIME type of the texture (must be supported by a registered loader).
696
- * @param srgb - If true, treat image as sRGB; otherwise linear.
697
- * @param samplerOptions - Optional sampler options passed to the loader path.
698
- * @param texture - Optional destination texture to populate.
699
- * @returns A promise that resolves to the created or populated texture.
728
+ /**
729
+ * Load a texture directly from an ArrayBuffer or typed array.
730
+ *
731
+ * - Chooses an appropriate loader based on the provided MIME type.
732
+ * - Can upload into an existing texture if `texture` is specified.
733
+ *
734
+ * @typeParam T - Expected concrete texture type.
735
+ * @param arrayBuffer - Raw texture data buffer.
736
+ * @param mimeType - MIME type of the texture (must be supported by a registered loader).
737
+ * @param srgb - If true, treat image as sRGB; otherwise linear.
738
+ * @param samplerOptions - Optional sampler options passed to the loader path.
739
+ * @param texture - Optional destination texture to populate.
740
+ * @returns A promise that resolves to the created or populated texture.
700
741
  */ async loadTextureFromBuffer(arrayBuffer, mimeType, srgb, samplerOptions, texture) {
701
742
  return this._assetManager.loadTextureFromBuffer(arrayBuffer, mimeType, srgb, samplerOptions, texture);
702
743
  }
703
- /**
704
- * Load a texture by ID and track the allocation for reverse lookup.
705
- *
706
- * @param id - Texture identifier or path.
707
- * @param options - Optional texture fetch options.
708
- *
709
- * @returns A Promise resolving to the loaded texture, or `null` if failed.
710
- */ async fetchTexture(id, options) {
744
+ /**
745
+ * Load a texture by ID and track the allocation for reverse lookup.
746
+ *
747
+ * @param path - VFS path of the texture file.
748
+ * @param options - Optional texture fetch options.
749
+ *
750
+ * @returns A Promise resolving to the loaded texture, or `null` if failed.
751
+ */ async fetchTexture(path, options) {
752
+ const id = this.VFS.normalizePath(path);
711
753
  const texture = await this._assetManager.fetchTexture(id, options);
712
754
  if (texture) {
713
755
  this._allocated.set(texture, id);
714
756
  }
715
757
  return texture;
716
758
  }
717
- /**
718
- * Load a material by ID and track the allocation for reverse lookup.
719
- *
720
- * @param id - Material identifier or path.
721
- *
722
- * @returns A Promise resolving to the loaded material, or `null` if failed.
723
- */ async fetchMaterial(id) {
759
+ /**
760
+ * Load a material by ID and track the allocation for reverse lookup.
761
+ *
762
+ * @param path - VFS path of the material file.
763
+ *
764
+ * @returns A Promise resolving to the loaded material, or `null` if failed.
765
+ */ async fetchMaterial(path) {
766
+ const id = this.VFS.normalizePath(path);
724
767
  const material = await this._assetManager.fetchMaterial(id);
725
768
  if (material) {
726
769
  this._allocated.set(material, id);
727
770
  }
728
771
  return material;
729
772
  }
730
- /**
731
- * Reload specific blue print materials
732
- *
733
- * @param filter - Determine whether a blue print material should reload.
734
- *
773
+ /**
774
+ * Reload specific blue print materials
775
+ *
776
+ * @param filter - Determine whether a blue print material should reload.
777
+ *
735
778
  */ async reloadBluePrintMaterials(filter) {
736
779
  await this._assetManager.reloadBluePrintMaterials(filter);
737
780
  }
738
- /**
739
- * Mark specific blue print as changed
740
- * @param path - BluePrint file path
781
+ /**
782
+ * Mark specific blue print as changed
783
+ * @param path - BluePrint file path
741
784
  */ invalidateBluePrint(path) {
742
785
  this._assetManager.invalidateBluePrint(path);
743
786
  }
744
- /**
745
- * Load a primitive by ID and track the allocation for reverse lookup.
746
- *
747
- * @param id - Primitive identifier or path.
748
- *
749
- * @returns A Promise resolving to the loaded primitive, or `null` if failed.
750
- */ async fetchPrimitive(id) {
787
+ /**
788
+ * Load a primitive by ID and track the allocation for reverse lookup.
789
+ *
790
+ * @param path - VFS path of the primitive file.
791
+ *
792
+ * @returns A Promise resolving to the loaded primitive, or `null` if failed.
793
+ */ async fetchPrimitive(path) {
794
+ const id = this.VFS.normalizePath(path);
751
795
  const primitive = await this._assetManager.fetchPrimitive(id);
752
796
  if (primitive) {
753
797
  this._allocated.set(primitive, id);
754
798
  }
755
799
  return primitive;
756
800
  }
757
- /**
758
- * Load a prefab content.
759
- * @param path - Path to the prefab JSON file in VFS.
760
- * @returns A Promise resolving to the prefab json object, or `null` on failure.
801
+ /**
802
+ * Load a prefab content.
803
+ * @param path - Path to the prefab JSON file in VFS.
804
+ * @returns A Promise resolving to the prefab json object, or `null` on failure.
761
805
  */ async loadPrefabContent(path) {
762
806
  try {
763
807
  const content = await this._vfs.readFile(path, {
@@ -770,11 +814,11 @@ const defaultValues = {
770
814
  return null;
771
815
  }
772
816
  }
773
- /**
774
- * Instantiate a prefab from a JSON file via VFS.
775
- * @param parent - Parent node to attach the instantiated prefab to.
776
- * @param path - Path to the prefab JSON file in VFS.
777
- * @returns A Promise resolving to the instantiated `SceneNode`, or `null` on failure.
817
+ /**
818
+ * Instantiate a prefab from a JSON file via VFS.
819
+ * @param parent - Parent node to attach the instantiated prefab to.
820
+ * @param path - Path to the prefab JSON file in VFS.
821
+ * @returns A Promise resolving to the instantiated `SceneNode`, or `null` on failure.
778
822
  */ async instantiatePrefab(parent, path) {
779
823
  try {
780
824
  const json = await this.loadPrefabContent(path);
@@ -793,16 +837,16 @@ const defaultValues = {
793
837
  return null;
794
838
  }
795
839
  }
796
- /**
797
- * Load a scene from a JSON file via VFS.
798
- *
799
- * @remarks
800
- * - Deserializes the scene graph.
801
- * - Attaches scripts referenced by nodes after load (asynchronous).
802
- *
803
- * @param filename - Path to the scene JSON file in VFS.
804
- *
805
- * @returns A Promise resolving to the loaded `Scene`.
840
+ /**
841
+ * Load a scene from a JSON file via VFS.
842
+ *
843
+ * @remarks
844
+ * - Deserializes the scene graph.
845
+ * - Attaches scripts referenced by nodes after load (asynchronous).
846
+ *
847
+ * @param filename - Path to the scene JSON file in VFS.
848
+ *
849
+ * @returns A Promise resolving to the loaded `Scene`.
806
850
  */ async loadScene(filename) {
807
851
  const content = await this._vfs.readFile(filename, {
808
852
  encoding: 'utf8'
@@ -810,15 +854,15 @@ const defaultValues = {
810
854
  const json = JSON.parse(content);
811
855
  return await this.deserializeObject(null, json);
812
856
  }
813
- /**
814
- * Save a scene to a JSON file via VFS.
815
- *
816
- * @remarks
817
- * - Collects async export tasks for embedded resources and awaits them.
818
- * - Writes a UTF-8 JSON representation to VFS.
819
- *
820
- * @param scene - Scene to serialize and save.
821
- * @param filename - Destination path in VFS.
857
+ /**
858
+ * Save a scene to a JSON file via VFS.
859
+ *
860
+ * @remarks
861
+ * - Collects async export tasks for embedded resources and awaits them.
862
+ * - Writes a UTF-8 JSON representation to VFS.
863
+ *
864
+ * @param scene - Scene to serialize and save.
865
+ * @param filename - Destination path in VFS.
822
866
  */ async saveScene(scene, filename) {
823
867
  const asyncTasks = [];
824
868
  const content = await this.serializeObject(scene, null, asyncTasks);
@@ -950,11 +994,11 @@ const defaultValues = {
950
994
  async loadBluePrint(path) {
951
995
  return this._assetManager.loadBluePrint(path);
952
996
  }
953
- /**
954
- * Clear cached allocations and asset-manager caches.
955
- *
956
- * @remarks
957
- * Useful when reloading content or changing VFS mounts.
997
+ /**
998
+ * Clear cached allocations and asset-manager caches.
999
+ *
1000
+ * @remarks
1001
+ * Useful when reloading content or changing VFS mounts.
958
1002
  */ clearCache() {
959
1003
  this._allocated = new WeakMap();
960
1004
  this._assetManager.clearCache();
@@ -973,18 +1017,18 @@ const defaultValues = {
973
1017
  }
974
1018
  return null;
975
1019
  }
976
- /**
977
- * Find the object targeted by an animation track starting from a node.
978
- *
979
- * @remarks
980
- * - Parses a target path like `prop/subprop[0]/child` where indexed entries
981
- * require `object_array` type and non-indexed entries require `object` type.
982
- * - Returns `null` if any segment cannot be resolved through registered metadata.
983
- *
984
- * @param node - Root node used as the starting point.
985
- * @param track - Property track containing a target path.
986
- *
987
- * @returns The resolved target object, or `null` if not found.
1020
+ /**
1021
+ * Find the object targeted by an animation track starting from a node.
1022
+ *
1023
+ * @remarks
1024
+ * - Parses a target path like `prop/subprop[0]/child` where indexed entries
1025
+ * require `object_array` type and non-indexed entries require `object` type.
1026
+ * - Returns `null` if any segment cannot be resolved through registered metadata.
1027
+ *
1028
+ * @param node - Root node used as the starting point.
1029
+ * @param track - Property track containing a target path.
1030
+ *
1031
+ * @returns The resolved target object, or `null` if not found.
988
1032
  */ findAnimationTarget(node, track) {
989
1033
  const target = track.target ?? '';
990
1034
  const value = {