@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.
Files changed (188) hide show
  1. package/dist/animation/animationmask.js +224 -0
  2. package/dist/animation/animationmask.js.map +1 -0
  3. package/dist/animation/animationset.js +268 -67
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js.map +1 -1
  6. package/dist/animation/eulerrotationtrack.js +3 -0
  7. package/dist/animation/eulerrotationtrack.js.map +1 -1
  8. package/dist/animation/fixed_geometry_cache_track.js +7 -0
  9. package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
  10. package/dist/animation/ik_modifier.js.map +1 -1
  11. package/dist/animation/joint_dynamics/collision.js +6 -4
  12. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  13. package/dist/animation/joint_dynamics/controller.js +390 -43
  14. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  15. package/dist/animation/joint_dynamics/joint_dynamics_system.js +62 -3
  16. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  17. package/dist/animation/joint_dynamics/solver.js +4 -3
  18. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  19. package/dist/animation/joint_dynamics/types.js.map +1 -1
  20. package/dist/animation/joint_dynamics_modifier.js +2 -0
  21. package/dist/animation/joint_dynamics_modifier.js.map +1 -1
  22. package/dist/animation/morphtarget.js +3 -72
  23. package/dist/animation/morphtarget.js.map +1 -1
  24. package/dist/animation/morphtrack.js +3 -0
  25. package/dist/animation/morphtrack.js.map +1 -1
  26. package/dist/animation/pca_geometry_cache_track.js +3 -0
  27. package/dist/animation/pca_geometry_cache_track.js.map +1 -1
  28. package/dist/animation/proptrack.js +3 -0
  29. package/dist/animation/proptrack.js.map +1 -1
  30. package/dist/animation/rotationtrack.js +3 -0
  31. package/dist/animation/rotationtrack.js.map +1 -1
  32. package/dist/animation/scaletrack.js +3 -0
  33. package/dist/animation/scaletrack.js.map +1 -1
  34. package/dist/animation/skeleton.js +254 -79
  35. package/dist/animation/skeleton.js.map +1 -1
  36. package/dist/animation/skeleton_modifier.js.map +1 -1
  37. package/dist/animation/spring/spring_particle.js +4 -4
  38. package/dist/animation/spring/spring_particle.js.map +1 -1
  39. package/dist/animation/spring_modifier.js.map +1 -1
  40. package/dist/animation/translationtrack.js +3 -0
  41. package/dist/animation/translationtrack.js.map +1 -1
  42. package/dist/app/engine.js +129 -17
  43. package/dist/app/engine.js.map +1 -1
  44. package/dist/app/scriptregistry.js +251 -80
  45. package/dist/app/scriptregistry.js.map +1 -1
  46. package/dist/asset/assetmanager.js +133 -102
  47. package/dist/asset/assetmanager.js.map +1 -1
  48. package/dist/asset/loaders/gltf/gltf_loader.js +18 -14
  49. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  50. package/dist/asset/loaders/loader.js +1 -6
  51. package/dist/asset/loaders/loader.js.map +1 -1
  52. package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -1
  53. package/dist/asset/model.js +1052 -183
  54. package/dist/asset/model.js.map +1 -1
  55. package/dist/avatar/wardrobe.js +474 -0
  56. package/dist/avatar/wardrobe.js.map +1 -0
  57. package/dist/index.d.ts +1810 -233
  58. package/dist/index.js +13 -3
  59. package/dist/index.js.map +1 -1
  60. package/dist/material/material.js +1 -1
  61. package/dist/material/material.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +6 -3
  63. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  64. package/dist/material/mixins/pbr/common.js +72 -15
  65. package/dist/material/mixins/pbr/common.js.map +1 -1
  66. package/dist/material/msdf_text.js +180 -0
  67. package/dist/material/msdf_text.js.map +1 -0
  68. package/dist/material/msdf_text_sprite.js +64 -0
  69. package/dist/material/msdf_text_sprite.js.map +1 -0
  70. package/dist/material/pbrblueprint.js +21 -6
  71. package/dist/material/pbrblueprint.js.map +1 -1
  72. package/dist/material/shader/helper.js +277 -277
  73. package/dist/material/shader/helper.js.map +1 -1
  74. package/dist/material/sprite_sdf.js +106 -0
  75. package/dist/material/sprite_sdf.js.map +1 -0
  76. package/dist/posteffect/ssr.js +1 -0
  77. package/dist/posteffect/ssr.js.map +1 -1
  78. package/dist/render/abuffer_oit.js +1 -0
  79. package/dist/render/abuffer_oit.js.map +1 -1
  80. package/dist/render/cluster_light.js.map +1 -1
  81. package/dist/render/cull_visitor.js +28 -0
  82. package/dist/render/cull_visitor.js.map +1 -1
  83. package/dist/render/drawable.js.map +1 -1
  84. package/dist/render/drawable_mixin.js +1 -0
  85. package/dist/render/drawable_mixin.js.map +1 -1
  86. package/dist/render/envlight.js +54 -1
  87. package/dist/render/envlight.js.map +1 -1
  88. package/dist/render/fbm_wavegenerator.js +1 -0
  89. package/dist/render/fbm_wavegenerator.js.map +1 -1
  90. package/dist/render/gerstner_wavegenerator.js +1 -0
  91. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  92. package/dist/render/globalbindgroup_allocator.js +1 -0
  93. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  94. package/dist/render/render_queue.js +1 -0
  95. package/dist/render/render_queue.js.map +1 -1
  96. package/dist/render/sky.js +9 -0
  97. package/dist/render/sky.js.map +1 -1
  98. package/dist/scene/basesprite.js +1 -5
  99. package/dist/scene/basesprite.js.map +1 -1
  100. package/dist/scene/batchgroup.js +18 -8
  101. package/dist/scene/batchgroup.js.map +1 -1
  102. package/dist/scene/environment.js +16 -2
  103. package/dist/scene/environment.js.map +1 -1
  104. package/dist/scene/mesh.js +164 -102
  105. package/dist/scene/mesh.js.map +1 -1
  106. package/dist/scene/meshdrawable.js +96 -0
  107. package/dist/scene/meshdrawable.js.map +1 -0
  108. package/dist/scene/msdftext.js +341 -0
  109. package/dist/scene/msdftext.js.map +1 -0
  110. package/dist/scene/msdftextsprite.js +349 -0
  111. package/dist/scene/msdftextsprite.js.map +1 -0
  112. package/dist/scene/particlesys.js +1 -0
  113. package/dist/scene/particlesys.js.map +1 -1
  114. package/dist/scene/scene.js +2 -0
  115. package/dist/scene/scene.js.map +1 -1
  116. package/dist/scene/scene_node.js +437 -230
  117. package/dist/scene/scene_node.js.map +1 -1
  118. package/dist/scene/sdftextsprite.js +322 -0
  119. package/dist/scene/sdftextsprite.js.map +1 -0
  120. package/dist/scene/terrain-cm/grass.js +1 -0
  121. package/dist/scene/terrain-cm/grass.js.map +1 -1
  122. package/dist/scene/terrain-cm/grassmaterial.js +1 -0
  123. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  124. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  125. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  126. package/dist/scene/textsprite.js +120 -0
  127. package/dist/scene/textsprite.js.map +1 -0
  128. package/dist/scene/water.js +1 -0
  129. package/dist/scene/water.js.map +1 -1
  130. package/dist/shadow/shader.js +1 -0
  131. package/dist/shadow/shader.js.map +1 -1
  132. package/dist/text/font/font_asset.js +884 -0
  133. package/dist/text/font/font_asset.js.map +1 -0
  134. package/dist/text/font/sfnt_reader.js +43 -0
  135. package/dist/text/font/sfnt_reader.js.map +1 -0
  136. package/dist/text/msdf/generator.js +417 -0
  137. package/dist/text/msdf/generator.js.map +1 -0
  138. package/dist/text/msdf/shape.js +146 -0
  139. package/dist/text/msdf/shape.js.map +1 -0
  140. package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
  141. package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
  142. package/dist/text/runtime/msdf_text_atlas_manager.js +50 -0
  143. package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
  144. package/dist/text/runtime/text_layout.js +96 -0
  145. package/dist/text/runtime/text_layout.js.map +1 -0
  146. package/dist/utility/blueprint/material/inputs.js +188 -1
  147. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  148. package/dist/utility/blueprint/material/ir.js +16 -1
  149. package/dist/utility/blueprint/material/ir.js.map +1 -1
  150. package/dist/utility/blueprint/material/pbr.js +32 -0
  151. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  152. package/dist/utility/bounding_volume.js.map +1 -1
  153. package/dist/utility/pmrem.js +34 -8
  154. package/dist/utility/pmrem.js.map +1 -1
  155. package/dist/utility/serialization/manager.js +340 -283
  156. package/dist/utility/serialization/manager.js.map +1 -1
  157. package/dist/utility/serialization/scene/animation.js +702 -7
  158. package/dist/utility/serialization/scene/animation.js.map +1 -1
  159. package/dist/utility/serialization/scene/batch.js +2 -0
  160. package/dist/utility/serialization/scene/batch.js.map +1 -1
  161. package/dist/utility/serialization/scene/camera.js +2 -0
  162. package/dist/utility/serialization/scene/camera.js.map +1 -1
  163. package/dist/utility/serialization/scene/light.js +2 -0
  164. package/dist/utility/serialization/scene/light.js.map +1 -1
  165. package/dist/utility/serialization/scene/material.js +1 -0
  166. package/dist/utility/serialization/scene/material.js.map +1 -1
  167. package/dist/utility/serialization/scene/mesh.js +66 -4
  168. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  169. package/dist/utility/serialization/scene/node.js +189 -8
  170. package/dist/utility/serialization/scene/node.js.map +1 -1
  171. package/dist/utility/serialization/scene/particle.js +2 -0
  172. package/dist/utility/serialization/scene/particle.js.map +1 -1
  173. package/dist/utility/serialization/scene/primitive.js +1 -0
  174. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  175. package/dist/utility/serialization/scene/sprite.js +2 -0
  176. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  177. package/dist/utility/serialization/scene/terrain.js +2 -0
  178. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  179. package/dist/utility/serialization/scene/text.js +516 -0
  180. package/dist/utility/serialization/scene/text.js.map +1 -0
  181. package/dist/utility/serialization/scene/water.js +2 -0
  182. package/dist/utility/serialization/scene/water.js.map +1 -1
  183. package/dist/utility/serialization/types.js.map +1 -1
  184. package/dist/utility/textures/sheenlut.js +138 -0
  185. package/dist/utility/textures/sheenlut.js.map +1 -0
  186. package/dist/values.js +48 -48
  187. package/dist/values.js.map +1 -1
  188. package/package.json +3 -3
@@ -12,7 +12,7 @@ import { getSceneClass } from './scene/scene.js';
12
12
  import { getScriptAttachmentClass } from './scene/script.js';
13
13
  import { getTerrainClass } from './scene/terrain.js';
14
14
  import { getWaterClass, getFFTWaveGeneratorClass, getFBMWaveGeneratorClass } from './scene/water.js';
15
- import { getInterpolatorClass, getSkeletonClass, getAnimationClass, getPropTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getNodeEulerRotationTrackClass, getFixedGeometryCacheTrackClass, getPCAGeometryCacheTrackClass, getMorphTrackClass } from './scene/animation.js';
15
+ import { getInterpolatorClass, getSkeletonRigClass, getSkinBindingClass, getSkeletonClass, getJointDynamicsModifierClass, getAnimationClass, getPropTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getNodeEulerRotationTrackClass, getFixedGeometryCacheTrackClass, getPCAGeometryCacheTrackClass, getMorphTrackClass } from './scene/animation.js';
16
16
  import '../../scene/scene.js';
17
17
  import '../../values.js';
18
18
  import '../../render/render_queue.js';
@@ -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';
@@ -52,13 +54,14 @@ import '../../scene/terrain-cm/terrain-cm.js';
52
54
  import '../../scene/terrain-cm/grass.js';
53
55
  import '../../scene/raycast_visitor.js';
54
56
  import { AssetManager } from '../../asset/assetmanager.js';
55
- import '../../animation/eulerrotationtrack.js';
56
57
  import '../../animation/skeleton.js';
58
+ import '../../animation/eulerrotationtrack.js';
57
59
  import '../../animation/joint_dynamics/collision.js';
58
60
  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;
@@ -165,7 +168,10 @@ const defaultValues = {
165
168
  getScriptAttachmentClass(),
166
169
  getAABBClass(),
167
170
  getInterpolatorClass(),
171
+ getSkeletonRigClass(),
172
+ getSkinBindingClass(),
168
173
  getSkeletonClass(),
174
+ getJointDynamicsModifierClass(),
169
175
  getAnimationClass(this),
170
176
  getPropTrackClass(this),
171
177
  getNodeRotationTrackClass(),
@@ -179,6 +185,9 @@ const defaultValues = {
179
185
  getGraphNodeClass(),
180
186
  getMeshClass(),
181
187
  getSpriteClass(),
188
+ getTextSpriteClass(),
189
+ getMSDFTextSpriteClass(),
190
+ getMSDFTextClass(),
182
191
  getWaterClass(this),
183
192
  getTerrainClass(this),
184
193
  getFFTWaveGeneratorClass(),
@@ -292,6 +301,9 @@ const defaultValues = {
292
301
  Hash3Node.getSerializationCls(),
293
302
  SimplexNoise2DNode.getSerializationCls(),
294
303
  PerlinNoise2DNode.getSerializationCls(),
304
+ VertexOutputNode.getSerializationCls(),
305
+ VertexIndexNode.getSerializationCls(),
306
+ InstanceIndexNode.getSerializationCls(),
295
307
  VertexColorNode.getSerializationCls(),
296
308
  VertexUVNode.getSerializationCls(),
297
309
  VertexPositionNode.getSerializationCls(),
@@ -330,49 +342,49 @@ const defaultValues = {
330
342
  this.registerProps(k[1]);
331
343
  }
332
344
  }
333
- /**
334
- * The virtual file system used by this manager.
335
- *
336
- * @remarks
337
- * Used by asset fetchers and scene save/load operations.
345
+ /**
346
+ * The virtual file system used by this manager.
347
+ *
348
+ * @remarks
349
+ * Used by asset fetchers and scene save/load operations.
338
350
  */ get VFS() {
339
351
  return this._vfs;
340
352
  }
341
353
  set VFS(vfs) {
342
354
  this._vfs = vfs;
343
355
  }
344
- /**
345
- * Wethether editor mode is enabled
346
- *
347
- * @remarks
348
- * In editor mode, some properties will be disabled
356
+ /**
357
+ * Wethether editor mode is enabled
358
+ *
359
+ * @remarks
360
+ * In editor mode, some properties will be disabled
349
361
  */ get editorMode() {
350
362
  return this._editorMode;
351
363
  }
352
- /**
353
- * AssetManager
364
+ /**
365
+ * AssetManager
354
366
  */ get assetManager() {
355
367
  return this._assetManager;
356
368
  }
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.
369
+ /**
370
+ * Get the list of all registered serializable classes.
371
+ *
372
+ * @remarks
373
+ * Includes built-in classes registered during construction and any custom classes
374
+ * registered via `registerClass`.
375
+ *
376
+ * @returns An array of `SerializableClass` metadata.
365
377
  */ getClasses() {
366
378
  return [
367
379
  ...this._classMap.values()
368
380
  ];
369
381
  }
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.
382
+ /**
383
+ * Get serialization metadata by a constructor function.
384
+ *
385
+ * @param ctor - The class constructor to look up.
386
+ *
387
+ * @returns The `SerializableClass` metadata, or `null` if not found.
376
388
  */ getClassByConstructor(ctor) {
377
389
  let current = ctor;
378
390
  while(typeof current === 'function' && current !== Function.prototype){
@@ -384,21 +396,21 @@ const defaultValues = {
384
396
  }
385
397
  return null;
386
398
  }
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.
399
+ /**
400
+ * Get serialization metadata by an object instance.
401
+ *
402
+ * @param obj - The object whose constructor will be used for the lookup.
403
+ *
404
+ * @returns The `SerializableClass` metadata, or `null` if not found.
393
405
  */ getClassByObject(obj) {
394
406
  return this.getClassByConstructor(obj.constructor);
395
407
  }
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.
408
+ /**
409
+ * Get serialization metadata by class name.
410
+ *
411
+ * @param className - Fully qualified class name as stored in JSON.
412
+ *
413
+ * @returns The `SerializableClass` metadata, or `null` if not found.
402
414
  */ getClassByName(className) {
403
415
  for (const val of this._classMap){
404
416
  if (val[0].name === className) {
@@ -407,12 +419,12 @@ const defaultValues = {
407
419
  }
408
420
  return null;
409
421
  }
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.
422
+ /**
423
+ * Find the class that owns a given property accessor.
424
+ *
425
+ * @param prop - Property accessor to search for.
426
+ *
427
+ * @returns The `SerializableClass` that declares the property, or `null` if unknown.
416
428
  */ getClassByProperty(prop) {
417
429
  for (const k of this._clsPropMap){
418
430
  if (k[1].indexOf(prop) >= 0) {
@@ -421,21 +433,21 @@ const defaultValues = {
421
433
  }
422
434
  return null;
423
435
  }
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.
436
+ /**
437
+ * Get the properties declared on a given class.
438
+ *
439
+ * @param cls - Serializable class metadata.
440
+ *
441
+ * @returns An array of `PropertyAccessor` entries, or `null` if none.
430
442
  */ getPropertiesByClass(cls) {
431
443
  return this._clsPropMap.get(cls) ?? null;
432
444
  }
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.
445
+ /**
446
+ * Get all properties declared on a given class and its ancestors.
447
+ *
448
+ * @param cls - Serializable class metadata.
449
+ *
450
+ * @returns An array of `PropertyAccessor` entries, or `null` if none.
439
451
  */ getAllPropertiesByClass(cls) {
440
452
  const props = new Map();
441
453
  while(cls){
@@ -453,72 +465,72 @@ const defaultValues = {
453
465
  ...props.values()
454
466
  ];
455
467
  }
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.
468
+ /**
469
+ * Get a property accessor by class and property name.
470
+ *
471
+ * @param cls - Serializable class metadata.
472
+ * @param name - Property name to search for.
473
+ *
474
+ * @returns The `PropertyAccessor`, or `null` if not found.
463
475
  */ getPropertyByClass(cls, name) {
464
476
  return this.getPropertiesByClass(cls)?.find((value)=>value.name === name) ?? null;
465
477
  }
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.
478
+ /**
479
+ * Get a property accessor by its canonical path.
480
+ *
481
+ * @remarks
482
+ * The canonical path format is `/ClassName/propName`.
483
+ *
484
+ * @param name - Canonical property path.
485
+ *
486
+ * @returns The `PropertyAccessor`, or `null` if not found.
475
487
  */ getPropertyByName(name) {
476
488
  return this._propMap[name] ?? null;
477
489
  }
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.
490
+ /**
491
+ * Get the canonical path for a property accessor.
492
+ *
493
+ * @remarks
494
+ * Returns a string like `/ClassName/propName` if the property is registered.
495
+ *
496
+ * @param prop - Property accessor.
497
+ *
498
+ * @returns The canonical path, or `null` if unknown.
487
499
  */ getPropertyName(prop) {
488
500
  return this._propNameMap.get(prop) ?? null;
489
501
  }
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.
502
+ /**
503
+ * Register a serializable class and its properties.
504
+ *
505
+ * @remarks
506
+ * - No effect if the class is already registered.
507
+ * - Also registers the class's properties with canonical paths.
508
+ *
509
+ * @param cls - Serializable class metadata to register.
498
510
  */ registerClass(cls) {
499
511
  if (!this._classMap.has(cls.ctor)) {
500
512
  this._classMap.set(cls.ctor, cls);
501
513
  this.registerProps(cls);
502
514
  }
503
515
  }
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.
516
+ /**
517
+ * Get the known asset ID previously associated with a loaded/allocated asset.
518
+ *
519
+ * @remarks
520
+ * Returns `null` if the asset was not loaded or tracked by this manager.
521
+ *
522
+ * @param asset - Asset instance (e.g., texture, model group) to look up.
523
+ *
524
+ * @returns The asset ID string, or `null` if unknown.
513
525
  */ getAssetId(asset) {
514
526
  return this._allocated.get(asset) ?? null;
515
527
  }
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
- *
528
+ /**
529
+ * Associate an asset ID to a loaded/allocated asset.
530
+ *
531
+ * @param asset - Asset instance (e.g., texture, model group) to set Id.
532
+ * @param id - Asset ID to associated to this asset.
533
+ *
522
534
  */ setAssetId(asset, id) {
523
535
  if (asset) {
524
536
  if (id) {
@@ -528,35 +540,74 @@ const defaultValues = {
528
540
  }
529
541
  }
530
542
  }
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) {
542
- const data = await this._assetManager.fetchBinaryData(id);
543
+ /**
544
+ * Register a model loader.
545
+ *
546
+ * @param mimeType - What MIME type of files this loader can load
547
+ * @param loader - A concrete model loader implementation.
548
+ */ setModelLoader(mimeType, loader) {
549
+ this._assetManager.setModelLoader(mimeType, loader);
550
+ }
551
+ /**
552
+ * Fetch a binary asset by ID via the asset manager.
553
+ *
554
+ * @remarks
555
+ * - Associates the returned data with the given ID for future reverse lookup.
556
+ * - The ID is typically a VFS path or locator.
557
+ *
558
+ * @param path - VFS path of the binary asset.
559
+ *
560
+ * @returns A Promise that resolves to the binary content, or `null` if not found.
561
+ */ async fetchBinary(path, options) {
562
+ const id = this.VFS.normalizePath(path);
563
+ const data = await this._assetManager.fetchBinaryData(id, null, null, options);
543
564
  if (data) {
544
565
  this._allocated.set(data, id);
545
566
  }
546
567
  return data;
547
568
  }
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.
569
+ /**
570
+ * Fetch a text asset by ID via the asset manager.
571
+ *
572
+ * @param path - VFS path of TTF/OTF file.
573
+ * @returns A Promise that resolves to the font asset, or `null` if not found.
574
+ */ async fetchFontAsset(path, options) {
575
+ const id = this.VFS.normalizePath(path);
576
+ const fontAsset = await this._assetManager.fetchFontAsset(id, options);
577
+ if (fontAsset) {
578
+ this._allocated.set(fontAsset, id);
579
+ }
580
+ return fontAsset;
581
+ }
582
+ /**
583
+ * Get a cached font asset by ID if already loaded.
584
+ *
585
+ * @param path - VFS path of TTF/OTF file.
586
+ * @returns The cached FontAsset if it exists and is loaded, or null if not cached or still loading.
587
+ */ getFontAsset(path) {
588
+ return this._assetManager.getFontAsset(this.VFS.normalizePath(path));
589
+ }
590
+ /**
591
+ * Removes a cached font asset entry by asset instance or asset ID.
592
+ *
593
+ * @param asset - Loaded font asset instance or its asset ID/path.
594
+ * @returns `true` if a cache entry existed and was removed.
595
+ */ releaseFontAsset(asset) {
596
+ const path = typeof asset === 'string' ? asset : this.getAssetId(asset);
597
+ return path ? this._assetManager.releaseFontAsset(this.VFS.normalizePath(path)) : false;
598
+ }
599
+ /**
600
+ * Serialize an object to a JSON structure using registered class metadata.
601
+ *
602
+ * @remarks
603
+ * - Throws if the object's class is not registered.
604
+ * - Populates `asyncTasks` with pending I/O tasks for embedded resources.
605
+ *
606
+ * @param obj - The object to serialize.
607
+ * @param json - Optional existing JSON object to fill.
608
+ * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
609
+ *
610
+ * @returns The serialized JSON structure.
560
611
  */ async serializeObject(obj, json, asyncTasks) {
561
612
  if (obj === null || obj === undefined) {
562
613
  return obj;
@@ -582,14 +633,14 @@ const defaultValues = {
582
633
  }
583
634
  return json;
584
635
  }
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.
636
+ /**
637
+ * Serialize object properties into a JSON structure.
638
+ *
639
+ * @param obj - The target object to serialize.
640
+ * @param json - The JSON structure to populate.
641
+ * @param asyncTasks - Optional list to collect async tasks for embedded asset export.
642
+ * @param info - Optional serialization metadata for the object's class.
643
+ * @returns A Promise that resolves when serialization is complete.
593
644
  */ async serializeObjectProps(obj, json, asyncTasks, info) {
594
645
  if (!info) {
595
646
  const cls = this.getClasses();
@@ -606,17 +657,17 @@ const defaultValues = {
606
657
  }
607
658
  return json;
608
659
  }
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.
660
+ /**
661
+ * Deserialize a JSON structure into an object instance.
662
+ *
663
+ * @remarks
664
+ * - Uses the `ClassName` field to locate the registered class.
665
+ * - Supports custom `createFunc` and phased property loading.
666
+ *
667
+ * @param ctx - Context object passed to custom constructors/resolvers.
668
+ * @param json - The serialized JSON structure.
669
+ *
670
+ * @returns A Promise resolving to the reconstructed object instance, or `null` on failure.
620
671
  */ async deserializeObject(ctx, json) {
621
672
  const cls = this.getClasses();
622
673
  const className = json['ClassName'];
@@ -649,12 +700,12 @@ const defaultValues = {
649
700
  }
650
701
  return obj;
651
702
  }
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.
703
+ /**
704
+ * Deserialize object properties from JSON into an existing object instance.
705
+ *
706
+ * @param obj - The target object to populate.
707
+ * @param json - The JSON structure containing serialized properties.
708
+ * @param info - Optional serialization metadata for the object's class.
658
709
  */ async deserializeObjectProps(obj, json, info) {
659
710
  if (!info) {
660
711
  const cls = this.getClasses();
@@ -669,95 +720,100 @@ const defaultValues = {
669
720
  info = this.getClassByConstructor(info.parent);
670
721
  }
671
722
  }
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) {
723
+ /**
724
+ * Load a model by ID and track the allocation for reverse lookup.
725
+ *
726
+ * @param path - VFS path of the model file.
727
+ * @param scene - Scene into which the model is loaded.
728
+ * @param options - Optional model fetch options.
729
+ *
730
+ * @returns A Promise resolving to the loaded model object, or `null` if failed.
731
+ */ async fetchModel(path, scene, options) {
732
+ const id = this.VFS.normalizePath(path);
681
733
  const model = await this._assetManager.fetchModel(scene, id, options);
682
734
  if (model) {
683
- this._allocated.set(model.group, id);
735
+ model.prefabId = id;
736
+ this._allocated.set(model, id);
684
737
  }
685
738
  return model;
686
739
  }
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.
740
+ /**
741
+ * Load a texture directly from an ArrayBuffer or typed array.
742
+ *
743
+ * - Chooses an appropriate loader based on the provided MIME type.
744
+ * - Can upload into an existing texture if `texture` is specified.
745
+ *
746
+ * @typeParam T - Expected concrete texture type.
747
+ * @param arrayBuffer - Raw texture data buffer.
748
+ * @param mimeType - MIME type of the texture (must be supported by a registered loader).
749
+ * @param srgb - If true, treat image as sRGB; otherwise linear.
750
+ * @param samplerOptions - Optional sampler options passed to the loader path.
751
+ * @param texture - Optional destination texture to populate.
752
+ * @returns A promise that resolves to the created or populated texture.
700
753
  */ async loadTextureFromBuffer(arrayBuffer, mimeType, srgb, samplerOptions, texture) {
701
754
  return this._assetManager.loadTextureFromBuffer(arrayBuffer, mimeType, srgb, samplerOptions, texture);
702
755
  }
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) {
756
+ /**
757
+ * Load a texture by ID and track the allocation for reverse lookup.
758
+ *
759
+ * @param path - VFS path of the texture file.
760
+ * @param options - Optional texture fetch options.
761
+ *
762
+ * @returns A Promise resolving to the loaded texture, or `null` if failed.
763
+ */ async fetchTexture(path, options) {
764
+ const id = this.VFS.normalizePath(path);
711
765
  const texture = await this._assetManager.fetchTexture(id, options);
712
766
  if (texture) {
713
767
  this._allocated.set(texture, id);
714
768
  }
715
769
  return texture;
716
770
  }
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) {
724
- const material = await this._assetManager.fetchMaterial(id);
771
+ /**
772
+ * Load a material by ID and track the allocation for reverse lookup.
773
+ *
774
+ * @param path - VFS path of the material file.
775
+ *
776
+ * @returns A Promise resolving to the loaded material, or `null` if failed.
777
+ */ async fetchMaterial(path, options) {
778
+ const id = this.VFS.normalizePath(path);
779
+ const material = await this._assetManager.fetchMaterial(id, options);
725
780
  if (material) {
726
781
  this._allocated.set(material, id);
727
782
  }
728
783
  return material;
729
784
  }
730
- /**
731
- * Reload specific blue print materials
732
- *
733
- * @param filter - Determine whether a blue print material should reload.
734
- *
785
+ /**
786
+ * Reload specific blue print materials
787
+ *
788
+ * @param filter - Determine whether a blue print material should reload.
789
+ *
735
790
  */ async reloadBluePrintMaterials(filter) {
736
791
  await this._assetManager.reloadBluePrintMaterials(filter);
737
792
  }
738
- /**
739
- * Mark specific blue print as changed
740
- * @param path - BluePrint file path
793
+ /**
794
+ * Mark specific blue print as changed
795
+ * @param path - BluePrint file path
741
796
  */ invalidateBluePrint(path) {
742
797
  this._assetManager.invalidateBluePrint(path);
743
798
  }
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) {
751
- const primitive = await this._assetManager.fetchPrimitive(id);
799
+ /**
800
+ * Load a primitive by ID and track the allocation for reverse lookup.
801
+ *
802
+ * @param path - VFS path of the primitive file.
803
+ *
804
+ * @returns A Promise resolving to the loaded primitive, or `null` if failed.
805
+ */ async fetchPrimitive(path, options) {
806
+ const id = this.VFS.normalizePath(path);
807
+ const primitive = await this._assetManager.fetchPrimitive(id, options);
752
808
  if (primitive) {
753
809
  this._allocated.set(primitive, id);
754
810
  }
755
811
  return primitive;
756
812
  }
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.
813
+ /**
814
+ * Load a prefab content.
815
+ * @param path - Path to the prefab JSON file in VFS.
816
+ * @returns A Promise resolving to the prefab json object, or `null` on failure.
761
817
  */ async loadPrefabContent(path) {
762
818
  try {
763
819
  const content = await this._vfs.readFile(path, {
@@ -770,11 +826,11 @@ const defaultValues = {
770
826
  return null;
771
827
  }
772
828
  }
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.
829
+ /**
830
+ * Instantiate a prefab from a JSON file via VFS.
831
+ * @param parent - Parent node to attach the instantiated prefab to.
832
+ * @param path - Path to the prefab JSON file in VFS.
833
+ * @returns A Promise resolving to the instantiated `SceneNode`, or `null` on failure.
778
834
  */ async instantiatePrefab(parent, path) {
779
835
  try {
780
836
  const json = await this.loadPrefabContent(path);
@@ -786,6 +842,7 @@ const defaultValues = {
786
842
  node.prefabId = tmpNode.get().prefabId;
787
843
  node.parent = parent;
788
844
  node.persistentId = randomUUID();
845
+ node.animationSet.resetSkeletonModifiers();
789
846
  tmpNode.dispose();
790
847
  return node;
791
848
  } catch (err) {
@@ -793,16 +850,16 @@ const defaultValues = {
793
850
  return null;
794
851
  }
795
852
  }
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`.
853
+ /**
854
+ * Load a scene from a JSON file via VFS.
855
+ *
856
+ * @remarks
857
+ * - Deserializes the scene graph.
858
+ * - Attaches scripts referenced by nodes after load (asynchronous).
859
+ *
860
+ * @param filename - Path to the scene JSON file in VFS.
861
+ *
862
+ * @returns A Promise resolving to the loaded `Scene`.
806
863
  */ async loadScene(filename) {
807
864
  const content = await this._vfs.readFile(filename, {
808
865
  encoding: 'utf8'
@@ -810,15 +867,15 @@ const defaultValues = {
810
867
  const json = JSON.parse(content);
811
868
  return await this.deserializeObject(null, json);
812
869
  }
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.
870
+ /**
871
+ * Save a scene to a JSON file via VFS.
872
+ *
873
+ * @remarks
874
+ * - Collects async export tasks for embedded resources and awaits them.
875
+ * - Writes a UTF-8 JSON representation to VFS.
876
+ *
877
+ * @param scene - Scene to serialize and save.
878
+ * @param filename - Destination path in VFS.
822
879
  */ async saveScene(scene, filename) {
823
880
  const asyncTasks = [];
824
881
  const content = await this.serializeObject(scene, null, asyncTasks);
@@ -950,11 +1007,11 @@ const defaultValues = {
950
1007
  async loadBluePrint(path) {
951
1008
  return this._assetManager.loadBluePrint(path);
952
1009
  }
953
- /**
954
- * Clear cached allocations and asset-manager caches.
955
- *
956
- * @remarks
957
- * Useful when reloading content or changing VFS mounts.
1010
+ /**
1011
+ * Clear cached allocations and asset-manager caches.
1012
+ *
1013
+ * @remarks
1014
+ * Useful when reloading content or changing VFS mounts.
958
1015
  */ clearCache() {
959
1016
  this._allocated = new WeakMap();
960
1017
  this._assetManager.clearCache();
@@ -973,18 +1030,18 @@ const defaultValues = {
973
1030
  }
974
1031
  return null;
975
1032
  }
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.
1033
+ /**
1034
+ * Find the object targeted by an animation track starting from a node.
1035
+ *
1036
+ * @remarks
1037
+ * - Parses a target path like `prop/subprop[0]/child` where indexed entries
1038
+ * require `object_array` type and non-indexed entries require `object` type.
1039
+ * - Returns `null` if any segment cannot be resolved through registered metadata.
1040
+ *
1041
+ * @param node - Root node used as the starting point.
1042
+ * @param track - Property track containing a target path.
1043
+ *
1044
+ * @returns The resolved target object, or `null` if not found.
988
1045
  */ findAnimationTarget(node, track) {
989
1046
  const target = track.target ?? '';
990
1047
  const value = {