@woosh/meep-engine 3.17.2 → 3.18.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 (263) hide show
  1. package/editor/actions/concrete/ComponentAddAction.d.ts +1 -0
  2. package/editor/actions/concrete/ComponentAddAction.d.ts.map +1 -1
  3. package/editor/actions/concrete/ComponentAddAction.js +4 -0
  4. package/editor/actions/concrete/ComponentRemoveAction.d.ts +1 -0
  5. package/editor/actions/concrete/ComponentRemoveAction.d.ts.map +1 -1
  6. package/editor/actions/concrete/ComponentRemoveAction.js +4 -0
  7. package/editor/actions/concrete/EntityCreateAction.d.ts +1 -0
  8. package/editor/actions/concrete/EntityCreateAction.d.ts.map +1 -1
  9. package/editor/actions/concrete/EntityCreateAction.js +7 -0
  10. package/editor/actions/concrete/EntityRemoveAction.d.ts +1 -0
  11. package/editor/actions/concrete/EntityRemoveAction.d.ts.map +1 -1
  12. package/editor/actions/concrete/EntityRemoveAction.js +4 -0
  13. package/editor/actions/concrete/PatchTerrainHeightAction.d.ts +10 -0
  14. package/editor/actions/concrete/PatchTerrainHeightAction.d.ts.map +1 -1
  15. package/editor/actions/concrete/PatchTerrainHeightAction.js +107 -85
  16. package/editor/actions/concrete/TransformModifyAction.d.ts +1 -0
  17. package/editor/actions/concrete/TransformModifyAction.d.ts.map +1 -1
  18. package/editor/actions/concrete/TransformModifyAction.js +4 -0
  19. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  20. package/editor/particles/effect/ParticleEffectDocument.js +10 -6
  21. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  22. package/editor/particles/effect/ParticleReferenceSimulation.js +98 -4
  23. package/editor/particles/effect/make_starter_particle_effect.d.ts.map +1 -1
  24. package/editor/particles/effect/make_starter_particle_effect.js +0 -2
  25. package/editor/tools/engine/ToolEngine.d.ts +30 -0
  26. package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
  27. package/editor/tools/engine/ToolEngine.js +257 -188
  28. package/editor/view/ecs/EntityList.d.ts.map +1 -1
  29. package/editor/view/ecs/EntityList.js +6 -5
  30. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  31. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +17 -9
  32. package/package.json +1 -1
  33. package/src/CODEC_LAYOUT_VERIFICATION.md +1 -2
  34. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts +56 -0
  35. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.d.ts.map +1 -0
  36. package/src/core/binary/meshopt/MESHOPT_VERTEX_BLOCK.js +73 -0
  37. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.d.ts.map +1 -1
  38. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +18 -63
  39. package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts +53 -0
  40. package/src/core/binary/meshopt/meshopt_encode_byte_group.d.ts.map +1 -0
  41. package/src/core/binary/meshopt/meshopt_encode_byte_group.js +140 -0
  42. package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts +32 -0
  43. package/src/core/binary/meshopt/meshopt_encode_data_block.d.ts.map +1 -0
  44. package/src/core/binary/meshopt/meshopt_encode_data_block.js +77 -0
  45. package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts +46 -0
  46. package/src/core/binary/meshopt/meshopt_encode_index_sequence.d.ts.map +1 -0
  47. package/src/core/binary/meshopt/meshopt_encode_index_sequence.js +146 -0
  48. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts +40 -0
  49. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.d.ts.map +1 -0
  50. package/src/core/binary/meshopt/meshopt_encode_vertex_buffer.js +700 -0
  51. package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts +24 -0
  52. package/src/core/binary/meshopt/meshopt_write_uint_var.d.ts.map +1 -0
  53. package/src/core/binary/meshopt/meshopt_write_uint_var.js +39 -0
  54. package/src/core/math/random/seededRandom_Mulberry32.d.ts.map +1 -1
  55. package/src/core/math/random/seededRandom_Mulberry32.js +4 -2
  56. package/src/core/process/undo/Action.d.ts +19 -0
  57. package/src/core/process/undo/Action.d.ts.map +1 -1
  58. package/src/core/process/undo/Action.js +17 -0
  59. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +78 -0
  60. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -0
  61. package/src/engine/graphics3/GPUParticleEmitterSystem.js +310 -0
  62. package/src/engine/graphics3/GraphicsEngine.d.ts +17 -0
  63. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  64. package/src/engine/graphics3/GraphicsEngine.js +30 -10
  65. package/src/engine/graphics3/particles/particle_gpu_records.d.ts.map +1 -1
  66. package/src/engine/graphics3/particles/particle_gpu_records.js +0 -2
  67. package/src/engine/interpolation/InterpolationSystem.d.ts +7 -0
  68. package/src/engine/interpolation/InterpolationSystem.d.ts.map +1 -1
  69. package/src/engine/interpolation/InterpolationSystem.js +10 -0
  70. package/src/engine/network/NetworkSession.d.ts.map +1 -1
  71. package/src/engine/network/NetworkSession.js +14 -34
  72. package/src/engine/network/time/RenderPlayout.d.ts +76 -0
  73. package/src/engine/network/time/RenderPlayout.d.ts.map +1 -0
  74. package/src/engine/network/time/RenderPlayout.js +163 -0
  75. package/src/engine/network/transport/adapters/WebSocketTransport.d.ts.map +1 -1
  76. package/src/engine/network/transport/adapters/WebSocketTransport.js +11 -4
  77. package/src/engine/physics/ecs/PhysicsSystem.d.ts +4 -12
  78. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  79. package/src/engine/physics/ecs/PhysicsSystem.js +39 -13
  80. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  81. package/src/engine/sound/simulation/core/VolumeField.d.ts.map +1 -1
  82. package/src/engine/sound/simulation/core/VolumeField.js +4 -1
  83. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +23 -2
  84. package/src/shade/playground/particle_system/README.md +139 -139
  85. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  86. package/src/shade/playground/particle_system/particle_prototype.js +0 -2
  87. package/src/shade/playground/particle_system/particle_scene.d.ts +6 -9
  88. package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
  89. package/src/shade/playground/particle_system/particle_scene.js +6 -13
  90. package/src/shade/playground/ssr_reprojection/README.md +103 -0
  91. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts +17 -0
  92. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.d.ts.map +1 -0
  93. package/src/shade/playground/ssr_reprojection/SpatialFilterProbe.js +68 -0
  94. package/src/shade/playground/ssr_reprojection/index.html +79 -0
  95. package/src/shade/playground/ssr_reprojection/main.d.ts +2 -0
  96. package/src/shade/playground/ssr_reprojection/main.d.ts.map +1 -0
  97. package/src/shade/playground/ssr_reprojection/main.js +245 -0
  98. package/src/shade/playground/ssr_reprojection/scene.d.ts +18 -0
  99. package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -0
  100. package/src/shade/playground/ssr_reprojection/scene.js +51 -0
  101. package/src/shade/renderer/Renderer.d.ts +2 -23
  102. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  103. package/src/shade/renderer/Renderer.js +185 -218
  104. package/src/shade/renderer/animation/GPUAnimationManager.d.ts +5 -8
  105. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  106. package/src/shade/renderer/animation/GPUAnimationManager.js +12 -12
  107. package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
  108. package/src/shade/renderer/buffer/table/GPUTypedTable.js +6 -0
  109. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  110. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +7 -0
  111. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts +4 -0
  112. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.d.ts.map +1 -0
  113. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_specular.js +51 -0
  114. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.d.ts.map +1 -1
  115. package/src/shade/renderer/global_illumination/brick4/gpu/draw/shader_brick4_specular.js +5 -35
  116. package/src/shade/renderer/particles/DESIGN.md +703 -514
  117. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +16 -4
  118. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  119. package/src/shade/renderer/particles/GPUParticleSystem.js +1189 -991
  120. package/src/shade/renderer/particles/ParticleConstants.d.ts +64 -0
  121. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  122. package/src/shade/renderer/particles/ParticleConstants.js +71 -0
  123. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts +57 -0
  124. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.d.ts.map +1 -0
  125. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +181 -0
  126. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts +7 -0
  127. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.d.ts.map +1 -0
  128. package/src/shade/renderer/particles/bounds/chunk_particle_bounds_unknown.js +12 -0
  129. package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts +33 -0
  130. package/src/shade/renderer/particles/bounds/graph_particle_bounds.d.ts.map +1 -0
  131. package/src/shade/renderer/particles/bounds/graph_particle_bounds.js +67 -0
  132. package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts +40 -0
  133. package/src/shade/renderer/particles/bounds/shader_particle_bounds.d.ts.map +1 -0
  134. package/src/shade/renderer/particles/bounds/shader_particle_bounds.js +187 -0
  135. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts +15 -2
  136. package/src/shade/renderer/particles/coherence/graph_particle_bucket.d.ts.map +1 -1
  137. package/src/shade/renderer/particles/coherence/graph_particle_bucket.js +14 -8
  138. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts +58 -4
  139. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.d.ts.map +1 -1
  140. package/src/shade/renderer/particles/data/PARTICLE_COUNTERS.js +79 -4
  141. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts +23 -1
  142. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.d.ts.map +1 -1
  143. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STATE.js +35 -2
  144. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +4 -2
  145. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  146. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +5 -8
  147. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -1
  148. package/src/shade/renderer/particles/data/particle_emitter_record.js +0 -6
  149. package/src/shade/renderer/particles/graph_particles.d.ts +25 -3
  150. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  151. package/src/shade/renderer/particles/graph_particles.js +108 -31
  152. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +6 -4
  153. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph_particles_avboit.js +5 -5
  155. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +5 -0
  156. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  157. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +27 -6
  158. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +4 -0
  159. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +6 -1
  161. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +35 -27
  162. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  163. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +424 -425
  164. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +20 -0
  165. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +1 -0
  166. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts +4 -0
  167. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.d.ts.map +1 -1
  168. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +38 -2
  169. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts +22 -0
  170. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.d.ts.map +1 -0
  171. package/src/shade/renderer/particles/shaders/chunk_particle_spawn_budget.js +42 -0
  172. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +1 -1
  173. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.d.ts.map +1 -1
  174. package/src/shade/renderer/particles/shaders/shader_particle_avboit_occupancy.js +53 -22
  175. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/shaders/shader_particle_emitter_tick.js +213 -216
  177. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +50 -0
  178. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +1 -0
  179. package/src/shade/renderer/particles/shaders/shader_particle_render.js +1 -1
  180. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts +36 -0
  181. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.d.ts.map +1 -0
  182. package/src/shade/renderer/particles/warmup/chunk_particle_warmup_step.js +102 -0
  183. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts +102 -0
  184. package/src/shade/renderer/particles/warmup/graph_particle_warmup.d.ts.map +1 -0
  185. package/src/shade/renderer/particles/warmup/graph_particle_warmup.js +329 -0
  186. package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts +112 -0
  187. package/src/shade/renderer/particles/warmup/shader_particle_warmup.d.ts.map +1 -0
  188. package/src/shade/renderer/particles/warmup/shader_particle_warmup.js +318 -0
  189. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts +35 -0
  190. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -0
  191. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +108 -0
  192. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts +3 -0
  193. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -0
  194. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +70 -0
  195. package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts +62 -0
  196. package/src/shade/renderer/particles/warmup/warmup_schedule.d.ts.map +1 -0
  197. package/src/shade/renderer/particles/warmup/warmup_schedule.js +55 -0
  198. package/src/shade/renderer/postprocess/PostProcess.d.ts.map +1 -1
  199. package/src/shade/renderer/postprocess/PostProcess.js +2 -1
  200. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +286 -0
  201. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +57 -21
  202. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  203. package/src/shade/renderer/postprocess/ssr/SSR.js +230 -129
  204. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts +11 -0
  205. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.d.ts.map +1 -0
  206. package/src/shade/renderer/postprocess/ssr/SSRReprojectionMode.js +6 -0
  207. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts +4 -0
  208. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.d.ts.map +1 -0
  209. package/src/shade/renderer/postprocess/ssr/chunk_ssr_metadata.js +32 -0
  210. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts +4 -0
  211. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.d.ts.map +1 -0
  212. package/src/shade/renderer/postprocess/ssr/chunk_ssr_spatial_variance.js +41 -0
  213. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts +3 -0
  214. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -0
  215. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +30 -0
  216. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts +4 -0
  217. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -0
  218. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +70 -0
  219. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts +21 -0
  220. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.d.ts.map +1 -0
  221. package/src/shade/renderer/postprocess/ssr/resolve/build_ssr_resolve_shader.js +363 -0
  222. package/src/shade/renderer/postprocess/ssr/resolve/chunk_get_neighbour_weight.js +1 -1
  223. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts +2 -0
  224. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.d.ts.map +1 -0
  225. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_Brick4.js +24 -0
  226. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts +1 -6
  227. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
  228. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +16 -332
  229. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts +1 -6
  230. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
  231. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +25 -358
  232. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -5
  233. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  234. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +201 -276
  235. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts +1 -0
  236. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  237. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +167 -143
  238. package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts +15 -0
  239. package/src/shade/renderer/shader/graph/graph_create_buffer.d.ts.map +1 -0
  240. package/src/shade/renderer/shader/graph/graph_create_buffer.js +20 -0
  241. package/src/shade/renderer/view/GPUViewContext.d.ts +3 -4
  242. package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
  243. package/src/shade/renderer/view/GPUViewContext.js +5 -5
  244. package/src/core/binary/meshopt/__meshopt_test_streams.d.ts +0 -24
  245. package/src/core/binary/meshopt/__meshopt_test_streams.d.ts.map +0 -1
  246. package/src/core/binary/meshopt/__meshopt_test_streams.js +0 -237
  247. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +0 -84
  248. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +0 -1
  249. package/src/core/geom/3d/atlas/atlas_test_fixtures.js +0 -266
  250. package/src/engine/asset/loaders/gltf_test_fixtures.d.ts +0 -97
  251. package/src/engine/asset/loaders/gltf_test_fixtures.d.ts.map +0 -1
  252. package/src/engine/asset/loaders/gltf_test_fixtures.js +0 -359
  253. package/src/shade/renderer/animation/skin_test_fixtures.d.ts +0 -86
  254. package/src/shade/renderer/animation/skin_test_fixtures.d.ts.map +0 -1
  255. package/src/shade/renderer/animation/skin_test_fixtures.js +0 -250
  256. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts +0 -16
  257. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.d.ts.map +0 -1
  258. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +0 -27
  259. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +0 -151
  260. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +0 -1
  261. package/src/shade/renderer/particles/particle_test_fixtures.js +0 -229
  262. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.js +0 -23
  263. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +0 -457
@@ -0,0 +1,700 @@
1
+ import { assert } from "../../assert.js";
2
+ import { MESHOPT_GROUP_SIZE } from "./MESHOPT_GROUP_SIZE.js";
3
+ import {
4
+ MESHOPT_BITS_BY_CONTROL,
5
+ MESHOPT_BITS_VERSION_0,
6
+ MESHOPT_MAX_BLOCK_BYTES,
7
+ MESHOPT_MAX_BLOCK_ELEMENTS,
8
+ MESHOPT_MAX_BYTE_STRIDE,
9
+ MESHOPT_TAIL_MIN_BY_VERSION,
10
+ MESHOPT_VERTEX_HEADER,
11
+ meshopt_max_block_elements
12
+ } from "./MESHOPT_VERTEX_BLOCK.js";
13
+ import { meshopt_choose_data_block, meshopt_encode_data_block } from "./meshopt_encode_data_block.js";
14
+
15
+ /**
16
+ * The most groups one block can hold, which bounds the per-block bookkeeping below.
17
+ * @type {number}
18
+ */
19
+ const MAX_GROUPS = MESHOPT_MAX_BLOCK_ELEMENTS / MESHOPT_GROUP_SIZE;
20
+
21
+ /**
22
+ * Control mode 2 stores nothing at all, and can only carry a byte position whose deltas are every
23
+ * one zero.
24
+ * @type {number}
25
+ */
26
+ const CONTROL_ZERO = 2;
27
+
28
+ /**
29
+ * Control mode 3 stores the deltas verbatim, with no group header in front of them. It is the
30
+ * fallback that always fits, and the ceiling every other mode is measured against.
31
+ * @type {number}
32
+ */
33
+ const CONTROL_LITERAL = 3;
34
+
35
+ /**
36
+ * One block's delta bytes, laid out per byte position exactly as the decoder's scratch is: position
37
+ * `k`'s deltas are `group_count * 16` bytes at `k * aligned_count`.
38
+ *
39
+ * Module-static, because encoding is synchronous and there is one caller. So are the four below.
40
+ *
41
+ * @type {Uint8Array}
42
+ */
43
+ const delta_scratch = new Uint8Array(MESHOPT_MAX_BLOCK_BYTES);
44
+
45
+ /**
46
+ * Where a candidate channel mode's deltas go while it is being priced, so that the incumbent's stay
47
+ * where the writer expects them.
48
+ * @type {Uint8Array}
49
+ */
50
+ const candidate_scratch = new Uint8Array(MESHOPT_MAX_BLOCK_BYTES);
51
+
52
+ /**
53
+ * The element each block's first delta is taken against — the stream's first element for the first
54
+ * block, and the previous block's last element after that.
55
+ * @type {Uint8Array}
56
+ */
57
+ const baseline = new Uint8Array(MESHOPT_MAX_BYTE_STRIDE);
58
+
59
+ /**
60
+ * The group header value chosen for each `(byte position, group)` of the block in hand.
61
+ * @type {Uint8Array}
62
+ */
63
+ const group_choice = new Uint8Array(MESHOPT_MAX_BYTE_STRIDE * MAX_GROUPS);
64
+
65
+ /**
66
+ * The same, for the control mode currently being priced against the incumbent.
67
+ * @type {Uint8Array}
68
+ */
69
+ const group_choice_candidate = new Uint8Array(MAX_GROUPS);
70
+
71
+ /**
72
+ * Somewhere for {@link price_channel} to throw away the choices it is not going to keep. Its own,
73
+ * because it is measuring a byte position whose incumbent choices must survive the measurement.
74
+ * @type {Uint8Array}
75
+ */
76
+ const group_choice_discard = new Uint8Array(MAX_GROUPS);
77
+
78
+ /**
79
+ * The baseline a candidate channel mode is priced against, kept apart from {@link baseline} for the
80
+ * same reason.
81
+ * @type {Uint8Array}
82
+ */
83
+ const candidate_baseline = new Uint8Array(MESHOPT_MAX_BYTE_STRIDE);
84
+
85
+ /**
86
+ * The control mode chosen for each byte position of the block in hand. Version 1 only; version 0
87
+ * has no control header and every byte position is a data block.
88
+ * @type {Uint8Array}
89
+ */
90
+ const control_choice = new Uint8Array(MESHOPT_MAX_BYTE_STRIDE);
91
+
92
+ /**
93
+ * Encode an attribute stream — the `"ATTRIBUTES"` mode of both meshopt extensions, and the inverse
94
+ * of {@link meshopt_decode_vertex_buffer}.
95
+ *
96
+ * Elements are delta-coded against the element before them, byte position by byte position. What
97
+ * the encoder gets to decide, and does:
98
+ *
99
+ * - **per group of sixteen deltas**, the width they are packed at, out of the four the block's
100
+ * control mode admits — including "all zero", which stores nothing;
101
+ * - **per byte position** (version 1), whether the groups carry a header at all: a position that
102
+ * never changes costs nothing, and one that is pure noise skips the header and is written
103
+ * verbatim rather than paying two bits a group to be told so;
104
+ * - **per channel of four byte positions** (version 1), whether its deltas are 8-bit, 16-bit, or a
105
+ * rotated 32-bit exclusive-or — see {@link choose_channel_mode}.
106
+ *
107
+ * Every one of those is priced against the alternatives on the data in hand rather than guessed at,
108
+ * so the output is never larger than the verbatim form and is usually a fraction of it.
109
+ *
110
+ * Version 0 is what `EXT_meshopt_compression` admits and is the default. Version 1 is
111
+ * `KHR_meshopt_compression` only, and buys the last two decisions above.
112
+ *
113
+ * @see https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_meshopt_compression
114
+ *
115
+ * @param {Uint8Array} source `count * byte_stride` bytes
116
+ * @param {number} count elements
117
+ * @param {number} byte_stride divisible by 4, at most 256
118
+ * @param {Object} [options]
119
+ * @param {number} [options.version] 0 or 1, defaulting to 0
120
+ * @param {number[]|Uint8Array} [options.channel_modes] one mode byte per channel — low nibble the
121
+ * mode, high nibble the rotation — imposed rather than chosen. Version 1 only, and the caller
122
+ * owns the consequences: a mode that suits the data less well than the one this would have picked
123
+ * makes a larger stream, not a wrong one.
124
+ * @returns {Uint8Array} the whole compressed stream, tail included
125
+ * @throws {Error} if the arguments do not describe an encodable buffer
126
+ */
127
+ export function meshopt_encode_vertex_buffer(source, count, byte_stride, options = {}) {
128
+ assert.isNonNegativeInteger(count, 'count');
129
+ assert.isPositiveInteger(byte_stride, 'byte_stride');
130
+ assert.equal(byte_stride % 4, 0, `byte_stride(=${byte_stride}) must be divisible by 4`);
131
+ assert.ok(byte_stride <= MESHOPT_MAX_BYTE_STRIDE, `byte_stride(=${byte_stride}) must be at most ${MESHOPT_MAX_BYTE_STRIDE}`);
132
+ assert.equal(
133
+ source.length, count * byte_stride,
134
+ `source(=${source.length} bytes) must hold count(=${count}) * byte_stride(=${byte_stride})`
135
+ );
136
+
137
+ const version = options.version ?? 0;
138
+
139
+ assert.isOneOf(version, [0, 1], 'version');
140
+
141
+ const channel_count = byte_stride >> 2;
142
+ const max_block_elements = meshopt_max_block_elements(byte_stride);
143
+
144
+ const channel_modes = resolve_channel_modes(source, count, byte_stride, version, options.channel_modes);
145
+
146
+ /*
147
+ Two tail sizes, as in the decoder: the tail block sits flush against the end of the stream and
148
+ is `tail_size` long, and the padding in front of it brings the pair up to `tail_size_pad`. The
149
+ padding is what gives the decoder's per-group bounds check its slack.
150
+ */
151
+ const tail_size = byte_stride + (version === 1 ? channel_count : 0);
152
+ const tail_min = MESHOPT_TAIL_MIN_BY_VERSION[version];
153
+ const tail_size_pad = tail_size < tail_min ? tail_min : tail_size;
154
+
155
+ const destination = new Uint8Array(
156
+ upper_bound(count, byte_stride, channel_count, version, max_block_elements) + tail_size_pad
157
+ );
158
+
159
+ destination[0] = MESHOPT_VERTEX_HEADER | version;
160
+
161
+ // the first block deltas against the first element, which is also what goes in the tail block
162
+ for (let k = 0; k < byte_stride; k++) {
163
+ baseline[k] = count > 0 ? source[k] : 0;
164
+ }
165
+
166
+ let offset = 1;
167
+ let element = 0;
168
+
169
+ while (element < count) {
170
+ const block_elements = Math.min(count - element, max_block_elements);
171
+
172
+ offset = encode_block(
173
+ destination, offset,
174
+ source, element, block_elements,
175
+ byte_stride, channel_count, version, channel_modes
176
+ );
177
+
178
+ element += block_elements;
179
+ }
180
+
181
+ // the padding goes IN FRONT of the tail block, which sits flush against the end of the stream
182
+ const end = offset + tail_size_pad;
183
+ const tail = end - tail_size;
184
+
185
+ destination.fill(0, offset, tail);
186
+
187
+ for (let k = 0; k < byte_stride; k++) {
188
+ destination[tail + k] = count > 0 ? source[k] : 0;
189
+ }
190
+
191
+ if (version === 1) {
192
+ for (let c = 0; c < channel_count; c++) {
193
+ destination[tail + byte_stride + c] = channel_modes[c];
194
+ }
195
+ }
196
+
197
+ return destination.slice(0, end);
198
+ }
199
+
200
+ /**
201
+ * The largest stream the encoder could possibly produce for this shape, blocks only — every byte
202
+ * position of every block written verbatim, with a group header it would not actually pay for.
203
+ *
204
+ * Bounding it up front is what lets the whole stream be written into one exactly-sized buffer:
205
+ * every decision is made from the deltas, so nothing here has to look at the data.
206
+ *
207
+ * @param {number} count
208
+ * @param {number} byte_stride
209
+ * @param {number} channel_count
210
+ * @param {number} version
211
+ * @param {number} max_block_elements
212
+ * @returns {number} bytes, the stream header included and the tail excluded
213
+ */
214
+ function upper_bound(count, byte_stride, channel_count, version, max_block_elements) {
215
+ let bound = 1;
216
+
217
+ for (let element = 0; element < count; element += max_block_elements) {
218
+ const block_elements = Math.min(count - element, max_block_elements);
219
+ const group_count = Math.ceil(block_elements / MESHOPT_GROUP_SIZE);
220
+
221
+ bound += (version === 1 ? channel_count : 0)
222
+ + byte_stride * (((group_count + 3) >> 2) + group_count * MESHOPT_GROUP_SIZE);
223
+ }
224
+
225
+ return bound;
226
+ }
227
+
228
+ /**
229
+ * Settle on a mode byte per channel: what the caller imposed, or nothing at all under version 0,
230
+ * or {@link choose_channel_mode}'s reading of the data.
231
+ *
232
+ * @param {Uint8Array} source
233
+ * @param {number} count
234
+ * @param {number} byte_stride
235
+ * @param {number} version
236
+ * @param {number[]|Uint8Array} [imposed]
237
+ * @returns {Uint8Array} one mode byte per channel
238
+ * @throws {Error} if the caller imposed modes that are not modes, or imposed any under version 0
239
+ */
240
+ function resolve_channel_modes(source, count, byte_stride, version, imposed) {
241
+ const channel_count = byte_stride >> 2;
242
+ const modes = new Uint8Array(channel_count);
243
+
244
+ if (version === 0) {
245
+ assert.ok(
246
+ imposed === undefined,
247
+ 'channel modes are a version 1 feature, and this stream is version 0'
248
+ );
249
+
250
+ return modes;
251
+ }
252
+
253
+ if (imposed !== undefined) {
254
+ assert.equal(
255
+ imposed.length, channel_count,
256
+ `channel_modes(=${imposed.length}) must have one entry per channel(=${channel_count})`
257
+ );
258
+
259
+ for (let c = 0; c < channel_count; c++) {
260
+ const mode_byte = imposed[c];
261
+ const mode = mode_byte & 0x0f;
262
+
263
+ assert.isOneOf(mode, [0, 1, 2], `channel_modes[${c}] mode`);
264
+ assert.ok(
265
+ mode === 2 || (mode_byte >> 4) === 0,
266
+ `channel_modes[${c}] carries a rotation in mode ${mode}, which has none`
267
+ );
268
+
269
+ modes[c] = mode_byte;
270
+ }
271
+
272
+ return modes;
273
+ }
274
+
275
+ for (let c = 0; c < channel_count; c++) {
276
+ modes[c] = choose_channel_mode(source, count, byte_stride, c);
277
+ }
278
+
279
+ return modes;
280
+ }
281
+
282
+ /**
283
+ * Pick the mode byte for one channel, by pricing the candidates on the stream's first block.
284
+ *
285
+ * The mode is a property of the whole stream — the decoder reads it once, out of the tail — so it
286
+ * cannot be revisited per block, and pricing every candidate against every block to choose it once
287
+ * would cost more than the choice is worth. The first block is what gets measured, and for the
288
+ * data this format carries (vertex attributes, laid out one way for their whole run) it is
289
+ * representative. A caller who knows better passes `channel_modes` and skips this.
290
+ *
291
+ * Mode 2's rotation is not searched exhaustively either. Every bit that ever changes between
292
+ * consecutive elements is collected into one mask, and the rotation that gathers those bits into
293
+ * the fewest whole bytes is the one tried — which is the whole point of the rotation, and reduces
294
+ * thirty-two candidates to one.
295
+ *
296
+ * @param {Uint8Array} source
297
+ * @param {number} count
298
+ * @param {number} byte_stride
299
+ * @param {number} channel
300
+ * @returns {number} the mode byte: low nibble the mode, high nibble the rotation
301
+ */
302
+ function choose_channel_mode(source, count, byte_stride, channel) {
303
+ const sample = Math.min(count, meshopt_max_block_elements(byte_stride));
304
+
305
+ if (sample === 0) {
306
+ return 0;
307
+ }
308
+
309
+ const k0 = channel * 4;
310
+
311
+ // every bit that changes anywhere in the sample, so the rotation is chosen from all of them
312
+ let mask = 0;
313
+ let previous = read_le_32(source, k0);
314
+
315
+ for (let i = 0; i < sample; i++) {
316
+ const value = read_le_32(source, i * byte_stride + k0);
317
+
318
+ mask = (mask | (value ^ previous)) >>> 0;
319
+ previous = value;
320
+ }
321
+
322
+ let rotation = 0;
323
+ let fewest = 5;
324
+
325
+ for (let r = 0; r < 32; r++) {
326
+ const rotated = rotate_left_32(mask, (32 - r) & 31);
327
+ const bytes = (rotated & 0xff ? 1 : 0)
328
+ + ((rotated >>> 8) & 0xff ? 1 : 0)
329
+ + ((rotated >>> 16) & 0xff ? 1 : 0)
330
+ + ((rotated >>> 24) & 0xff ? 1 : 0);
331
+
332
+ if (bytes < fewest) {
333
+ rotation = r;
334
+ fewest = bytes;
335
+ }
336
+ }
337
+
338
+ const candidates = [0, 1, 2 | (rotation << 4)];
339
+
340
+ let best = 0;
341
+ let best_size = Number.POSITIVE_INFINITY;
342
+
343
+ for (const mode_byte of candidates) {
344
+ const size = price_channel(source, 0, sample, byte_stride, channel, mode_byte);
345
+
346
+ if (size < best_size) {
347
+ best = mode_byte;
348
+ best_size = size;
349
+ }
350
+ }
351
+
352
+ return best;
353
+ }
354
+
355
+ /**
356
+ * What one channel's four byte positions cost over a block under a given mode, version 1 rules.
357
+ *
358
+ * The deltas go into {@link candidate_scratch} rather than {@link delta_scratch}, because this runs
359
+ * before the block loop and must not disturb what the block loop is holding.
360
+ *
361
+ * @param {Uint8Array} source
362
+ * @param {number} element_offset
363
+ * @param {number} block_elements
364
+ * @param {number} byte_stride
365
+ * @param {number} channel
366
+ * @param {number} mode_byte
367
+ * @returns {number} bytes, the share of the control header included
368
+ */
369
+ function price_channel(source, element_offset, block_elements, byte_stride, channel, mode_byte) {
370
+ const group_count = Math.ceil(block_elements / MESHOPT_GROUP_SIZE);
371
+ const aligned_count = group_count * MESHOPT_GROUP_SIZE;
372
+
373
+ // the sample's own baseline, which is the first element, exactly as the real encode will see it
374
+ const first = element_offset * byte_stride;
375
+
376
+ for (let j = 0; j < 4; j++) {
377
+ candidate_baseline[channel * 4 + j] = source[first + channel * 4 + j];
378
+ }
379
+
380
+ write_channel_deltas(
381
+ candidate_scratch, candidate_baseline, source, element_offset, block_elements,
382
+ byte_stride, aligned_count, channel, mode_byte
383
+ );
384
+
385
+ let size = 1; // the channel's byte of the block's control header
386
+
387
+ for (let j = 0; j < 4; j++) {
388
+ const k = channel * 4 + j;
389
+
390
+ size += price_byte_position(
391
+ candidate_scratch, k * aligned_count, group_count, aligned_count,
392
+ group_choice_discard, 0
393
+ ).size;
394
+ }
395
+
396
+ return size;
397
+ }
398
+
399
+ /**
400
+ * The cheapest way to store one byte position's deltas, and what it costs.
401
+ *
402
+ * Version 1's four control modes are not four widths — two of them are answers to questions the
403
+ * group header cannot ask. A position that never changes is free, and one whose every group would
404
+ * have to be stored raw anyway is cheaper without the header that says so.
405
+ *
406
+ * @param {Uint8Array} deltas
407
+ * @param {number} deltas_offset
408
+ * @param {number} group_count
409
+ * @param {number} aligned_count
410
+ * @param {Uint8Array} choices `group_count` header values are written here, for whichever data
411
+ * block control mode won — untouched if neither did
412
+ * @param {number} choices_offset
413
+ * @returns {{control: number, size: number}}
414
+ */
415
+ function price_byte_position(deltas, deltas_offset, group_count, aligned_count, choices, choices_offset) {
416
+ let all_zero = true;
417
+
418
+ for (let i = 0; i < aligned_count; i++) {
419
+ if (deltas[deltas_offset + i] !== 0) {
420
+ all_zero = false;
421
+ break;
422
+ }
423
+ }
424
+
425
+ if (all_zero) {
426
+ return { control: CONTROL_ZERO, size: 0 };
427
+ }
428
+
429
+ let control = CONTROL_LITERAL;
430
+ let size = aligned_count;
431
+
432
+ const size_0 = meshopt_choose_data_block(
433
+ deltas, deltas_offset, group_count, MESHOPT_BITS_BY_CONTROL[0], choices, choices_offset
434
+ );
435
+
436
+ if (size_0 < size) {
437
+ control = 0;
438
+ size = size_0;
439
+ }
440
+
441
+ const size_1 = meshopt_choose_data_block(
442
+ deltas, deltas_offset, group_count, MESHOPT_BITS_BY_CONTROL[1], group_choice_candidate, 0
443
+ );
444
+
445
+ if (size_1 < size) {
446
+ control = 1;
447
+ size = size_1;
448
+
449
+ for (let g = 0; g < group_count; g++) {
450
+ choices[choices_offset + g] = group_choice_candidate[g];
451
+ }
452
+ }
453
+
454
+ return { control, size };
455
+ }
456
+
457
+ /**
458
+ * Encode one block: its control header if it has one, then every byte position in turn.
459
+ *
460
+ * @param {Uint8Array} destination
461
+ * @param {number} offset
462
+ * @param {Uint8Array} source
463
+ * @param {number} element_offset first element of this block, counted in the whole stream
464
+ * @param {number} block_elements
465
+ * @param {number} byte_stride
466
+ * @param {number} channel_count
467
+ * @param {number} version
468
+ * @param {Uint8Array} channel_modes
469
+ * @returns {number} the offset just past the block
470
+ */
471
+ function encode_block(
472
+ destination, offset,
473
+ source, element_offset, block_elements,
474
+ byte_stride, channel_count, version, channel_modes
475
+ ) {
476
+ const group_count = Math.ceil(block_elements / MESHOPT_GROUP_SIZE);
477
+ const aligned_count = group_count * MESHOPT_GROUP_SIZE;
478
+
479
+ for (let c = 0; c < channel_count; c++) {
480
+ write_channel_deltas(
481
+ delta_scratch, baseline, source, element_offset, block_elements,
482
+ byte_stride, aligned_count, c, channel_modes[c]
483
+ );
484
+ }
485
+
486
+ if (version === 0) {
487
+ // no control header stands between the choosing and the writing, so they are one pass
488
+ for (let k = 0; k < byte_stride; k++) {
489
+ meshopt_choose_data_block(
490
+ delta_scratch, k * aligned_count, group_count,
491
+ MESHOPT_BITS_VERSION_0, group_choice, 0
492
+ );
493
+
494
+ offset = meshopt_encode_data_block(
495
+ destination, offset,
496
+ delta_scratch, k * aligned_count,
497
+ group_count, MESHOPT_BITS_VERSION_0,
498
+ group_choice, 0
499
+ );
500
+ }
501
+ } else {
502
+ const control_offset = offset;
503
+
504
+ destination.fill(0, control_offset, control_offset + channel_count);
505
+ offset += channel_count;
506
+
507
+ for (let k = 0; k < byte_stride; k++) {
508
+ const chosen = price_byte_position(
509
+ delta_scratch, k * aligned_count, group_count, aligned_count,
510
+ group_choice, k * MAX_GROUPS
511
+ );
512
+
513
+ control_choice[k] = chosen.control;
514
+
515
+ destination[control_offset + (k >> 2)] |= chosen.control << ((k & 3) * 2);
516
+ }
517
+
518
+ for (let k = 0; k < byte_stride; k++) {
519
+ const control = control_choice[k];
520
+ const deltas_offset = k * aligned_count;
521
+
522
+ if (control === CONTROL_ZERO) {
523
+ continue;
524
+ }
525
+
526
+ if (control === CONTROL_LITERAL) {
527
+ for (let i = 0; i < aligned_count; i++) {
528
+ destination[offset + i] = delta_scratch[deltas_offset + i];
529
+ }
530
+
531
+ offset += aligned_count;
532
+
533
+ continue;
534
+ }
535
+
536
+ offset = meshopt_encode_data_block(
537
+ destination, offset,
538
+ delta_scratch, deltas_offset,
539
+ group_count, MESHOPT_BITS_BY_CONTROL[control],
540
+ group_choice, k * MAX_GROUPS
541
+ );
542
+ }
543
+ }
544
+
545
+ const last = (element_offset + block_elements - 1) * byte_stride;
546
+
547
+ for (let k = 0; k < byte_stride; k++) {
548
+ baseline[k] = source[last + k];
549
+ }
550
+
551
+ return offset;
552
+ }
553
+
554
+ /**
555
+ * Turn one channel's values into the delta bytes the decoder will reconstruct them from — the
556
+ * inverse of `reconstruct_channel`, and the only place the three modes differ.
557
+ *
558
+ * The deltas past `block_elements` are the group alignment's padding. They are written as zero
559
+ * because zero is what costs least, and the decoder discards them.
560
+ *
561
+ * @param {Uint8Array} deltas
562
+ * @param {Uint8Array} from the element the block's first delta is taken against
563
+ * @param {Uint8Array} source
564
+ * @param {number} element_offset
565
+ * @param {number} block_elements
566
+ * @param {number} byte_stride
567
+ * @param {number} aligned_count stride of `deltas`, per byte position
568
+ * @param {number} channel
569
+ * @param {number} mode_byte low nibble the mode, high nibble the rotation
570
+ */
571
+ function write_channel_deltas(
572
+ deltas, from, source, element_offset, block_elements,
573
+ byte_stride, aligned_count, channel, mode_byte
574
+ ) {
575
+ const k0 = channel * 4;
576
+ const mode = mode_byte & 0x0f;
577
+
578
+ for (let j = 0; j < 4; j++) {
579
+ const k = k0 + j;
580
+
581
+ deltas.fill(0, k * aligned_count + block_elements, (k + 1) * aligned_count);
582
+ }
583
+
584
+ if (mode === 0) {
585
+ for (let j = 0; j < 4; j++) {
586
+ const k = k0 + j;
587
+ const out = k * aligned_count;
588
+
589
+ let previous = from[k];
590
+ let read = element_offset * byte_stride + k;
591
+
592
+ for (let i = 0; i < block_elements; i++) {
593
+ const value = source[read];
594
+
595
+ deltas[out + i] = zigzag_8(previous, value);
596
+
597
+ previous = value;
598
+ read += byte_stride;
599
+ }
600
+ }
601
+
602
+ return;
603
+ }
604
+
605
+ if (mode === 1) {
606
+ for (let h = 0; h < 2; h++) {
607
+ const k = k0 + h * 2;
608
+ const out_low = k * aligned_count;
609
+ const out_high = (k + 1) * aligned_count;
610
+
611
+ let previous = from[k] | (from[k + 1] << 8);
612
+ let read = element_offset * byte_stride + k;
613
+
614
+ for (let i = 0; i < block_elements; i++) {
615
+ const value = source[read] | (source[read + 1] << 8);
616
+ const zigzag = zigzag_16(previous, value);
617
+
618
+ deltas[out_low + i] = zigzag & 0xff;
619
+ deltas[out_high + i] = zigzag >>> 8;
620
+
621
+ previous = value;
622
+ read += byte_stride;
623
+ }
624
+ }
625
+
626
+ return;
627
+ }
628
+
629
+ const rotation = mode_byte >> 4;
630
+
631
+ const out_0 = k0 * aligned_count;
632
+ const out_1 = (k0 + 1) * aligned_count;
633
+ const out_2 = (k0 + 2) * aligned_count;
634
+ const out_3 = (k0 + 3) * aligned_count;
635
+
636
+ let previous = read_le_32(from, k0);
637
+ let read = element_offset * byte_stride + k0;
638
+
639
+ for (let i = 0; i < block_elements; i++) {
640
+ const value = read_le_32(source, read);
641
+
642
+ // the decoder rotates left by `rotation`, so this rotates back by the same amount
643
+ const delta = rotate_left_32((value ^ previous) >>> 0, (32 - rotation) & 31);
644
+
645
+ deltas[out_0 + i] = delta & 0xff;
646
+ deltas[out_1 + i] = (delta >>> 8) & 0xff;
647
+ deltas[out_2 + i] = (delta >>> 16) & 0xff;
648
+ deltas[out_3 + i] = delta >>> 24;
649
+
650
+ previous = value;
651
+ read += byte_stride;
652
+ }
653
+ }
654
+
655
+ /**
656
+ * @param {Uint8Array} data
657
+ * @param {number} offset
658
+ * @returns {number} the little-endian 32-bit word there, unsigned
659
+ */
660
+ function read_le_32(data, offset) {
661
+ return (
662
+ data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)
663
+ ) >>> 0;
664
+ }
665
+
666
+ /**
667
+ * @param {number} value
668
+ * @param {number} amount
669
+ * @returns {number} unsigned
670
+ */
671
+ function rotate_left_32(value, amount) {
672
+ return ((value << amount) | (value >>> (32 - amount))) >>> 0;
673
+ }
674
+
675
+ /**
676
+ * Zigzag one 8-bit delta, so that a small step either way is a small number: the difference is
677
+ * taken modulo 256, and its sign bit folded into bit 0.
678
+ *
679
+ * @param {number} previous
680
+ * @param {number} current
681
+ * @returns {number}
682
+ */
683
+ function zigzag_8(previous, current) {
684
+ const delta = (current - previous) & 0xff;
685
+
686
+ return ((delta & 0x80) !== 0 ? ~(delta << 1) : (delta << 1)) & 0xff;
687
+ }
688
+
689
+ /**
690
+ * The same, over sixteen bits.
691
+ *
692
+ * @param {number} previous
693
+ * @param {number} current
694
+ * @returns {number}
695
+ */
696
+ function zigzag_16(previous, current) {
697
+ const delta = (current - previous) & 0xffff;
698
+
699
+ return ((delta & 0x8000) !== 0 ? ~(delta << 1) : (delta << 1)) & 0xffff;
700
+ }