@zephyr3d/scene 0.9.24 → 0.9.26

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 (264) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4040 -1290
  42. package/dist/index.js +16 -6
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +766 -456
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cluster_light.js +4 -4
  122. package/dist/render/cluster_light.js.map +1 -1
  123. package/dist/render/cull_visitor.js +19 -0
  124. package/dist/render/cull_visitor.js.map +1 -1
  125. package/dist/render/depthpass.js +36 -2
  126. package/dist/render/depthpass.js.map +1 -1
  127. package/dist/render/drawable_mixin.js +26 -1
  128. package/dist/render/drawable_mixin.js.map +1 -1
  129. package/dist/render/dualdepthpeeling_oit.js +52 -51
  130. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  131. package/dist/render/envlight.js +1 -1
  132. package/dist/render/envlight.js.map +1 -1
  133. package/dist/render/fbm_wavegenerator.js +3 -0
  134. package/dist/render/fbm_wavegenerator.js.map +1 -1
  135. package/dist/render/gerstner_wavegenerator.js +3 -0
  136. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  137. package/dist/render/globalbindgroup_allocator.js +3 -0
  138. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  139. package/dist/render/oit.js +29 -0
  140. package/dist/render/oit.js.map +1 -0
  141. package/dist/render/render_queue.js +3 -0
  142. package/dist/render/render_queue.js.map +1 -1
  143. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  144. package/dist/render/rendergraph/executor.js +2 -0
  145. package/dist/render/rendergraph/executor.js.map +1 -1
  146. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  147. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  148. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  149. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  150. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  151. package/dist/render/rendergraph/types.js.map +1 -1
  152. package/dist/render/shadow_mask_pass.js +73 -8
  153. package/dist/render/shadow_mask_pass.js.map +1 -1
  154. package/dist/render/sky.js +166 -126
  155. package/dist/render/sky.js.map +1 -1
  156. package/dist/render/weightedblended_oit.js +36 -35
  157. package/dist/render/weightedblended_oit.js.map +1 -1
  158. package/dist/scene/basesprite.js +8 -0
  159. package/dist/scene/basesprite.js.map +1 -1
  160. package/dist/scene/batchgroup.js +3 -0
  161. package/dist/scene/batchgroup.js.map +1 -1
  162. package/dist/scene/environment.js +4 -1
  163. package/dist/scene/environment.js.map +1 -1
  164. package/dist/scene/hair.js +963 -0
  165. package/dist/scene/hair.js.map +1 -0
  166. package/dist/scene/light.js +5 -1
  167. package/dist/scene/light.js.map +1 -1
  168. package/dist/scene/mesh.js +481 -47
  169. package/dist/scene/mesh.js.map +1 -1
  170. package/dist/scene/meshdrawable.js +6 -0
  171. package/dist/scene/meshdrawable.js.map +1 -1
  172. package/dist/scene/msdftext.js +3 -0
  173. package/dist/scene/msdftext.js.map +1 -1
  174. package/dist/scene/msdftextsprite.js +3 -0
  175. package/dist/scene/msdftextsprite.js.map +1 -1
  176. package/dist/scene/particlesys.js +6 -0
  177. package/dist/scene/particlesys.js.map +1 -1
  178. package/dist/scene/scene.js +3 -0
  179. package/dist/scene/scene.js.map +1 -1
  180. package/dist/scene/scene_node.js +6 -1
  181. package/dist/scene/scene_node.js.map +1 -1
  182. package/dist/scene/terrain-cm/grass.js +273 -249
  183. package/dist/scene/terrain-cm/grass.js.map +1 -1
  184. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  185. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  186. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  187. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  188. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  189. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  190. package/dist/scene/water.js +6 -0
  191. package/dist/scene/water.js.map +1 -1
  192. package/dist/shaders/atmosphere.js.map +1 -1
  193. package/dist/shaders/diffusion.js +54 -0
  194. package/dist/shaders/diffusion.js.map +1 -0
  195. package/dist/shaders/shadow.js +33 -21
  196. package/dist/shaders/shadow.js.map +1 -1
  197. package/dist/shaders/temporal.js +71 -33
  198. package/dist/shaders/temporal.js.map +1 -1
  199. package/dist/shadow/dom.js +546 -0
  200. package/dist/shadow/dom.js.map +1 -0
  201. package/dist/shadow/pcf_opt.js +3 -5
  202. package/dist/shadow/pcf_opt.js.map +1 -1
  203. package/dist/shadow/pcf_pd.js +1 -1
  204. package/dist/shadow/pcf_pd.js.map +1 -1
  205. package/dist/shadow/receiver_bias.js +41 -0
  206. package/dist/shadow/receiver_bias.js.map +1 -0
  207. package/dist/shadow/shader.js +20 -60
  208. package/dist/shadow/shader.js.map +1 -1
  209. package/dist/shadow/shadow_impl.js +89 -0
  210. package/dist/shadow/shadow_impl.js.map +1 -1
  211. package/dist/shadow/shadow_region.js +50 -50
  212. package/dist/shadow/shadow_region.js.map +1 -1
  213. package/dist/shadow/shadowmapper.js +150 -37
  214. package/dist/shadow/shadowmapper.js.map +1 -1
  215. package/dist/shapes/shape.js +11 -2
  216. package/dist/shapes/shape.js.map +1 -1
  217. package/dist/shapes/sphere.js +50 -9
  218. package/dist/shapes/sphere.js.map +1 -1
  219. package/dist/utility/blueprint/common/constants.js +112 -2
  220. package/dist/utility/blueprint/common/constants.js.map +1 -1
  221. package/dist/utility/blueprint/material/func.js +142 -49
  222. package/dist/utility/blueprint/material/func.js.map +1 -1
  223. package/dist/utility/blueprint/material/ir.js +490 -25
  224. package/dist/utility/blueprint/material/ir.js.map +1 -1
  225. package/dist/utility/blueprint/material/texture.js +898 -4
  226. package/dist/utility/blueprint/material/texture.js.map +1 -1
  227. package/dist/utility/serialization/manager.js +431 -100
  228. package/dist/utility/serialization/manager.js.map +1 -1
  229. package/dist/utility/serialization/scene/animation.js +370 -3
  230. package/dist/utility/serialization/scene/animation.js.map +1 -1
  231. package/dist/utility/serialization/scene/batch.js +4 -0
  232. package/dist/utility/serialization/scene/batch.js.map +1 -1
  233. package/dist/utility/serialization/scene/camera.js +133 -1
  234. package/dist/utility/serialization/scene/camera.js.map +1 -1
  235. package/dist/utility/serialization/scene/common.js +26 -5
  236. package/dist/utility/serialization/scene/common.js.map +1 -1
  237. package/dist/utility/serialization/scene/hair.js +1141 -0
  238. package/dist/utility/serialization/scene/hair.js.map +1 -0
  239. package/dist/utility/serialization/scene/light.js +84 -4
  240. package/dist/utility/serialization/scene/light.js.map +1 -1
  241. package/dist/utility/serialization/scene/material.js +1867 -166
  242. package/dist/utility/serialization/scene/material.js.map +1 -1
  243. package/dist/utility/serialization/scene/mesh.js +231 -14
  244. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  245. package/dist/utility/serialization/scene/node.js +141 -7
  246. package/dist/utility/serialization/scene/node.js.map +1 -1
  247. package/dist/utility/serialization/scene/particle.js +4 -0
  248. package/dist/utility/serialization/scene/particle.js.map +1 -1
  249. package/dist/utility/serialization/scene/primitive.js +18 -0
  250. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  251. package/dist/utility/serialization/scene/sprite.js +4 -0
  252. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  253. package/dist/utility/serialization/scene/terrain.js +92 -69
  254. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  255. package/dist/utility/serialization/scene/text.js +4 -0
  256. package/dist/utility/serialization/scene/text.js.map +1 -1
  257. package/dist/utility/serialization/scene/water.js +4 -0
  258. package/dist/utility/serialization/scene/water.js.map +1 -1
  259. package/dist/utility/serialization/types.js.map +1 -1
  260. package/dist/utility/shprojector.js +96 -95
  261. package/dist/utility/shprojector.js.map +1 -1
  262. package/dist/values.js +105 -58
  263. package/dist/values.js.map +1 -1
  264. package/package.json +3 -3
@@ -1,18 +1,19 @@
1
- import { ASSERT, DRef, randomUUID } from '@zephyr3d/base';
1
+ import { DWeakRef, ASSERT, DRef, randomUUID } from '@zephyr3d/base';
2
2
  import { getAABBClass } from './scene/misc.js';
3
3
  import { getSceneNodeClass, getGraphNodeClass } from './scene/node.js';
4
4
  import { getBatchGroupClass } from './scene/batch.js';
5
5
  import { getCameraClass, getPerspectiveCameraClass, getOrthoCameraClass } from './scene/camera.js';
6
6
  import { getPunctualLightClass, getDirectionalLightClass, getSpotLightClass, getPointLightClass, getRectLightClass } from './scene/light.js';
7
- import { getSubsurfaceProfileClass, getMeshMaterialClass, getPBRBluePrintMaterialClass, getSpriteBlueprintMaterialClass, getUnlitMaterialClass, getMToonMaterialClass, getLambertMaterialClass, getBlinnMaterialClass, getSkinMaterialClass, getPBRMetallicRoughnessMaterialClass, getPBRSpecularGlossinessMaterialClass, getParticleMaterialClass, getSpriteMaterialClass, getStandardSpriteMaterialClass } from './scene/material.js';
7
+ import { getSubsurfaceProfileClass, getMeshMaterialClass, getPBRBluePrintMaterialClass, getPBRBluePrintMaterialInstanceClass, getSpriteBlueprintMaterialClass, getUnlitMaterialClass, getMToonMaterialClass, getLambertMaterialClass, getBlinnMaterialClass, getHairMaterialClass, getSkinMaterialClass, getEyeMaterialClass, getPBRMetallicRoughnessMaterialClass, getPBRSpecularGlossinessMaterialClass, getParticleMaterialClass, getSpriteMaterialClass, getStandardSpriteMaterialClass } from './scene/material.js';
8
8
  import { getMeshClass } from './scene/mesh.js';
9
9
  import { getParticleNodeClass } from './scene/particle.js';
10
10
  import { getBoxShapeClass, getBoxFrameShapeClass, getCapsuleShapeClass, getSphereShapeClass, getTorusShapeClass, getCylinderShapeClass, getPlaneShapeClass, getTetrahedronShapeClass } from './scene/primitive.js';
11
11
  import { getSceneClass } from './scene/scene.js';
12
12
  import { getTerrainClass } from './scene/terrain.js';
13
13
  import { getWaterClass, getFFTWaveGeneratorClass, getFBMWaveGeneratorClass } from './scene/water.js';
14
+ import { getHairNodeClass } from './scene/hair.js';
14
15
  import { getTextSpriteClass, getMSDFTextSpriteClass, getMSDFTextClass } from './scene/text.js';
15
- import { getInterpolatorClass, getInterpolatorScalarClass, getSkeletonClass, getSkeletonRigClass, getSkinBindingClass, getJointDynamicsModifierClass, getAnimationClass, getPropTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getNodeEulerRotationTrackClass, getFixedGeometryCacheTrackClass, getPCAGeometryCacheTrackClass, getMorphTrackClass, getMorphTargetGroupTrackClass } from './scene/animation.js';
16
+ import { getInterpolatorClass, getInterpolatorScalarClass, getSkeletonClass, getSkeletonRigClass, getSkinBindingClass, getJointDynamicsModifierClass, getSpringModifierClass, getAnimationClass, getPropTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getNodeEulerRotationTrackClass, getFixedGeometryCacheTrackClass, getPCAGeometryCacheTrackClass, getMorphTrackClass, getMorphTargetGroupTrackClass } from './scene/animation.js';
16
17
  import '../../scene/scene.js';
17
18
  import '../../values.js';
18
19
  import '../../render/render_queue.js';
@@ -25,18 +26,22 @@ import '../../material/unlit.js';
25
26
  import '../../material/particle.js';
26
27
  import '../../material/subsurfaceprofile.js';
27
28
  import '../../material/skin.js';
29
+ import '../../material/eye.js';
30
+ import { Material } from '../../material/material.js';
28
31
  import '../../material/meshmaterial.js';
32
+ import '../../material/hair.js';
33
+ import '../../material/hairstrand.js';
29
34
  import '../../material/grassmaterial.js';
30
35
  import '../../material/terrain-cm.js';
31
36
  import '../../material/pbrmr.js';
32
37
  import '../../material/pbrsg.js';
33
38
  import '../../material/mtoon.js';
34
- import '../../material/pbrblueprint.js';
39
+ import { PBRBluePrintMaterial } from '../../material/pbrblueprint.js';
35
40
  import '../../material/sprite.js';
36
41
  import '../../material/sprite_std.js';
37
42
  import { PBRBlockNode, SpriteBlockNode, VertexBlockNode } from '../blueprint/material/pbr.js';
38
43
  import { ConstantScalarNode, ConstantVec2Node, ConstantVec3Node, ConstantVec4Node, ConstantBooleanNode, ConstantBVec2Node, ConstantBVec3Node, ConstantBVec4Node } from '../blueprint/common/constants.js';
39
- import { ConstantTexture2DNode, ConstantTexture2DArrayNode, ConstantTextureCubeNode, PannerNode, TextureSampleNode } from '../blueprint/material/texture.js';
44
+ import { ConstantTexture2DNode, ConstantTexture2DArrayNode, ConstantTextureCubeNode, ChannelSDFMaskNode, MorphBlurNode, PannerNode, TexturePropertyNode, TextureSampleNode } from '../blueprint/material/texture.js';
40
45
  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';
41
46
  import { VertexColorNode, VertexUVNode, VertexPositionNode, PixelWorldPositionNode, VertexNormalNode, PixelNormalNode, VertexTangentNode, VertexBinormalNode, ViewMatrixNode, ProjectionMatrixNode, ViewProjMatrixNode, InvProjMatrixNode, InvViewProjMatrixNode, BillboardMatrixNode, CameraPositionNode, CameraVectorNode, CameraNearFarNode, SkyEnvTextureNode, ElapsedTimeNode, ResolveVertexPositionNode, ResolveVertexTangentNode, ResolveVertexNormalNode, VertexOutputNode, VertexIndexNode, InstanceIndexNode } from '../blueprint/material/inputs.js';
42
47
  import { FunctionInputNode, FunctionOutputNode, FunctionCallNode } from '../blueprint/material/func.js';
@@ -55,6 +60,7 @@ import '../../scene/meshdrawable.js';
55
60
  import '../../scene/basesprite.js';
56
61
  import '../../material/msdf_text.js';
57
62
  import '../../scene/water.js';
63
+ import '../../scene/hair.js';
58
64
  import '../../scene/particlesys.js';
59
65
  import '../../scene/batchgroup.js';
60
66
  import '../../scene/terrain-cm/terrain-cm.js';
@@ -154,6 +160,8 @@ const defaultValues = {
154
160
  _assetManager;
155
161
  _editorMode;
156
162
  _allocated;
163
+ _materialsByAssetId;
164
+ _prefabContentCache;
157
165
  /**
158
166
  * Create a ResourceManager bound to a virtual file system.
159
167
  *
@@ -162,6 +170,8 @@ const defaultValues = {
162
170
  this._vfs = vfs;
163
171
  this._editorMode = editorMode;
164
172
  this._allocated = new WeakMap();
173
+ this._materialsByAssetId = new Map();
174
+ this._prefabContentCache = null;
165
175
  this._assetManager = new AssetManager(this);
166
176
  this._propMap = {};
167
177
  this._propNameMap = new Map();
@@ -181,6 +191,7 @@ const defaultValues = {
181
191
  getSkeletonRigClass(),
182
192
  getSkinBindingClass(),
183
193
  getJointDynamicsModifierClass(),
194
+ getSpringModifierClass(),
184
195
  getAnimationClass(this),
185
196
  getPropTrackClass(this),
186
197
  getNodeRotationTrackClass(),
@@ -193,12 +204,13 @@ const defaultValues = {
193
204
  getMorphTargetGroupTrackClass(),
194
205
  getSceneNodeClass(this),
195
206
  getGraphNodeClass(),
196
- getMeshClass(),
207
+ getMeshClass(this),
197
208
  getSpriteClass(),
198
209
  getTextSpriteClass(),
199
210
  getMSDFTextSpriteClass(),
200
211
  getMSDFTextClass(),
201
212
  getWaterClass(this),
213
+ getHairNodeClass(),
202
214
  getTerrainClass(this),
203
215
  getFFTWaveGeneratorClass(),
204
216
  getFBMWaveGeneratorClass(),
@@ -216,12 +228,15 @@ const defaultValues = {
216
228
  getSubsurfaceProfileClass(),
217
229
  ...getMeshMaterialClass(),
218
230
  ...getPBRBluePrintMaterialClass(),
231
+ ...getPBRBluePrintMaterialInstanceClass(),
219
232
  ...getSpriteBlueprintMaterialClass(),
220
233
  ...getUnlitMaterialClass(this),
221
234
  ...getMToonMaterialClass(this),
222
235
  ...getLambertMaterialClass(this),
223
236
  ...getBlinnMaterialClass(this),
237
+ ...getHairMaterialClass(this),
224
238
  ...getSkinMaterialClass(this),
239
+ ...getEyeMaterialClass(this),
225
240
  ...getPBRMetallicRoughnessMaterialClass(this),
226
241
  ...getPBRSpecularGlossinessMaterialClass(this),
227
242
  ...getParticleMaterialClass(this),
@@ -342,11 +357,14 @@ const defaultValues = {
342
357
  FunctionInputNode.getSerializationCls(),
343
358
  FunctionOutputNode.getSerializationCls(),
344
359
  FunctionCallNode.getSerializationCls(this),
360
+ ChannelSDFMaskNode.getSerializationCls(),
361
+ MorphBlurNode.getSerializationCls(),
345
362
  PannerNode.getSerializationCls(),
346
- TextureSampleNode.getSerializationCls(),
347
363
  VertexOutputNode.getSerializationCls(),
348
364
  VertexIndexNode.getSerializationCls(),
349
- InstanceIndexNode.getSerializationCls()
365
+ InstanceIndexNode.getSerializationCls(),
366
+ TexturePropertyNode.getSerializationCls(),
367
+ TextureSampleNode.getSerializationCls()
350
368
  ].map((val)=>[
351
369
  val.ctor,
352
370
  val
@@ -354,6 +372,7 @@ const defaultValues = {
354
372
  for (const k of this._classMap){
355
373
  this.registerProps(k[1]);
356
374
  }
375
+ this._vfs.on('changed', this.handleVFSChanged, this);
357
376
  }
358
377
  /**
359
378
  * The virtual file system used by this manager.
@@ -364,7 +383,12 @@ const defaultValues = {
364
383
  return this._vfs;
365
384
  }
366
385
  set VFS(vfs) {
367
- this._vfs = vfs;
386
+ if (vfs !== this._vfs) {
387
+ this._vfs?.off('changed', this.handleVFSChanged, this);
388
+ this._vfs = vfs;
389
+ this.clearCache();
390
+ this._vfs?.on('changed', this.handleVFSChanged, this);
391
+ }
368
392
  }
369
393
  /**
370
394
  * Wethether editor mode is enabled
@@ -526,13 +550,224 @@ const defaultValues = {
526
550
  *
527
551
  */ setAssetId(asset, id) {
528
552
  if (asset) {
553
+ const material = asset instanceof Material ? asset : null;
554
+ const prevId = material ? this.getAssetId(material) : null;
555
+ if (material && prevId && prevId !== id) {
556
+ this.unregisterMaterialReference(prevId, material);
557
+ }
529
558
  if (id) {
530
559
  this._allocated.set(asset, id);
560
+ if (material) {
561
+ this.registerMaterialReference(id, material);
562
+ }
531
563
  } else {
532
564
  this._allocated.delete(asset);
533
565
  }
534
566
  }
535
567
  }
568
+ getMaterialRefsByAssetId(id) {
569
+ return this._materialsByAssetId.get(id) ?? null;
570
+ }
571
+ /** @internal */ getTrackedMaterialAssetIds() {
572
+ const ids = [];
573
+ for (const [id, refs] of this._materialsByAssetId){
574
+ for (const ref of [
575
+ ...refs
576
+ ]){
577
+ const material = ref.get();
578
+ if (!material || material.disposed) {
579
+ ref.dispose();
580
+ refs.delete(ref);
581
+ }
582
+ }
583
+ if (refs.size === 0) {
584
+ this._materialsByAssetId.delete(id);
585
+ } else {
586
+ ids.push(id);
587
+ }
588
+ }
589
+ return ids;
590
+ }
591
+ syncMaterialReferences(source) {
592
+ const id = this.getAssetId(source);
593
+ if (!id) {
594
+ return;
595
+ }
596
+ const refs = this._materialsByAssetId.get(id);
597
+ if (!refs) {
598
+ return;
599
+ }
600
+ for (const ref of [
601
+ ...refs
602
+ ]){
603
+ const material = ref.get();
604
+ if (!material || material.disposed) {
605
+ ref.dispose();
606
+ refs.delete(ref);
607
+ } else if (material !== source && material.constructor === source.constructor) {
608
+ const instance = material;
609
+ if (instance.$isInstance && instance.getInstancedUniforms) {
610
+ const coreMaterial = instance.coreMaterial;
611
+ if (coreMaterial && coreMaterial !== source && coreMaterial.constructor === source.constructor) {
612
+ coreMaterial.copyFrom(source);
613
+ }
614
+ for (const { prop } of instance.getInstancedUniforms()){
615
+ instance[prop] = source[prop];
616
+ }
617
+ } else {
618
+ material.copyFrom(source);
619
+ }
620
+ }
621
+ }
622
+ if (refs.size === 0) {
623
+ this._materialsByAssetId.delete(id);
624
+ }
625
+ }
626
+ syncMaterialUniformReferences(source) {
627
+ const id = this.getAssetId(source);
628
+ if (!id) {
629
+ return;
630
+ }
631
+ const refs = this._materialsByAssetId.get(id);
632
+ if (!refs) {
633
+ return;
634
+ }
635
+ const synced = new Set();
636
+ for (const ref of [
637
+ ...refs
638
+ ]){
639
+ const material = ref.get();
640
+ if (!material || material.disposed) {
641
+ ref.dispose();
642
+ refs.delete(ref);
643
+ continue;
644
+ }
645
+ const runtimeInstance = material;
646
+ const target = runtimeInstance.$isInstance ? runtimeInstance.coreMaterial : material;
647
+ if (!target || target === source || synced.has(target) || !(target instanceof PBRBluePrintMaterial) || target.constructor !== source.constructor) {
648
+ continue;
649
+ }
650
+ synced.add(target);
651
+ const targetWithOverrides = target;
652
+ if (targetWithOverrides.setOverrides) {
653
+ targetWithOverrides.setOverrides(source.uniformValues, source.uniformTextures);
654
+ } else {
655
+ target.uniformValues = source.uniformValues;
656
+ target.uniformTextures = source.uniformTextures;
657
+ }
658
+ target.uniformChanged();
659
+ }
660
+ if (refs.size === 0) {
661
+ this._materialsByAssetId.delete(id);
662
+ }
663
+ }
664
+ async syncMaterialPropertyReferences(source, prop) {
665
+ const id = this.getAssetId(source);
666
+ const refs = id ? this._materialsByAssetId.get(id) : null;
667
+ if (!refs || !prop.get || !prop.set) {
668
+ return;
669
+ }
670
+ const sourceValue = {
671
+ num: [
672
+ 0,
673
+ 0,
674
+ 0,
675
+ 0
676
+ ],
677
+ str: [
678
+ ''
679
+ ],
680
+ bool: [
681
+ false
682
+ ],
683
+ object: [
684
+ null
685
+ ]
686
+ };
687
+ prop.get.call(source, sourceValue);
688
+ const tasks = [];
689
+ for (const ref of [
690
+ ...refs
691
+ ]){
692
+ const material = ref.get();
693
+ if (!material || material.disposed) {
694
+ ref.dispose();
695
+ refs.delete(ref);
696
+ continue;
697
+ }
698
+ if (material === source || material.constructor !== source.constructor) {
699
+ continue;
700
+ }
701
+ const instance = material;
702
+ const isInstanceUniform = !!instance.$isInstance && !!instance.getInstancedUniforms?.().some((uniform)=>uniform.name === prop.name);
703
+ const target = instance.$isInstance && !isInstanceUniform ? instance.coreMaterial : material;
704
+ if (!target || target === source || target.constructor !== source.constructor) {
705
+ continue;
706
+ }
707
+ const value = {
708
+ num: [
709
+ ...sourceValue.num
710
+ ],
711
+ str: [
712
+ ...sourceValue.str
713
+ ],
714
+ bool: [
715
+ ...sourceValue.bool
716
+ ],
717
+ object: [
718
+ ...sourceValue.object
719
+ ]
720
+ };
721
+ tasks.push(Promise.resolve(prop.set.call(target, value)));
722
+ }
723
+ await Promise.all(tasks);
724
+ if (refs.size === 0) {
725
+ this._materialsByAssetId.delete(id);
726
+ }
727
+ }
728
+ trackMaterialReference(material, id) {
729
+ if (!material || !id) {
730
+ return;
731
+ }
732
+ this.setAssetId(material, id);
733
+ }
734
+ registerMaterialReference(id, material) {
735
+ let refs = this._materialsByAssetId.get(id);
736
+ if (!refs) {
737
+ refs = new Set();
738
+ this._materialsByAssetId.set(id, refs);
739
+ }
740
+ for (const ref of [
741
+ ...refs
742
+ ]){
743
+ const obj = ref.get();
744
+ if (!obj) {
745
+ ref.dispose();
746
+ refs.delete(ref);
747
+ } else if (obj === material) {
748
+ return;
749
+ }
750
+ }
751
+ refs.add(new DWeakRef(material));
752
+ }
753
+ unregisterMaterialReference(id, material) {
754
+ const refs = this._materialsByAssetId.get(id);
755
+ if (!refs) {
756
+ return;
757
+ }
758
+ for (const ref of [
759
+ ...refs
760
+ ]){
761
+ const obj = ref.get();
762
+ if (!obj || obj === material) {
763
+ ref.dispose();
764
+ refs.delete(ref);
765
+ }
766
+ }
767
+ if (refs.size === 0) {
768
+ this._materialsByAssetId.delete(id);
769
+ }
770
+ }
536
771
  /**
537
772
  * Fetch a binary asset by ID via the asset manager.
538
773
  *
@@ -540,13 +775,31 @@ const defaultValues = {
540
775
  * - Associates the returned data with the given ID for future reverse lookup.
541
776
  * - The ID is typically a VFS path or locator.
542
777
  *
543
- * @param id - Asset identifier or path.
778
+ * @param path - VFS path.
779
+ * @param options - Optional fetch options
544
780
  *
545
781
  * @returns A Promise that resolves to the binary content, or `null` if not found.
546
- */ async fetchBinary(id) {
547
- const data = await this._assetManager.fetchBinaryData(id);
782
+ */ async fetchBinary(path, options) {
783
+ const data = await this._assetManager.fetchBinaryData(path, null, null, options);
548
784
  if (data) {
549
- this._allocated.set(data, id);
785
+ this._allocated.set(data, path);
786
+ }
787
+ return data;
788
+ }
789
+ /**
790
+ * Fetch a JSON resource via VFS.
791
+ *
792
+ * - Parses as JSON after text load.
793
+ * - Cached per resolved URL. Post-process is applied only on the first load for a given cache key.
794
+ *
795
+ * @param path - Resource URL or VFS path.
796
+ * @param options - Optional fetch options
797
+ *
798
+ * @returns A promise that resolves to the loaded JSON value.
799
+ */ async fetchJsonData(path, options) {
800
+ const data = await this._assetManager.fetchJsonData(path, null, null, options);
801
+ if (data) {
802
+ this._allocated.set(data, path);
550
803
  }
551
804
  return data;
552
805
  }
@@ -730,11 +983,18 @@ const defaultValues = {
730
983
  */ async fetchMaterial(id, options) {
731
984
  const material = await this._assetManager.fetchMaterial(id, options);
732
985
  if (material) {
733
- this._allocated.set(material, id);
986
+ this.setAssetId(material, id);
734
987
  }
735
988
  return material;
736
989
  }
737
990
  /**
991
+ * Remove one material from the asset cache.
992
+ *
993
+ * @param id - Material identifier or path.
994
+ */ invalidateMaterial(id) {
995
+ this._assetManager.invalidateMaterial(id);
996
+ }
997
+ /**
738
998
  * Reload specific blue print materials
739
999
  *
740
1000
  * @param filter - Determine whether a blue print material should reload.
@@ -792,16 +1052,25 @@ const defaultValues = {
792
1052
  * @param path - Path to the prefab JSON file in VFS.
793
1053
  * @returns A Promise resolving to the prefab json object, or `null` on failure.
794
1054
  */ async loadPrefabContent(path) {
795
- try {
796
- const content = await this._vfs.readFile(path, {
797
- encoding: 'utf8'
798
- });
799
- const json = JSON.parse(content);
800
- return json;
801
- } catch (err) {
802
- console.error(`Failed to load prefab from ${path}:`, err);
803
- return null;
1055
+ const normalizedPath = this._vfs.normalizePath(path);
1056
+ const cached = this._prefabContentCache?.get(normalizedPath);
1057
+ if (cached) {
1058
+ return cached;
804
1059
  }
1060
+ const loadTask = (async ()=>{
1061
+ try {
1062
+ const content = await this._vfs.readFile(normalizedPath, {
1063
+ encoding: 'utf8'
1064
+ });
1065
+ const json = JSON.parse(content);
1066
+ return json;
1067
+ } catch (err) {
1068
+ console.error(`Failed to load prefab from ${normalizedPath}:`, err);
1069
+ return null;
1070
+ }
1071
+ })();
1072
+ this._prefabContentCache?.set(normalizedPath, loadTask);
1073
+ return loadTask;
805
1074
  }
806
1075
  /**
807
1076
  * Instantiate a prefab from a JSON file via VFS.
@@ -854,12 +1123,20 @@ const defaultValues = {
854
1123
  * @param filename - Destination path in VFS.
855
1124
  */ async saveScene(scene, filename) {
856
1125
  const asyncTasks = [];
857
- const content = await this.serializeObject(scene, null, asyncTasks);
858
- await Promise.all(asyncTasks);
859
- await this._vfs.writeFile(filename, JSON.stringify(content, null, 2), {
860
- encoding: 'utf8',
861
- create: true
862
- });
1126
+ const previousPrefabContentCache = this._prefabContentCache;
1127
+ if (!previousPrefabContentCache) {
1128
+ this._prefabContentCache = new Map();
1129
+ }
1130
+ try {
1131
+ const content = await this.serializeObject(scene, null, asyncTasks);
1132
+ await Promise.all(asyncTasks);
1133
+ await this._vfs.writeFile(filename, JSON.stringify(content, null, 2), {
1134
+ encoding: 'utf8',
1135
+ create: true
1136
+ });
1137
+ } finally{
1138
+ this._prefabContentCache = previousPrefabContentCache;
1139
+ }
863
1140
  }
864
1141
  rebuildGraphStructure(nodes, links) {
865
1142
  const gs = {
@@ -990,8 +1267,47 @@ const defaultValues = {
990
1267
  * Useful when reloading content or changing VFS mounts.
991
1268
  */ clearCache() {
992
1269
  this._allocated = new WeakMap();
1270
+ this._prefabContentCache?.clear();
993
1271
  this._assetManager.clearCache();
994
1272
  }
1273
+ handleVFSChanged(type, path, itemType, oldPath) {
1274
+ if (type === 'moved') {
1275
+ if (!oldPath) {
1276
+ this._prefabContentCache?.clear();
1277
+ this._assetManager.clearCache();
1278
+ return;
1279
+ }
1280
+ const normalizedOldPath = this._vfs.normalizePath(oldPath);
1281
+ const normalizedPath = this._vfs.normalizePath(path);
1282
+ const recursive = itemType === 'directory';
1283
+ this._assetManager.invalidateAsset(normalizedOldPath, recursive);
1284
+ this._assetManager.invalidateAsset(normalizedPath, recursive);
1285
+ this.invalidatePrefabContent(normalizedOldPath, recursive);
1286
+ this.invalidatePrefabContent(normalizedPath, recursive);
1287
+ return;
1288
+ }
1289
+ const normalizedPath = this._vfs.normalizePath(path);
1290
+ const recursive = itemType === 'directory';
1291
+ this._assetManager.invalidateAsset(normalizedPath, recursive);
1292
+ this.invalidatePrefabContent(normalizedPath, recursive);
1293
+ }
1294
+ invalidatePrefabContent(path, recursive) {
1295
+ if (!this._prefabContentCache) {
1296
+ return;
1297
+ }
1298
+ if (recursive) {
1299
+ const prefix = path.endsWith('/') ? path : `${path}/`;
1300
+ for (const key of [
1301
+ ...this._prefabContentCache.keys()
1302
+ ]){
1303
+ if (key === path || key.startsWith(prefix)) {
1304
+ this._prefabContentCache.delete(key);
1305
+ }
1306
+ }
1307
+ } else {
1308
+ this._prefabContentCache.delete(path);
1309
+ }
1310
+ }
995
1311
  static _pathPattern = /^([^\][]+)(?:\[(\d+)\])?$/;
996
1312
  static parsePropertyPath(str) {
997
1313
  const match = str.match(this._pathPattern);
@@ -1111,81 +1427,96 @@ const defaultValues = {
1111
1427
  continue;
1112
1428
  }
1113
1429
  const k = prop.name;
1114
- const v = json[k] ?? this.getDefaultValue(obj, prop);
1115
- const tmpVal = {
1116
- num: [
1117
- 0,
1118
- 0,
1119
- 0,
1120
- 0
1121
- ],
1122
- str: [
1123
- ''
1124
- ],
1125
- bool: [
1126
- false
1127
- ],
1128
- object: [
1129
- null
1130
- ]
1131
- };
1132
- switch(prop.type){
1133
- case 'object':
1134
- if (typeof v === 'string' && v) {
1135
- tmpVal.str[0] = v;
1136
- } else {
1137
- tmpVal.object[0] = v ? Array.isArray(v) ? v : this.isSerializedObjectEnvelope(v) ? await this.deserializeObject(obj, v) ?? null : v : null;
1138
- }
1139
- break;
1140
- case 'object_array':
1141
- tmpVal.object = [];
1142
- if (Array.isArray(v)) {
1143
- for (const p of v){
1144
- if (typeof p === 'string' && p) {
1145
- tmpVal.str[0] = p;
1430
+ promises.push((async ()=>{
1431
+ try {
1432
+ const v = json[k] ?? this.getDefaultValue(obj, prop);
1433
+ const tmpVal = {
1434
+ num: [
1435
+ 0,
1436
+ 0,
1437
+ 0,
1438
+ 0
1439
+ ],
1440
+ str: [
1441
+ ''
1442
+ ],
1443
+ bool: [
1444
+ false
1445
+ ],
1446
+ object: [
1447
+ null
1448
+ ]
1449
+ };
1450
+ switch(prop.type){
1451
+ case 'object':
1452
+ if (typeof v === 'string' && v) {
1453
+ tmpVal.str[0] = v;
1146
1454
  } else {
1147
- tmpVal.object.push(p ? this.isSerializedObjectEnvelope(p) ? await this.deserializeObject(obj, p) ?? null : p : null);
1455
+ tmpVal.object[0] = v ? Array.isArray(v) ? v : this.isSerializedObjectEnvelope(v) ? await this.deserializeObject(obj, v) ?? null : v : null;
1148
1456
  }
1149
- }
1457
+ break;
1458
+ case 'object_array':
1459
+ tmpVal.object = [];
1460
+ if (Array.isArray(v)) {
1461
+ const values = await Promise.all(v.map(async (p)=>typeof p === 'string' && p ? {
1462
+ kind: 'ref',
1463
+ ref: p
1464
+ } : {
1465
+ kind: 'value',
1466
+ value: p ? this.isSerializedObjectEnvelope(p) ? await this.deserializeObject(obj, p) ?? null : p : null
1467
+ }));
1468
+ for (const value of values){
1469
+ if (value.kind === 'ref') {
1470
+ tmpVal.str[0] = value.ref;
1471
+ } else {
1472
+ tmpVal.object.push(value.value);
1473
+ }
1474
+ }
1475
+ }
1476
+ break;
1477
+ case 'embedded':
1478
+ if (typeof v === 'string' && v) {
1479
+ tmpVal.str[0] = v;
1480
+ }
1481
+ break;
1482
+ case 'float':
1483
+ case 'int':
1484
+ tmpVal.num[0] = v;
1485
+ break;
1486
+ case 'string':
1487
+ tmpVal.str[0] = v;
1488
+ break;
1489
+ case 'bool':
1490
+ tmpVal.bool[0] = v;
1491
+ break;
1492
+ case 'vec2':
1493
+ case 'int2':
1494
+ tmpVal.num[0] = v[0];
1495
+ tmpVal.num[1] = v[1];
1496
+ break;
1497
+ case 'vec3':
1498
+ case 'int3':
1499
+ case 'rgb':
1500
+ tmpVal.num[0] = v[0];
1501
+ tmpVal.num[1] = v[1];
1502
+ tmpVal.num[2] = v[2];
1503
+ break;
1504
+ case 'vec4':
1505
+ case 'int4':
1506
+ case 'rgba':
1507
+ tmpVal.num[0] = v[0];
1508
+ tmpVal.num[1] = v[1];
1509
+ tmpVal.num[2] = v[2];
1510
+ tmpVal.num[3] = v[3];
1511
+ break;
1150
1512
  }
1151
- break;
1152
- case 'embedded':
1153
- if (typeof v === 'string' && v) {
1154
- tmpVal.str[0] = v;
1513
+ if (prop.set) {
1514
+ await Promise.resolve(prop.set.call(obj, tmpVal, -1));
1155
1515
  }
1156
- break;
1157
- case 'float':
1158
- case 'int':
1159
- tmpVal.num[0] = v;
1160
- break;
1161
- case 'string':
1162
- tmpVal.str[0] = v;
1163
- break;
1164
- case 'bool':
1165
- tmpVal.bool[0] = v;
1166
- break;
1167
- case 'vec2':
1168
- case 'int2':
1169
- tmpVal.num[0] = v[0];
1170
- tmpVal.num[1] = v[1];
1171
- break;
1172
- case 'vec3':
1173
- case 'int3':
1174
- case 'rgb':
1175
- tmpVal.num[0] = v[0];
1176
- tmpVal.num[1] = v[1];
1177
- tmpVal.num[2] = v[2];
1178
- break;
1179
- case 'vec4':
1180
- case 'int4':
1181
- case 'rgba':
1182
- tmpVal.num[0] = v[0];
1183
- tmpVal.num[1] = v[1];
1184
- tmpVal.num[2] = v[2];
1185
- tmpVal.num[3] = v[3];
1186
- break;
1187
- }
1188
- promises.push(Promise.resolve(prop.set.call(obj, tmpVal, -1)));
1516
+ } catch (err) {
1517
+ console.warn(`Deserialize property failed: ${cls.name}.${k} on ${obj?.constructor?.name ?? 'UnknownObject'}: ${String(err)}`);
1518
+ }
1519
+ })());
1189
1520
  }
1190
1521
  if (promises.length > 0) {
1191
1522
  await Promise.all(promises);