@zephyr3d/scene 0.9.27 → 0.10.0

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 (502) hide show
  1. package/README.md +60 -27
  2. package/dist/animation/animation_bank.js +634 -0
  3. package/dist/animation/animation_bank.js.map +1 -0
  4. package/dist/animation/animation_bank_gpu.js +256 -0
  5. package/dist/animation/animation_bank_gpu.js.map +1 -0
  6. package/dist/animation/animationset.js +54 -0
  7. package/dist/animation/animationset.js.map +1 -1
  8. package/dist/animation/cloth/gpu_cloth_component.js +406 -0
  9. package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
  10. package/dist/animation/cloth/gpu_cloth_system.js +332 -202
  11. package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
  12. package/dist/animation/gpu_animation_driver.js +289 -0
  13. package/dist/animation/gpu_animation_driver.js.map +1 -0
  14. package/dist/animation/joint_dynamics/collision.js +112 -1
  15. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  16. package/dist/animation/joint_dynamics/controller.js +6 -0
  17. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  18. package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
  19. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  20. package/dist/animation/joint_dynamics/solver.js +50 -12
  21. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  22. package/dist/animation/joint_dynamics/types.js.map +1 -1
  23. package/dist/animation/skeleton.js +279 -55
  24. package/dist/animation/skeleton.js.map +1 -1
  25. package/dist/animation/skin_palette_atlas.js +252 -0
  26. package/dist/animation/skin_palette_atlas.js.map +1 -0
  27. package/dist/animation/spring/multi_chain_spring_system.js +298 -38
  28. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  29. package/dist/animation/spring/spring_chain.js +2 -0
  30. package/dist/animation/spring/spring_chain.js.map +1 -1
  31. package/dist/animation/spring/spring_collider.js +159 -21
  32. package/dist/animation/spring/spring_collider.js.map +1 -1
  33. package/dist/animation/spring/spring_particle.js +1 -0
  34. package/dist/animation/spring/spring_particle.js.map +1 -1
  35. package/dist/animation/spring/spring_solver.js +173 -0
  36. package/dist/animation/spring/spring_solver.js.map +1 -0
  37. package/dist/animation/spring/spring_system.js +249 -24
  38. package/dist/animation/spring/spring_system.js.map +1 -1
  39. package/dist/animation/spring_modifier.js +32 -1
  40. package/dist/animation/spring_modifier.js.map +1 -1
  41. package/dist/app/app.js +26 -0
  42. package/dist/app/app.js.map +1 -1
  43. package/dist/app/engine.js +86 -15
  44. package/dist/app/engine.js.map +1 -1
  45. package/dist/app/gamepad.js +191 -0
  46. package/dist/app/gamepad.js.map +1 -0
  47. package/dist/app/inputactions.js +271 -0
  48. package/dist/app/inputactions.js.map +1 -0
  49. package/dist/app/inputmgr.js +331 -22
  50. package/dist/app/inputmgr.js.map +1 -1
  51. package/dist/app/loading.js +138 -0
  52. package/dist/app/loading.js.map +1 -0
  53. package/dist/app/pipelinecache.js +209 -0
  54. package/dist/app/pipelinecache.js.map +1 -0
  55. package/dist/app/runtimescript.js +25 -0
  56. package/dist/app/runtimescript.js.map +1 -1
  57. package/dist/app/scriptingsystem.js +54 -0
  58. package/dist/app/scriptingsystem.js.map +1 -1
  59. package/dist/app/scriptregistry.js +7 -2
  60. package/dist/app/scriptregistry.js.map +1 -1
  61. package/dist/asset/asset_manifest.js +59 -0
  62. package/dist/asset/asset_manifest.js.map +1 -0
  63. package/dist/asset/asset_preload.js +258 -0
  64. package/dist/asset/asset_preload.js.map +1 -0
  65. package/dist/asset/assetmanager.js +117 -65
  66. package/dist/asset/assetmanager.js.map +1 -1
  67. package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
  68. package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  69. package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  70. package/dist/asset/loaders/ktx2/basis_location.js +17 -0
  71. package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
  72. package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
  73. package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
  74. package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
  75. package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
  76. package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
  77. package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
  78. package/dist/asset/mesh_lod_builder.js +104 -0
  79. package/dist/asset/mesh_lod_builder.js.map +1 -0
  80. package/dist/asset/mesh_settings.js +111 -0
  81. package/dist/asset/mesh_settings.js.map +1 -0
  82. package/dist/asset/meshopt_decoder.js +18 -0
  83. package/dist/asset/meshopt_decoder.js.map +1 -0
  84. package/dist/asset/meshopt_simplifier.js +26 -0
  85. package/dist/asset/meshopt_simplifier.js.map +1 -0
  86. package/dist/asset/model.js +171 -1
  87. package/dist/asset/model.js.map +1 -1
  88. package/dist/asset/texture_settings.js +231 -0
  89. package/dist/asset/texture_settings.js.map +1 -0
  90. package/dist/asset/zmsh_binary.js +131 -0
  91. package/dist/asset/zmsh_binary.js.map +1 -0
  92. package/dist/asset/zsdf_binary.js +111 -0
  93. package/dist/asset/zsdf_binary.js.map +1 -0
  94. package/dist/blitter/bilateralblur.js +1 -2
  95. package/dist/blitter/bilateralblur.js.map +1 -1
  96. package/dist/blitter/gaussianblur.js +1 -6
  97. package/dist/blitter/gaussianblur.js.map +1 -1
  98. package/dist/camera/base.js +31 -10
  99. package/dist/camera/base.js.map +1 -1
  100. package/dist/camera/camera.js +104 -178
  101. package/dist/camera/camera.js.map +1 -1
  102. package/dist/camera/follow.js +342 -0
  103. package/dist/camera/follow.js.map +1 -0
  104. package/dist/camera/fps.js +9 -7
  105. package/dist/camera/fps.js.map +1 -1
  106. package/dist/camera/orbit.js +46 -19
  107. package/dist/camera/orbit.js.map +1 -1
  108. package/dist/index.d.ts +25436 -15990
  109. package/dist/index.js +65 -11
  110. package/dist/index.js.map +1 -1
  111. package/dist/material/blinn.js +3 -0
  112. package/dist/material/blinn.js.map +1 -1
  113. package/dist/material/eye.js +1 -1
  114. package/dist/material/eye.js.map +1 -1
  115. package/dist/material/hair.js +2 -3
  116. package/dist/material/hair.js.map +1 -1
  117. package/dist/material/lambert.js +4 -1
  118. package/dist/material/lambert.js.map +1 -1
  119. package/dist/material/material.js +66 -4
  120. package/dist/material/material.js.map +1 -1
  121. package/dist/material/meshmaterial.js +118 -45
  122. package/dist/material/meshmaterial.js.map +1 -1
  123. package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
  124. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  125. package/dist/material/mixins/lightmodel/lambert.js +1 -1
  126. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  127. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
  128. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  129. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
  130. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  131. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
  132. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  133. package/dist/material/mixins/lit.js +191 -83
  134. package/dist/material/mixins/lit.js.map +1 -1
  135. package/dist/material/mixins/pbr/common.js +31 -206
  136. package/dist/material/mixins/pbr/common.js.map +1 -1
  137. package/dist/material/mtoon.js +1 -1
  138. package/dist/material/mtoon.js.map +1 -1
  139. package/dist/material/pbrmr.js +3 -0
  140. package/dist/material/pbrmr.js.map +1 -1
  141. package/dist/material/pbrsg.js +3 -0
  142. package/dist/material/pbrsg.js.map +1 -1
  143. package/dist/material/sdf_debug.js +78 -0
  144. package/dist/material/sdf_debug.js.map +1 -0
  145. package/dist/material/shader/helper.js +333 -191
  146. package/dist/material/shader/helper.js.map +1 -1
  147. package/dist/material/shader/terrain_blend.js +204 -43
  148. package/dist/material/shader/terrain_blend.js.map +1 -1
  149. package/dist/material/skin.js +331 -297
  150. package/dist/material/skin.js.map +1 -1
  151. package/dist/material/skinprofile.js +1058 -0
  152. package/dist/material/skinprofile.js.map +1 -0
  153. package/dist/material/sss.js +353 -0
  154. package/dist/material/sss.js.map +1 -0
  155. package/dist/material/sss_kernel.js +265 -0
  156. package/dist/material/sss_kernel.js.map +1 -0
  157. package/dist/material/sssprofile.js +879 -0
  158. package/dist/material/sssprofile.js.map +1 -0
  159. package/dist/material/subsurfaceprofile.js +4 -8
  160. package/dist/material/subsurfaceprofile.js.map +1 -1
  161. package/dist/material/terrain-cm.js +464 -188
  162. package/dist/material/terrain-cm.js.map +1 -1
  163. package/dist/material/unlit.js +3 -0
  164. package/dist/material/unlit.js.map +1 -1
  165. package/dist/material/water.js +1261 -1438
  166. package/dist/material/water.js.map +1 -1
  167. package/dist/node_modules/meshoptimizer/LICENSE +21 -0
  168. package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
  169. package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
  170. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
  171. package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
  172. package/dist/physics/character.js +226 -0
  173. package/dist/physics/character.js.map +1 -0
  174. package/dist/physics/collider.js +209 -0
  175. package/dist/physics/collider.js.map +1 -0
  176. package/dist/physics/events.js +79 -0
  177. package/dist/physics/events.js.map +1 -0
  178. package/dist/physics/joint.js +272 -0
  179. package/dist/physics/joint.js.map +1 -0
  180. package/dist/physics/node_physics.js +234 -0
  181. package/dist/physics/node_physics.js.map +1 -0
  182. package/dist/physics/part.js +91 -0
  183. package/dist/physics/part.js.map +1 -0
  184. package/dist/physics/rigid_body.js +379 -0
  185. package/dist/physics/rigid_body.js.map +1 -0
  186. package/dist/physics/vehicle.js +335 -0
  187. package/dist/physics/vehicle.js.map +1 -0
  188. package/dist/physics/world.js +25 -0
  189. package/dist/physics/world.js.map +1 -0
  190. package/dist/posteffect/bloom.js +49 -14
  191. package/dist/posteffect/bloom.js.map +1 -1
  192. package/dist/posteffect/motionblur.js +106 -106
  193. package/dist/posteffect/motionblur.js.map +1 -1
  194. package/dist/posteffect/postsss.js +572 -0
  195. package/dist/posteffect/postsss.js.map +1 -0
  196. package/dist/posteffect/sao.js +2 -6
  197. package/dist/posteffect/sao.js.map +1 -1
  198. package/dist/posteffect/skinsss.js +605 -355
  199. package/dist/posteffect/skinsss.js.map +1 -1
  200. package/dist/posteffect/ssgi.js +91 -162
  201. package/dist/posteffect/ssgi.js.map +1 -1
  202. package/dist/posteffect/ssr.js +3 -11
  203. package/dist/posteffect/ssr.js.map +1 -1
  204. package/dist/posteffect/sss.js +4 -13
  205. package/dist/posteffect/sss.js.map +1 -1
  206. package/dist/posteffect/taa.js +1 -0
  207. package/dist/posteffect/taa.js.map +1 -1
  208. package/dist/render/abuffer_oit.js +3 -2
  209. package/dist/render/abuffer_oit.js.map +1 -1
  210. package/dist/render/clipmap.js +179 -64
  211. package/dist/render/clipmap.js.map +1 -1
  212. package/dist/render/cluster_light.js +958 -224
  213. package/dist/render/cluster_light.js.map +1 -1
  214. package/dist/render/cull_visitor.js +25 -5
  215. package/dist/render/cull_visitor.js.map +1 -1
  216. package/dist/render/debug_views.js +37 -0
  217. package/dist/render/debug_views.js.map +1 -0
  218. package/dist/render/depthpass.js +5 -1
  219. package/dist/render/depthpass.js.map +1 -1
  220. package/dist/render/drawable_mixin.js +53 -6
  221. package/dist/render/drawable_mixin.js.map +1 -1
  222. package/dist/render/dualdepthpeeling_oit.js +5 -5
  223. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  224. package/dist/render/envlight.js +196 -113
  225. package/dist/render/envlight.js.map +1 -1
  226. package/dist/render/fbm_wavegenerator.js +5 -10
  227. package/dist/render/fbm_wavegenerator.js.map +1 -1
  228. package/dist/render/fft_wavegenerator.js +247 -157
  229. package/dist/render/fft_wavegenerator.js.map +1 -1
  230. package/dist/render/gerstner_wavegenerator.js +16 -38
  231. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  232. package/dist/render/gi/probe_volume.js +1334 -0
  233. package/dist/render/gi/probe_volume.js.map +1 -0
  234. package/dist/render/gi/scene_gi.js +282 -0
  235. package/dist/render/gi/scene_gi.js.map +1 -0
  236. package/dist/render/gi/voxel_atlas.js +198 -0
  237. package/dist/render/gi/voxel_atlas.js.map +1 -0
  238. package/dist/render/gi/voxel_lighting.js +652 -0
  239. package/dist/render/gi/voxel_lighting.js.map +1 -0
  240. package/dist/render/gi/voxel_scene.js +642 -0
  241. package/dist/render/gi/voxel_scene.js.map +1 -0
  242. package/dist/render/gi/voxelize_pass.js +223 -0
  243. package/dist/render/gi/voxelize_pass.js.map +1 -0
  244. package/dist/render/globalbindgroup_allocator.js +3 -2
  245. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  246. package/dist/render/gpu_picking.js +9 -36
  247. package/dist/render/gpu_picking.js.map +1 -1
  248. package/dist/render/instance_culling.js +499 -0
  249. package/dist/render/instance_culling.js.map +1 -0
  250. package/dist/render/lightpass.js +19 -8
  251. package/dist/render/lightpass.js.map +1 -1
  252. package/dist/render/lod.js +46 -0
  253. package/dist/render/lod.js.map +1 -0
  254. package/dist/render/primitive.js +301 -9
  255. package/dist/render/primitive.js.map +1 -1
  256. package/dist/render/primitive_readback.js +209 -0
  257. package/dist/render/primitive_readback.js.map +1 -0
  258. package/dist/render/render_queue.js +162 -11
  259. package/dist/render/render_queue.js.map +1 -1
  260. package/dist/render/renderer.js +10 -7
  261. package/dist/render/renderer.js.map +1 -1
  262. package/dist/render/rendergraph/blackboard.js +14 -1
  263. package/dist/render/rendergraph/blackboard.js.map +1 -1
  264. package/dist/render/rendergraph/executor.js +136 -0
  265. package/dist/render/rendergraph/executor.js.map +1 -1
  266. package/dist/render/rendergraph/forward_plus_builder.js +272 -55
  267. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  268. package/dist/render/rendergraph/frame_graph_context.js +41 -0
  269. package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
  270. package/dist/render/rendergraph/scene_render_context.js +31 -2
  271. package/dist/render/rendergraph/scene_render_context.js.map +1 -1
  272. package/dist/render/rendergraph/types.js.map +1 -1
  273. package/dist/render/renderpass.js +28 -5
  274. package/dist/render/renderpass.js.map +1 -1
  275. package/dist/render/sdf/box_allocator.js +98 -0
  276. package/dist/render/sdf/box_allocator.js.map +1 -0
  277. package/dist/render/sdf/global_sdf.js +865 -0
  278. package/dist/render/sdf/global_sdf.js.map +1 -0
  279. package/dist/render/sdf/scene_sdf.js +562 -0
  280. package/dist/render/sdf/scene_sdf.js.map +1 -0
  281. package/dist/render/sdf/sdf_atlas.js +227 -0
  282. package/dist/render/sdf/sdf_atlas.js.map +1 -0
  283. package/dist/render/sdf/sdf_programs.js +42 -0
  284. package/dist/render/sdf/sdf_programs.js.map +1 -0
  285. package/dist/render/sdf/sdf_view.js +199 -0
  286. package/dist/render/sdf/sdf_view.js.map +1 -0
  287. package/dist/render/sdf/waterline.js +610 -0
  288. package/dist/render/sdf/waterline.js.map +1 -0
  289. package/dist/render/shadow_mask_pass.js +142 -25
  290. package/dist/render/shadow_mask_pass.js.map +1 -1
  291. package/dist/render/shore_wave_generator.js +1193 -0
  292. package/dist/render/shore_wave_generator.js.map +1 -0
  293. package/dist/render/sky.js +516 -86
  294. package/dist/render/sky.js.map +1 -1
  295. package/dist/render/transmission_thickness_pass.js +477 -0
  296. package/dist/render/transmission_thickness_pass.js.map +1 -0
  297. package/dist/render/underwater.js +58 -158
  298. package/dist/render/underwater.js.map +1 -1
  299. package/dist/render/virtualtexture/virtual_texture.js +1214 -0
  300. package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
  301. package/dist/render/volumetric_cloud/cloud_common.js +472 -0
  302. package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
  303. package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
  304. package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
  305. package/dist/render/volumetric_cloud/debug_view.js +131 -0
  306. package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
  307. package/dist/render/volumetric_cloud/resources.js +380 -0
  308. package/dist/render/volumetric_cloud/resources.js.map +1 -0
  309. package/dist/render/volumetric_cloud/sky_cache.js +380 -0
  310. package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
  311. package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
  312. package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
  313. package/dist/render/water_caustics.js +134 -319
  314. package/dist/render/water_caustics.js.map +1 -1
  315. package/dist/render/water_foam.js +627 -0
  316. package/dist/render/water_foam.js.map +1 -0
  317. package/dist/render/water_interaction.js +1795 -0
  318. package/dist/render/water_interaction.js.map +1 -0
  319. package/dist/render/weightedblended_oit.js +3 -3
  320. package/dist/render/weightedblended_oit.js.map +1 -1
  321. package/dist/scene/basesprite.js +9 -4
  322. package/dist/scene/basesprite.js.map +1 -1
  323. package/dist/scene/batchgroup.js +108 -12
  324. package/dist/scene/batchgroup.js.map +1 -1
  325. package/dist/scene/environment.js +28 -7
  326. package/dist/scene/environment.js.map +1 -1
  327. package/dist/scene/foliage.js +1020 -0
  328. package/dist/scene/foliage.js.map +1 -0
  329. package/dist/scene/foliage_buckets.js +147 -0
  330. package/dist/scene/foliage_buckets.js.map +1 -0
  331. package/dist/scene/foliage_mask.js +358 -0
  332. package/dist/scene/foliage_mask.js.map +1 -0
  333. package/dist/scene/hair.js +15 -4
  334. package/dist/scene/hair.js.map +1 -1
  335. package/dist/scene/light.js +179 -13
  336. package/dist/scene/light.js.map +1 -1
  337. package/dist/scene/mesh.js +327 -45
  338. package/dist/scene/mesh.js.map +1 -1
  339. package/dist/scene/meshdrawable.js +6 -0
  340. package/dist/scene/meshdrawable.js.map +1 -1
  341. package/dist/scene/msdftext.js +9 -3
  342. package/dist/scene/msdftext.js.map +1 -1
  343. package/dist/scene/msdftextsprite.js +9 -3
  344. package/dist/scene/msdftextsprite.js.map +1 -1
  345. package/dist/scene/particlesys.js +8 -2
  346. package/dist/scene/particlesys.js.map +1 -1
  347. package/dist/scene/physics_settings.js +157 -0
  348. package/dist/scene/physics_settings.js.map +1 -0
  349. package/dist/scene/scene.js +190 -44
  350. package/dist/scene/scene.js.map +1 -1
  351. package/dist/scene/scene_node.js +147 -6
  352. package/dist/scene/scene_node.js.map +1 -1
  353. package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
  354. package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
  355. package/dist/scene/terrain-cm/grass.js +881 -42
  356. package/dist/scene/terrain-cm/grass.js.map +1 -1
  357. package/dist/scene/terrain-cm/grass_gpu.js +929 -0
  358. package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
  359. package/dist/scene/terrain-cm/grassmaterial.js +180 -9
  360. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  361. package/dist/scene/terrain-cm/terrain-cm.js +465 -36
  362. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  363. package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
  364. package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
  365. package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
  366. package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
  367. package/dist/scene/update_queue.js +54 -0
  368. package/dist/scene/update_queue.js.map +1 -0
  369. package/dist/scene/water.js +633 -268
  370. package/dist/scene/water.js.map +1 -1
  371. package/dist/scene/water_surface_sampler.js +324 -0
  372. package/dist/scene/water_surface_sampler.js.map +1 -0
  373. package/dist/scene/wind.js +317 -0
  374. package/dist/scene/wind.js.map +1 -0
  375. package/dist/shaders/atmosphere.js +388 -166
  376. package/dist/shaders/atmosphere.js.map +1 -1
  377. package/dist/shaders/fog.js +100 -32
  378. package/dist/shaders/fog.js.map +1 -1
  379. package/dist/shaders/gi.js +365 -0
  380. package/dist/shaders/gi.js.map +1 -0
  381. package/dist/shaders/ltc_rect.js +202 -0
  382. package/dist/shaders/ltc_rect.js.map +1 -0
  383. package/dist/shaders/misc.js +1 -10
  384. package/dist/shaders/misc.js.map +1 -1
  385. package/dist/shaders/noise.js +5 -1
  386. package/dist/shaders/noise.js.map +1 -1
  387. package/dist/shaders/probes.js +309 -0
  388. package/dist/shaders/probes.js.map +1 -0
  389. package/dist/shaders/sdf.js +537 -0
  390. package/dist/shaders/sdf.js.map +1 -0
  391. package/dist/shaders/shadow.js +104 -70
  392. package/dist/shaders/shadow.js.map +1 -1
  393. package/dist/shaders/skin_brdf.js +243 -0
  394. package/dist/shaders/skin_brdf.js.map +1 -0
  395. package/dist/shaders/ssgi.js +63 -0
  396. package/dist/shaders/ssgi.js.map +1 -0
  397. package/dist/shaders/ssgi_reprojection.js +118 -0
  398. package/dist/shaders/ssgi_reprojection.js.map +1 -0
  399. package/dist/shaders/ssr.js +6 -159
  400. package/dist/shaders/ssr.js.map +1 -1
  401. package/dist/shaders/temporal.js +38 -27
  402. package/dist/shaders/temporal.js.map +1 -1
  403. package/dist/shaders/water.js +32 -82
  404. package/dist/shaders/water.js.map +1 -1
  405. package/dist/shaders/water_medium.js +7 -21
  406. package/dist/shaders/water_medium.js.map +1 -1
  407. package/dist/shadow/dom.js +110 -19
  408. package/dist/shadow/dom.js.map +1 -1
  409. package/dist/shadow/esm.js +3 -3
  410. package/dist/shadow/esm.js.map +1 -1
  411. package/dist/shadow/pcf_opt.js +15 -48
  412. package/dist/shadow/pcf_opt.js.map +1 -1
  413. package/dist/shadow/pcf_pd.js +15 -53
  414. package/dist/shadow/pcf_pd.js.map +1 -1
  415. package/dist/shadow/pcss.js +34 -9
  416. package/dist/shadow/pcss.js.map +1 -1
  417. package/dist/shadow/shadow_impl.js +3 -8
  418. package/dist/shadow/shadow_impl.js.map +1 -1
  419. package/dist/shadow/shadow_region.js +40 -2
  420. package/dist/shadow/shadow_region.js.map +1 -1
  421. package/dist/shadow/shadowmapper.js +93 -53
  422. package/dist/shadow/shadowmapper.js.map +1 -1
  423. package/dist/shadow/ssm.js +18 -72
  424. package/dist/shadow/ssm.js.map +1 -1
  425. package/dist/shadow/vsm.js +3 -3
  426. package/dist/shadow/vsm.js.map +1 -1
  427. package/dist/shapes/shape.js +44 -1
  428. package/dist/shapes/shape.js.map +1 -1
  429. package/dist/utility/buoyancy.js +287 -0
  430. package/dist/utility/buoyancy.js.map +1 -0
  431. package/dist/utility/physical.js +10 -1
  432. package/dist/utility/physical.js.map +1 -1
  433. package/dist/utility/pmrem.js +17 -43
  434. package/dist/utility/pmrem.js.map +1 -1
  435. package/dist/utility/sdf/bake.js +435 -0
  436. package/dist/utility/sdf/bake.js.map +1 -0
  437. package/dist/utility/sdf/bvh.js +576 -0
  438. package/dist/utility/sdf/bvh.js.map +1 -0
  439. package/dist/utility/serialization/manager.js +34 -6
  440. package/dist/utility/serialization/manager.js.map +1 -1
  441. package/dist/utility/serialization/scene/animation.js +46 -5
  442. package/dist/utility/serialization/scene/animation.js.map +1 -1
  443. package/dist/utility/serialization/scene/batch.js +11 -4
  444. package/dist/utility/serialization/scene/batch.js.map +1 -1
  445. package/dist/utility/serialization/scene/camera.js +87 -254
  446. package/dist/utility/serialization/scene/camera.js.map +1 -1
  447. package/dist/utility/serialization/scene/cloth.js +25 -0
  448. package/dist/utility/serialization/scene/cloth.js.map +1 -0
  449. package/dist/utility/serialization/scene/common.js +14 -6
  450. package/dist/utility/serialization/scene/common.js.map +1 -1
  451. package/dist/utility/serialization/scene/foliage.js +821 -0
  452. package/dist/utility/serialization/scene/foliage.js.map +1 -0
  453. package/dist/utility/serialization/scene/hair.js +11 -4
  454. package/dist/utility/serialization/scene/hair.js.map +1 -1
  455. package/dist/utility/serialization/scene/light.js +115 -7
  456. package/dist/utility/serialization/scene/light.js.map +1 -1
  457. package/dist/utility/serialization/scene/material.js +388 -220
  458. package/dist/utility/serialization/scene/material.js.map +1 -1
  459. package/dist/utility/serialization/scene/mesh.js +69 -4
  460. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  461. package/dist/utility/serialization/scene/node.js +140 -5
  462. package/dist/utility/serialization/scene/node.js.map +1 -1
  463. package/dist/utility/serialization/scene/node_physics.js +1318 -0
  464. package/dist/utility/serialization/scene/node_physics.js.map +1 -0
  465. package/dist/utility/serialization/scene/particle.js +11 -4
  466. package/dist/utility/serialization/scene/particle.js.map +1 -1
  467. package/dist/utility/serialization/scene/physics.js +120 -0
  468. package/dist/utility/serialization/scene/physics.js.map +1 -0
  469. package/dist/utility/serialization/scene/primitive.js +124 -10
  470. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  471. package/dist/utility/serialization/scene/scene.js +1687 -51
  472. package/dist/utility/serialization/scene/scene.js.map +1 -1
  473. package/dist/utility/serialization/scene/sprite.js +11 -4
  474. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  475. package/dist/utility/serialization/scene/terrain.js +163 -33
  476. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  477. package/dist/utility/serialization/scene/text.js +11 -4
  478. package/dist/utility/serialization/scene/text.js.map +1 -1
  479. package/dist/utility/serialization/scene/water.js +1543 -264
  480. package/dist/utility/serialization/scene/water.js.map +1 -1
  481. package/dist/utility/serialization/types.js.map +1 -1
  482. package/dist/utility/shprojector.js +10 -22
  483. package/dist/utility/shprojector.js.map +1 -1
  484. package/dist/utility/textures/foam.js +170 -0
  485. package/dist/utility/textures/foam.js.map +1 -0
  486. package/dist/utility/textures/ggxlut.js +17 -43
  487. package/dist/utility/textures/ggxlut.js.map +1 -1
  488. package/dist/utility/textures/ltcdata.js +4 -4
  489. package/dist/utility/textures/ltcdata.js.map +1 -1
  490. package/dist/utility/textures/ltclut.js +16 -6
  491. package/dist/utility/textures/ltclut.js.map +1 -1
  492. package/dist/utility/unsupported.js +24 -0
  493. package/dist/utility/unsupported.js.map +1 -0
  494. package/dist/values.js +13 -1
  495. package/dist/values.js.map +1 -1
  496. package/package.json +25 -12
  497. package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
  498. package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
  499. package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
  500. package/src/asset/meshoptimizer/LICENSE +21 -0
  501. package/dist/animation/joint_dynamics/convex_collider.js +0 -320
  502. package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
@@ -0,0 +1,231 @@
1
+ /** Extension of asset sidecar files, appended to the asset's full file name. @public */ const ASSET_META_EXTENSION = '.zmeta';
2
+ /** Current `.zmeta` format version. @public */ const ASSET_META_VERSION = 1;
3
+ /** Usages that hold colour and are sampled as sRGB. */ const SRGB_USAGES = new Set([
4
+ 'color',
5
+ 'ui'
6
+ ]);
7
+ const USAGES = [
8
+ 'color',
9
+ 'normal',
10
+ 'mask',
11
+ 'hdr',
12
+ 'ui'
13
+ ];
14
+ const COMPRESSIONS = [
15
+ 'auto',
16
+ 'etc1s',
17
+ 'uastc',
18
+ 'none'
19
+ ];
20
+ const QUALITIES = [
21
+ 'low',
22
+ 'normal',
23
+ 'high'
24
+ ];
25
+ /**
26
+ * Path of the sidecar `.zmeta` file of an asset.
27
+ * @public
28
+ */ function getAssetMetaPath(assetPath) {
29
+ return `${assetPath}${ASSET_META_EXTENSION}`;
30
+ }
31
+ /**
32
+ * True if a path is an asset sidecar file rather than an asset.
33
+ * @public
34
+ */ function isAssetMetaPath(path) {
35
+ return path.toLowerCase().endsWith(ASSET_META_EXTENSION);
36
+ }
37
+ /**
38
+ * Whether textures of a usage are sampled as sRGB.
39
+ * @public
40
+ */ function isSRGBTextureUsage(usage) {
41
+ return SRGB_USAGES.has(usage);
42
+ }
43
+ /**
44
+ * Default settings for a usage.
45
+ *
46
+ * Compression is opt-in: a texture is only compressed when its settings say so,
47
+ * so updating the engine or editor never changes how an existing project ships.
48
+ * @public
49
+ */ function defaultTextureImportSettings(usage, compression = 'none') {
50
+ return {
51
+ usage,
52
+ compression,
53
+ quality: 'normal',
54
+ maxSize: 0,
55
+ mipmaps: usage !== 'ui'
56
+ };
57
+ }
58
+ /**
59
+ * The encoding a texture actually gets, with `auto` resolved from its usage.
60
+ * @public
61
+ */ function resolveTextureCompression(settings) {
62
+ if (settings.compression !== 'auto') {
63
+ return settings.compression;
64
+ }
65
+ switch(settings.usage){
66
+ case 'color':
67
+ return 'etc1s';
68
+ case 'normal':
69
+ return 'uastc';
70
+ case 'mask':
71
+ return settings.quality === 'low' ? 'etc1s' : 'uastc';
72
+ default:
73
+ return 'none';
74
+ }
75
+ }
76
+ // File name tokens, matched whole after splitting on separators and case changes.
77
+ // Common suffix conventions of DCC tools and texture libraries (Substance,
78
+ // Quixel, Poly Haven, glTF samples). Only consulted when no material slot told
79
+ // the importer what the image is.
80
+ const NORMAL_TOKENS = new Set([
81
+ 'n',
82
+ 'nrm',
83
+ 'nor',
84
+ 'norm',
85
+ 'normal',
86
+ 'normals',
87
+ 'normalmap',
88
+ 'nml'
89
+ ]);
90
+ const MASK_TOKENS = new Set([
91
+ 'orm',
92
+ 'arm',
93
+ 'mra',
94
+ 'rma',
95
+ 'rough',
96
+ 'roughness',
97
+ 'metal',
98
+ 'metallic',
99
+ 'metalness',
100
+ 'ao',
101
+ 'occlusion',
102
+ 'ambientocclusion',
103
+ 'mask',
104
+ 'masks',
105
+ 'spec',
106
+ 'specular',
107
+ 'gloss',
108
+ 'glossiness',
109
+ 'height',
110
+ 'disp',
111
+ 'displacement',
112
+ 'bump',
113
+ 'opacity',
114
+ 'cavity',
115
+ 'thickness'
116
+ ]);
117
+ function fileNameTokens(path) {
118
+ const name = path.slice(path.lastIndexOf('/') + 1);
119
+ const dot = name.lastIndexOf('.');
120
+ const stem = dot > 0 ? name.slice(0, dot) : name;
121
+ return stem.replace(/([a-z0-9])([A-Z])/g, '$1 $2').toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
122
+ }
123
+ /**
124
+ * Guesses the usage of a texture from its path, for images that arrive without
125
+ * material context (dropped into the project, or referenced by no material).
126
+ * @public
127
+ */ function inferTextureUsageFromPath(path) {
128
+ const lower = path.toLowerCase();
129
+ if (lower.endsWith('.hdr') || lower.endsWith('.exr')) {
130
+ return 'hdr';
131
+ }
132
+ if (/(^|\/)ui\//.test(lower)) {
133
+ return 'ui';
134
+ }
135
+ const tokens = fileNameTokens(path);
136
+ // The last tokens carry the map type in suffix conventions ("rock_01_nrm")
137
+ for(let i = tokens.length - 1; i >= 0; i--){
138
+ if (NORMAL_TOKENS.has(tokens[i])) {
139
+ return 'normal';
140
+ }
141
+ if (MASK_TOKENS.has(tokens[i])) {
142
+ return 'mask';
143
+ }
144
+ }
145
+ return 'color';
146
+ }
147
+ /**
148
+ * Usage of an image referenced from a model material slot.
149
+ *
150
+ * @param slot - Material property holding the texture, e.g. `normalMap`
151
+ * @param sRGB - Whether the importer samples the slot as sRGB
152
+ *
153
+ * @public
154
+ */ function inferTextureUsageFromSlot(slot, sRGB) {
155
+ if (/normal/i.test(slot)) {
156
+ return 'normal';
157
+ }
158
+ return sRGB ? 'color' : 'mask';
159
+ }
160
+ // When one image feeds several slots, the most demanding usage wins: a normal
161
+ // map compressed as colour loses far more than a colour map compressed as data.
162
+ const USAGE_PRIORITY = {
163
+ normal: 3,
164
+ mask: 2,
165
+ hdr: 2,
166
+ color: 1,
167
+ ui: 0
168
+ };
169
+ /**
170
+ * Picks the usage that serves every slot an image is used in.
171
+ * @public
172
+ */ function mergeTextureUsage(a, b) {
173
+ return USAGE_PRIORITY[b] > USAGE_PRIORITY[a] ? b : a;
174
+ }
175
+ function pick(value, allowed, fallback) {
176
+ return allowed.includes(value) ? value : fallback;
177
+ }
178
+ /**
179
+ * Validates parsed settings, filling anything missing or invalid from the defaults
180
+ * of the stored usage (or of `fallbackUsage` when the usage itself is unusable).
181
+ * @public
182
+ */ function normalizeTextureImportSettings(value, fallbackUsage) {
183
+ const v = value && typeof value === 'object' ? value : {};
184
+ const usage = pick(v.usage, USAGES, fallbackUsage);
185
+ const defaults = defaultTextureImportSettings(usage);
186
+ const maxSize = Number(v.maxSize);
187
+ return {
188
+ usage,
189
+ compression: pick(v.compression, COMPRESSIONS, defaults.compression),
190
+ quality: pick(v.quality, QUALITIES, defaults.quality),
191
+ maxSize: Number.isFinite(maxSize) && maxSize > 0 ? Math.floor(maxSize) : 0,
192
+ mipmaps: typeof v.mipmaps === 'boolean' ? v.mipmaps : defaults.mipmaps
193
+ };
194
+ }
195
+ /**
196
+ * Reads the import settings of a texture. Without a `.zmeta` file (or with an
197
+ * unreadable one) the texture is not compressed and its usage is inferred from
198
+ * the path, so a texture that was never touched in the editor still has
199
+ * well-defined settings that leave it exactly as it was.
200
+ * @public
201
+ */ async function readTextureImportSettings(vfs, path) {
202
+ const fallbackUsage = inferTextureUsageFromPath(path);
203
+ const metaPath = getAssetMetaPath(path);
204
+ try {
205
+ if (await vfs.exists(metaPath)) {
206
+ const meta = JSON.parse(await vfs.readFile(metaPath, {
207
+ encoding: 'utf8'
208
+ }));
209
+ return normalizeTextureImportSettings(meta?.texture, fallbackUsage);
210
+ }
211
+ } catch (err) {
212
+ console.warn(`Ignoring unreadable asset meta ${metaPath}: ${err}`);
213
+ }
214
+ return defaultTextureImportSettings(fallbackUsage);
215
+ }
216
+ /**
217
+ * Writes the import settings of a texture to its `.zmeta` file.
218
+ * @public
219
+ */ async function writeTextureImportSettings(vfs, path, settings) {
220
+ const content = JSON.stringify({
221
+ version: ASSET_META_VERSION,
222
+ texture: settings
223
+ }, null, 2);
224
+ await vfs.writeFile(getAssetMetaPath(path), content, {
225
+ encoding: 'utf8',
226
+ create: true
227
+ });
228
+ }
229
+
230
+ export { ASSET_META_EXTENSION, ASSET_META_VERSION, defaultTextureImportSettings, getAssetMetaPath, inferTextureUsageFromPath, inferTextureUsageFromSlot, isAssetMetaPath, isSRGBTextureUsage, mergeTextureUsage, normalizeTextureImportSettings, readTextureImportSettings, resolveTextureCompression, writeTextureImportSettings };
231
+ //# sourceMappingURL=texture_settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"texture_settings.js","sources":["../../src/asset/texture_settings.ts"],"sourcesContent":["import type { VFS } from '@zephyr3d/base';\r\n\r\n/**\r\n * What a texture holds, which decides its colour space and how it compresses.\r\n *\r\n * - `color`: albedo, emissive and other colour data, sampled as sRGB\r\n * - `normal`: tangent-space normal maps\r\n * - `mask`: linear data such as occlusion/roughness/metallic packs, masks, height\r\n * - `hdr`: high dynamic range images (.hdr, .exr)\r\n * - `ui`: interface images, which keep sharp edges and are never block compressed\r\n *\r\n * @public\r\n */\r\nexport type TextureUsage = 'color' | 'normal' | 'mask' | 'hdr' | 'ui';\r\n\r\n/**\r\n * Basis Universal encoding for a texture.\r\n *\r\n * `auto` picks from the usage: ETC1S for colour (small, block artefacts are hard\r\n * to see), UASTC for normals and masks (artefacts there get amplified by lighting\r\n * or leak between packed channels), none for HDR and UI.\r\n *\r\n * @public\r\n */\r\nexport type TextureCompression = 'auto' | 'etc1s' | 'uastc' | 'none';\r\n\r\n/**\r\n * Encoder effort and fidelity: the ETC1S quality level or the UASTC rate-distortion setting.\r\n * @public\r\n */\r\nexport type TextureQuality = 'low' | 'normal' | 'high';\r\n\r\n/**\r\n * Per-texture import settings, stored next to the source image in a `.zmeta` file.\r\n *\r\n * The source image is never modified; these settings only describe how the asset\r\n * pipeline derives the shipped texture from it.\r\n *\r\n * @public\r\n */\r\nexport interface TextureImportSettings {\r\n usage: TextureUsage;\r\n compression: TextureCompression;\r\n quality: TextureQuality;\r\n /** Largest allowed width or height in texels, 0 keeps the source size */\r\n maxSize: number;\r\n mipmaps: boolean;\r\n}\r\n\r\n/** Extension of asset sidecar files, appended to the asset's full file name. @public */\r\nexport const ASSET_META_EXTENSION = '.zmeta';\r\n\r\n/** Current `.zmeta` format version. @public */\r\nexport const ASSET_META_VERSION = 1;\r\n\r\n/** Usages that hold colour and are sampled as sRGB. */\r\nconst SRGB_USAGES: ReadonlySet<TextureUsage> = new Set(['color', 'ui']);\r\n\r\nconst USAGES: readonly TextureUsage[] = ['color', 'normal', 'mask', 'hdr', 'ui'];\r\nconst COMPRESSIONS: readonly TextureCompression[] = ['auto', 'etc1s', 'uastc', 'none'];\r\nconst QUALITIES: readonly TextureQuality[] = ['low', 'normal', 'high'];\r\n\r\n/**\r\n * Path of the sidecar `.zmeta` file of an asset.\r\n * @public\r\n */\r\nexport function getAssetMetaPath(assetPath: string) {\r\n return `${assetPath}${ASSET_META_EXTENSION}`;\r\n}\r\n\r\n/**\r\n * True if a path is an asset sidecar file rather than an asset.\r\n * @public\r\n */\r\nexport function isAssetMetaPath(path: string) {\r\n return path.toLowerCase().endsWith(ASSET_META_EXTENSION);\r\n}\r\n\r\n/**\r\n * Whether textures of a usage are sampled as sRGB.\r\n * @public\r\n */\r\nexport function isSRGBTextureUsage(usage: TextureUsage) {\r\n return SRGB_USAGES.has(usage);\r\n}\r\n\r\n/**\r\n * Default settings for a usage.\r\n *\r\n * Compression is opt-in: a texture is only compressed when its settings say so,\r\n * so updating the engine or editor never changes how an existing project ships.\r\n * @public\r\n */\r\nexport function defaultTextureImportSettings(\r\n usage: TextureUsage,\r\n compression: TextureCompression = 'none'\r\n): TextureImportSettings {\r\n return { usage, compression, quality: 'normal', maxSize: 0, mipmaps: usage !== 'ui' };\r\n}\r\n\r\n/**\r\n * The encoding a texture actually gets, with `auto` resolved from its usage.\r\n * @public\r\n */\r\nexport function resolveTextureCompression(settings: TextureImportSettings): 'etc1s' | 'uastc' | 'none' {\r\n if (settings.compression !== 'auto') {\r\n return settings.compression;\r\n }\r\n switch (settings.usage) {\r\n case 'color':\r\n return 'etc1s';\r\n case 'normal':\r\n return 'uastc';\r\n case 'mask':\r\n return settings.quality === 'low' ? 'etc1s' : 'uastc';\r\n default:\r\n return 'none';\r\n }\r\n}\r\n\r\n// File name tokens, matched whole after splitting on separators and case changes.\r\n// Common suffix conventions of DCC tools and texture libraries (Substance,\r\n// Quixel, Poly Haven, glTF samples). Only consulted when no material slot told\r\n// the importer what the image is.\r\nconst NORMAL_TOKENS = new Set(['n', 'nrm', 'nor', 'norm', 'normal', 'normals', 'normalmap', 'nml']);\r\nconst MASK_TOKENS = new Set([\r\n 'orm',\r\n 'arm',\r\n 'mra',\r\n 'rma',\r\n 'rough',\r\n 'roughness',\r\n 'metal',\r\n 'metallic',\r\n 'metalness',\r\n 'ao',\r\n 'occlusion',\r\n 'ambientocclusion',\r\n 'mask',\r\n 'masks',\r\n 'spec',\r\n 'specular',\r\n 'gloss',\r\n 'glossiness',\r\n 'height',\r\n 'disp',\r\n 'displacement',\r\n 'bump',\r\n 'opacity',\r\n 'cavity',\r\n 'thickness'\r\n]);\r\n\r\nfunction fileNameTokens(path: string) {\r\n const name = path.slice(path.lastIndexOf('/') + 1);\r\n const dot = name.lastIndexOf('.');\r\n const stem = dot > 0 ? name.slice(0, dot) : name;\r\n return stem\r\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\r\n .toLowerCase()\r\n .split(/[^a-z0-9]+/)\r\n .filter(Boolean);\r\n}\r\n\r\n/**\r\n * Guesses the usage of a texture from its path, for images that arrive without\r\n * material context (dropped into the project, or referenced by no material).\r\n * @public\r\n */\r\nexport function inferTextureUsageFromPath(path: string): TextureUsage {\r\n const lower = path.toLowerCase();\r\n if (lower.endsWith('.hdr') || lower.endsWith('.exr')) {\r\n return 'hdr';\r\n }\r\n if (/(^|\\/)ui\\//.test(lower)) {\r\n return 'ui';\r\n }\r\n const tokens = fileNameTokens(path);\r\n // The last tokens carry the map type in suffix conventions (\"rock_01_nrm\")\r\n for (let i = tokens.length - 1; i >= 0; i--) {\r\n if (NORMAL_TOKENS.has(tokens[i])) {\r\n return 'normal';\r\n }\r\n if (MASK_TOKENS.has(tokens[i])) {\r\n return 'mask';\r\n }\r\n }\r\n return 'color';\r\n}\r\n\r\n/**\r\n * Usage of an image referenced from a model material slot.\r\n *\r\n * @param slot - Material property holding the texture, e.g. `normalMap`\r\n * @param sRGB - Whether the importer samples the slot as sRGB\r\n *\r\n * @public\r\n */\r\nexport function inferTextureUsageFromSlot(slot: string, sRGB: boolean): TextureUsage {\r\n if (/normal/i.test(slot)) {\r\n return 'normal';\r\n }\r\n return sRGB ? 'color' : 'mask';\r\n}\r\n\r\n// When one image feeds several slots, the most demanding usage wins: a normal\r\n// map compressed as colour loses far more than a colour map compressed as data.\r\nconst USAGE_PRIORITY: Record<TextureUsage, number> = { normal: 3, mask: 2, hdr: 2, color: 1, ui: 0 };\r\n\r\n/**\r\n * Picks the usage that serves every slot an image is used in.\r\n * @public\r\n */\r\nexport function mergeTextureUsage(a: TextureUsage, b: TextureUsage): TextureUsage {\r\n return USAGE_PRIORITY[b] > USAGE_PRIORITY[a] ? b : a;\r\n}\r\n\r\nfunction pick<T>(value: unknown, allowed: readonly T[], fallback: T): T {\r\n return allowed.includes(value as T) ? (value as T) : fallback;\r\n}\r\n\r\n/**\r\n * Validates parsed settings, filling anything missing or invalid from the defaults\r\n * of the stored usage (or of `fallbackUsage` when the usage itself is unusable).\r\n * @public\r\n */\r\nexport function normalizeTextureImportSettings(\r\n value: unknown,\r\n fallbackUsage: TextureUsage\r\n): TextureImportSettings {\r\n const v = (value && typeof value === 'object' ? value : {}) as Record<string, unknown>;\r\n const usage = pick(v.usage, USAGES, fallbackUsage);\r\n const defaults = defaultTextureImportSettings(usage);\r\n const maxSize = Number(v.maxSize);\r\n return {\r\n usage,\r\n compression: pick(v.compression, COMPRESSIONS, defaults.compression),\r\n quality: pick(v.quality, QUALITIES, defaults.quality),\r\n maxSize: Number.isFinite(maxSize) && maxSize > 0 ? Math.floor(maxSize) : 0,\r\n mipmaps: typeof v.mipmaps === 'boolean' ? v.mipmaps : defaults.mipmaps\r\n };\r\n}\r\n\r\n/**\r\n * Reads the import settings of a texture. Without a `.zmeta` file (or with an\r\n * unreadable one) the texture is not compressed and its usage is inferred from\r\n * the path, so a texture that was never touched in the editor still has\r\n * well-defined settings that leave it exactly as it was.\r\n * @public\r\n */\r\nexport async function readTextureImportSettings(vfs: VFS, path: string): Promise<TextureImportSettings> {\r\n const fallbackUsage = inferTextureUsageFromPath(path);\r\n const metaPath = getAssetMetaPath(path);\r\n try {\r\n if (await vfs.exists(metaPath)) {\r\n const meta = JSON.parse((await vfs.readFile(metaPath, { encoding: 'utf8' })) as string);\r\n return normalizeTextureImportSettings(meta?.texture, fallbackUsage);\r\n }\r\n } catch (err) {\r\n console.warn(`Ignoring unreadable asset meta ${metaPath}: ${err}`);\r\n }\r\n return defaultTextureImportSettings(fallbackUsage);\r\n}\r\n\r\n/**\r\n * Writes the import settings of a texture to its `.zmeta` file.\r\n * @public\r\n */\r\nexport async function writeTextureImportSettings(vfs: VFS, path: string, settings: TextureImportSettings) {\r\n const content = JSON.stringify({ version: ASSET_META_VERSION, texture: settings }, null, 2);\r\n await vfs.writeFile(getAssetMetaPath(path), content, { encoding: 'utf8', create: true });\r\n}\r\n"],"names":["ASSET_META_EXTENSION","ASSET_META_VERSION","SRGB_USAGES","Set","USAGES","COMPRESSIONS","QUALITIES","getAssetMetaPath","assetPath","isAssetMetaPath","path","toLowerCase","endsWith","isSRGBTextureUsage","usage","has","defaultTextureImportSettings","compression","quality","maxSize","mipmaps","resolveTextureCompression","settings","NORMAL_TOKENS","MASK_TOKENS","fileNameTokens","name","slice","lastIndexOf","dot","stem","replace","split","filter","Boolean","inferTextureUsageFromPath","lower","test","tokens","i","length","inferTextureUsageFromSlot","slot","sRGB","USAGE_PRIORITY","normal","mask","hdr","color","ui","mergeTextureUsage","a","b","pick","value","allowed","fallback","includes","normalizeTextureImportSettings","fallbackUsage","v","defaults","Number","isFinite","Math","floor","readTextureImportSettings","vfs","metaPath","exists","meta","JSON","parse","readFile","encoding","texture","err","console","warn","writeTextureImportSettings","content","stringify","version","writeFile","create"],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ /** @public */ const ZMSH_MAGIC = 0x48534d5a;
2
+ /** @public */ const ZMSH_BINARY_VERSION = 2;
3
+ const PREAMBLE_SIZE = 12;
4
+ function align4(n) {
5
+ return n + 3 & -4;
6
+ }
7
+ /**
8
+ * True if the data is a binary `.zmsh` rather than the JSON form.
9
+ * @public
10
+ */ function isZmshBinary(data) {
11
+ return data.byteLength >= PREAMBLE_SIZE && new DataView(data).getUint32(0, true) === ZMSH_MAGIC;
12
+ }
13
+ /**
14
+ * Assembles a binary `.zmsh`. Stream offsets and lengths in the header are
15
+ * filled in from `attributeData` and `indexData`, which must be in the order of
16
+ * `header.attributes`.
17
+ * @public
18
+ */ function writeZmshBinary(header, attributeData, indexData) {
19
+ if (attributeData.length !== header.attributes.length) {
20
+ throw new Error('writeZmshBinary(): one data array is needed per attribute');
21
+ }
22
+ if (!!indexData !== !!header.indices) {
23
+ throw new Error('writeZmshBinary(): index data and index header must be given together');
24
+ }
25
+ let blobSize = 0;
26
+ const place = (length)=>{
27
+ const offset = blobSize;
28
+ blobSize = align4(blobSize + length);
29
+ return {
30
+ offset,
31
+ length
32
+ };
33
+ };
34
+ const full = {
35
+ ...header,
36
+ attributes: header.attributes.map((a, i)=>({
37
+ ...a,
38
+ ...place(attributeData[i].byteLength)
39
+ })),
40
+ indices: header.indices ? {
41
+ ...header.indices,
42
+ ...place(indexData.byteLength)
43
+ } : null
44
+ };
45
+ const json = new TextEncoder().encode(JSON.stringify(full));
46
+ const headerLength = align4(json.byteLength);
47
+ const out = new Uint8Array(PREAMBLE_SIZE + headerLength + blobSize);
48
+ const view = new DataView(out.buffer);
49
+ view.setUint32(0, ZMSH_MAGIC, true);
50
+ view.setUint32(4, ZMSH_BINARY_VERSION, true);
51
+ view.setUint32(8, headerLength, true);
52
+ out.fill(0x20, PREAMBLE_SIZE, PREAMBLE_SIZE + headerLength);
53
+ out.set(json, PREAMBLE_SIZE);
54
+ const blobStart = PREAMBLE_SIZE + headerLength;
55
+ full.attributes.forEach((a, i)=>out.set(attributeData[i], blobStart + a.offset));
56
+ if (full.indices) {
57
+ out.set(indexData, blobStart + full.indices.offset);
58
+ }
59
+ return out.buffer;
60
+ }
61
+ /**
62
+ * Splits a binary `.zmsh` into its header and stream views. Streams are returned
63
+ * as stored, still encoded when the header says `meshopt`.
64
+ * @public
65
+ */ function readZmshBinary(data) {
66
+ if (!isZmshBinary(data)) {
67
+ throw new Error('Not a binary .zmsh file');
68
+ }
69
+ const view = new DataView(data);
70
+ const version = view.getUint32(4, true);
71
+ if (version !== ZMSH_BINARY_VERSION) {
72
+ throw new Error(`Unsupported binary .zmsh version ${version}`);
73
+ }
74
+ const headerLength = view.getUint32(8, true);
75
+ const blobStart = PREAMBLE_SIZE + headerLength;
76
+ if (blobStart > data.byteLength) {
77
+ throw new Error('Truncated binary .zmsh header');
78
+ }
79
+ const header = JSON.parse(new TextDecoder().decode(new Uint8Array(data, PREAMBLE_SIZE, headerLength)));
80
+ const slice = (offset, length)=>{
81
+ if (blobStart + offset + length > data.byteLength) {
82
+ throw new Error('Truncated binary .zmsh stream');
83
+ }
84
+ return new Uint8Array(data, blobStart + offset, length);
85
+ };
86
+ return {
87
+ header,
88
+ attributes: header.attributes.map((a)=>slice(a.offset, a.length)),
89
+ indices: header.indices ? slice(header.indices.offset, header.indices.length) : null
90
+ };
91
+ }
92
+ /**
93
+ * Decodes the streams of a binary `.zmsh` into raw vertex and index data, ready
94
+ * for GPU upload.
95
+ * @public
96
+ */ function decodeZmshBinary(data, decoder) {
97
+ const { header, attributes, indices } = readZmshBinary(data);
98
+ const meshopt = header.encoding === 'meshopt';
99
+ if (meshopt && !decoder) {
100
+ throw new Error('A meshopt decoder is required for this .zmsh');
101
+ }
102
+ const vertexData = header.attributes.map((a, i)=>{
103
+ if (!meshopt) {
104
+ return attributes[i];
105
+ }
106
+ const target = new Uint8Array(header.vertexCount * a.byteStride);
107
+ decoder.decodeGltfBuffer(target, header.vertexCount, a.byteStride, attributes[i], 'ATTRIBUTES', a.filter);
108
+ return target;
109
+ });
110
+ let indexData = null;
111
+ if (header.indices && indices) {
112
+ const size = header.indices.type === 'u16' ? 2 : 4;
113
+ let bytes;
114
+ if (meshopt) {
115
+ bytes = new Uint8Array(header.indexCount * size);
116
+ decoder.decodeGltfBuffer(bytes, header.indexCount, size, indices, header.indices.mode);
117
+ } else {
118
+ // Copy so the typed array is aligned regardless of where the stream sat in the file
119
+ bytes = indices.slice();
120
+ }
121
+ indexData = size === 2 ? new Uint16Array(bytes.buffer, bytes.byteOffset, header.indexCount) : new Uint32Array(bytes.buffer, bytes.byteOffset, header.indexCount);
122
+ }
123
+ return {
124
+ header,
125
+ vertexData,
126
+ indexData
127
+ };
128
+ }
129
+
130
+ export { ZMSH_BINARY_VERSION, ZMSH_MAGIC, decodeZmshBinary, isZmshBinary, readZmshBinary, writeZmshBinary };
131
+ //# sourceMappingURL=zmsh_binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zmsh_binary.js","sources":["../../src/asset/zmsh_binary.ts"],"sourcesContent":["import type { VertexAttribFormat } from '@zephyr3d/device';\r\nimport type { PrimitiveType } from '@zephyr3d/device';\r\n\r\n/**\r\n * Binary `.zmsh` container, version 2.\r\n *\r\n * Laid out like GLB: a fixed preamble, a JSON header describing the mesh, then\r\n * one binary blob holding every stream back to back.\r\n *\r\n * ```\r\n * u32 magic 'ZMSH' (0x48534d5a little endian)\r\n * u32 version 2\r\n * u32 headerLength byte length of the JSON header, a multiple of 4\r\n * u8[headerLength] JSON header (UTF-8, padded with spaces)\r\n * u8[...] blob; every stream offset is relative to its start and 4-byte aligned\r\n * ```\r\n *\r\n * Streams are meshoptimizer-encoded when `encoding` is `meshopt` (the\r\n * KHR_meshopt_compression bitstream, decoded with `decodeGltfBuffer`), raw\r\n * otherwise. Version 1 is the JSON + base64 form, which readers keep accepting.\r\n *\r\n * @public\r\n */\r\nexport interface ZmshBinaryHeader {\r\n primitiveType: PrimitiveType;\r\n vertexCount: number;\r\n indexCount: number;\r\n boxMin: [number, number, number];\r\n boxMax: [number, number, number];\r\n encoding: 'meshopt' | 'none';\r\n attributes: ZmshBinaryStream[];\r\n indices: ZmshBinaryIndexStream | null;\r\n /**\r\n * Levels of detail, finest first, each a range of the index stream drawing the shared vertices.\r\n * Absent for a single level, which draws all indexCount indices. The screen size of the first\r\n * level is not used.\r\n */\r\n lods?: ZmshBinaryLod[];\r\n}\r\n\r\n/**\r\n * One level of detail of a binary `.zmsh`, see {@link PrimitiveLod}.\r\n * @public\r\n */\r\nexport interface ZmshBinaryLod {\r\n indexStart: number;\r\n indexCount: number;\r\n screenSize: number;\r\n hysteresis: number;\r\n}\r\n\r\n/**\r\n * One vertex stream of a binary `.zmsh`.\r\n * @public\r\n */\r\nexport interface ZmshBinaryStream {\r\n format: VertexAttribFormat;\r\n /** Bytes per vertex; meshopt requires a multiple of 4 no larger than 256 */\r\n byteStride: number;\r\n /** meshopt filter the stream was encoded with: OCTAHEDRAL, QUATERNION, EXPONENTIAL or COLOR */\r\n filter?: string;\r\n offset: number;\r\n length: number;\r\n}\r\n\r\n/**\r\n * The index stream of a binary `.zmsh`.\r\n * @public\r\n */\r\nexport interface ZmshBinaryIndexStream {\r\n type: 'u16' | 'u32';\r\n /** meshopt mode: TRIANGLES for triangle lists, INDICES for any other topology */\r\n mode: 'TRIANGLES' | 'INDICES';\r\n offset: number;\r\n length: number;\r\n}\r\n\r\n/** @public */\r\nexport const ZMSH_MAGIC = 0x48534d5a;\r\n/** @public */\r\nexport const ZMSH_BINARY_VERSION = 2;\r\n\r\nconst PREAMBLE_SIZE = 12;\r\n\r\nfunction align4(n: number) {\r\n return (n + 3) & ~3;\r\n}\r\n\r\n/**\r\n * True if the data is a binary `.zmsh` rather than the JSON form.\r\n * @public\r\n */\r\nexport function isZmshBinary(data: ArrayBuffer) {\r\n return data.byteLength >= PREAMBLE_SIZE && new DataView(data).getUint32(0, true) === ZMSH_MAGIC;\r\n}\r\n\r\n/**\r\n * Assembles a binary `.zmsh`. Stream offsets and lengths in the header are\r\n * filled in from `attributeData` and `indexData`, which must be in the order of\r\n * `header.attributes`.\r\n * @public\r\n */\r\nexport function writeZmshBinary(\r\n header: Omit<ZmshBinaryHeader, 'attributes' | 'indices'> & {\r\n attributes: Omit<ZmshBinaryStream, 'offset' | 'length'>[];\r\n indices: Omit<ZmshBinaryIndexStream, 'offset' | 'length'> | null;\r\n },\r\n attributeData: Uint8Array[],\r\n indexData: Uint8Array | null\r\n): ArrayBuffer {\r\n if (attributeData.length !== header.attributes.length) {\r\n throw new Error('writeZmshBinary(): one data array is needed per attribute');\r\n }\r\n if (!!indexData !== !!header.indices) {\r\n throw new Error('writeZmshBinary(): index data and index header must be given together');\r\n }\r\n let blobSize = 0;\r\n const place = (length: number) => {\r\n const offset = blobSize;\r\n blobSize = align4(blobSize + length);\r\n return { offset, length };\r\n };\r\n const full: ZmshBinaryHeader = {\r\n ...header,\r\n attributes: header.attributes.map((a, i) => ({ ...a, ...place(attributeData[i].byteLength) })),\r\n indices: header.indices ? { ...header.indices, ...place(indexData!.byteLength) } : null\r\n };\r\n const json = new TextEncoder().encode(JSON.stringify(full));\r\n const headerLength = align4(json.byteLength);\r\n const out = new Uint8Array(PREAMBLE_SIZE + headerLength + blobSize);\r\n const view = new DataView(out.buffer);\r\n view.setUint32(0, ZMSH_MAGIC, true);\r\n view.setUint32(4, ZMSH_BINARY_VERSION, true);\r\n view.setUint32(8, headerLength, true);\r\n out.fill(0x20, PREAMBLE_SIZE, PREAMBLE_SIZE + headerLength);\r\n out.set(json, PREAMBLE_SIZE);\r\n const blobStart = PREAMBLE_SIZE + headerLength;\r\n full.attributes.forEach((a, i) => out.set(attributeData[i], blobStart + a.offset));\r\n if (full.indices) {\r\n out.set(indexData!, blobStart + full.indices.offset);\r\n }\r\n return out.buffer;\r\n}\r\n\r\n/**\r\n * Splits a binary `.zmsh` into its header and stream views. Streams are returned\r\n * as stored, still encoded when the header says `meshopt`.\r\n * @public\r\n */\r\nexport function readZmshBinary(data: ArrayBuffer) {\r\n if (!isZmshBinary(data)) {\r\n throw new Error('Not a binary .zmsh file');\r\n }\r\n const view = new DataView(data);\r\n const version = view.getUint32(4, true);\r\n if (version !== ZMSH_BINARY_VERSION) {\r\n throw new Error(`Unsupported binary .zmsh version ${version}`);\r\n }\r\n const headerLength = view.getUint32(8, true);\r\n const blobStart = PREAMBLE_SIZE + headerLength;\r\n if (blobStart > data.byteLength) {\r\n throw new Error('Truncated binary .zmsh header');\r\n }\r\n const header = JSON.parse(\r\n new TextDecoder().decode(new Uint8Array(data, PREAMBLE_SIZE, headerLength))\r\n ) as ZmshBinaryHeader;\r\n const slice = (offset: number, length: number) => {\r\n if (blobStart + offset + length > data.byteLength) {\r\n throw new Error('Truncated binary .zmsh stream');\r\n }\r\n return new Uint8Array(data, blobStart + offset, length);\r\n };\r\n return {\r\n header,\r\n attributes: header.attributes.map((a) => slice(a.offset, a.length)),\r\n indices: header.indices ? slice(header.indices.offset, header.indices.length) : null\r\n };\r\n}\r\n\r\n/**\r\n * The subset of meshoptimizer's MeshoptDecoder the engine uses.\r\n * @public\r\n */\r\nexport interface MeshoptDecoderModule {\r\n ready: Promise<void>;\r\n decodeGltfBuffer(\r\n target: Uint8Array,\r\n count: number,\r\n size: number,\r\n source: Uint8Array,\r\n mode: string,\r\n filter?: string\r\n ): void;\r\n}\r\n\r\n/**\r\n * Decodes the streams of a binary `.zmsh` into raw vertex and index data, ready\r\n * for GPU upload.\r\n * @public\r\n */\r\nexport function decodeZmshBinary(data: ArrayBuffer, decoder: MeshoptDecoderModule | null) {\r\n const { header, attributes, indices } = readZmshBinary(data);\r\n const meshopt = header.encoding === 'meshopt';\r\n if (meshopt && !decoder) {\r\n throw new Error('A meshopt decoder is required for this .zmsh');\r\n }\r\n const vertexData = header.attributes.map((a, i) => {\r\n if (!meshopt) {\r\n return attributes[i];\r\n }\r\n const target = new Uint8Array(header.vertexCount * a.byteStride);\r\n decoder!.decodeGltfBuffer(\r\n target,\r\n header.vertexCount,\r\n a.byteStride,\r\n attributes[i],\r\n 'ATTRIBUTES',\r\n a.filter\r\n );\r\n return target;\r\n });\r\n let indexData: Uint16Array<ArrayBuffer> | Uint32Array<ArrayBuffer> | null = null;\r\n if (header.indices && indices) {\r\n const size = header.indices.type === 'u16' ? 2 : 4;\r\n let bytes: Uint8Array;\r\n if (meshopt) {\r\n bytes = new Uint8Array(header.indexCount * size);\r\n decoder!.decodeGltfBuffer(bytes, header.indexCount, size, indices, header.indices.mode);\r\n } else {\r\n // Copy so the typed array is aligned regardless of where the stream sat in the file\r\n bytes = indices.slice();\r\n }\r\n indexData =\r\n size === 2\r\n ? new Uint16Array(bytes.buffer as ArrayBuffer, bytes.byteOffset, header.indexCount)\r\n : new Uint32Array(bytes.buffer as ArrayBuffer, bytes.byteOffset, header.indexCount);\r\n }\r\n return { header, vertexData, indexData };\r\n}\r\n"],"names":["ZMSH_MAGIC","ZMSH_BINARY_VERSION","PREAMBLE_SIZE","align4","n","isZmshBinary","data","byteLength","DataView","getUint32","writeZmshBinary","header","attributeData","indexData","length","attributes","Error","indices","blobSize","place","offset","full","map","a","i","json","TextEncoder","encode","JSON","stringify","headerLength","out","Uint8Array","view","buffer","setUint32","fill","set","blobStart","forEach","readZmshBinary","version","parse","TextDecoder","decode","slice","decodeZmshBinary","decoder","meshopt","encoding","vertexData","target","vertexCount","byteStride","decodeGltfBuffer","filter","size","type","bytes","indexCount","mode","Uint16Array","byteOffset","Uint32Array"],"mappings":"AA6EA,eACaA,MAAAA,UAAAA,GAAa;AAC1B,eACaC,MAAAA,mBAAAA,GAAsB;AAEnC,MAAMC,aAAgB,GAAA,EAAA;AAEtB,SAASC,OAAOC,CAAS,EAAA;IACvB,OAAQA,CAAI,GAAA,CAAA,GAAK,EAAC;AACpB;AAEA;;;IAIO,SAASC,YAAAA,CAAaC,IAAiB,EAAA;IAC5C,OAAOA,IAAAA,CAAKC,UAAU,IAAIL,aAAiB,IAAA,IAAIM,SAASF,IAAMG,CAAAA,CAAAA,SAAS,CAAC,CAAA,EAAG,IAAUT,CAAAA,KAAAA,UAAAA;AACvF;AAEA;;;;;AAKC,IACM,SAASU,eAAAA,CACdC,MAGC,EACDC,aAA2B,EAC3BC,SAA4B,EAAA;AAE5B,IAAA,IAAID,cAAcE,MAAM,KAAKH,OAAOI,UAAU,CAACD,MAAM,EAAE;AACrD,QAAA,MAAM,IAAIE,KAAM,CAAA,2DAAA,CAAA;AAClB;AACA,IAAA,IAAI,CAAC,CAACH,SAAAA,KAAc,CAAC,CAACF,MAAAA,CAAOM,OAAO,EAAE;AACpC,QAAA,MAAM,IAAID,KAAM,CAAA,uEAAA,CAAA;AAClB;AACA,IAAA,IAAIE,QAAW,GAAA,CAAA;AACf,IAAA,MAAMC,QAAQ,CAACL,MAAAA,GAAAA;AACb,QAAA,MAAMM,MAASF,GAAAA,QAAAA;AACfA,QAAAA,QAAAA,GAAWf,OAAOe,QAAWJ,GAAAA,MAAAA,CAAAA;QAC7B,OAAO;AAAEM,YAAAA,MAAAA;AAAQN,YAAAA;AAAO,SAAA;AAC1B,KAAA;AACA,IAAA,MAAMO,IAAyB,GAAA;AAC7B,QAAA,GAAGV,MAAM;QACTI,UAAYJ,EAAAA,MAAAA,CAAOI,UAAU,CAACO,GAAG,CAAC,CAACC,CAAAA,EAAGC,KAAO;AAAE,gBAAA,GAAGD,CAAC;AAAE,gBAAA,GAAGJ,MAAMP,aAAa,CAACY,CAAE,CAAA,CAACjB,UAAU;aAAE,CAAA,CAAA;QAC3FU,OAASN,EAAAA,MAAAA,CAAOM,OAAO,GAAG;AAAE,YAAA,GAAGN,OAAOM,OAAO;YAAE,GAAGE,KAAAA,CAAMN,SAAWN,CAAAA,UAAU;SAAM,GAAA;AACrF,KAAA;AACA,IAAA,MAAMkB,OAAO,IAAIC,WAAAA,EAAAA,CAAcC,MAAM,CAACC,IAAAA,CAAKC,SAAS,CAACR,IAAAA,CAAAA,CAAAA;IACrD,MAAMS,YAAAA,GAAe3B,MAAOsB,CAAAA,IAAAA,CAAKlB,UAAU,CAAA;AAC3C,IAAA,MAAMwB,GAAM,GAAA,IAAIC,UAAW9B,CAAAA,aAAAA,GAAgB4B,YAAeZ,GAAAA,QAAAA,CAAAA;AAC1D,IAAA,MAAMe,IAAO,GAAA,IAAIzB,QAASuB,CAAAA,GAAAA,CAAIG,MAAM,CAAA;IACpCD,IAAKE,CAAAA,SAAS,CAAC,CAAA,EAAGnC,UAAY,EAAA,IAAA,CAAA;IAC9BiC,IAAKE,CAAAA,SAAS,CAAC,CAAA,EAAGlC,mBAAqB,EAAA,IAAA,CAAA;IACvCgC,IAAKE,CAAAA,SAAS,CAAC,CAAA,EAAGL,YAAc,EAAA,IAAA,CAAA;AAChCC,IAAAA,GAAAA,CAAIK,IAAI,CAAC,IAAMlC,EAAAA,aAAAA,EAAeA,aAAgB4B,GAAAA,YAAAA,CAAAA;IAC9CC,GAAIM,CAAAA,GAAG,CAACZ,IAAMvB,EAAAA,aAAAA,CAAAA;AACd,IAAA,MAAMoC,YAAYpC,aAAgB4B,GAAAA,YAAAA;AAClCT,IAAAA,IAAAA,CAAKN,UAAU,CAACwB,OAAO,CAAC,CAAChB,GAAGC,CAAMO,GAAAA,GAAAA,CAAIM,GAAG,CAACzB,aAAa,CAACY,CAAAA,CAAE,EAAEc,SAAAA,GAAYf,EAAEH,MAAM,CAAA,CAAA;IAChF,IAAIC,IAAAA,CAAKJ,OAAO,EAAE;AAChBc,QAAAA,GAAAA,CAAIM,GAAG,CAACxB,SAAAA,EAAYyB,YAAYjB,IAAKJ,CAAAA,OAAO,CAACG,MAAM,CAAA;AACrD;AACA,IAAA,OAAOW,IAAIG,MAAM;AACnB;AAEA;;;;IAKO,SAASM,cAAAA,CAAelC,IAAiB,EAAA;IAC9C,IAAI,CAACD,aAAaC,IAAO,CAAA,EAAA;AACvB,QAAA,MAAM,IAAIU,KAAM,CAAA,yBAAA,CAAA;AAClB;IACA,MAAMiB,IAAAA,GAAO,IAAIzB,QAASF,CAAAA,IAAAA,CAAAA;AAC1B,IAAA,MAAMmC,OAAUR,GAAAA,IAAAA,CAAKxB,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AAClC,IAAA,IAAIgC,YAAYxC,mBAAqB,EAAA;AACnC,QAAA,MAAM,IAAIe,KAAAA,CAAM,CAAC,iCAAiC,EAAEyB,OAAS,CAAA,CAAA,CAAA;AAC/D;AACA,IAAA,MAAMX,YAAeG,GAAAA,IAAAA,CAAKxB,SAAS,CAAC,CAAG,EAAA,IAAA,CAAA;AACvC,IAAA,MAAM6B,YAAYpC,aAAgB4B,GAAAA,YAAAA;IAClC,IAAIQ,SAAAA,GAAYhC,IAAKC,CAAAA,UAAU,EAAE;AAC/B,QAAA,MAAM,IAAIS,KAAM,CAAA,+BAAA,CAAA;AAClB;IACA,MAAML,MAAAA,GAASiB,IAAKc,CAAAA,KAAK,CACvB,IAAIC,WAAcC,EAAAA,CAAAA,MAAM,CAAC,IAAIZ,UAAW1B,CAAAA,IAAAA,EAAMJ,aAAe4B,EAAAA,YAAAA,CAAAA,CAAAA,CAAAA;IAE/D,MAAMe,KAAAA,GAAQ,CAACzB,MAAgBN,EAAAA,MAAAA,GAAAA;AAC7B,QAAA,IAAIwB,SAAYlB,GAAAA,MAAAA,GAASN,MAASR,GAAAA,IAAAA,CAAKC,UAAU,EAAE;AACjD,YAAA,MAAM,IAAIS,KAAM,CAAA,+BAAA,CAAA;AAClB;AACA,QAAA,OAAO,IAAIgB,UAAAA,CAAW1B,IAAMgC,EAAAA,SAAAA,GAAYlB,MAAQN,EAAAA,MAAAA,CAAAA;AAClD,KAAA;IACA,OAAO;AACLH,QAAAA,MAAAA;AACAI,QAAAA,UAAAA,EAAYJ,MAAOI,CAAAA,UAAU,CAACO,GAAG,CAAC,CAACC,CAAMsB,GAAAA,KAAAA,CAAMtB,CAAEH,CAAAA,MAAM,EAAEG,CAAAA,CAAET,MAAM,CAAA,CAAA;AACjEG,QAAAA,OAAAA,EAASN,MAAOM,CAAAA,OAAO,GAAG4B,KAAAA,CAAMlC,MAAOM,CAAAA,OAAO,CAACG,MAAM,EAAET,MAAAA,CAAOM,OAAO,CAACH,MAAM,CAAI,GAAA;AAClF,KAAA;AACF;AAkBA;;;;AAIC,IACM,SAASgC,gBAAiBxC,CAAAA,IAAiB,EAAEyC,OAAoC,EAAA;IACtF,MAAM,EAAEpC,MAAM,EAAEI,UAAU,EAAEE,OAAO,EAAE,GAAGuB,cAAelC,CAAAA,IAAAA,CAAAA;IACvD,MAAM0C,OAAAA,GAAUrC,MAAOsC,CAAAA,QAAQ,KAAK,SAAA;IACpC,IAAID,OAAAA,IAAW,CAACD,OAAS,EAAA;AACvB,QAAA,MAAM,IAAI/B,KAAM,CAAA,8CAAA,CAAA;AAClB;AACA,IAAA,MAAMkC,aAAavC,MAAOI,CAAAA,UAAU,CAACO,GAAG,CAAC,CAACC,CAAGC,EAAAA,CAAAA,GAAAA;AAC3C,QAAA,IAAI,CAACwB,OAAS,EAAA;YACZ,OAAOjC,UAAU,CAACS,CAAE,CAAA;AACtB;AACA,QAAA,MAAM2B,SAAS,IAAInB,UAAAA,CAAWrB,OAAOyC,WAAW,GAAG7B,EAAE8B,UAAU,CAAA;AAC/DN,QAAAA,OAAAA,CAASO,gBAAgB,CACvBH,MACAxC,EAAAA,MAAAA,CAAOyC,WAAW,EAClB7B,CAAAA,CAAE8B,UAAU,EACZtC,UAAU,CAACS,CAAAA,CAAE,EACb,YAAA,EACAD,EAAEgC,MAAM,CAAA;QAEV,OAAOJ,MAAAA;AACT,KAAA,CAAA;AACA,IAAA,IAAItC,SAAwE,GAAA,IAAA;IAC5E,IAAIF,MAAAA,CAAOM,OAAO,IAAIA,OAAS,EAAA;AAC7B,QAAA,MAAMuC,OAAO7C,MAAOM,CAAAA,OAAO,CAACwC,IAAI,KAAK,QAAQ,CAAI,GAAA,CAAA;QACjD,IAAIC,KAAAA;AACJ,QAAA,IAAIV,OAAS,EAAA;AACXU,YAAAA,KAAAA,GAAQ,IAAI1B,UAAAA,CAAWrB,MAAOgD,CAAAA,UAAU,GAAGH,IAAAA,CAAAA;YAC3CT,OAASO,CAAAA,gBAAgB,CAACI,KAAAA,EAAO/C,MAAOgD,CAAAA,UAAU,EAAEH,IAAAA,EAAMvC,OAASN,EAAAA,MAAAA,CAAOM,OAAO,CAAC2C,IAAI,CAAA;SACjF,MAAA;;AAELF,YAAAA,KAAAA,GAAQzC,QAAQ4B,KAAK,EAAA;AACvB;QACAhC,SACE2C,GAAAA,IAAAA,KAAS,IACL,IAAIK,WAAAA,CAAYH,MAAMxB,MAAM,EAAiBwB,KAAMI,CAAAA,UAAU,EAAEnD,MAAAA,CAAOgD,UAAU,CAChF,GAAA,IAAII,YAAYL,KAAMxB,CAAAA,MAAM,EAAiBwB,KAAMI,CAAAA,UAAU,EAAEnD,MAAAA,CAAOgD,UAAU,CAAA;AACxF;IACA,OAAO;AAAEhD,QAAAA,MAAAA;AAAQuC,QAAAA,UAAAA;AAAYrC,QAAAA;AAAU,KAAA;AACzC;;;;"}
@@ -0,0 +1,111 @@
1
+ import { float2half, halfToFloat } from '@zephyr3d/base';
2
+
3
+ /** @public */ const ZSDF_MAGIC = 0x4644535a;
4
+ /** @public */ const ZSDF_VERSION = 1;
5
+ const PREAMBLE_SIZE = 12;
6
+ /**
7
+ * True if the data is a `.zsdf`.
8
+ * @public
9
+ */ function isZsdf(data) {
10
+ return data.byteLength >= PREAMBLE_SIZE && new DataView(data).getUint32(0, true) === ZSDF_MAGIC;
11
+ }
12
+ /**
13
+ * Encodes a baked field as a `.zsdf`.
14
+ * @public
15
+ */ function writeZsdf(sdf, source) {
16
+ const header = {
17
+ encoding: 'f16',
18
+ boxMin: sdf.boxMin,
19
+ boxMax: sdf.boxMax,
20
+ resolution: sdf.resolution,
21
+ voxelSize: sdf.voxelSize,
22
+ meshBoxMin: sdf.meshBoxMin,
23
+ meshBoxMax: sdf.meshBoxMax,
24
+ twoSided: sdf.twoSided,
25
+ minDistance: sdf.minDistance,
26
+ maxDistance: sdf.maxDistance,
27
+ ...source ? {
28
+ source
29
+ } : {}
30
+ };
31
+ const json = new TextEncoder().encode(JSON.stringify(header));
32
+ const headerLength = json.byteLength + 3 & -4;
33
+ const count = sdf.distances.length;
34
+ const out = new Uint8Array(PREAMBLE_SIZE + headerLength + count * 2);
35
+ const view = new DataView(out.buffer);
36
+ view.setUint32(0, ZSDF_MAGIC, true);
37
+ view.setUint32(4, ZSDF_VERSION, true);
38
+ view.setUint32(8, headerLength, true);
39
+ out.fill(0x20, PREAMBLE_SIZE, PREAMBLE_SIZE + headerLength);
40
+ out.set(json, PREAMBLE_SIZE);
41
+ const voxels = new Uint16Array(out.buffer, PREAMBLE_SIZE + headerLength, count);
42
+ for(let i = 0; i < count; i++){
43
+ voxels[i] = float2half(sdf.distances[i]);
44
+ }
45
+ return out.buffer;
46
+ }
47
+ /**
48
+ * Splits a `.zsdf` into its header and its raw half-float voxels, as stored,
49
+ * ready for upload to an `r16f` texture.
50
+ * @public
51
+ */ function readZsdf(data) {
52
+ if (!isZsdf(data)) {
53
+ throw new Error('Not a .zsdf file');
54
+ }
55
+ const view = new DataView(data);
56
+ const version = view.getUint32(4, true);
57
+ if (version !== ZSDF_VERSION) {
58
+ throw new Error(`Unsupported .zsdf version ${version}`);
59
+ }
60
+ const headerLength = view.getUint32(8, true);
61
+ const header = JSON.parse(new TextDecoder().decode(new Uint8Array(data, PREAMBLE_SIZE, headerLength)));
62
+ if (header.encoding !== 'f16') {
63
+ throw new Error(`Unsupported .zsdf encoding ${header.encoding}`);
64
+ }
65
+ const count = header.resolution[0] * header.resolution[1] * header.resolution[2];
66
+ const start = PREAMBLE_SIZE + headerLength;
67
+ if (start + count * 2 > data.byteLength) {
68
+ throw new Error('Truncated .zsdf');
69
+ }
70
+ // Copy so the view is aligned and independent of the file buffer
71
+ const voxels = new Uint16Array(data.slice(start, start + count * 2));
72
+ return {
73
+ header,
74
+ voxels
75
+ };
76
+ }
77
+ /**
78
+ * Decodes a `.zsdf` into a {@link MeshSDFData} with float distances, for CPU queries.
79
+ * @public
80
+ */ function decodeZsdf(data) {
81
+ const { header, voxels } = readZsdf(data);
82
+ const distances = new Float32Array(voxels.length);
83
+ for(let i = 0; i < voxels.length; i++){
84
+ distances[i] = halfToFloat(voxels[i]);
85
+ }
86
+ return {
87
+ boxMin: header.boxMin,
88
+ boxMax: header.boxMax,
89
+ resolution: header.resolution,
90
+ voxelSize: header.voxelSize,
91
+ meshBoxMin: header.meshBoxMin,
92
+ meshBoxMax: header.meshBoxMax,
93
+ twoSided: header.twoSided,
94
+ minDistance: header.minDistance,
95
+ maxDistance: header.maxDistance,
96
+ distances
97
+ };
98
+ }
99
+ /** Directory the baked fields of a project live in. @public */ const MESH_SDF_DIR = '/assets/.sdf';
100
+ /**
101
+ * Path of the field baked for a mesh asset: the asset path flattened into one
102
+ * file name under {@link MESH_SDF_DIR}, so the runtime finds it without an index.
103
+ * @param primitivePath - Asset path of the `.zmsh`, e.g. `/assets/models/car/chassis.zmsh`.
104
+ * @public
105
+ */ function getMeshSDFPath(primitivePath) {
106
+ const rel = primitivePath.replace(/^\/assets\//, '').replace(/^\/+/, '');
107
+ return `${MESH_SDF_DIR}/${rel.replace(/[\\/]/g, '__')}.zsdf`;
108
+ }
109
+
110
+ export { MESH_SDF_DIR, ZSDF_MAGIC, ZSDF_VERSION, decodeZsdf, getMeshSDFPath, isZsdf, readZsdf, writeZsdf };
111
+ //# sourceMappingURL=zsdf_binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zsdf_binary.js","sources":["../../src/asset/zsdf_binary.ts"],"sourcesContent":["import { float2half, halfToFloat } from '@zephyr3d/base';\r\nimport type { MeshSDFData } from '../utility/sdf/bake';\r\n\r\n/**\r\n * Binary `.zsdf` container: the signed distance field baked for a mesh.\r\n *\r\n * ```\r\n * u32 magic 'ZSDF' (0x4644535a little endian)\r\n * u32 version 1\r\n * u32 headerLength byte length of the JSON header, a multiple of 4\r\n * u8[headerLength] JSON header (UTF-8, padded with spaces)\r\n * u8[...] voxel data, `resolution` x * y * z samples, x fastest\r\n * ```\r\n *\r\n * `encoding` `f16` stores one half float per voxel, the distance in the\r\n * mesh's local units. The field leaves room for sparse or quantized encodings.\r\n *\r\n * @public\r\n */\r\nexport interface ZsdfHeader {\r\n encoding: 'f16';\r\n boxMin: [number, number, number];\r\n boxMax: [number, number, number];\r\n resolution: [number, number, number];\r\n voxelSize: number;\r\n meshBoxMin: [number, number, number];\r\n meshBoxMax: [number, number, number];\r\n twoSided: boolean;\r\n minDistance: number;\r\n maxDistance: number;\r\n /**\r\n * What the field was baked from, for the editor to tell a stale bake: the\r\n * content hash of the source mesh and the bake settings key.\r\n */\r\n source?: { hash: string; settings: string };\r\n}\r\n\r\n/** @public */\r\nexport const ZSDF_MAGIC = 0x4644535a;\r\n/** @public */\r\nexport const ZSDF_VERSION = 1;\r\n\r\nconst PREAMBLE_SIZE = 12;\r\n\r\n/**\r\n * True if the data is a `.zsdf`.\r\n * @public\r\n */\r\nexport function isZsdf(data: ArrayBuffer) {\r\n return data.byteLength >= PREAMBLE_SIZE && new DataView(data).getUint32(0, true) === ZSDF_MAGIC;\r\n}\r\n\r\n/**\r\n * Encodes a baked field as a `.zsdf`.\r\n * @public\r\n */\r\nexport function writeZsdf(sdf: MeshSDFData, source?: ZsdfHeader['source']): ArrayBuffer {\r\n const header: ZsdfHeader = {\r\n encoding: 'f16',\r\n boxMin: sdf.boxMin,\r\n boxMax: sdf.boxMax,\r\n resolution: sdf.resolution,\r\n voxelSize: sdf.voxelSize,\r\n meshBoxMin: sdf.meshBoxMin,\r\n meshBoxMax: sdf.meshBoxMax,\r\n twoSided: sdf.twoSided,\r\n minDistance: sdf.minDistance,\r\n maxDistance: sdf.maxDistance,\r\n ...(source ? { source } : {})\r\n };\r\n const json = new TextEncoder().encode(JSON.stringify(header));\r\n const headerLength = (json.byteLength + 3) & ~3;\r\n const count = sdf.distances.length;\r\n const out = new Uint8Array(PREAMBLE_SIZE + headerLength + count * 2);\r\n const view = new DataView(out.buffer);\r\n view.setUint32(0, ZSDF_MAGIC, true);\r\n view.setUint32(4, ZSDF_VERSION, true);\r\n view.setUint32(8, headerLength, true);\r\n out.fill(0x20, PREAMBLE_SIZE, PREAMBLE_SIZE + headerLength);\r\n out.set(json, PREAMBLE_SIZE);\r\n const voxels = new Uint16Array(out.buffer, PREAMBLE_SIZE + headerLength, count);\r\n for (let i = 0; i < count; i++) {\r\n voxels[i] = float2half(sdf.distances[i]);\r\n }\r\n return out.buffer;\r\n}\r\n\r\n/**\r\n * Splits a `.zsdf` into its header and its raw half-float voxels, as stored,\r\n * ready for upload to an `r16f` texture.\r\n * @public\r\n */\r\nexport function readZsdf(data: ArrayBuffer) {\r\n if (!isZsdf(data)) {\r\n throw new Error('Not a .zsdf file');\r\n }\r\n const view = new DataView(data);\r\n const version = view.getUint32(4, true);\r\n if (version !== ZSDF_VERSION) {\r\n throw new Error(`Unsupported .zsdf version ${version}`);\r\n }\r\n const headerLength = view.getUint32(8, true);\r\n const header = JSON.parse(\r\n new TextDecoder().decode(new Uint8Array(data, PREAMBLE_SIZE, headerLength))\r\n ) as ZsdfHeader;\r\n if (header.encoding !== 'f16') {\r\n throw new Error(`Unsupported .zsdf encoding ${header.encoding}`);\r\n }\r\n const count = header.resolution[0] * header.resolution[1] * header.resolution[2];\r\n const start = PREAMBLE_SIZE + headerLength;\r\n if (start + count * 2 > data.byteLength) {\r\n throw new Error('Truncated .zsdf');\r\n }\r\n // Copy so the view is aligned and independent of the file buffer\r\n const voxels = new Uint16Array(data.slice(start, start + count * 2));\r\n return { header, voxels };\r\n}\r\n\r\n/**\r\n * Decodes a `.zsdf` into a {@link MeshSDFData} with float distances, for CPU queries.\r\n * @public\r\n */\r\nexport function decodeZsdf(data: ArrayBuffer): MeshSDFData {\r\n const { header, voxels } = readZsdf(data);\r\n const distances = new Float32Array(voxels.length);\r\n for (let i = 0; i < voxels.length; i++) {\r\n distances[i] = halfToFloat(voxels[i]);\r\n }\r\n return {\r\n boxMin: header.boxMin,\r\n boxMax: header.boxMax,\r\n resolution: header.resolution,\r\n voxelSize: header.voxelSize,\r\n meshBoxMin: header.meshBoxMin,\r\n meshBoxMax: header.meshBoxMax,\r\n twoSided: header.twoSided,\r\n minDistance: header.minDistance,\r\n maxDistance: header.maxDistance,\r\n distances\r\n };\r\n}\r\n\r\n/** Directory the baked fields of a project live in. @public */\r\nexport const MESH_SDF_DIR = '/assets/.sdf';\r\n\r\n/**\r\n * Path of the field baked for a mesh asset: the asset path flattened into one\r\n * file name under {@link MESH_SDF_DIR}, so the runtime finds it without an index.\r\n * @param primitivePath - Asset path of the `.zmsh`, e.g. `/assets/models/car/chassis.zmsh`.\r\n * @public\r\n */\r\nexport function getMeshSDFPath(primitivePath: string) {\r\n const rel = primitivePath.replace(/^\\/assets\\//, '').replace(/^\\/+/, '');\r\n return `${MESH_SDF_DIR}/${rel.replace(/[\\\\/]/g, '__')}.zsdf`;\r\n}\r\n"],"names":["ZSDF_MAGIC","ZSDF_VERSION","PREAMBLE_SIZE","isZsdf","data","byteLength","DataView","getUint32","writeZsdf","sdf","source","header","encoding","boxMin","boxMax","resolution","voxelSize","meshBoxMin","meshBoxMax","twoSided","minDistance","maxDistance","json","TextEncoder","encode","JSON","stringify","headerLength","count","distances","length","out","Uint8Array","view","buffer","setUint32","fill","set","voxels","Uint16Array","i","float2half","readZsdf","Error","version","parse","TextDecoder","decode","start","slice","decodeZsdf","Float32Array","halfToFloat","MESH_SDF_DIR","getMeshSDFPath","primitivePath","rel","replace"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Blitter } from './blitter.js';
2
- import { decodeNormalizedFloatFromRGBA } from '../shaders/misc.js';
3
2
  import { Vector2 } from '@zephyr3d/base';
4
3
  import { fetchSampler } from '../utility/misc.js';
5
4
 
@@ -173,7 +172,7 @@ import { fetchSampler } from '../utility/misc.js';
173
172
  pb.vec2('uv')
174
173
  ], function() {
175
174
  this.$l.depthValue = pb.textureSample(this.depthTex, this.uv);
176
- this.$l.depth01 = pb.getDevice().type === 'webgl' ? decodeNormalizedFloatFromRGBA(this, this.depthValue) : this.depthValue.r;
175
+ this.$l.depth01 = this.depthValue.r;
177
176
  this.$return(pb.mul(this.depth01, this.cameraNearFar.y));
178
177
  });
179
178
  pb.func('getLogDepth', [