@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,24 @@
1
+ /**
2
+ * Write one LEB128 ("varint-7") unsigned integer — the inverse of {@link meshopt_read_uint_var}.
3
+ *
4
+ * Seven bits of the value go in each byte, least significant group first, and the top bit says
5
+ * whether another byte follows. A value's encoding is unique because the loop stops as soon as
6
+ * nothing is left, so a stream this wrote reads back at exactly the length it wrote.
7
+ *
8
+ * {@link BinaryBuffer#writeUintVar} is the same encoding and is deliberately not used here, for the
9
+ * same reasons the reader gives: this writes into a plain byte range at an offset the caller
10
+ * carries, not through a `DataView` over a whole `ArrayBuffer`.
11
+ *
12
+ * @param {Uint8Array} destination at least {@link MESHOPT_UINT_VAR_MAX_BYTES} writable bytes at
13
+ * `offset`, which is what lets this be checked once per stream instead of once per byte
14
+ * @param {number} offset
15
+ * @param {number} value unsigned 32-bit
16
+ * @returns {number} the offset just past what was written
17
+ */
18
+ export function meshopt_write_uint_var(destination: Uint8Array, offset: number, value: number): number;
19
+ /**
20
+ * The most bytes a 32-bit value can take: four groups of seven bits, then the four that are left.
21
+ * @type {number}
22
+ */
23
+ export const MESHOPT_UINT_VAR_MAX_BYTES: number;
24
+ //# sourceMappingURL=meshopt_write_uint_var.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meshopt_write_uint_var.d.ts","sourceRoot":"","sources":["../../../../../src/core/binary/meshopt/meshopt_write_uint_var.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AACH,oDANW,UAAU,UAEV,MAAM,SACN,MAAM,GACJ,MAAM,CAelB;AApCD;;;GAGG;AACH,yCAFU,MAAM,CAE4B"}
@@ -0,0 +1,39 @@
1
+ import { assert } from "../../assert.js";
2
+
3
+ /**
4
+ * The most bytes a 32-bit value can take: four groups of seven bits, then the four that are left.
5
+ * @type {number}
6
+ */
7
+ export const MESHOPT_UINT_VAR_MAX_BYTES = 5;
8
+
9
+ /**
10
+ * Write one LEB128 ("varint-7") unsigned integer — the inverse of {@link meshopt_read_uint_var}.
11
+ *
12
+ * Seven bits of the value go in each byte, least significant group first, and the top bit says
13
+ * whether another byte follows. A value's encoding is unique because the loop stops as soon as
14
+ * nothing is left, so a stream this wrote reads back at exactly the length it wrote.
15
+ *
16
+ * {@link BinaryBuffer#writeUintVar} is the same encoding and is deliberately not used here, for the
17
+ * same reasons the reader gives: this writes into a plain byte range at an offset the caller
18
+ * carries, not through a `DataView` over a whole `ArrayBuffer`.
19
+ *
20
+ * @param {Uint8Array} destination at least {@link MESHOPT_UINT_VAR_MAX_BYTES} writable bytes at
21
+ * `offset`, which is what lets this be checked once per stream instead of once per byte
22
+ * @param {number} offset
23
+ * @param {number} value unsigned 32-bit
24
+ * @returns {number} the offset just past what was written
25
+ */
26
+ export function meshopt_write_uint_var(destination, offset, value) {
27
+ assert.isNonNegativeInteger(offset, 'offset');
28
+
29
+ let remaining = value >>> 0;
30
+
31
+ while (remaining >= 0x80) {
32
+ destination[offset++] = (remaining & 0x7f) | 0x80;
33
+ remaining = remaining >>> 7;
34
+ }
35
+
36
+ destination[offset++] = remaining;
37
+
38
+ return offset;
39
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"seededRandom_Mulberry32.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/random/seededRandom_Mulberry32.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,+CAHW,MAAM,UACQ,MAAM;wBAAwB,MAAM,KAAK,IAAI;oBAAiB,OAAY,MAAM,CAAC;EA2BzG"}
1
+ {"version":3,"file":"seededRandom_Mulberry32.d.ts","sourceRoot":"","sources":["../../../../../src/core/math/random/seededRandom_Mulberry32.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,+CAHW,MAAM,UACQ,MAAM;wBAAwB,MAAM,KAAK,IAAI;oBAAiB,OAAY,MAAM,CAAC;EA6BzG"}
@@ -7,7 +7,7 @@ export function seededRandom_Mulberry32(seed = 0) {
7
7
  let _seed = seed;
8
8
 
9
9
  function random() {
10
- _seed += 0x6D2B79F5;
10
+ _seed = (_seed + 0x6D2B79F5) | 0;
11
11
 
12
12
  // Mulberry32 generator
13
13
  let t = _seed;
@@ -16,7 +16,9 @@ export function seededRandom_Mulberry32(seed = 0) {
16
16
 
17
17
  t ^= t + Math.imul(t ^ t >>> 7, t | 61);
18
18
 
19
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
19
+ const u = (t ^ t >>> 14) >>> 0;
20
+
21
+ return u / 4294967296;
20
22
  }
21
23
 
22
24
  random.setCurrentSeed = function (v) {
@@ -22,6 +22,25 @@ export class Action<CTX> {
22
22
  * @param {CTX} context
23
23
  */
24
24
  revert(context: CTX): Promise<void>;
25
+ /**
26
+ * Declare what {@link apply} will write, before it runs. A host that records actions into a
27
+ * shared history (the scene editor's project session) captures the prior state of every
28
+ * declared key, lets the action apply, and diffs; an action that declares nothing is local
29
+ * to the host (a selection change) and is never recorded. {@link ActionProcessor} itself
30
+ * never calls this.
31
+ *
32
+ * `writes` offers `component(entity, componentClass)`, `entity(entity)` for creation or
33
+ * removal of the entity itself, and `blob(entity, componentClass, field, x, y, w, h)` for a
34
+ * rectangle of an externalised array field.
35
+ *
36
+ * @param {CTX} context
37
+ * @param {{component: function(number, Function): void, entity: function(number): void, blob: function(number, Function, string, number, number, number, number): void}} writes
38
+ */
39
+ collectWrites(context: CTX, writes: {
40
+ component: (arg0: number, arg1: Function) => void;
41
+ entity: (arg0: number) => void;
42
+ blob: (arg0: number, arg1: Function, arg2: string, arg3: number, arg4: number, arg5: number, arg6: number) => void;
43
+ }): void;
25
44
  /**
26
45
  * Used for quick instanceof checks
27
46
  * @type {boolean}
@@ -1 +1 @@
1
- {"version":3,"file":"Action.d.ts","sourceRoot":"","sources":["../../../../../src/core/process/undo/Action.js"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH;IACI;;;OAGG;IACH,mBAFY,MAAM,CAIjB;IAED;;;OAGG;IACH,eAFW,GAAG,iBAIb;IAED;;;OAGG;IACH,gBAFW,GAAG,iBAIb;IAGL;;;OAGG;IACH,UAFU,OAAO,CAEQ;CANxB"}
1
+ {"version":3,"file":"Action.d.ts","sourceRoot":"","sources":["../../../../../src/core/process/undo/Action.js"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH;IACI;;;OAGG;IACH,mBAFY,MAAM,CAIjB;IAED;;;OAGG;IACH,eAFW,GAAG,iBAIb;IAED;;;OAGG;IACH,gBAFW,GAAG,iBAIb;IAED;;;;;;;;;;;;;OAaG;IACH,uBAHW,GAAG,UACH;QAAC,SAAS,SAAW,MAAM,qBAAa,IAAI,CAAC;QAAC,MAAM,SAAW,MAAM,KAAG,IAAI,CAAC;QAAC,IAAI,SAAW,MAAM,wBAAY,MAAM,QAAE,MAAM,QAAE,MAAM,QAAE,MAAM,QAAE,MAAM,KAAG,IAAI,CAAA;KAAC,QAGvK;IAGL;;;OAGG;IACH,UAFU,OAAO,CAEQ;CANxB"}
@@ -31,6 +31,23 @@ export class Action {
31
31
  async revert(context) {
32
32
  throw new Error('Not Implemented. Needs to be overridden in subclass');
33
33
  }
34
+
35
+ /**
36
+ * Declare what {@link apply} will write, before it runs. A host that records actions into a
37
+ * shared history (the scene editor's project session) captures the prior state of every
38
+ * declared key, lets the action apply, and diffs; an action that declares nothing is local
39
+ * to the host (a selection change) and is never recorded. {@link ActionProcessor} itself
40
+ * never calls this.
41
+ *
42
+ * `writes` offers `component(entity, componentClass)`, `entity(entity)` for creation or
43
+ * removal of the entity itself, and `blob(entity, componentClass, field, x, y, w, h)` for a
44
+ * rectangle of an externalised array field.
45
+ *
46
+ * @param {CTX} context
47
+ * @param {{component: function(number, Function): void, entity: function(number): void, blob: function(number, Function, string, number, number, number, number): void}} writes
48
+ */
49
+ collectWrites(context, writes) {
50
+ }
34
51
  }
35
52
 
36
53
  /**
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @typedef {object} ParticleAtlasTexture
3
+ * @property {number} references Number of emitters using this URL.
4
+ * @property {import("../graphics/texture/atlas/AtlasPatch.js").AtlasPatch|null} patch Null while loading or after failure.
5
+ */
6
+ /**
7
+ * @typedef {object} ParticleAtlasEntry
8
+ * @property {string|null} url Last observed emitter texture URL.
9
+ * @property {ParticleAtlasTexture|null} texture Shared image record, or null for an untextured emitter.
10
+ * @property {number} seen Last membership sweep that visited this emitter.
11
+ */
12
+ /**
13
+ * Asset and atlas ownership for Shade's GPU particle emitters in one scene.
14
+ *
15
+ * This ECS system observes the scene's ParticleEmitter nodes, so it needs no additional component
16
+ * or duplicate transform. Add/remove nodes through the scene as usual. One system owns the sprite
17
+ * atlas for that scene; the legacy ParticleEmitterSystem continues to serve CPU particle effects.
18
+ *
19
+ * Images load through the supplied AssetManager and share a patch by URL. TextureAtlas already
20
+ * handles packing, growth and repacking with MaxRectanglesPacker. A FrameStart extension publishes
21
+ * the pixels and every current patch before the renderer records particle simulation and drawing.
22
+ * Pending/failed images sample transparent; emitters without an image sample white.
23
+ */
24
+ export class GPUParticleEmitterSystem extends System<any> {
25
+ /**
26
+ * @param {import("./GraphicsEngine.js").GraphicsEngine} graphics
27
+ * @param {import("../../shade/renderer/scene/Scene.js").Scene} scene scene whose particle atlas this system owns
28
+ * @param {import("../asset/AssetManager.js").AssetManager} assets
29
+ */
30
+ constructor(graphics: import("./GraphicsEngine.js").GraphicsEngine, scene: import("../../shade/renderer/scene/Scene.js").Scene, assets: import("../asset/AssetManager.js").AssetManager<any>);
31
+ /**
32
+ * CPU atlas, exposed for inspection. Owned by this system.
33
+ * @type {TextureAtlas}
34
+ */
35
+ atlas: TextureAtlas;
36
+ /**
37
+ * @param {import("../ecs/EntityManager.js").EntityManager} entityManager
38
+ * @returns {Promise<void>}
39
+ */
40
+ startup(entityManager: import("../ecs/EntityManager.js").EntityManager): Promise<void>;
41
+ /** @returns {Promise<void>} */
42
+ shutdown(): Promise<void>;
43
+ /** @returns {void} */
44
+ update(): void;
45
+ /** Publish atlas data at FrameStart, after scene rows exist and before particle passes record.
46
+ * @param {import("../../shade/renderer/extension/FrameContext.js").FrameContext} frame
47
+ * @returns {void}
48
+ */
49
+ prepare(frame: import("../../shade/renderer/extension/FrameContext.js").FrameContext): void;
50
+ #private;
51
+ }
52
+ export type ParticleAtlasTexture = {
53
+ /**
54
+ * Number of emitters using this URL.
55
+ */
56
+ references: number;
57
+ /**
58
+ * Null while loading or after failure.
59
+ */
60
+ patch: import("../graphics/texture/atlas/AtlasPatch.js").AtlasPatch | null;
61
+ };
62
+ export type ParticleAtlasEntry = {
63
+ /**
64
+ * Last observed emitter texture URL.
65
+ */
66
+ url: string | null;
67
+ /**
68
+ * Shared image record, or null for an untextured emitter.
69
+ */
70
+ texture: ParticleAtlasTexture | null;
71
+ /**
72
+ * Last membership sweep that visited this emitter.
73
+ */
74
+ seen: number;
75
+ };
76
+ import { System } from "../ecs/System.js";
77
+ import { TextureAtlas } from "../graphics/texture/atlas/TextureAtlas.js";
78
+ //# sourceMappingURL=GPUParticleEmitterSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GPUParticleEmitterSystem.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GPUParticleEmitterSystem.js"],"names":[],"mappings":"AAWA;;;;GAIG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH;IA0CI;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,cAAc,SAC5C,OAAO,qCAAqC,EAAE,KAAK,gEAY7D;IAvDD;;;OAGG;IACH,OAFU,YAAY,CAEO;IAqD7B;;;OAGG;IACH,uBAHW,OAAO,yBAAyB,EAAE,aAAa,GAC7C,QAAQ,IAAI,CAAC,CASzB;IAED,+BAA+B;IAC/B,YADc,QAAQ,IAAI,CAAC,CAkB1B;IAUD,sBAAsB;IACtB,UADc,IAAI,CAWjB;IA6DD;;;OAGG;IACH,eAHW,OAAO,gDAAgD,EAAE,YAAY,GACnE,IAAI,CAqChB;;CA2CJ;;;;;gBApRa,MAAM;;;;WACN,OAAO,yCAAyC,EAAE,UAAU,GAAC,IAAI;;;;;;SAKjE,MAAM,GAAC,IAAI;;;;aACX,oBAAoB,GAAC,IAAI;;;;UACzB,MAAM;;uBAjBG,kBAAkB;6BAGZ,2CAA2C"}
@@ -0,0 +1,310 @@
1
+ import { assert } from "../../core/assert.js";
2
+ import { FramePhase } from "../../shade/renderer/extension/FramePhase.js";
3
+ import { RenderExtension } from "../../shade/renderer/extension/RenderExtension.js";
4
+ import { GPUTextureContext } from "../../shade/renderer/texture/GPUTextureContext.js";
5
+ import { System } from "../ecs/System.js";
6
+ import { GameAssetType } from "../asset/GameAssetType.js";
7
+ import { ImageRGBADataLoader } from "../asset/loaders/image/ImageRGBADataLoader.js";
8
+ import { TextureAtlas } from "../graphics/texture/atlas/TextureAtlas.js";
9
+ import { Sampler2D } from "../graphics/texture/sampler/Sampler2D.js";
10
+ import { sampler2d_ensure_uint8_RGBA } from "../graphics/texture/sampler/sampler2d_ensure_uint8_RGBA.js";
11
+
12
+ /**
13
+ * @typedef {object} ParticleAtlasTexture
14
+ * @property {number} references Number of emitters using this URL.
15
+ * @property {import("../graphics/texture/atlas/AtlasPatch.js").AtlasPatch|null} patch Null while loading or after failure.
16
+ */
17
+
18
+ /**
19
+ * @typedef {object} ParticleAtlasEntry
20
+ * @property {string|null} url Last observed emitter texture URL.
21
+ * @property {ParticleAtlasTexture|null} texture Shared image record, or null for an untextured emitter.
22
+ * @property {number} seen Last membership sweep that visited this emitter.
23
+ */
24
+
25
+ /**
26
+ * Asset and atlas ownership for Shade's GPU particle emitters in one scene.
27
+ *
28
+ * This ECS system observes the scene's ParticleEmitter nodes, so it needs no additional component
29
+ * or duplicate transform. Add/remove nodes through the scene as usual. One system owns the sprite
30
+ * atlas for that scene; the legacy ParticleEmitterSystem continues to serve CPU particle effects.
31
+ *
32
+ * Images load through the supplied AssetManager and share a patch by URL. TextureAtlas already
33
+ * handles packing, growth and repacking with MaxRectanglesPacker. A FrameStart extension publishes
34
+ * the pixels and every current patch before the renderer records particle simulation and drawing.
35
+ * Pending/failed images sample transparent; emitters without an image sample white.
36
+ */
37
+ export class GPUParticleEmitterSystem extends System {
38
+ /**
39
+ * CPU atlas, exposed for inspection. Owned by this system.
40
+ * @type {TextureAtlas}
41
+ */
42
+ atlas = new TextureAtlas(64);
43
+
44
+ /** @type {import("./GraphicsEngine.js").GraphicsEngine} */
45
+ #graphics;
46
+ /** @type {import("../../shade/renderer/scene/Scene.js").Scene} */
47
+ #scene;
48
+ /** @type {import("../asset/AssetManager.js").AssetManager} */
49
+ #assets;
50
+ /** @type {Map<import("../../shade/renderer/particles/runtime/ParticleEmitter.js").ParticleEmitter, ParticleAtlasEntry>} */
51
+ #entries = new Map();
52
+ /** @type {Map<string, ParticleAtlasTexture>} */
53
+ #textures = new Map();
54
+ /** @type {number} */
55
+ #sweep = 0;
56
+ /** @type {number} */
57
+ #membership_version = -1;
58
+ /** @type {import("../graphics/texture/atlas/AtlasPatch.js").AtlasPatch} */
59
+ #white;
60
+ /** @type {import("../graphics/texture/atlas/AtlasPatch.js").AtlasPatch} */
61
+ #transparent;
62
+ /** @type {GPUParticleAtlasExtension|null} */
63
+ #extension = null;
64
+ /** @type {GPUTextureContext|null} */
65
+ #texture = null;
66
+ /** @type {GPUTextureView|null} */
67
+ #view = null;
68
+ /** @type {GPUDevice|null} */
69
+ #device = null;
70
+ /** @type {number} */
71
+ #uploaded_version = -1;
72
+ /** @type {import("../../shade/renderer/particles/GPUParticleSystem.js").GPUParticleSystem|null} */
73
+ #particles = null;
74
+ /** @type {GPUTextureView|null} */
75
+ #previous_atlas = null;
76
+ /** @type {Float32Array} */
77
+ #region = new Float32Array(4);
78
+
79
+ /**
80
+ * @param {import("./GraphicsEngine.js").GraphicsEngine} graphics
81
+ * @param {import("../../shade/renderer/scene/Scene.js").Scene} scene scene whose particle atlas this system owns
82
+ * @param {import("../asset/AssetManager.js").AssetManager} assets
83
+ */
84
+ constructor(graphics, scene, assets) {
85
+ super();
86
+ assert.defined(graphics, "graphics");
87
+ assert.equal(scene.isScene, true, "scene.isScene !== true");
88
+ assert.defined(assets, "assets");
89
+ this.#graphics = graphics;
90
+ this.#scene = scene;
91
+ this.#assets = assets;
92
+ this.#create_defaults();
93
+ }
94
+
95
+ /**
96
+ * @param {import("../ecs/EntityManager.js").EntityManager} entityManager
97
+ * @returns {Promise<void>}
98
+ */
99
+ async startup(entityManager) {
100
+ this.entityManager = entityManager;
101
+ if (!this.#assets.hasLoaderForType(GameAssetType.Image)) {
102
+ await this.#assets.registerLoader(GameAssetType.Image, new ImageRGBADataLoader());
103
+ }
104
+ this.#extension = new GPUParticleAtlasExtension(this);
105
+ this.#graphics.add_extension(this.#extension);
106
+ }
107
+
108
+ /** @returns {Promise<void>} */
109
+ async shutdown() {
110
+ if (this.#extension !== null) {
111
+ this.#graphics.remove_extension(this.#extension);
112
+ this.#extension = null;
113
+ }
114
+ this.#detach();
115
+ this.#texture?.destroy();
116
+ this.#texture = null;
117
+ this.#view = null;
118
+ this.#device = null;
119
+ this.#uploaded_version = -1;
120
+ this.#entries.clear();
121
+ this.#membership_version = -1;
122
+ // An in-flight load checks its record's identity here before adding a patch.
123
+ this.#textures.clear();
124
+ this.atlas.reset();
125
+ this.#create_defaults();
126
+ }
127
+
128
+ /** @returns {void} */
129
+ #create_defaults() {
130
+ const white = Sampler2D.uint8(4, 1, 1);
131
+ white.data.fill(255);
132
+ this.#white = this.atlas.add(white);
133
+ this.#transparent = this.atlas.add(Sampler2D.uint8(4, 1, 1));
134
+ }
135
+
136
+ /** @returns {void} */
137
+ update() {
138
+ this.#sync_membership();
139
+ for (const [emitter, entry] of this.#entries) {
140
+ if (entry.url !== emitter.texture) {
141
+ this.#release(entry.url);
142
+ entry.url = emitter.texture;
143
+ entry.texture = entry.url === null ? null : this.#acquire(entry.url);
144
+ }
145
+ }
146
+ this.atlas.update();
147
+ }
148
+
149
+ /** @returns {void} */
150
+ #sync_membership() {
151
+ const instances = this.#scene.instances;
152
+ if (instances.version === this.#membership_version) { return; }
153
+ const sweep = ++this.#sweep;
154
+ for (const emitter of instances.nodes) {
155
+ if (emitter.isParticleEmitter !== true) { continue; }
156
+ let entry = this.#entries.get(emitter);
157
+ if (entry === undefined) {
158
+ entry = { url: null, texture: null, seen: sweep };
159
+ this.#entries.set(emitter, entry);
160
+ }
161
+ entry.seen = sweep;
162
+ }
163
+ for (const [emitter, entry] of this.#entries) {
164
+ if (entry.seen !== sweep) {
165
+ this.#release(entry.url);
166
+ this.#entries.delete(emitter);
167
+ }
168
+ }
169
+ this.#membership_version = instances.version;
170
+ }
171
+
172
+ /**
173
+ * @param {string} url
174
+ * @returns {ParticleAtlasTexture}
175
+ */
176
+ #acquire(url) {
177
+ let texture = this.#textures.get(url);
178
+ if (texture !== undefined) {
179
+ texture.references++;
180
+ return texture;
181
+ }
182
+ texture = { references: 1, patch: null };
183
+ this.#textures.set(url, texture);
184
+ this.#assets.promise(url, GameAssetType.Image).then(asset => {
185
+ // Removed, changed URL, or shut down while loading: the completion owns nothing now.
186
+ if (this.#textures.get(url) !== texture) { return; }
187
+ texture.patch = this.atlas.add(sampler2d_ensure_uint8_RGBA(asset.create()));
188
+ }).catch(error => {
189
+ if (this.#textures.get(url) === texture) {
190
+ console.warn(`GPU particle texture '${url}' could not be loaded`, error);
191
+ }
192
+ });
193
+ return texture;
194
+ }
195
+
196
+ /**
197
+ * @param {string|null} url
198
+ * @returns {void}
199
+ */
200
+ #release(url) {
201
+ if (url === null) { return; }
202
+ const texture = this.#textures.get(url);
203
+ if (--texture.references !== 0) { return; }
204
+ this.#textures.delete(url);
205
+ if (texture.patch !== null) { this.atlas.remove(texture.patch); }
206
+ }
207
+
208
+ /** Publish atlas data at FrameStart, after scene rows exist and before particle passes record.
209
+ * @param {import("../../shade/renderer/extension/FrameContext.js").FrameContext} frame
210
+ * @returns {void}
211
+ */
212
+ prepare(frame) {
213
+ if (frame.view.scene.scene !== this.#scene) { return; }
214
+ this.update();
215
+ const renderer = this.#graphics.renderer;
216
+ renderer.feature_particles_enabled = true;
217
+ const particles = renderer.particles(frame.view.scene);
218
+ if (particles !== this.#particles) {
219
+ this.#detach();
220
+ this.#particles = particles;
221
+ this.#previous_atlas = particles.atlas;
222
+ }
223
+ particles.sync_membership();
224
+ this.#upload(renderer.graphics.device);
225
+ particles.atlas = this.#view;
226
+
227
+ for (const [emitter, entry] of this.#entries) {
228
+ if (particles.registry.context(emitter) === undefined) { continue; }
229
+ const patch = entry.texture === null ? this.#white : entry.texture.patch ?? this.#transparent;
230
+ const uv = patch.uv;
231
+ const region = this.#region;
232
+ if (patch === this.#white || patch === this.#transparent) {
233
+ // Sample the texel centre everywhere, avoiding interpolation into the gutter.
234
+ region[0] = uv.position.x + uv.size.x * 0.5;
235
+ region[1] = uv.position.y + uv.size.y * 0.5;
236
+ region[2] = 0;
237
+ region[3] = 0;
238
+ } else {
239
+ region[0] = uv.position.x;
240
+ region[1] = uv.position.y;
241
+ region[2] = uv.size.x;
242
+ region[3] = uv.size.y;
243
+ }
244
+ // Re-read every patch after packing: growth also changes UVs of unchanged images.
245
+ particles.registry.set_atlas_region(emitter, region);
246
+ }
247
+ }
248
+
249
+ /**
250
+ * @param {GPUDevice} device
251
+ * @returns {void}
252
+ */
253
+ #upload(device) {
254
+ const source = this.atlas.sampler;
255
+ if (this.#device !== device || this.#texture === null) {
256
+ this.#texture?.destroy();
257
+ this.#device = device;
258
+ this.#texture = new GPUTextureContext(device);
259
+ const descriptor = this.#texture.descriptor;
260
+ descriptor.label = "particles/sprite atlas";
261
+ descriptor.format = "rgba8unorm";
262
+ descriptor.usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST;
263
+ this.#uploaded_version = -1;
264
+ }
265
+ const texture = this.#texture;
266
+ if (texture.width !== source.width || texture.height !== source.height) {
267
+ texture.resize(source.width, source.height);
268
+ this.#uploaded_version = -1;
269
+ }
270
+ if (this.#uploaded_version !== source.version) {
271
+ device.queue.writeTexture({ texture: texture.gpu_texture }, source.data,
272
+ { bytesPerRow: source.width * 4 }, [source.width, source.height]);
273
+ texture.incrementVersion();
274
+ this.#uploaded_version = source.version;
275
+ }
276
+ this.#view = texture.obtainView();
277
+ }
278
+
279
+ /** @returns {void} */
280
+ #detach() {
281
+ if (this.#particles !== null && this.#particles.atlas === this.#view) {
282
+ this.#particles.atlas = this.#previous_atlas;
283
+ for (const emitter of this.#particles.emitters) {
284
+ this.#particles.registry.set_atlas_region(emitter, [0, 0, 1, 1]);
285
+ }
286
+ }
287
+ this.#particles = null;
288
+ this.#previous_atlas = null;
289
+ }
290
+ }
291
+
292
+ class GPUParticleAtlasExtension extends RenderExtension {
293
+ /** @type {string} */
294
+ name = "gpu particle atlas";
295
+ /** @type {FramePhase} */
296
+ phase = FramePhase.FrameStart;
297
+ /** @type {GPUParticleEmitterSystem} */
298
+ #system;
299
+
300
+ /** @param {GPUParticleEmitterSystem} system */
301
+ constructor(system) {
302
+ super();
303
+ this.#system = system;
304
+ }
305
+ /**
306
+ * @param {import("../../shade/renderer/extension/FrameContext.js").FrameContext} frame
307
+ * @returns {void}
308
+ */
309
+ record(frame) { this.#system.prepare(frame); }
310
+ }
@@ -272,6 +272,23 @@ export class GraphicsEngine {
272
272
  * @returns {Promise<void>}
273
273
  */
274
274
  start(): Promise<void>;
275
+ /**
276
+ * Re-point the viewport at a canvas, and the page with it. This is the wrinkle E1 named:
277
+ * `start` builds a *new* canvas, so a restart would otherwise leave the dead one mounted and
278
+ * the live one detached. `View.el` is read unguarded all over the view layer, so it is replaced
279
+ * rather than cleared — it always holds an element.
280
+ *
281
+ * The inline `pointer-events` of the element being replaced comes along: the engine opts the
282
+ * viewport back in (`auto`) under a game view that lets clicks fall through (`none`), and it
283
+ * does so on the placeholder element before there is a canvas. A canvas that did not inherit
284
+ * the opt-in inherited the fall-through instead, and every pointer device bound to the canvas
285
+ * — the editor's tools — was deaf to every press.
286
+ *
287
+ * Public so that the swap can be driven without a device.
288
+ *
289
+ * @param {HTMLCanvasElement} canvas
290
+ */
291
+ adopt_canvas(canvas: HTMLCanvasElement): void;
275
292
  /**
276
293
  * Tear the device down and let go of the canvas.
277
294
  *
@@ -1 +1 @@
1
- {"version":3,"file":"GraphicsEngine.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GraphicsEngine.js"],"names":[],"mappings":"AAiDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH;IACI;;;;;OAKG;IACH,gCAEC;IAUD;;;;OAIG;IACH,yBAEC;IA0DG;;;;;;OAMG;IACH,QAFU,kBAAkB,CAEsB;IAElD;QACI;;;;;;;;WAQG;mBADO,MAAM;QAIhB;;;;;WAKG;oBADO,MAAM;QAIhB;;;;WAIG;qBADO,MAAM;QAIhB;;;;;;;WAOG;;QAGH;;;;;WAKG;;MAEN;IAID;;;;;OAKG;IACH,4BAFU,OAAO,CAEyB;IAE1C;;;;;;OAMG;IACH,UAFU,SAAS,CAEY;IAG/B;;OAEG;IACH,YAFU,iBAAiB,GAAC,IAAI,CAEV;IAEtB;;;;;OAKG;IACH,UAFU,OAAO,CAEG;IAEpB;;;;;OAKG;IACH,UAFU,OAAO,CAEG;IAEpB;;OAEG;IACH,YAFU,MAAM,CAEG;IAoBvB;;;;;;;;;;;;OAYG;IACH,mDAEC;IAED;;;;;;;;OAQG;IACH,iBAFW,KAAK,QAoBf;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,iDAOC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,2DAWC;IAED;;;;;;;;;;OAUG;IACH,oCAFa,MAAM,CAclB;IAED;;;;;;OAMG;IACH,8CAFa,OAAO,CAgBnB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,qBALW,KAAK,GACH,kBAAgB,IAAI,CAehC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,yBARW,KAAK,yBAEL,MAAM,UACN,MAAM,GACJ,QAAQ,SAAS,CAAC,CAwD9B;IAED;;;;OAIG;IACH,0BAEC;IAED;;;;;;;;;;OAUG;IACH,SAFa,QAAQ,IAAI,CAAC,CA4DzB;IAED;;;;;OAKG;IACH,aAiBC;IASD;;;;;;;;OAQG;IACH,8BAHW,OAAO,UAAQ,UACf,OAAO,UAAQ,QAQzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,yBALW,MAAM,KACN,MAAM,6CAMhB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,mBAyBC;IAED;;;;;OAKG;IACH,4BAHW,MAAM,GACJ,OAAO,CAoDnB;;CACJ;yBAzxBwB,kCAAkC;mCAMxB,yBAAyB;mBAZzC,oCAAoC;wBAC/B,4BAA4B;sBAQ9B,kCAAkC;yCAJf,kDAAkD;sBAErE,qCAAqC;0BACjC,0CAA0C"}
1
+ {"version":3,"file":"GraphicsEngine.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics3/GraphicsEngine.js"],"names":[],"mappings":"AAiDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH;IACI;;;;;OAKG;IACH,gCAEC;IAUD;;;;OAIG;IACH,yBAEC;IA0DG;;;;;;OAMG;IACH,QAFU,kBAAkB,CAEsB;IAElD;QACI;;;;;;;;WAQG;mBADO,MAAM;QAIhB;;;;;WAKG;oBADO,MAAM;QAIhB;;;;WAIG;qBADO,MAAM;QAIhB;;;;;;;WAOG;;QAGH;;;;;WAKG;;MAEN;IAID;;;;;OAKG;IACH,4BAFU,OAAO,CAEyB;IAE1C;;;;;;OAMG;IACH,UAFU,SAAS,CAEY;IAG/B;;OAEG;IACH,YAFU,iBAAiB,GAAC,IAAI,CAEV;IAEtB;;;;;OAKG;IACH,UAFU,OAAO,CAEG;IAEpB;;;;;OAKG;IACH,UAFU,OAAO,CAEG;IAEpB;;OAEG;IACH,YAFU,MAAM,CAEG;IAoBvB;;;;;;;;;;;;OAYG;IACH,mDAEC;IAED;;;;;;;;OAQG;IACH,iBAFW,KAAK,QAoBf;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,iDAOC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,2DAWC;IAED;;;;;;;;;;OAUG;IACH,oCAFa,MAAM,CAclB;IAED;;;;;;OAMG;IACH,8CAFa,OAAO,CAgBnB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,qBALW,KAAK,GACH,kBAAgB,IAAI,CAehC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,yBARW,KAAK,yBAEL,MAAM,UACN,MAAM,GACJ,QAAQ,SAAS,CAAC,CAwD9B;IAED;;;;OAIG;IACH,0BAEC;IAED;;;;;;;;;;OAUG;IACH,SAFa,QAAQ,IAAI,CAAC,CAkDzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,qBAFW,iBAAiB,QAc3B;IAED;;;;;OAKG;IACH,aAiBC;IASD;;;;;;;;OAQG;IACH,8BAHW,OAAO,UAAQ,UACf,OAAO,UAAQ,QAQzB;IAED;;;;;;;;;;;;;;;OAeG;IACH,yBALW,MAAM,KACN,MAAM,6CAMhB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,mBAyBC;IAED;;;;;OAKG;IACH,4BAHW,MAAM,GACJ,OAAO,CAoDnB;;CACJ;yBA7yBwB,kCAAkC;mCAMxB,yBAAyB;mBAZzC,oCAAoC;wBAC/B,4BAA4B;sBAQ9B,kCAAkC;yCAJf,kDAAkD;sBAErE,qCAAqC;0BACjC,0CAA0C"}
@@ -603,22 +603,42 @@ export class GraphicsEngine {
603
603
  this.#renderer = renderer;
604
604
  this.domElement = canvas;
605
605
 
606
- // Re-point the viewport, and the page with it. This is the wrinkle E1 named: `start` builds
607
- // a *new* canvas, so a restart would otherwise leave the dead one mounted and the live one
608
- // detached. `View.el` is read unguarded all over the view layer, so it is replaced rather
609
- // than cleared — it always holds an element.
606
+ this.adopt_canvas(canvas);
607
+
608
+ this.updateSize();
609
+
610
+ // so the first frame's interval is a real one rather than the whole of the boot
611
+ this.#last_render_timestamp = performance.now();
612
+ }
613
+
614
+ /**
615
+ * Re-point the viewport at a canvas, and the page with it. This is the wrinkle E1 named:
616
+ * `start` builds a *new* canvas, so a restart would otherwise leave the dead one mounted and
617
+ * the live one detached. `View.el` is read unguarded all over the view layer, so it is replaced
618
+ * rather than cleared — it always holds an element.
619
+ *
620
+ * The inline `pointer-events` of the element being replaced comes along: the engine opts the
621
+ * viewport back in (`auto`) under a game view that lets clicks fall through (`none`), and it
622
+ * does so on the placeholder element before there is a canvas. A canvas that did not inherit
623
+ * the opt-in inherited the fall-through instead, and every pointer device bound to the canvas
624
+ * — the editor's tools — was deaf to every press.
625
+ *
626
+ * Public so that the swap can be driven without a device.
627
+ *
628
+ * @param {HTMLCanvasElement} canvas
629
+ */
630
+ adopt_canvas(canvas) {
610
631
  const previous = this.viewport.el;
611
632
 
633
+ if (previous != null && previous !== canvas && previous.style !== undefined && previous.style.pointerEvents !== "") {
634
+ canvas.style.pointerEvents = previous.style.pointerEvents;
635
+ }
636
+
612
637
  this.viewport.el = canvas;
613
638
 
614
- if (previous != null && previous.parentNode !== null) {
639
+ if (previous != null && previous !== canvas && previous.parentNode !== null) {
615
640
  previous.parentNode.replaceChild(canvas, previous);
616
641
  }
617
-
618
- this.updateSize();
619
-
620
- // so the first frame's interval is a real one rather than the whole of the boot
621
- this.#last_render_timestamp = performance.now();
622
642
  }
623
643
 
624
644
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"particle_gpu_records.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/particles/particle_gpu_records.js"],"names":[],"mappings":"AAiDA;;;;;;;;;;;GAWG;AACH,+DAHW,YAAY,GACV,MAAM,CAQlB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IALoC,YAAY,EAArC,UAAU,MAAM,CAAC;IACH,KAAK,EAAnB,MAAM;IACS,UAAU,EAAzB,OAAO;IACL,MAAM,CA0ClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,6CATW,WAAW,YACX,YAAY,cACZ,MAAM,2CAEN,MAAM,EAAE,gBACR,MAAM,EAAE,aACR,MAAM,EAAE,GACN,MAAM,CA4ElB;AA5MD;;;;;;;GAOG;AACH,qCAFU,MAAM,CAEwB;AAExC;;GAEG;AACH,iCAFU,MAAM,CAEoB;AAEpC;;GAEG;AACH,kCAFU,MAAM,CAEqB;AAErC;;GAEG;AACH,qCAFU,MAAM,CAEwB;6BA9CX,gDAAgD"}
1
+ {"version":3,"file":"particle_gpu_records.d.ts","sourceRoot":"","sources":["../../../../../src/engine/graphics3/particles/particle_gpu_records.js"],"names":[],"mappings":"AAiDA;;;;;;;;;;;GAWG;AACH,+DAHW,YAAY,GACV,MAAM,CAQlB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IALoC,YAAY,EAArC,UAAU,MAAM,CAAC;IACH,KAAK,EAAnB,MAAM;IACS,UAAU,EAAzB,OAAO;IACL,MAAM,CAwClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,6CATW,WAAW,YACX,YAAY,cACZ,MAAM,2CAEN,MAAM,EAAE,gBACR,MAAM,EAAE,aACR,MAAM,EAAE,GACN,MAAM,CA4ElB;AA1MD;;;;;;;GAOG;AACH,qCAFU,MAAM,CAEwB;AAExC;;GAEG;AACH,iCAFU,MAAM,CAEoB;AAEpC;;GAEG;AACH,kCAFU,MAAM,CAEqB;AAErC;;GAEG;AACH,qCAFU,MAAM,CAEwB;6BA9CX,gDAAgD"}
@@ -124,8 +124,6 @@ export function particle_layer_record({ atlas_region, blend, soft_depth }) {
124
124
  spawn_rate: 0,
125
125
  node: NODE3D_SCENE_ID,
126
126
  generation: PARTICLE_GENERATION_FIRST,
127
- bounds_center: [0, 0, 0],
128
- bounds_radius: 0,
129
127
  };
130
128
  }
131
129
 
@@ -88,6 +88,13 @@ export class InterpolationSystem extends System<any> {
88
88
  tick_b: number;
89
89
  t: number;
90
90
  }): void;
91
+ /**
92
+ * Forget a source (its peer left). Entities still marked with it are left where they are
93
+ * until their marker goes; the system does not blend from a source it does not have.
94
+ * @param {number} sourceId
95
+ * @returns {boolean} whether it was registered
96
+ */
97
+ unregisterSource(sourceId: number): boolean;
91
98
  /**
92
99
  * @param {Interpolated} interpolated
93
100
  * @param {number} entity