@woosh/meep-engine 3.16.0 → 3.17.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 (410) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +21 -6
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +38 -17
  4. package/editor/view/node-graph/NodeGraphClipboard.d.ts +186 -0
  5. package/editor/view/node-graph/NodeGraphClipboard.d.ts.map +1 -0
  6. package/editor/view/node-graph/NodeGraphClipboard.js +231 -0
  7. package/editor/view/node-graph/NodeGraphEditorView.d.ts +59 -1
  8. package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
  9. package/editor/view/node-graph/NodeGraphEditorView.js +248 -5
  10. package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
  11. package/editor/view/node-graph/NodeGraphView.js +84 -8
  12. package/editor/view/node-graph/actions/connection_bind_actions.d.ts +23 -0
  13. package/editor/view/node-graph/actions/connection_bind_actions.d.ts.map +1 -0
  14. package/editor/view/node-graph/actions/connection_bind_actions.js +39 -0
  15. package/editor/view/particles/effect/ParticleCodeEditorView.d.ts.map +1 -1
  16. package/editor/view/particles/effect/ParticleCodeEditorView.js +4 -3
  17. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts +20 -0
  18. package/editor/view/particles/effect/ParticleCurveEditorView.d.ts.map +1 -0
  19. package/editor/view/particles/effect/ParticleCurveEditorView.js +574 -0
  20. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  21. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +27 -1
  22. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts +24 -0
  23. package/editor/view/particles/effect/ParticleGradientEditorView.d.ts.map +1 -0
  24. package/editor/view/particles/effect/ParticleGradientEditorView.js +472 -0
  25. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts +5 -0
  26. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  27. package/editor/view/particles/effect/ParticleGraphEditorView.js +61 -31
  28. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  29. package/editor/view/particles/effect/ParticleNodeParametersView.js +33 -0
  30. package/editor/view/particles/effect/particle-editor.css +123 -35
  31. package/package.json +1 -1
  32. package/src/core/binary/allocator/OffsetAllocator.d.ts +25 -16
  33. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  34. package/src/core/binary/allocator/OffsetAllocator.js +10 -1
  35. package/src/core/collection/array/typed/float32_array_hash.d.ts +21 -0
  36. package/src/core/collection/array/typed/float32_array_hash.d.ts.map +1 -0
  37. package/src/core/collection/array/typed/float32_array_hash.js +38 -0
  38. package/src/core/graph/csr/CSRGraph.d.ts +8 -1
  39. package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
  40. package/src/core/graph/csr/CSRGraph.js +14 -6
  41. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts +24 -0
  42. package/src/core/model/node-graph/visual/layout/LayoutProblem.d.ts.map +1 -1
  43. package/src/core/model/node-graph/visual/layout/LayoutProblem.js +27 -0
  44. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +26 -0
  45. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  46. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +28 -0
  47. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts +92 -3
  48. package/src/core/model/node-graph/visual/layout/RouteGrid.d.ts.map +1 -1
  49. package/src/core/model/node-graph/visual/layout/RouteGrid.js +405 -242
  50. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts +50 -5
  51. package/src/core/model/node-graph/visual/layout/RouteSearch.d.ts.map +1 -1
  52. package/src/core/model/node-graph/visual/layout/RouteSearch.js +160 -24
  53. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts +7 -0
  54. package/src/core/model/node-graph/visual/layout/RouteSet.d.ts.map +1 -1
  55. package/src/core/model/node-graph/visual/layout/RouteSet.js +8 -0
  56. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.js +9 -3
  57. package/src/core/model/node-graph/visual/layout/layout_build_problem.d.ts.map +1 -1
  58. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +7 -0
  59. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts +9 -3
  60. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +1 -1
  61. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.js +17 -3
  62. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts +9 -6
  63. package/src/core/model/node-graph/visual/layout/layout_node_graph.d.ts.map +1 -1
  64. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +49 -7
  65. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts +11 -1
  66. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +1 -1
  67. package/src/core/model/node-graph/visual/layout/layout_order_layers.js +135 -16
  68. package/src/core/model/node-graph/visual/layout/route_connections.d.ts +29 -0
  69. package/src/core/model/node-graph/visual/layout/route_connections.d.ts.map +1 -1
  70. package/src/core/model/node-graph/visual/layout/route_connections.js +716 -309
  71. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts +3 -2
  72. package/src/core/model/node-graph/visual/layout/route_grid_build.d.ts.map +1 -1
  73. package/src/core/model/node-graph/visual/layout/route_grid_build.js +7 -15
  74. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts +6 -0
  75. package/src/core/model/node-graph/visual/layout/route_nudge.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/route_nudge.js +42 -13
  77. package/src/engine/animation/AnimationUtils.js +246 -246
  78. package/src/engine/animation/Animations.js +74 -74
  79. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2078 -2078
  80. package/src/engine/ecs/EventType.d.ts +0 -1
  81. package/src/engine/ecs/EventType.js +1 -26
  82. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +1 -1
  83. package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
  84. package/src/engine/ecs/ik/ik_write_local_rotation.js +3 -7
  85. package/src/engine/ecs/parent/EntityNode.d.ts.map +1 -1
  86. package/src/engine/ecs/parent/EntityNode.js +4 -9
  87. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
  88. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +360 -364
  89. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts +41 -0
  90. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.d.ts.map +1 -0
  91. package/src/engine/ecs/transform/TRANSFORM64_EVENT_CHANGE.js +40 -0
  92. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +8 -0
  93. package/src/engine/ecs/transform/t64_announce_change.d.ts +10 -7
  94. package/src/engine/ecs/transform/t64_announce_change.d.ts.map +1 -1
  95. package/src/engine/ecs/transform/t64_announce_change.js +12 -12
  96. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts +30 -0
  97. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.d.ts.map +1 -0
  98. package/src/engine/ecs/transform-attachment/TRANSFORM_ATTACHMENT_EVENT_CHANGE.js +29 -0
  99. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
  100. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +13 -21
  101. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  102. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +4 -8
  103. package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
  104. package/src/engine/graphics3/LightSystem.js +4 -8
  105. package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
  106. package/src/engine/graphics3/MeshSystem.js +9 -19
  107. package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -1
  108. package/src/engine/graphics3/ParticleEmitterSystem.js +4 -8
  109. package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
  110. package/src/engine/graphics3/ShadedGeometrySystem.js +4 -10
  111. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts +1 -1
  112. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.d.ts.map +1 -1
  113. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +4 -8
  114. package/src/engine/intelligence/behavior/ecs/OrbitingBehavior.js +218 -218
  115. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  116. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  117. package/src/engine/sound/ecs/SoundListenerSystem.d.ts.map +1 -1
  118. package/src/engine/sound/ecs/SoundListenerSystem.js +6 -8
  119. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts +0 -4
  120. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.d.ts.map +1 -1
  121. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +5 -11
  122. package/src/shade/playground/particle_editor/README.md +43 -2
  123. package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
  124. package/src/shade/playground/particle_system/particle_prototype.js +4 -5
  125. package/src/shade/playground/particle_system/particle_scene.js +4 -4
  126. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  127. package/src/shade/renderer/Renderer.js +13 -1
  128. package/src/shade/renderer/particles/DESIGN.md +104 -19
  129. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +64 -50
  130. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/GPUParticleSystem.js +176 -78
  132. package/src/shade/renderer/particles/ParticleConstants.d.ts +59 -23
  133. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  134. package/src/shade/renderer/particles/ParticleConstants.js +66 -23
  135. package/src/shade/renderer/particles/ParticleRenderMode.d.ts +19 -0
  136. package/src/shade/renderer/particles/ParticleRenderMode.d.ts.map +1 -0
  137. package/src/shade/renderer/particles/ParticleRenderMode.js +33 -0
  138. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  139. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +167 -166
  140. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts +37 -0
  141. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -0
  142. package/src/shade/renderer/particles/data/particle_emitter_record.js +109 -0
  143. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +3 -3
  144. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +303 -303
  145. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +18 -0
  146. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +152 -133
  148. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +0 -11
  149. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +720 -621
  151. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/graph/compile_particle_graph.js +8 -3
  153. package/src/shade/renderer/particles/graph/flatten_particle_graph.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/graph/flatten_particle_graph.js +244 -213
  155. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/graph/groups/particle_builtin_groups.js +6 -0
  157. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.d.ts.map +1 -1
  158. package/src/shade/renderer/particles/graph/groups/particle_groups_geometry.js +294 -319
  159. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.d.ts.map +1 -1
  160. package/src/shade/renderer/particles/graph/groups/particle_groups_noise.js +524 -517
  161. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts +22 -0
  162. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.d.ts.map +1 -0
  163. package/src/shade/renderer/particles/graph/groups/particle_groups_psrdnoise.js +517 -0
  164. package/src/shade/renderer/particles/graph/groups/simplex_reference.d.ts.map +1 -1
  165. package/src/shade/renderer/particles/graph/groups/simplex_reference.js +185 -159
  166. package/src/shade/renderer/particles/graph/make_particle_group.d.ts.map +1 -1
  167. package/src/shade/renderer/particles/graph/make_particle_group.js +2 -20
  168. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts +17 -0
  169. package/src/shade/renderer/particles/graph/particle_compare_ops.d.ts.map +1 -0
  170. package/src/shade/renderer/particles/graph/particle_compare_ops.js +22 -0
  171. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts +28 -8
  172. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.d.ts.map +1 -1
  173. package/src/shade/renderer/particles/graph/particle_graph_diagnostic.js +49 -25
  174. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +40 -0
  175. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  176. package/src/shade/renderer/particles/graph/particle_node_parameters.js +312 -234
  177. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  178. package/src/shade/renderer/particles/graph/particle_node_presentation.js +59 -3
  179. package/src/shade/renderer/particles/graph/particle_ramp.d.ts +230 -0
  180. package/src/shade/renderer/particles/graph/particle_ramp.d.ts.map +1 -0
  181. package/src/shade/renderer/particles/graph/particle_ramp.js +403 -0
  182. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +7 -1
  183. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  184. package/src/shade/renderer/particles/graph/validate_particle_graph.js +66 -10
  185. package/src/shade/renderer/particles/graph_particles.d.ts +23 -69
  186. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  187. package/src/shade/renderer/particles/graph_particles.js +105 -262
  188. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  189. package/src/shade/renderer/particles/graph_particles_avboit.js +3 -2
  190. package/src/shade/renderer/particles/graph_particles_billboard.d.ts +37 -0
  191. package/src/shade/renderer/particles/graph_particles_billboard.d.ts.map +1 -0
  192. package/src/shade/renderer/particles/graph_particles_billboard.js +93 -0
  193. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +51 -22
  194. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  195. package/src/shade/renderer/particles/isa/InstructionStream.js +98 -38
  196. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +49 -8
  197. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  198. package/src/shade/renderer/particles/isa/ParticleProgram.js +95 -150
  199. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +306 -64
  200. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  201. package/src/shade/renderer/particles/isa/ParticleVMISA.js +505 -136
  202. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +36 -12
  203. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  204. package/src/shade/renderer/particles/isa/particle_assembly.js +354 -139
  205. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts +9 -0
  206. package/src/shade/renderer/particles/isa/validate_particle_program.d.ts.map +1 -0
  207. package/src/shade/renderer/particles/isa/validate_particle_program.js +128 -0
  208. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +23 -0
  209. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  210. package/src/shade/renderer/particles/layout/ParticleLayout.js +68 -0
  211. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts +77 -0
  212. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -0
  213. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +219 -0
  214. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts +83 -0
  215. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.d.ts.map +1 -0
  216. package/src/shade/renderer/particles/optimizer/dag/particle_vector_extract.js +283 -0
  217. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts +133 -0
  218. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.d.ts.map +1 -0
  219. package/src/shade/renderer/particles/optimizer/dag/particle_vector_graph.js +334 -0
  220. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts +117 -0
  221. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.d.ts.map +1 -0
  222. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +70 -0
  223. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts +97 -0
  224. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.d.ts.map +1 -0
  225. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +462 -0
  226. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts +116 -0
  227. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.d.ts.map +1 -0
  228. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +687 -0
  229. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +57 -0
  230. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts.map +1 -0
  231. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +860 -0
  232. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts +115 -0
  233. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.d.ts.map +1 -0
  234. package/src/shade/renderer/particles/optimizer/dag/particle_vector_rules.js +264 -0
  235. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +81 -42
  236. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  237. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +477 -478
  238. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +100 -0
  239. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts.map +1 -0
  240. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +236 -0
  241. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts +139 -59
  242. package/src/shade/renderer/particles/optimizer/particle_program_analysis.d.ts.map +1 -1
  243. package/src/shade/renderer/particles/optimizer/particle_program_analysis.js +764 -647
  244. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +40 -7
  245. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  246. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +376 -213
  247. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts +30 -3
  248. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.d.ts.map +1 -1
  249. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +337 -223
  250. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +24 -38
  251. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  252. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +166 -206
  253. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts +99 -0
  254. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -0
  255. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.js +313 -0
  256. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts +3 -2
  257. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  258. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.js +198 -197
  259. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  260. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts +19 -0
  261. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  262. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +678 -561
  263. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts +22 -0
  264. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -0
  265. package/src/shade/renderer/particles/optimizer/pass_inline_constants.js +221 -0
  266. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  267. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.js +63 -72
  268. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  269. package/src/shade/renderer/particles/optimizer/pass_pack_registers.js +87 -86
  270. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  271. package/src/shade/renderer/particles/optimizer/pass_peephole.js +392 -271
  272. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  273. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.js +361 -268
  274. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts +4 -0
  275. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -0
  276. package/src/shade/renderer/particles/optimizer/pass_schedule.js +244 -0
  277. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  278. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +154 -151
  279. package/src/shade/renderer/particles/particle_test_fixtures.d.ts +20 -0
  280. package/src/shade/renderer/particles/particle_test_fixtures.d.ts.map +1 -1
  281. package/src/shade/renderer/particles/particle_test_fixtures.js +229 -203
  282. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +99 -25
  283. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  284. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +438 -286
  285. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +109 -0
  286. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -0
  287. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +127 -0
  288. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +87 -102
  289. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  290. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +184 -163
  291. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts +26 -0
  292. package/src/shade/renderer/particles/runtime/ProgramArena.d.ts.map +1 -1
  293. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +130 -0
  294. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -0
  295. package/src/shade/renderer/particles/runtime/ProgramHeap.js +595 -0
  296. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts +91 -0
  297. package/src/shade/renderer/particles/runtime/ProgramPlacement.d.ts.map +1 -0
  298. package/src/shade/renderer/particles/runtime/ProgramPlacement.js +106 -0
  299. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +5 -2
  300. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  301. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -19
  302. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts +28 -0
  303. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.d.ts.map +1 -0
  304. package/src/shade/renderer/particles/shaders/chunk_particle_emit_step.js +136 -0
  305. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts +35 -0
  306. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.d.ts.map +1 -0
  307. package/src/shade/renderer/particles/shaders/chunk_particle_simulate_step.js +133 -0
  308. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts +18 -9
  309. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  310. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +20 -80
  311. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts +33 -0
  312. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.d.ts.map +1 -0
  313. package/src/shade/renderer/particles/shaders/shader_particle_emit_wide.js +114 -0
  314. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts +8 -0
  315. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  316. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +33 -101
  317. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts +45 -0
  318. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.d.ts.map +1 -0
  319. package/src/shade/renderer/particles/shaders/shader_particle_simulate_wide.js +123 -0
  320. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts +51 -0
  321. package/src/shade/renderer/particles/sort/graph_particle_sort.d.ts.map +1 -0
  322. package/src/shade/renderer/particles/sort/graph_particle_sort.js +120 -0
  323. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts +6 -0
  324. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -0
  325. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +16 -0
  326. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +4 -1
  327. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  328. package/src/shade/renderer/particles/vm/ParticleVMReference.js +261 -140
  329. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  330. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +217 -255
  331. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts +43 -0
  332. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.d.ts.map +1 -0
  333. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_fast.js +55 -0
  334. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts +62 -0
  335. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.d.ts.map +1 -0
  336. package/src/shade/renderer/particles/vm/chunk_particle_vm_registers_wide.js +86 -0
  337. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts +22 -0
  338. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.d.ts.map +1 -0
  339. package/src/shade/renderer/shader/chunk/math/chunk_mod_v3f.js +32 -0
  340. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts +9 -0
  341. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.d.ts.map +1 -0
  342. package/src/shade/renderer/shader/chunk/math/chunk_mod_v4f.js +19 -0
  343. package/src/shade/renderer/shader/chunk/noise/psrdnoise/README.md +65 -0
  344. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts +24 -0
  345. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.d.ts.map +1 -0
  346. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2.js +83 -0
  347. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts +25 -0
  348. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.d.ts.map +1 -0
  349. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_hash.js +42 -0
  350. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts +31 -0
  351. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.d.ts.map +1 -0
  352. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise2_kernel.js +80 -0
  353. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts +26 -0
  354. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.d.ts.map +1 -0
  355. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3.js +109 -0
  356. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts +38 -0
  357. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.d.ts.map +1 -0
  358. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_kernel.js +129 -0
  359. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts +21 -0
  360. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.d.ts.map +1 -0
  361. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_permute.js +35 -0
  362. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts +19 -0
  363. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.d.ts.map +1 -0
  364. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_skew.js +28 -0
  365. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts +13 -0
  366. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.d.ts.map +1 -0
  367. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_psrdnoise3_unskew.js +22 -0
  368. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts +22 -0
  369. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.d.ts.map +1 -0
  370. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise2.js +59 -0
  371. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts +23 -0
  372. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.d.ts.map +1 -0
  373. package/src/shade/renderer/shader/chunk/noise/psrdnoise/chunk_srdnoise3.js +74 -0
  374. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts +34 -1
  375. package/src/shade/wgsl/emulator/ComputeShaderEmulator.d.ts.map +1 -1
  376. package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +41 -1
  377. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts +3 -2
  378. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  379. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +49 -10
  380. package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
  381. package/src/view/minimap/dom/MinimapCameraView.js +4 -9
  382. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts +0 -15
  383. package/src/core/model/node-graph/visual/layout/BoxLayoutSpec.d.ts.map +0 -1
  384. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts +0 -45
  385. package/src/core/model/node-graph/visual/layout/ConnectedBoxLayouter.d.ts.map +0 -1
  386. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts +0 -24
  387. package/src/core/model/node-graph/visual/layout/ConnectionEndpointLayoutSpec.d.ts.map +0 -1
  388. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts +0 -19
  389. package/src/core/model/node-graph/visual/layout/ConnectionLayoutSpec.d.ts.map +0 -1
  390. package/src/engine/ecs/transform/__probe.d.ts +0 -4
  391. package/src/engine/ecs/transform/__probe.d.ts.map +0 -1
  392. package/src/engine/ecs/util/hideEntityGracefully.d.ts +0 -9
  393. package/src/engine/ecs/util/hideEntityGracefully.d.ts.map +0 -1
  394. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts +0 -27
  395. package/src/shade/renderer/buffer/table/gpu_database_emulator_image.d.ts.map +0 -1
  396. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts +0 -14
  397. package/src/shade/renderer/particles/cull/chunk_particle_cull.d.ts.map +0 -1
  398. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts +0 -156
  399. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_LAYOUT.d.ts.map +0 -1
  400. package/src/shade/renderer/particles/runtime/Emitter.d.ts +0 -219
  401. package/src/shade/renderer/particles/runtime/Emitter.d.ts.map +0 -1
  402. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts +0 -77
  403. package/src/shade/renderer/particles/runtime/ParticleSpawnScheduler.d.ts.map +0 -1
  404. package/src/shade/renderer/particles/runtime/ProgramArena.js +0 -155
  405. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts +0 -15
  406. package/src/shade/renderer/particles/runtime/emitter_database_image.d.ts.map +0 -1
  407. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts +0 -34
  408. package/src/shade/renderer/particles/runtime/spawn_request_encoding.d.ts.map +0 -1
  409. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts +0 -32
  410. package/src/shade/renderer/particles/shaders/chunk_particle_context.d.ts.map +0 -1
@@ -1,364 +1,360 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { Deque } from "../../../../../core/collection/queue/Deque.js";
3
- import { SurfacePoint3 } from "../../../../../core/geom/3d/SurfacePoint3.js";
4
- import Quaternion from "../../../../../core/geom/Quaternion.js";
5
-
6
- import Vector3 from '../../../../../core/geom/Vector3.js';
7
- import { clamp01 } from "../../../../../core/math/clamp01.js";
8
- import { EPSILON } from "../../../../../core/math/EPSILON.js";
9
- import { min2 } from "../../../../../core/math/min2.js";
10
- import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
11
- import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
12
- import { System } from '../../../System.js';
13
- import { Transform64 } from '../../../transform/Transform64.js';
14
- import { obtainTerrain } from "../../util/obtainTerrain.js";
15
- import Terrain from "../Terrain.js";
16
-
17
- import ClingToTerrain from './ClingToTerrain.js';
18
- import { EventType } from "../../../EventType.js";
19
- import { t64_announce_change } from "../../../transform/t64_announce_change.js";
20
- import { t64_read_rotation } from "../../../transform/t64_read_rotation.js";
21
- import { t64_read_translation } from "../../../transform/t64_read_translation.js";
22
-
23
-
24
- /**
25
- *
26
- * @type {SurfacePoint3}
27
- */
28
- const temp_sp = new SurfacePoint3();
29
-
30
- /**
31
- * @param {{update:function,ecd:EntityComponentDataset,entity:number}} datum
32
- */
33
- function deregister(datum) {
34
- datum.ecd.removeEntityEventListener(
35
- datum.entity, EventType.ComponentChanged, datum.update
36
- );
37
- }
38
-
39
- /**
40
- * How many entities can be updated in a single tick, this is useful for performance optimization.
41
- * If you have a large number of entities that need to be updated, updates can be executed over several ticks
42
- * @readonly
43
- * @type {number}
44
- */
45
- const DEFAULT_UPDATE_LIMIT = 1024;
46
-
47
- class ClingToTerrainSystem extends System {
48
-
49
-
50
- dependencies = [ClingToTerrain, Transform64];
51
-
52
-
53
- components_used = [
54
- ResourceAccessSpecification.from(Transform64, ResourceAccessKind.Read | ResourceAccessKind.Write),
55
- ResourceAccessSpecification.from(Terrain, ResourceAccessKind.Read)
56
- ];
57
-
58
- /**
59
- *
60
- * @type {Deque<number>}
61
- */
62
- updateQueue = new Deque();
63
-
64
- data = [];
65
-
66
- /**
67
- * How many entities can be updated in a single tick, this is useful for performance optimization, if you have a large number of entities that need to be updated, updates can be executed over several ticks
68
- * @type {number}
69
- */
70
- updateBatchLimit = DEFAULT_UPDATE_LIMIT;
71
-
72
- /**
73
- *
74
- * @param {number} entity
75
- */
76
- requestUpdate(entity) {
77
- if (!this.updateQueue.has(entity)) {
78
- //queue up update
79
- this.updateQueue.addLast(entity);
80
- }
81
- }
82
-
83
- /**
84
- *
85
- * @param {Transform64} transform
86
- * @param {ClingToTerrain} cling
87
- * @param {number} entityId
88
- */
89
- link(cling, transform, entityId) {
90
-
91
- const ecd = this.entityManager.dataset;
92
-
93
- /*
94
- The transform used to carry three signals and this listened to two of them. It carries
95
- none now, so the interest is registered against the entity instead and filtered by class:
96
- one listener where there were two, and it hears a write from anywhere - a spawner, a
97
- script, a physics step - rather than only one that went through a sub-object.
98
- */
99
- const update = event => {
100
- if (event.klass === Transform64) {
101
- this.requestUpdate(entityId);
102
- }
103
- };
104
-
105
- this.data[entityId] = {
106
- update,
107
- transform,
108
- component: cling,
109
- ecd,
110
- entity: entityId
111
- };
112
-
113
- ecd.addEntityEventListener(entityId, EventType.ComponentChanged, update);
114
-
115
- this.requestUpdate(entityId);
116
- }
117
-
118
- /**
119
- *
120
- * @param {Transform64} transform
121
- * @param {ClingToTerrain} cling
122
- * @param {number} entityId
123
- */
124
- unlink(cling, transform, entityId) {
125
- const datum = this.data[entityId];
126
-
127
- if (datum === undefined) {
128
- console.error(`Tried to remove entity ${entityId}, but it was not registered. This is an inconsistency bug.`, transform, cling, `component dump:`, this.entityManager.getComponents(entityId));
129
- return;
130
- }
131
-
132
- deregister(datum);
133
-
134
- delete this.data[entityId];
135
-
136
- //clear update request if one is pending
137
- this.updateQueue.remove(entityId);
138
- }
139
-
140
- update(timeDelta) {
141
- const em = this.entityManager;
142
-
143
- /**
144
- *
145
- * @type {EntityComponentDataset}
146
- */
147
- const dataset = em.dataset;
148
-
149
- if (dataset === null) {
150
- //no dataset attached
151
- return;
152
- }
153
-
154
- const updateCandidates = this.updateQueue;
155
-
156
- const terrain = obtainTerrain(dataset);
157
-
158
- if (terrain === null) {
159
- return;
160
- }
161
-
162
- const batchSize = min2(
163
- updateCandidates.size(),
164
- this.updateBatchLimit
165
- );
166
-
167
- for (let i = 0; i < batchSize; i++) {
168
- const entity = updateCandidates.removeFirst();
169
-
170
- const c = this.data[entity];
171
-
172
- if (c === undefined) {
173
- /*
174
- this should never happen as update queue is cleaned up when component is removed
175
- the entity is gone
176
- */
177
-
178
- //console.warn("ClingToTerrain component was in the update queue, but no data found. Skipping");
179
- continue;
180
- }
181
-
182
- const position_updated = doCling(c, terrain, timeDelta);
183
-
184
- if (!position_updated) {
185
- // no change, move back to update candidates
186
- this.requestUpdate(entity);
187
- }
188
- }
189
- }
190
- }
191
-
192
-
193
- const v3_temp = new Vector3();
194
- const v3_forward = new Vector3();
195
- const v3_up = new Vector3();
196
-
197
- const q_temp = new Quaternion();
198
-
199
- /**
200
- * The pose of whichever entity is being clung right now, read out of its transform.
201
- *
202
- * @type {Vector3}
203
- */
204
- const scratch_position = new Vector3();
205
-
206
- /**
207
- * @type {Quaternion}
208
- */
209
- const scratch_rotation = new Quaternion();
210
-
211
- /**
212
- * TODO look into "swing-twist decomposition"
213
- * @param {Quaternion} rotation
214
- * @param {Vector3} direction
215
- * @param {number} angularLimit
216
- * @param up
217
- * @param forward
218
- */
219
- export function alignToVector(rotation, direction, angularLimit, up = Vector3.up, forward = Vector3.forward) {
220
- assert.isNumber(angularLimit, 'angularLimit');
221
- assert.notNaN(angularLimit, 'angularLimit');
222
-
223
- //compute old facing direction vector
224
- v3_forward.copy(forward);
225
-
226
- v3_forward.applyQuaternion(rotation);
227
-
228
- //compute perpendicular vector between old and desired alignment
229
- v3_temp.crossVectors(direction, v3_forward);
230
-
231
- //compute new facing vector that is perpendicular to alignment direction
232
- v3_temp.crossVectors(v3_temp, direction);
233
-
234
- q_temp.lookRotation(v3_temp, direction);
235
-
236
- v3_up.copy(up);
237
-
238
- v3_up.applyQuaternion(rotation);
239
-
240
- const angle = v3_up.angleTo(direction);
241
-
242
- assert.notNaN(angle, 'angle');
243
-
244
- if (angle === 0) {
245
- //no change
246
- return;
247
- }
248
-
249
- const t = clamp01(angularLimit / angle);
250
-
251
- // TODO Consider replacing this with slerp
252
- rotation.lerp(q_temp, t);
253
- }
254
-
255
-
256
- /**
257
- *
258
- * @param {Vector3} point
259
- * @param {Transform64} t
260
- * @param {Vector3} normal
261
- * @param {ClingToTerrain} cling
262
- * @param {number} timeDelta
263
- */
264
- function processRaycastHit(point, t, normal, cling, timeDelta, el) {
265
- assert.defined(point, 'point');
266
- assert.equal(point.isVector3, true, 'point.isVector3 !== true');
267
- assert.isNumber(timeDelta, 'timeDelta');
268
-
269
- // filled by the caller, which had to read them to decide there was anything to do
270
- const position = scratch_position;
271
- const rotation = scratch_rotation;
272
-
273
- const hitDistance = position.distanceTo(point);
274
-
275
- //cache current position
276
- cling.__lastPosition.copy(position);
277
- cling.__lastRotation.copy(rotation);
278
-
279
- let moved = false;
280
-
281
- if (hitDistance > EPSILON) {
282
- t.setTranslation(position.x, point.y, position.z);
283
-
284
- moved = true;
285
- }
286
-
287
- let angularLimit;
288
-
289
- if (Number.isFinite(cling.rotationSpeed)) {
290
- angularLimit = cling.rotationSpeed * timeDelta;
291
- } else {
292
- angularLimit = Number.POSITIVE_INFINITY;
293
- }
294
-
295
- if (cling.normalAlign) {
296
- alignToVector(rotation, normal, angularLimit);
297
-
298
- if (
299
- rotation.x !== t.rotation_x || rotation.y !== t.rotation_y
300
- || rotation.z !== t.rotation_z || rotation.w !== t.rotation_w
301
- ) {
302
- t.setRotation(rotation.x, rotation.y, rotation.z, rotation.w);
303
-
304
- // the rotation is the only write that leaves the matrix behind
305
- t.updateMatrix();
306
-
307
- moved = true;
308
- }
309
- }
310
-
311
- /*
312
- Announced only when something actually changed. The system is listening to this entity itself,
313
- so an announcement it did not earn would queue the entity again, find nothing to do, and queue
314
- it again - a spin that never settles.
315
- */
316
- if (moved) {
317
- t64_announce_change(el.ecd, el.entity, t);
318
- }
319
- }
320
-
321
- /**
322
- *
323
- * @param {{component:ClingToTerrain,transform:Transform}} el
324
- * @param {Terrain} terrain
325
- * @param {number} timeDelta
326
- * @returns {boolean} whether position was updated or not
327
- */
328
- function doCling(el, terrain, timeDelta) {
329
- /**
330
- * @type {ClingToTerrain}
331
- */
332
- const cling = el.component;
333
-
334
- /**
335
- *
336
- * @type {Transform64}
337
- */
338
- const t = el.transform;
339
-
340
- // read out once; the comparison, the cast and the write below all want the same numbers, and
341
- // reading them through the component's view accessors would allocate two arrays per entity
342
- t64_read_translation(scratch_position, t);
343
- t64_read_rotation(scratch_rotation, t);
344
-
345
- if (
346
- cling.__lastPosition.roughlyEquals(scratch_position, 0.001)
347
- && cling.__lastRotation.roughlyEquals(scratch_rotation, 0.0001)
348
- ) {
349
- //do nothing, cached position matches with existing position
350
- return false;
351
- }
352
-
353
- const hit_found = terrain.raycastVerticalFirstSync(
354
- temp_sp, scratch_position.x, scratch_position.z
355
- );
356
-
357
- if (hit_found) {
358
- processRaycastHit(temp_sp.position, t, temp_sp.normal, cling, timeDelta, el);
359
- }
360
-
361
- return hit_found;
362
- }
363
-
364
- export default ClingToTerrainSystem;
1
+ import { assert } from "../../../../../core/assert.js";
2
+ import { Deque } from "../../../../../core/collection/queue/Deque.js";
3
+ import { SurfacePoint3 } from "../../../../../core/geom/3d/SurfacePoint3.js";
4
+ import Quaternion from "../../../../../core/geom/Quaternion.js";
5
+
6
+ import Vector3 from '../../../../../core/geom/Vector3.js';
7
+ import { clamp01 } from "../../../../../core/math/clamp01.js";
8
+ import { EPSILON } from "../../../../../core/math/EPSILON.js";
9
+ import { min2 } from "../../../../../core/math/min2.js";
10
+ import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
11
+ import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
12
+ import { System } from '../../../System.js';
13
+ import { Transform64 } from '../../../transform/Transform64.js';
14
+ import { obtainTerrain } from "../../util/obtainTerrain.js";
15
+ import Terrain from "../Terrain.js";
16
+
17
+ import ClingToTerrain from './ClingToTerrain.js';
18
+ import { TRANSFORM64_EVENT_CHANGE } from "../../../transform/TRANSFORM64_EVENT_CHANGE.js";
19
+ import { t64_announce_change } from "../../../transform/t64_announce_change.js";
20
+ import { t64_read_rotation } from "../../../transform/t64_read_rotation.js";
21
+ import { t64_read_translation } from "../../../transform/t64_read_translation.js";
22
+
23
+
24
+ /**
25
+ *
26
+ * @type {SurfacePoint3}
27
+ */
28
+ const temp_sp = new SurfacePoint3();
29
+
30
+ /**
31
+ * @param {{update:function,ecd:EntityComponentDataset,entity:number}} datum
32
+ */
33
+ function deregister(datum) {
34
+ datum.ecd.removeEntityEventListener(
35
+ datum.entity, TRANSFORM64_EVENT_CHANGE, datum.update
36
+ );
37
+ }
38
+
39
+ /**
40
+ * How many entities can be updated in a single tick, this is useful for performance optimization.
41
+ * If you have a large number of entities that need to be updated, updates can be executed over several ticks
42
+ * @readonly
43
+ * @type {number}
44
+ */
45
+ const DEFAULT_UPDATE_LIMIT = 1024;
46
+
47
+ class ClingToTerrainSystem extends System {
48
+
49
+
50
+ dependencies = [ClingToTerrain, Transform64];
51
+
52
+
53
+ components_used = [
54
+ ResourceAccessSpecification.from(Transform64, ResourceAccessKind.Read | ResourceAccessKind.Write),
55
+ ResourceAccessSpecification.from(Terrain, ResourceAccessKind.Read)
56
+ ];
57
+
58
+ /**
59
+ *
60
+ * @type {Deque<number>}
61
+ */
62
+ updateQueue = new Deque();
63
+
64
+ data = [];
65
+
66
+ /**
67
+ * How many entities can be updated in a single tick, this is useful for performance optimization, if you have a large number of entities that need to be updated, updates can be executed over several ticks
68
+ * @type {number}
69
+ */
70
+ updateBatchLimit = DEFAULT_UPDATE_LIMIT;
71
+
72
+ /**
73
+ *
74
+ * @param {number} entity
75
+ */
76
+ requestUpdate(entity) {
77
+ if (!this.updateQueue.has(entity)) {
78
+ //queue up update
79
+ this.updateQueue.addLast(entity);
80
+ }
81
+ }
82
+
83
+ /**
84
+ *
85
+ * @param {Transform64} transform
86
+ * @param {ClingToTerrain} cling
87
+ * @param {number} entityId
88
+ */
89
+ link(cling, transform, entityId) {
90
+
91
+ const ecd = this.entityManager.dataset;
92
+
93
+ /*
94
+ The transform used to carry three signals and this listened to two of them. It carries
95
+ none now, so the interest is registered against the entity and the transform's own change
96
+ event: one listener where there were two, and it hears a write from anywhere - a spawner,
97
+ a script, a physics step - rather than only one that went through a sub-object.
98
+ */
99
+ const update = () => this.requestUpdate(entityId);
100
+
101
+ this.data[entityId] = {
102
+ update,
103
+ transform,
104
+ component: cling,
105
+ ecd,
106
+ entity: entityId
107
+ };
108
+
109
+ ecd.addEntityEventListener(entityId, TRANSFORM64_EVENT_CHANGE, update);
110
+
111
+ this.requestUpdate(entityId);
112
+ }
113
+
114
+ /**
115
+ *
116
+ * @param {Transform64} transform
117
+ * @param {ClingToTerrain} cling
118
+ * @param {number} entityId
119
+ */
120
+ unlink(cling, transform, entityId) {
121
+ const datum = this.data[entityId];
122
+
123
+ if (datum === undefined) {
124
+ console.error(`Tried to remove entity ${entityId}, but it was not registered. This is an inconsistency bug.`, transform, cling, `component dump:`, this.entityManager.getComponents(entityId));
125
+ return;
126
+ }
127
+
128
+ deregister(datum);
129
+
130
+ delete this.data[entityId];
131
+
132
+ //clear update request if one is pending
133
+ this.updateQueue.remove(entityId);
134
+ }
135
+
136
+ update(timeDelta) {
137
+ const em = this.entityManager;
138
+
139
+ /**
140
+ *
141
+ * @type {EntityComponentDataset}
142
+ */
143
+ const dataset = em.dataset;
144
+
145
+ if (dataset === null) {
146
+ //no dataset attached
147
+ return;
148
+ }
149
+
150
+ const updateCandidates = this.updateQueue;
151
+
152
+ const terrain = obtainTerrain(dataset);
153
+
154
+ if (terrain === null) {
155
+ return;
156
+ }
157
+
158
+ const batchSize = min2(
159
+ updateCandidates.size(),
160
+ this.updateBatchLimit
161
+ );
162
+
163
+ for (let i = 0; i < batchSize; i++) {
164
+ const entity = updateCandidates.removeFirst();
165
+
166
+ const c = this.data[entity];
167
+
168
+ if (c === undefined) {
169
+ /*
170
+ this should never happen as update queue is cleaned up when component is removed
171
+ the entity is gone
172
+ */
173
+
174
+ //console.warn("ClingToTerrain component was in the update queue, but no data found. Skipping");
175
+ continue;
176
+ }
177
+
178
+ const position_updated = doCling(c, terrain, timeDelta);
179
+
180
+ if (!position_updated) {
181
+ // no change, move back to update candidates
182
+ this.requestUpdate(entity);
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+
189
+ const v3_temp = new Vector3();
190
+ const v3_forward = new Vector3();
191
+ const v3_up = new Vector3();
192
+
193
+ const q_temp = new Quaternion();
194
+
195
+ /**
196
+ * The pose of whichever entity is being clung right now, read out of its transform.
197
+ *
198
+ * @type {Vector3}
199
+ */
200
+ const scratch_position = new Vector3();
201
+
202
+ /**
203
+ * @type {Quaternion}
204
+ */
205
+ const scratch_rotation = new Quaternion();
206
+
207
+ /**
208
+ * TODO look into "swing-twist decomposition"
209
+ * @param {Quaternion} rotation
210
+ * @param {Vector3} direction
211
+ * @param {number} angularLimit
212
+ * @param up
213
+ * @param forward
214
+ */
215
+ export function alignToVector(rotation, direction, angularLimit, up = Vector3.up, forward = Vector3.forward) {
216
+ assert.isNumber(angularLimit, 'angularLimit');
217
+ assert.notNaN(angularLimit, 'angularLimit');
218
+
219
+ //compute old facing direction vector
220
+ v3_forward.copy(forward);
221
+
222
+ v3_forward.applyQuaternion(rotation);
223
+
224
+ //compute perpendicular vector between old and desired alignment
225
+ v3_temp.crossVectors(direction, v3_forward);
226
+
227
+ //compute new facing vector that is perpendicular to alignment direction
228
+ v3_temp.crossVectors(v3_temp, direction);
229
+
230
+ q_temp.lookRotation(v3_temp, direction);
231
+
232
+ v3_up.copy(up);
233
+
234
+ v3_up.applyQuaternion(rotation);
235
+
236
+ const angle = v3_up.angleTo(direction);
237
+
238
+ assert.notNaN(angle, 'angle');
239
+
240
+ if (angle === 0) {
241
+ //no change
242
+ return;
243
+ }
244
+
245
+ const t = clamp01(angularLimit / angle);
246
+
247
+ // TODO Consider replacing this with slerp
248
+ rotation.lerp(q_temp, t);
249
+ }
250
+
251
+
252
+ /**
253
+ *
254
+ * @param {Vector3} point
255
+ * @param {Transform64} t
256
+ * @param {Vector3} normal
257
+ * @param {ClingToTerrain} cling
258
+ * @param {number} timeDelta
259
+ */
260
+ function processRaycastHit(point, t, normal, cling, timeDelta, el) {
261
+ assert.defined(point, 'point');
262
+ assert.equal(point.isVector3, true, 'point.isVector3 !== true');
263
+ assert.isNumber(timeDelta, 'timeDelta');
264
+
265
+ // filled by the caller, which had to read them to decide there was anything to do
266
+ const position = scratch_position;
267
+ const rotation = scratch_rotation;
268
+
269
+ const hitDistance = position.distanceTo(point);
270
+
271
+ //cache current position
272
+ cling.__lastPosition.copy(position);
273
+ cling.__lastRotation.copy(rotation);
274
+
275
+ let moved = false;
276
+
277
+ if (hitDistance > EPSILON) {
278
+ t.setTranslation(position.x, point.y, position.z);
279
+
280
+ moved = true;
281
+ }
282
+
283
+ let angularLimit;
284
+
285
+ if (Number.isFinite(cling.rotationSpeed)) {
286
+ angularLimit = cling.rotationSpeed * timeDelta;
287
+ } else {
288
+ angularLimit = Number.POSITIVE_INFINITY;
289
+ }
290
+
291
+ if (cling.normalAlign) {
292
+ alignToVector(rotation, normal, angularLimit);
293
+
294
+ if (
295
+ rotation.x !== t.rotation_x || rotation.y !== t.rotation_y
296
+ || rotation.z !== t.rotation_z || rotation.w !== t.rotation_w
297
+ ) {
298
+ t.setRotation(rotation.x, rotation.y, rotation.z, rotation.w);
299
+
300
+ // the rotation is the only write that leaves the matrix behind
301
+ t.updateMatrix();
302
+
303
+ moved = true;
304
+ }
305
+ }
306
+
307
+ /*
308
+ Announced only when something actually changed. The system is listening to this entity itself,
309
+ so an announcement it did not earn would queue the entity again, find nothing to do, and queue
310
+ it again - a spin that never settles.
311
+ */
312
+ if (moved) {
313
+ t64_announce_change(el.ecd, el.entity);
314
+ }
315
+ }
316
+
317
+ /**
318
+ *
319
+ * @param {{component:ClingToTerrain,transform:Transform}} el
320
+ * @param {Terrain} terrain
321
+ * @param {number} timeDelta
322
+ * @returns {boolean} whether position was updated or not
323
+ */
324
+ function doCling(el, terrain, timeDelta) {
325
+ /**
326
+ * @type {ClingToTerrain}
327
+ */
328
+ const cling = el.component;
329
+
330
+ /**
331
+ *
332
+ * @type {Transform64}
333
+ */
334
+ const t = el.transform;
335
+
336
+ // read out once; the comparison, the cast and the write below all want the same numbers, and
337
+ // reading them through the component's view accessors would allocate two arrays per entity
338
+ t64_read_translation(scratch_position, t);
339
+ t64_read_rotation(scratch_rotation, t);
340
+
341
+ if (
342
+ cling.__lastPosition.roughlyEquals(scratch_position, 0.001)
343
+ && cling.__lastRotation.roughlyEquals(scratch_rotation, 0.0001)
344
+ ) {
345
+ //do nothing, cached position matches with existing position
346
+ return false;
347
+ }
348
+
349
+ const hit_found = terrain.raycastVerticalFirstSync(
350
+ temp_sp, scratch_position.x, scratch_position.z
351
+ );
352
+
353
+ if (hit_found) {
354
+ processRaycastHit(temp_sp.position, t, temp_sp.normal, cling, timeDelta, el);
355
+ }
356
+
357
+ return hit_found;
358
+ }
359
+
360
+ export default ClingToTerrainSystem;