@woosh/meep-engine 3.18.0 → 3.20.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 (228) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -1
  4. package/editor/view/particles/effect/ParticleCurveEditorView.js +303 -120
  5. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -1
  6. package/editor/view/particles/effect/ParticleGradientEditorView.js +108 -63
  7. package/editor/view/particles/effect/ParticleGraphEditorView.js +2 -2
  8. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  9. package/editor/view/particles/effect/ParticleNodeParametersView.js +7 -46
  10. package/editor/view/particles/effect/particle-editor.css +60 -30
  11. package/package.json +1 -2
  12. package/samples/engine/README.md +1 -1
  13. package/src/core/binary/compression/decompress_bytes.d.ts +13 -0
  14. package/src/core/binary/compression/decompress_bytes.d.ts.map +1 -0
  15. package/src/core/binary/compression/decompress_bytes.js +28 -0
  16. package/src/core/collection/array/array_group_by.d.ts.map +1 -1
  17. package/src/core/collection/array/array_group_by.js +2 -11
  18. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -1
  19. package/src/core/geom/3d/shape/HeightMapShape3D.js +4 -9
  20. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +67 -22
  21. package/src/core/model/object/optional_clone.d.ts +7 -0
  22. package/src/core/model/object/optional_clone.d.ts.map +1 -0
  23. package/src/core/model/object/optional_equality.d.ts +10 -0
  24. package/src/core/model/object/optional_equality.d.ts.map +1 -0
  25. package/src/{shade/descriptor/util → core/model/object}/optional_equality.js +2 -2
  26. package/src/core/model/object/optional_hash.d.ts +9 -0
  27. package/src/core/model/object/optional_hash.d.ts.map +1 -0
  28. package/src/{shade/descriptor/util → core/model/object}/optional_hash.js +3 -3
  29. package/src/engine/asset/Asset.d.ts +1 -1
  30. package/src/engine/asset/Asset.d.ts.map +1 -1
  31. package/src/engine/asset/Asset.js +3 -1
  32. package/src/engine/asset/loaders/image/ImageDecoderWorker.js +12 -27
  33. package/src/engine/asset/loaders/image/prototypePNG.js +8 -7
  34. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.d.ts.map +1 -1
  35. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +9 -10
  36. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  37. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  38. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +266 -0
  39. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -0
  40. package/src/engine/graphics/ecs/particles/ParticleEffect.js +439 -0
  41. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +58 -0
  42. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -0
  43. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +219 -0
  44. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +178 -25
  45. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  46. package/src/engine/graphics3/GPUParticleEmitterSystem.js +809 -310
  47. package/src/format/image/png/PNGReader.d.ts +7 -6
  48. package/src/format/image/png/PNGReader.d.ts.map +1 -1
  49. package/src/format/image/png/PNGReader.js +13 -12
  50. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts +3 -2
  51. package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
  52. package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +5 -4
  53. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts +3 -2
  54. package/src/format/image/png/chunk/png_chunk_decode_zTXt.d.ts.map +1 -1
  55. package/src/format/image/png/chunk/png_chunk_decode_zTXt.js +5 -4
  56. package/src/format/image/png/png_inflate.d.ts +3 -3
  57. package/src/format/image/png/png_inflate.d.ts.map +1 -1
  58. package/src/format/image/png/png_inflate.js +29 -39
  59. package/src/format/texture/ktx2/ktx2_read.d.ts +4 -4
  60. package/src/format/texture/ktx2/ktx2_read.d.ts.map +1 -1
  61. package/src/format/texture/ktx2/ktx2_read.js +18 -21
  62. package/src/shade/descriptor/binding/BindGroupLayoutDescriptor.js +1 -1
  63. package/src/shade/descriptor/binding/BindGroupLayoutEntry.js +3 -3
  64. package/src/shade/descriptor/pipeline/PipelineDescriptorBase.js +1 -1
  65. package/src/shade/descriptor/pipeline/PipelineLayoutDescriptor.js +1 -1
  66. package/src/shade/descriptor/pipeline/render/ColorTargetState.js +3 -3
  67. package/src/shade/descriptor/pipeline/render/FragmentState.js +1 -1
  68. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +3 -3
  69. package/src/shade/playground/particle_ecs/README.md +203 -0
  70. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts +39 -0
  71. package/src/shade/playground/particle_ecs/bonfire_editor.d.ts.map +1 -0
  72. package/src/shade/playground/particle_ecs/bonfire_editor.js +315 -0
  73. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +145 -0
  74. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts.map +1 -0
  75. package/src/shade/playground/particle_ecs/bonfire_effects.js +202 -0
  76. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts +23 -0
  77. package/src/shade/playground/particle_ecs/bonfire_sprites.d.ts.map +1 -0
  78. package/src/shade/playground/particle_ecs/bonfire_sprites.js +315 -0
  79. package/src/shade/playground/particle_ecs/bonfire_world.d.ts +86 -0
  80. package/src/shade/playground/particle_ecs/bonfire_world.d.ts.map +1 -0
  81. package/src/shade/playground/particle_ecs/bonfire_world.js +303 -0
  82. package/src/shade/playground/particle_ecs/effects/embers.json +1634 -0
  83. package/src/shade/playground/particle_ecs/effects/flame.json +1882 -0
  84. package/src/shade/playground/particle_ecs/effects/smoke.json +1860 -0
  85. package/src/shade/playground/particle_ecs/effects/soot.json +1606 -0
  86. package/src/shade/playground/particle_ecs/index.html +330 -0
  87. package/src/shade/playground/particle_ecs/main.d.ts +2 -0
  88. package/src/shade/playground/particle_ecs/main.d.ts.map +1 -0
  89. package/src/shade/playground/particle_ecs/main.js +566 -0
  90. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts +16 -0
  91. package/src/shade/playground/particle_ecs/moonlit_environment.d.ts.map +1 -0
  92. package/src/shade/playground/particle_ecs/moonlit_environment.js +144 -0
  93. package/src/shade/playground/particle_editor/README.md +5 -4
  94. package/src/shade/playground/particle_system/particle_prototype.d.ts +7 -9
  95. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  96. package/src/shade/playground/particle_system/particle_prototype.js +7 -9
  97. package/src/shade/playground/profile_hotkey.d.ts +58 -0
  98. package/src/shade/playground/profile_hotkey.d.ts.map +1 -0
  99. package/src/shade/playground/profile_hotkey.js +325 -0
  100. package/src/shade/playground/ssr_motion/README.md +22 -0
  101. package/src/shade/playground/ssr_motion/index.html +18 -0
  102. package/src/shade/playground/ssr_motion/main.d.ts +2 -0
  103. package/src/shade/playground/ssr_motion/main.d.ts.map +1 -0
  104. package/src/shade/playground/ssr_motion/main.js +149 -0
  105. package/src/shade/playground/ssr_variance/README.md +105 -0
  106. package/src/shade/playground/ssr_variance/capture.d.ts +16 -0
  107. package/src/shade/playground/ssr_variance/capture.d.ts.map +1 -0
  108. package/src/shade/playground/ssr_variance/capture.js +96 -0
  109. package/src/shade/playground/ssr_variance/index.html +23 -0
  110. package/src/shade/playground/ssr_variance/main.d.ts +2 -0
  111. package/src/shade/playground/ssr_variance/main.d.ts.map +1 -0
  112. package/src/shade/playground/ssr_variance/main.js +246 -0
  113. package/src/shade/playground/ssr_variance/reference.d.ts +18 -0
  114. package/src/shade/playground/ssr_variance/reference.d.ts.map +1 -0
  115. package/src/shade/playground/ssr_variance/reference.js +78 -0
  116. package/src/shade/playground/ssr_variance/scene.d.ts +11 -0
  117. package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -0
  118. package/src/shade/playground/ssr_variance/scene.js +61 -0
  119. package/src/shade/playground/ssr_variance/statistics.d.ts +44 -0
  120. package/src/shade/playground/ssr_variance/statistics.d.ts.map +1 -0
  121. package/src/shade/playground/ssr_variance/statistics.js +51 -0
  122. package/src/shade/renderer/geometry/Geometry.d.ts.map +1 -1
  123. package/src/shade/renderer/geometry/Geometry.js +4 -7
  124. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts.map +1 -1
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.js +9 -3
  126. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts +4 -4
  127. package/src/shade/renderer/loader/usd/usd_decode_image.d.ts.map +1 -1
  128. package/src/shade/renderer/loader/usd/usd_decode_image.js +4 -4
  129. package/src/shade/renderer/material/StandardShadeMaterial.js +2 -2
  130. package/src/shade/renderer/particles/DESIGN.md +745 -702
  131. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  132. package/src/shade/renderer/particles/GPUParticleSystem.js +3 -1
  133. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
  134. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
  135. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  136. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +9 -15
  137. package/src/shade/renderer/particles/graph/particle_group_library.d.ts.map +1 -1
  138. package/src/shade/renderer/particles/graph/particle_group_library.js +8 -3
  139. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +0 -2
  140. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  141. package/src/shade/renderer/particles/graph/particle_node_parameters.js +0 -9
  142. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  143. package/src/shade/renderer/particles/graph/particle_node_presentation.js +0 -10
  144. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +2 -8
  145. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -1
  146. package/src/shade/renderer/particles/graph/particle_ramp.js +2 -8
  147. package/src/shade/renderer/particles/graph/validate_particle_graph.js +0 -6
  148. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  149. package/src/shade/renderer/particles/graph_particles_avboit.js +13 -4
  150. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +1 -12
  151. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/isa/InstructionStream.js +1 -12
  153. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +54 -60
  154. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  155. package/src/shade/renderer/particles/isa/ParticleVMISA.js +9 -17
  156. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +0 -1
  157. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/isa/particle_assembly.js +2 -16
  159. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +1 -1
  160. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +1 -1
  161. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +0 -14
  162. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +3 -17
  163. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  164. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +15 -36
  165. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  166. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +1 -5
  167. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  168. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +1 -8
  169. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +2 -11
  170. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  171. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +2 -11
  172. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +11 -4
  173. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  174. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +431 -424
  175. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/shaders/chunk_particle_avboit_contribution.js +13 -0
  177. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts +3 -6
  178. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  179. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +49 -17
  180. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  181. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +0 -2
  182. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -1
  183. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +0 -2
  184. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  185. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +1 -5
  186. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +0 -2
  188. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +1 -3
  189. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  190. package/src/shade/renderer/particles/vm/ParticleVMReference.js +4 -20
  191. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  192. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +2 -5
  193. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.d.ts.map +1 -1
  194. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance.js +0 -2
  195. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.d.ts.map +1 -1
  196. package/src/shade/renderer/particles/warmup/shader_particle_warmup_advance_wide.js +0 -2
  197. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  198. package/src/shade/renderer/postprocess/ssr/SSR.js +2 -1
  199. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.d.ts.map +1 -1
  200. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_reprojection.js +20 -5
  201. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.d.ts.map +1 -1
  202. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_sample_history.js +19 -5
  203. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts +4 -0
  204. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -0
  205. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +137 -0
  206. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts +0 -8
  207. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.d.ts.map +1 -1
  208. package/src/shade/renderer/postprocess/ssr/ssr_reproject_shader.js +18 -114
  209. package/src/shade/renderer/scene/Mesh.js +1 -1
  210. package/src/shade/renderer/texture/ShadeTexture.js +1 -1
  211. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts +2 -2
  212. package/src/shade/renderer/texture/source/texel_data_from_ktx2.d.ts.map +1 -1
  213. package/src/shade/renderer/texture/source/texel_data_from_ktx2.js +3 -3
  214. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts +0 -19
  215. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.d.ts.map +0 -1
  216. package/src/shade/renderer/particles/shaders/chunk_particle_curve_animation.js +0 -30
  217. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts +0 -11
  218. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.d.ts.map +0 -1
  219. package/src/shade/renderer/particles/shaders/chunk_particle_curve_disabled.js +0 -13
  220. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts +0 -20
  221. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_warmup.d.ts.map +0 -1
  222. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts +0 -14
  223. package/src/shade/renderer/particles/shaders/chunk_particle_emitter_world_sphere.d.ts.map +0 -1
  224. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts +0 -50
  225. package/src/shade/renderer/particles/shaders/shader_particle_reclaim.d.ts.map +0 -1
  226. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +0 -17
  227. package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +0 -1
  228. /package/src/{shade/descriptor/util → core/model/object}/optional_clone.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ParticleGradientEditorView.d.ts","sourceRoot":"","sources":["../../../../../editor/view/particles/effect/ParticleGradientEditorView.js"],"names":[],"mappings":"AAkDA;IAsCI;;;;;;OAMG;IACH;QALqC,IAAI;QACA,KAAK,mBAAnB,IAAI;QACF,KAAK,GAAvB,OAAO;OAqFjB;IA3EG,mBAAuC;IAyF3C;;;OAGG;IACH,gBAWC;IAoLD,eAoDC;;CACJ;iBAnbgB,8BAA8B"}
1
+ {"version":3,"file":"ParticleGradientEditorView.d.ts","sourceRoot":"","sources":["../../../../../editor/view/particles/effect/ParticleGradientEditorView.js"],"names":[],"mappings":"AAwDA;IAyCI;;;;;;OAMG;IACH;QALqC,IAAI;QACA,KAAK,mBAAnB,IAAI;QACF,KAAK,GAAvB,OAAO;OAgGjB;IAtFG,mBAAuC;IA0G3C;;;OAGG;IACH,gBAaC;IA8LD,eAsDC;;CACJ;iBA3dgB,8BAA8B"}
@@ -26,13 +26,19 @@ import View from "../../../../src/view/View.js";
26
26
  */
27
27
 
28
28
  /** How wide the strip is drawn, in CSS pixels. @type {number} */
29
- const WIDTH = 208;
29
+ const WIDTH = 240;
30
30
 
31
31
  /** How tall the colour strip is. @type {number} */
32
32
  const STRIP_HEIGHT = 24;
33
33
 
34
34
  /** How tall the lane of stop markers under it is. @type {number} */
35
- const LANE_HEIGHT = 13;
35
+ const LANE_HEIGHT = 18;
36
+
37
+ /** Keep the complete marker and its hit area inside the canvas, including at t = 0 and 1. */
38
+ const MARGIN = 10;
39
+ const STRIP_TOP = 4;
40
+ const STRIP_WIDTH = WIDTH - MARGIN * 2;
41
+ const HEIGHT = STRIP_TOP + STRIP_HEIGHT + LANE_HEIGHT;
36
42
 
37
43
  /** How near a stop marker a press has to be to take hold of it rather than make a new one. */
38
44
  const GRAB_RADIUS = 7;
@@ -65,8 +71,11 @@ export class ParticleGradientEditorView extends View {
65
71
  /** @type {number} which stop the swatch and the fields below are about */
66
72
  #selected = 0;
67
73
 
68
- /** @type {boolean} */
69
- #dragging = false;
74
+ /** @type {number|null} the pointer that owns the current gesture */
75
+ #pointerId = null;
76
+
77
+ /** @type {boolean} ignore the synchronous echo of our own commit */
78
+ #writing = false;
70
79
 
71
80
  /** @type {function(Array):void} */
72
81
  #write;
@@ -107,8 +116,10 @@ export class ParticleGradientEditorView extends View {
107
116
  const canvas = this.#canvas = document.createElement('canvas');
108
117
 
109
118
  canvas.width = WIDTH;
110
- canvas.height = STRIP_HEIGHT + LANE_HEIGHT;
111
- canvas.classList.add('strip');
119
+ canvas.height = HEIGHT;
120
+ canvas.classList.add('strip');
121
+ canvas.tabIndex = 0;
122
+ canvas.setAttribute('aria-label', 'Gradient stops. Drag to move; click to add; Escape to cancel.');
112
123
 
113
124
  this.el.appendChild(canvas);
114
125
 
@@ -118,9 +129,9 @@ export class ParticleGradientEditorView extends View {
118
129
 
119
130
  this.el.appendChild(fields);
120
131
 
121
- this.#swatch = field(fields, 'color', 'swatch');
122
- this.#alpha = field(fields, 'number', 'alpha');
123
- this.#position = field(fields, 'number', 'position');
132
+ this.#swatch = field(fields, 'color', 'swatch', 'Color');
133
+ this.#alpha = field(fields, 'number', 'alpha', 'Alpha');
134
+ this.#position = field(fields, 'number', 'position', 'Position');
124
135
 
125
136
  for (const input of [this.#alpha, this.#position]) {
126
137
  input.setAttribute('min', '0');
@@ -128,7 +139,8 @@ export class ParticleGradientEditorView extends View {
128
139
  input.setAttribute('step', 'any');
129
140
  }
130
141
 
131
- this.#alpha.hidden = !alpha;
142
+ this.#alpha.hidden = !alpha;
143
+ this.#alpha.parentElement.hidden = !alpha;
132
144
 
133
145
  const remove = document.createElement('button');
134
146
 
@@ -146,7 +158,15 @@ export class ParticleGradientEditorView extends View {
146
158
  canvas.addEventListener('pointerdown', event => this.#press(event));
147
159
  canvas.addEventListener('pointermove', event => this.#move(event));
148
160
  canvas.addEventListener('pointerup', event => this.#release(event));
149
- canvas.addEventListener('pointercancel', event => this.#release(event));
161
+ canvas.addEventListener('pointercancel', event => this.#cancel(event));
162
+ canvas.addEventListener('lostpointercapture', event => this.#cancel(event));
163
+ canvas.addEventListener('keydown', event => {
164
+ if (event.key === 'Escape' && this.#pointerId !== null) {
165
+ event.stopPropagation();
166
+ this.refresh();
167
+ }
168
+ });
169
+ this.on.unlinked.add(() => this.refresh());
150
170
 
151
171
  this.#swatch.addEventListener('change', () => this.#editSelected(stop => {
152
172
  const rgb = hex_to_rgb(this.#swatch.value);
@@ -161,7 +181,7 @@ export class ParticleGradientEditorView extends View {
161
181
  }));
162
182
 
163
183
  this.#position.addEventListener('change', () => this.#editSelected(stop => {
164
- stop.position = number_in(this.#position, stop.position);
184
+ stop.position = clamp01(number_in(this.#position, stop.position));
165
185
  }));
166
186
 
167
187
  remove.addEventListener('click', () => this.#removeSelected());
@@ -185,16 +205,24 @@ export class ParticleGradientEditorView extends View {
185
205
  * next. It is also what makes each commit a distinct value, which is how the node knows anything
186
206
  * changed at all.
187
207
  */
188
- #commit() {
189
- this.#write(structuredClone(this.#stops));
208
+ #commit() {
209
+ if (JSON.stringify(this.#stops) === JSON.stringify(this.#read())) return;
210
+ this.#writing = true;
211
+ try {
212
+ this.#write(structuredClone(this.#stops));
213
+ } finally {
214
+ this.#writing = false;
215
+ }
190
216
  }
191
217
 
192
218
  /**
193
219
  * Re-read the parameter and redraw. Called when the value changed somewhere else — an undo, the
194
220
  * code layer, a script.
195
221
  */
196
- refresh() {
197
- const value = this.#read();
222
+ refresh() {
223
+ if (this.#writing) return;
224
+ this.#endDrag();
225
+ const value = this.#read();
198
226
 
199
227
  this.#stops = Array.isArray(value)
200
228
  ? value.map(stop => ({ position: stop.position, color: (stop.color ?? []).slice() }))
@@ -228,7 +256,7 @@ export class ParticleGradientEditorView extends View {
228
256
  #positionOf(event) {
229
257
  const rect = this.#canvas.getBoundingClientRect();
230
258
 
231
- return clamp01((event.clientX - rect.left) / rect.width);
259
+ return clamp01(((event.clientX - rect.left) / rect.width * WIDTH - MARGIN) / STRIP_WIDTH);
232
260
  }
233
261
 
234
262
  /**
@@ -238,18 +266,15 @@ export class ParticleGradientEditorView extends View {
238
266
  #stopUnder(event) {
239
267
  const rect = this.#canvas.getBoundingClientRect();
240
268
 
241
- const x = event.clientX - rect.left;
242
-
243
- // in CSS pixels, so the grab radius is the same however far the graph is zoomed out
244
- const radius = GRAB_RADIUS * (rect.width / WIDTH);
269
+ const x = (event.clientX - rect.left) / rect.width * WIDTH;
245
270
 
246
271
  let nearest = -1;
247
272
  let distance = Infinity;
248
273
 
249
274
  this.#stops.forEach((stop, index) => {
250
- const away = Math.abs(stop.position * rect.width - x);
275
+ const away = Math.abs(MARGIN + clamp01(stop.position) * STRIP_WIDTH - x);
251
276
 
252
- if (away <= radius && away < distance) {
277
+ if (away <= GRAB_RADIUS && (away < distance || (away === distance && index === this.#selected))) {
253
278
  nearest = index;
254
279
  distance = away;
255
280
  }
@@ -261,8 +286,12 @@ export class ParticleGradientEditorView extends View {
261
286
  /**
262
287
  * @param {PointerEvent} event
263
288
  */
264
- #press(event) {
265
- const stop = this.#stopUnder(event);
289
+ #press(event) {
290
+ if (this.#pointerId !== null) return;
291
+ const rect = this.#canvas.getBoundingClientRect();
292
+ const y = (event.clientY - rect.top) / rect.height * HEIGHT;
293
+ if (y < STRIP_TOP || y > STRIP_TOP + STRIP_HEIGHT + LANE_HEIGHT) return;
294
+ const stop = this.#stopUnder(event);
266
295
 
267
296
  if (event.button === 1) {
268
297
  // the power-user path to the remove button beside the fields
@@ -291,12 +320,12 @@ export class ParticleGradientEditorView extends View {
291
320
  color: particle_gradient_sample(this.#stops, position),
292
321
  });
293
322
 
294
- this.#selected = this.#stops.length - 1;
295
-
296
- this.#commit();
297
- }
298
-
299
- this.#dragging = true;
323
+ this.#selected = this.#stops.length - 1;
324
+ }
325
+
326
+ event.preventDefault();
327
+ this.#canvas.focus({ preventScroll: true });
328
+ this.#pointerId = event.pointerId ?? 0;
300
329
 
301
330
  if (typeof this.#canvas.setPointerCapture === "function") {
302
331
  this.#canvas.setPointerCapture(event.pointerId);
@@ -309,8 +338,8 @@ export class ParticleGradientEditorView extends View {
309
338
  /**
310
339
  * @param {PointerEvent} event
311
340
  */
312
- #move(event) {
313
- if (!this.#dragging) {
341
+ #move(event) {
342
+ if (this.#pointerId !== (event.pointerId ?? 0)) {
314
343
  return;
315
344
  }
316
345
 
@@ -323,20 +352,29 @@ export class ParticleGradientEditorView extends View {
323
352
  /**
324
353
  * @param {PointerEvent} event
325
354
  */
326
- #release(event) {
327
- if (!this.#dragging) {
355
+ #release(event) {
356
+ if (this.#pointerId !== (event.pointerId ?? 0)) {
328
357
  return;
329
358
  }
330
359
 
331
- this.#dragging = false;
332
-
333
- if (typeof this.#canvas.releasePointerCapture === "function" && this.#canvas.hasPointerCapture?.(event.pointerId)) {
334
- this.#canvas.releasePointerCapture(event.pointerId);
335
- }
360
+ this.#endDrag();
336
361
 
337
362
  // one entry on the timeline for the whole drag; see the note at the top of this file
338
- this.#commit();
339
- }
363
+ this.#commit();
364
+ }
365
+
366
+ #endDrag() {
367
+ const pointerId = this.#pointerId;
368
+ this.#pointerId = null;
369
+ if (pointerId !== null && this.#canvas.hasPointerCapture?.(pointerId)) {
370
+ this.#canvas.releasePointerCapture(pointerId);
371
+ }
372
+ }
373
+
374
+ /** @param {PointerEvent} event */
375
+ #cancel(event) {
376
+ if (this.#pointerId === (event.pointerId ?? 0)) this.refresh();
377
+ }
340
378
 
341
379
  /**
342
380
  * @param {function(object):void} edit applied to the selected stop
@@ -381,7 +419,7 @@ export class ParticleGradientEditorView extends View {
381
419
 
382
420
  this.#swatch.value = `#${rgb_to_hex(byte_of(colour[0]), byte_of(colour[1]), byte_of(colour[2]))}`;
383
421
  this.#alpha.value = String(colour[3] ?? 1);
384
- this.#position.value = String(stop === undefined ? 0 : stop.position);
422
+ this.#position.value = String(stop === undefined ? 0 : Number(stop.position.toFixed(6)));
385
423
  }
386
424
 
387
425
  render() {
@@ -398,33 +436,35 @@ export class ParticleGradientEditorView extends View {
398
436
  // A checkerboard behind the strip, so that a stop's alpha is visible as transparency rather
399
437
  // than as a colour that happens to look like the panel behind it.
400
438
  if (this.#has_alpha) {
401
- for (let x = 0; x < canvas.width; x += CHECKER) {
439
+ for (let x = 0; x < STRIP_WIDTH; x += CHECKER) {
402
440
  for (let y = 0; y < STRIP_HEIGHT; y += CHECKER) {
403
441
  context.fillStyle = ((x + y) / CHECKER) % 2 === 0 ? '#4c4f54' : '#6a6e74';
404
- context.fillRect(x, y, CHECKER, CHECKER);
442
+ context.fillRect(MARGIN + x, STRIP_TOP + y, Math.min(CHECKER, STRIP_WIDTH - x), CHECKER);
405
443
  }
406
444
  }
407
445
  }
408
446
 
409
447
  // The strip is drawn by sampling the same function the node compiles to, so what is on
410
448
  // screen is what the effect will do — including a hard edge where two stops share a place.
411
- for (let x = 0; x < canvas.width; x++) {
412
- const colour = particle_gradient_sample(this.#stops, x / (canvas.width - 1));
449
+ for (let x = 0; x <= STRIP_WIDTH; x++) {
450
+ const colour = particle_gradient_sample(this.#stops, x / STRIP_WIDTH);
413
451
 
414
452
  const alpha = this.#has_alpha ? clamp01(colour[3] ?? 1) : 1;
415
453
 
416
454
  context.fillStyle = `rgba(${byte_of(colour[0])}, ${byte_of(colour[1])}, ${byte_of(colour[2])}, ${alpha})`;
417
- context.fillRect(x, 0, 1, STRIP_HEIGHT);
418
- }
419
-
420
- for (const { stop, index } of this.#ordered()) {
421
- const x = clamp01(stop.position) * canvas.width;
455
+ context.fillRect(MARGIN + x, STRIP_TOP, 1, STRIP_HEIGHT);
456
+ }
457
+
458
+ // Paint selection last so a coincident stop cannot hide its outline.
459
+ const ordered = this.#ordered().sort((a, b) => Number(a.index === this.#selected) - Number(b.index === this.#selected));
460
+ for (const { stop, index } of ordered) {
461
+ const x = MARGIN + clamp01(stop.position) * STRIP_WIDTH;
422
462
  const selected = index === this.#selected;
423
463
 
424
464
  context.beginPath();
425
- context.moveTo(x, STRIP_HEIGHT + 1);
426
- context.lineTo(x - 5, STRIP_HEIGHT + LANE_HEIGHT - 1);
427
- context.lineTo(x + 5, STRIP_HEIGHT + LANE_HEIGHT - 1);
465
+ context.moveTo(x, STRIP_TOP + STRIP_HEIGHT + 2);
466
+ context.lineTo(x - 5, STRIP_TOP + STRIP_HEIGHT + LANE_HEIGHT - 4);
467
+ context.lineTo(x + 5, STRIP_TOP + STRIP_HEIGHT + LANE_HEIGHT - 4);
428
468
  context.closePath();
429
469
 
430
470
  // the marker carries the stop's own colour, so the lane reads as the stops rather than
@@ -434,24 +474,29 @@ export class ParticleGradientEditorView extends View {
434
474
 
435
475
  context.lineWidth = selected ? 2 : 1;
436
476
  context.strokeStyle = selected ? '#ffd35c' : '#20242a';
437
- context.stroke();
438
- }
439
- }
440
- }
477
+ context.stroke();
478
+ }
479
+ }
480
+ }
441
481
 
442
482
  /**
443
483
  * @param {HTMLElement} parent
444
484
  * @param {string} type
445
- * @param {string} className
485
+ * @param {string} className
486
+ * @param {string} text
446
487
  * @returns {HTMLInputElement}
447
488
  */
448
- function field(parent, type, className) {
449
- const input = document.createElement('input');
489
+ function field(parent, type, className, text) {
490
+ const label = document.createElement('label');
491
+ label.classList.add('ramp-field', `field-${className}`);
492
+ label.appendChild(document.createTextNode(text));
493
+ const input = document.createElement('input');
450
494
 
451
495
  input.setAttribute('type', type);
452
496
  input.classList.add(className);
453
497
 
454
- parent.appendChild(input);
498
+ label.appendChild(input);
499
+ parent.appendChild(label);
455
500
 
456
501
  return input;
457
502
  }
@@ -135,10 +135,10 @@ const PARTICLE_TYPE_COLORS = new Map([
135
135
  * @type {Array<{name: string, types: string[]}>}
136
136
  */
137
137
  const PALETTE_CATEGORIES = [
138
- { name: "sources", types: ["const", "color", "builtin", "attribute", "random", "curve"] },
138
+ { name: "sources", types: ["const", "color", "builtin", "attribute", "random"] },
139
139
  { name: "output", types: ["setAttribute", "kill"] },
140
140
  // The three that are authored data rather than wiring, and are edited as a picture: a gradient
141
- // strip and a curve in the unit square. Their own heading, because "a colour ramp" is a thing an
141
+ // strip and a curve plot. Their own heading, because "a colour ramp" is a thing an
142
142
  // author goes looking for by name and would not think to look for under `sources`.
143
143
  { name: "ramps", types: ["gradientRGBA", "gradientRGB", "curveLiteral"] },
144
144
  { name: "arithmetic", types: ["add", "sub", "mul", "div", "mad", "scale", "min", "max", "pow", "step", "mix", "clamp", "saturate", "smoothstep", "remap", "oneMinus"] },
@@ -1 +1 @@
1
- {"version":3,"file":"ParticleNodeParametersView.d.ts","sourceRoot":"","sources":["../../../../../editor/view/particles/effect/ParticleNodeParametersView.js"],"names":[],"mappings":"AAqCA;IAOI;;;;;;OAMG;IACH;QALyG,MAAM,EAApG,OAAO,qDAAqD,EAAE,sBAAsB;QAE9D,IAAI;QACG,MAAM,SAA1B,MAAM;OA6BzB;IAxBG,mBAAuC;IAIvC;;OAEG;IACH,mBAAgB;;CA0cvB;iBAlgBgB,8BAA8B"}
1
+ {"version":3,"file":"ParticleNodeParametersView.d.ts","sourceRoot":"","sources":["../../../../../editor/view/particles/effect/ParticleNodeParametersView.js"],"names":[],"mappings":"AAqCA;IAOI;;;;;;OAMG;IACH;QALyG,MAAM,EAApG,OAAO,qDAAqD,EAAE,sBAAsB;QAE9D,IAAI;QACG,MAAM,SAA1B,MAAM;OA6BzB;IAxBG,mBAAuC;IAIvC;;OAEG;IACH,mBAAgB;;CAmavB;iBA3dgB,8BAA8B"}
@@ -87,7 +87,9 @@ export class ParticleNodeParametersView extends View {
87
87
  #buildRow(effect, parameter, commit) {
88
88
  const row = new EmptyView({ classList: ['parameter-row', `kind-${parameter.kind}`] });
89
89
 
90
- row.addChild(new LabelView(parameter.name, { classList: ['name'] }));
90
+ if (parameter.kind !== PARTICLE_PARAMETER_KIND.GRADIENT && parameter.kind !== PARTICLE_PARAMETER_KIND.CURVE) {
91
+ row.addChild(new LabelView(parameter.name, { classList: ['name'] }));
92
+ }
91
93
 
92
94
  if (typeof parameter.description === "string") {
93
95
  row.el.setAttribute('title', parameter.description);
@@ -136,10 +138,6 @@ export class ParticleNodeParametersView extends View {
136
138
  row.bindSignal(effect.on.changed, () => control.refresh());
137
139
  break;
138
140
 
139
- case PARTICLE_PARAMETER_KIND.INTEGER:
140
- control = this.#buildIntegerControl(parameter, value, write);
141
- break;
142
-
143
141
  case PARTICLE_PARAMETER_KIND.CURVE:
144
142
  control = editor_control(new ParticleCurveEditorView({ read: value, write }));
145
143
  break;
@@ -477,47 +475,10 @@ export class ParticleNodeParametersView extends View {
477
475
  return {
478
476
  view: new EmptyView({ el: select }),
479
477
  write: push,
480
- refresh
481
- };
482
- }
483
-
484
- /**
485
- * @param {object} parameter
486
- * @param {function():number} read
487
- * @param {function(number)} write
488
- * @returns {{view: View, write: function(*):void, refresh: function():void}}
489
- */
490
- #buildIntegerControl(parameter, read, write) {
491
- const field = create_input('number');
492
-
493
- field.classList.add('integer');
494
- field.setAttribute('min', '0');
495
- field.setAttribute('step', '1');
496
-
497
- const push = value => {
498
- field.value = String(value ?? 0);
499
- };
500
-
501
- field.addEventListener('change', () => {
502
- const parsed = Number.parseInt(field.value, 10);
503
-
504
- if (!Number.isInteger(parsed) || parsed < 0) {
505
- push(read());
506
- return;
507
- }
508
-
509
- write(parsed);
510
- });
511
-
512
- push(read());
513
-
514
- return {
515
- view: new EmptyView({ el: field }),
516
- write: push,
517
- refresh: () => push(read())
518
- };
519
- }
520
- }
478
+ refresh
479
+ };
480
+ }
481
+ }
521
482
 
522
483
  /**
523
484
  * A control that is a view of its own, in the shape the rest of this file uses.
@@ -213,10 +213,9 @@
213
213
  /*
214
214
  The ramp controls — a gradient's strip and a curve's plot.
215
215
 
216
- Both are wider than a label and a field side by side, so their rows put the label on its own line
217
- and give the control the width of the node. The canvases scale with the row rather than holding
218
- their drawn size: the graph is zoomable, and a control that stayed 208 pixels while everything
219
- around it grew would be the one thing on the node that could not be read.
216
+ Both controls use the width of the node. The canvases scale with the row rather than holding
217
+ their drawn size: the graph is zoomable, and a control that stayed 240 pixels while everything
218
+ around it grew would be the one thing on the node that could not be read.
220
219
  */
221
220
 
222
221
  .ui-particle-node-parameters .parameter-row.kind-gradient,
@@ -226,11 +225,13 @@
226
225
  gap: 3px;
227
226
  }
228
227
 
229
- .ui-particle-gradient,
230
- .ui-particle-curve {
231
- display: flex;
232
- flex-direction: column;
233
- gap: 3px;
228
+ .ui-particle-gradient,
229
+ .ui-particle-curve {
230
+ display: flex;
231
+ flex-direction: column;
232
+ gap: 5px;
233
+ width: 240px;
234
+ max-width: 100%;
234
235
  }
235
236
 
236
237
  .ui-particle-gradient > .strip,
@@ -238,7 +239,10 @@
238
239
  display: block;
239
240
  width: 100%;
240
241
  height: auto;
241
- border: 1px solid var(--meep-graph-node-border, #363c46);
242
+ /* An inset border keeps the canvas's drawing and pointer coordinate spaces identical. */
243
+ border: 0;
244
+ padding: 0;
245
+ box-shadow: inset 0 0 0 1px var(--meep-graph-node-border, #363c46);
242
246
  border-radius: 3px;
243
247
  background: var(--meep-graph-input-bg, #171b21);
244
248
  /* the strip and the plot are both dragged in, and a drag that selects text is a drag that fights */
@@ -248,30 +252,56 @@
248
252
 
249
253
  .ui-particle-gradient > .stop-fields,
250
254
  .ui-particle-curve > .key-fields {
251
- display: flex;
252
- gap: 2px;
253
- align-items: center;
254
- }
255
-
256
- .ui-particle-gradient .swatch {
257
- flex: 1 1 auto;
258
- min-width: 3em;
259
- padding: 0;
260
- }
261
-
262
- .ui-particle-gradient .alpha,
263
- .ui-particle-gradient .position {
264
- flex: 0 0 auto;
265
- width: 4em;
266
- }
267
-
268
- .ui-particle-curve .tangents {
269
- flex: 1 1 auto;
255
+ display: grid;
256
+ gap: 5px;
257
+ align-items: end;
258
+ }
259
+
260
+ .ui-particle-gradient > .stop-fields {
261
+ grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr) minmax(0, 1.4fr) auto;
262
+ }
263
+
264
+ .ui-particle-gradient > .stop-fields:has(.field-alpha[hidden]) {
265
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
266
+ }
267
+
268
+ .ui-particle-curve > .key-fields {
269
+ grid-template-columns: repeat(2, minmax(0, 1fr));
270
+ }
271
+
272
+ .ramp-field {
273
+ display: flex;
274
+ flex-direction: column;
275
+ gap: 2px;
276
+ min-width: 0;
277
+ color: var(--meep-fg-muted, #9da0a3);
278
+ font-size: 10px;
279
+ }
280
+
281
+ .ramp-field[hidden] {
282
+ display: none;
283
+ }
284
+
285
+ .ramp-field > input,
286
+ .ramp-field > select {
287
+ width: 100%;
288
+ min-width: 0;
289
+ }
290
+
291
+ .ui-particle-gradient .swatch {
292
+ height: 23px;
293
+ padding: 0;
294
+ }
295
+
296
+ .ui-particle-gradient > .strip:focus-visible,
297
+ .ui-particle-curve > .plot:focus-visible {
298
+ outline: 1px solid var(--meep-accent, #2d7dd2);
270
299
  }
271
300
 
272
301
  .ui-particle-gradient .remove,
273
302
  .ui-particle-curve .remove {
274
- flex: 0 0 auto;
303
+ flex: 0 0 auto;
304
+ justify-self: end;
275
305
  width: 1.8em;
276
306
  padding: 2px 0;
277
307
  border: 1px solid var(--meep-graph-node-border, #363c46);
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Advanced 3D game engine",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "3.18.0",
9
+ "version": "3.20.0",
10
10
  "exports": {
11
11
  "./build/*": "./build/*",
12
12
  "./src/*": "./src/*",
@@ -48,7 +48,6 @@
48
48
  ],
49
49
  "dependencies": {
50
50
  "opentype.js": "1.3.3",
51
- "pako": "2.0.3",
52
51
  "robust-predicates": "3.0.2"
53
52
  },
54
53
  "peerDependencies": {
@@ -19,7 +19,7 @@ export default {
19
19
  // CommonJS dependencies, so those have to be named. Without this, the first thing a new
20
20
  // consumer sees is a SyntaxError about a package their application never referenced,
21
21
  // a blank page, and no stack trace pointing anywhere near the engine.
22
- include: ['dat.gui', 'pako', 'opentype.js'],
22
+ include: ['dat.gui', 'opentype.js'],
23
23
  },
24
24
  };
25
25
  ```
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Decompress pieces of one stream using the platform's compression API.
3
+ *
4
+ * Feed the input through a pipe so that read failures also cancel the input and settle the
5
+ * writable side. Awaiting writes before draining the output can deadlock on backpressure.
6
+ * The input views must remain unchanged until the returned promise settles.
7
+ *
8
+ * @param {Uint8Array[]} chunks
9
+ * @param {"deflate"|"deflate-raw"|"gzip"} [format] `deflate` includes the zlib header and checksum
10
+ * @returns {Promise<Uint8Array>}
11
+ */
12
+ export function decompress_bytes(chunks: Uint8Array[], format?: "deflate" | "deflate-raw" | "gzip"): Promise<Uint8Array>;
13
+ //# sourceMappingURL=decompress_bytes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompress_bytes.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/compression/decompress_bytes.js"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,yCAJW,UAAU,EAAE,WACZ,SAAS,GAAC,aAAa,GAAC,MAAM,GAC5B,QAAQ,UAAU,CAAC,CAkB/B"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Decompress pieces of one stream using the platform's compression API.
3
+ *
4
+ * Feed the input through a pipe so that read failures also cancel the input and settle the
5
+ * writable side. Awaiting writes before draining the output can deadlock on backpressure.
6
+ * The input views must remain unchanged until the returned promise settles.
7
+ *
8
+ * @param {Uint8Array[]} chunks
9
+ * @param {"deflate"|"deflate-raw"|"gzip"} [format] `deflate` includes the zlib header and checksum
10
+ * @returns {Promise<Uint8Array>}
11
+ */
12
+ export async function decompress_bytes(chunks, format = "deflate") {
13
+ let index = 0;
14
+
15
+ const input = new ReadableStream({
16
+ pull(controller) {
17
+ if (index === chunks.length) {
18
+ controller.close();
19
+ } else {
20
+ controller.enqueue(chunks[index++]);
21
+ }
22
+ }
23
+ });
24
+
25
+ const output = input.pipeThrough(new DecompressionStream(format));
26
+
27
+ return new Uint8Array(await new Response(output).arrayBuffer());
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"array_group_by.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/array/array_group_by.js"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,0IA+BC;2BAzC0B,8BAA8B"}
1
+ {"version":3,"file":"array_group_by.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/array/array_group_by.js"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,0IAqBC;2BA/B0B,8BAA8B"}
@@ -1,3 +1,4 @@
1
+ import { objectsEqual } from "../../function/objectsEqual.js";
1
2
  import { returnZero } from "../../function/returnZero.js";
2
3
  import { HashMap } from "../map/HashMap.js";
3
4
 
@@ -11,17 +12,7 @@ import { HashMap } from "../map/HashMap.js";
11
12
  export function array_group_by(array, grouping_key_producer, keyHashFunction = returnZero) {
12
13
  const result = new HashMap({
13
14
  keyHashFunction,
14
- keyEqualityFunction(a, b) {
15
- if (a === b) {
16
- return true;
17
- }
18
-
19
- if (typeof a === "object" && a !== null && typeof a.equals === "function") {
20
- return a.equals(b);
21
- }
22
-
23
- return false;
24
- }
15
+ keyEqualityFunction: objectsEqual
25
16
  });
26
17
 
27
18
  for (let i = 0; i < array.length; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"HeightMapShape3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/HeightMapShape3D.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IA4DI;;;;;;;;;;;OAWG;IACH,wCATW,MAAM,UACN,MAAM,UACN,MAAM,gBACN,OAAO,iBACP,MAAM,GAGJ,gBAAgB,CAqB5B;IA1FD;;;;;OAKG;IACH,sBAFU,OAAO,CAEkB;IAEnC;;;;;;;OAOG;IACH,eAFU,OAAO,CAEW;IAE5B;;;;;OAKG;IACH,SAFU,YAAY,IAAI,CAEX;IAEf;;;;;;;;;;;;;;;;OAgBG;IACH,cAFU,MAAM,CAEC;IAEjB;;;;;OAKG;IACH,eAA6B;IAG7B,6BAA2B;IAE3B,6BAA2B;IAC3B,6BAA2B;IAmC3B;;;;;;;;;OASG;IACH,sBA+CC;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,8BALW,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAelB;IAED,wCA8BC;IAED,oCA2BC;IAED;;;;;;;;OAQG;IACH,6CAmBC;IAED;;;;OAIG;IACH,4DA2BC;IAED;;;;;;;;;OASG;IACH,qGAEC;IAED,kFAiBC;IA6CD;;;OAGG;IACH,cAHW,gBAAgB,GACd,OAAO,CAiBnB;IAWL;;;;;;OAMG;IACH,6BAFU,OAAO,CAE4B;CAT5C;gCAvc+B,sBAAsB;wBAD9B,kBAAkB"}
1
+ {"version":3,"file":"HeightMapShape3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/HeightMapShape3D.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH;IA4DI;;;;;;;;;;;OAWG;IACH,wCATW,MAAM,UACN,MAAM,UACN,MAAM,gBACN,OAAO,iBACP,MAAM,GAGJ,gBAAgB,CAqB5B;IA1FD;;;;;OAKG;IACH,sBAFU,OAAO,CAEkB;IAEnC;;;;;;;OAOG;IACH,eAFU,OAAO,CAEW;IAE5B;;;;;OAKG;IACH,SAFU,YAAY,IAAI,CAEX;IAEf;;;;;;;;;;;;;;;;OAgBG;IACH,cAFU,MAAM,CAEC;IAEjB;;;;;OAKG;IACH,eAA6B;IAG7B,6BAA2B;IAE3B,6BAA2B;IAC3B,6BAA2B;IAmC3B;;;;;;;;;OASG;IACH,sBA+CC;IAED;;;;;;OAMG;IACH,yBAJW,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;OAQG;IACH,8BALW,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAelB;IAED,wCA8BC;IAED,oCA2BC;IAED;;;;;;;;OAQG;IACH,6CAmBC;IAED;;;;OAIG;IACH,4DA2BC;IAED;;;;;;;;;OASG;IACH,qGAEC;IAED,kFAiBC;IA6CD;;;OAGG;IACH,cAHW,gBAAgB,GACd,OAAO,CAUnB;IAWL;;;;;;OAMG;IACH,6BAFU,OAAO,CAE4B;CAT5C;gCAhc+B,sBAAsB;wBAD9B,kBAAkB"}