@woosh/meep-engine 3.58.0 → 3.59.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 (609) hide show
  1. package/editor/particles/effect/ParticleEffectDocument.d.ts +162 -43
  2. package/editor/particles/effect/ParticleEffectDocument.d.ts.map +1 -1
  3. package/editor/particles/effect/ParticleEffectDocument.js +450 -43
  4. package/editor/particles/effect/ParticleReferenceSimulation.d.ts +12 -3
  5. package/editor/particles/effect/ParticleReferenceSimulation.d.ts.map +1 -1
  6. package/editor/particles/effect/ParticleReferenceSimulation.js +78 -23
  7. package/editor/particles/effect/make_starter_particle_effect.js +17 -17
  8. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts +3 -3
  9. package/editor/view/particles/effect/ParticleEmitterInspectorView.d.ts.map +1 -1
  10. package/editor/view/particles/effect/ParticleEmitterInspectorView.js +224 -67
  11. package/editor/view/particles/effect/ParticleGraphEditorView.d.ts.map +1 -1
  12. package/editor/view/particles/effect/ParticleGraphEditorView.js +44 -11
  13. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts +2 -1
  14. package/editor/view/particles/effect/ParticleNodeParametersView.d.ts.map +1 -1
  15. package/editor/view/particles/effect/ParticleNodeParametersView.js +46 -16
  16. package/editor/view/particles/effect/ParticlePreviewView.js +2 -2
  17. package/editor/view/particles/effect/particle-editor.css +77 -68
  18. package/package.json +1 -1
  19. package/src/engine/Engine.d.ts.map +1 -1
  20. package/src/engine/Engine.js +2 -2
  21. package/src/engine/ecs/EntityManager.d.ts +29 -5
  22. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  23. package/src/engine/ecs/EntityManager.js +37 -1
  24. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  25. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +4 -0
  26. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +74 -17
  27. package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts.map +1 -1
  28. package/src/engine/graphics/ecs/particles/ParticleEffect.js +156 -25
  29. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts +13 -3
  30. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.d.ts.map +1 -1
  31. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationAdapter.js +59 -13
  32. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.d.ts +3 -3
  33. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_1_2.js +9 -9
  34. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.d.ts +15 -0
  35. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.d.ts.map +1 -0
  36. package/src/engine/graphics/ecs/particles/ParticleEffectSerializationUpgrader_2_3.js +78 -0
  37. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts +2 -0
  38. package/src/engine/graphics/ecs/trail3d/Trail3D.d.ts.map +1 -1
  39. package/src/engine/graphics/ecs/trail3d/Trail3D.js +2 -0
  40. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +1 -1
  41. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +1 -1
  42. package/src/engine/graphics/trail/tube/TubeX.d.ts +5 -3
  43. package/src/engine/graphics/trail/tube/TubeX.d.ts.map +1 -1
  44. package/src/engine/graphics/trail/tube/TubeX.js +5 -3
  45. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts +3 -2
  46. package/src/engine/graphics/trail/tube/tube_attributes_spec.d.ts.map +1 -1
  47. package/src/engine/graphics/trail/tube/tube_attributes_spec.js +9 -8
  48. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +65 -4
  49. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  50. package/src/engine/graphics3/GPUParticleEmitterSystem.js +1351 -904
  51. package/src/engine/graphics3/trail/trail_tube_write_geometry.d.ts +1 -1
  52. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +13 -13
  53. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  54. package/src/generation/foliage/FOLIAGE_DESIGN.md +26 -5
  55. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +35 -0
  56. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +2 -1
  57. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +552 -0
  58. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts.map +1 -1
  59. package/src/generation/foliage/analysis/tree_crown_opacity.js +2 -1
  60. package/src/generation/foliage/analysis/tree_render_cost.d.ts +5 -3
  61. package/src/generation/foliage/analysis/tree_render_cost.d.ts.map +1 -1
  62. package/src/generation/foliage/analysis/tree_render_cost.js +8 -7
  63. package/src/generation/foliage/asset/TreeAsset.d.ts +17 -0
  64. package/src/generation/foliage/asset/TreeAsset.d.ts.map +1 -1
  65. package/src/generation/foliage/asset/TreeAsset.js +20 -0
  66. package/src/generation/foliage/asset/TreeSpeciesCache.d.ts +69 -0
  67. package/src/generation/foliage/asset/TreeSpeciesCache.d.ts.map +1 -0
  68. package/src/generation/foliage/asset/TreeSpeciesCache.js +147 -0
  69. package/src/generation/foliage/asset/generate_tree.d.ts +10 -0
  70. package/src/generation/foliage/asset/generate_tree.d.ts.map +1 -1
  71. package/src/generation/foliage/asset/generate_tree.js +57 -29
  72. package/src/generation/foliage/asset/place_tree.d.ts +2 -1
  73. package/src/generation/foliage/asset/place_tree.d.ts.map +1 -1
  74. package/src/generation/foliage/asset/place_tree.js +2 -1
  75. package/src/generation/foliage/asset/tree_lod_plan.d.ts +4 -2
  76. package/src/generation/foliage/asset/tree_lod_plan.d.ts.map +1 -1
  77. package/src/generation/foliage/asset/tree_lod_plan.js +12 -14
  78. package/src/generation/foliage/asset/tree_shoot_instances.d.ts +119 -0
  79. package/src/generation/foliage/asset/tree_shoot_instances.d.ts.map +1 -0
  80. package/src/generation/foliage/asset/tree_shoot_instances.js +410 -0
  81. package/src/generation/foliage/asset/tree_shoot_prototypes.d.ts +155 -0
  82. package/src/generation/foliage/asset/tree_shoot_prototypes.d.ts.map +1 -0
  83. package/src/generation/foliage/asset/tree_shoot_prototypes.js +251 -0
  84. package/src/generation/foliage/config/TreeGrowth.d.ts +10 -0
  85. package/src/generation/foliage/config/TreeGrowth.d.ts.map +1 -0
  86. package/src/generation/foliage/config/TreeGrowth.js +18 -0
  87. package/src/generation/foliage/config/TreeLODConfig.d.ts +6 -0
  88. package/src/generation/foliage/config/TreeLODConfig.d.ts.map +1 -1
  89. package/src/generation/foliage/config/TreeLODConfig.js +7 -0
  90. package/src/generation/foliage/index.d.ts +3 -0
  91. package/src/generation/foliage/index.js +3 -0
  92. package/src/generation/foliage/material/foliage_tile.d.ts +6 -6
  93. package/src/generation/foliage/material/foliage_tile.js +3 -3
  94. package/src/generation/foliage/material/tree_cluster_atlas.d.ts +44 -0
  95. package/src/generation/foliage/material/tree_cluster_atlas.d.ts.map +1 -0
  96. package/src/generation/foliage/material/tree_cluster_atlas.js +37 -0
  97. package/src/generation/foliage/mesh/foliage_collect_attachments.js +2 -2
  98. package/src/generation/foliage/mesh/foliage_scale_spread.d.ts +14 -0
  99. package/src/generation/foliage/mesh/foliage_scale_spread.d.ts.map +1 -0
  100. package/src/generation/foliage/mesh/foliage_scale_spread.js +15 -0
  101. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts +8 -7
  102. package/src/generation/foliage/mesh/tree_cluster_representatives.d.ts.map +1 -1
  103. package/src/generation/foliage/mesh/tree_cluster_representatives.js +85 -40
  104. package/src/generation/foliage/mesh/tree_clusters.d.ts +26 -5
  105. package/src/generation/foliage/mesh/tree_clusters.d.ts.map +1 -1
  106. package/src/generation/foliage/mesh/tree_clusters.js +52 -39
  107. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  108. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +32 -54
  109. package/src/generation/foliage/presets/make_tree_species_preset.d.ts +6 -1
  110. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  111. package/src/generation/foliage/presets/make_tree_species_preset.js +157 -3
  112. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts +19 -0
  113. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts.map +1 -1
  114. package/src/generation/foliage/skeleton/TreeSkeleton.js +41 -0
  115. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts +5 -0
  116. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts.map +1 -1
  117. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.js +8 -1
  118. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.d.ts +70 -0
  119. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.d.ts.map +1 -0
  120. package/src/generation/foliage/skeleton/tree_skeleton_copy_branches.js +171 -0
  121. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.d.ts +17 -0
  122. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.d.ts.map +1 -0
  123. package/src/generation/foliage/skeleton/tree_skeleton_extend_branch.js +79 -0
  124. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.d.ts +12 -0
  125. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.d.ts.map +1 -0
  126. package/src/generation/foliage/skeleton/tree_skeleton_fit_crown_frame.js +56 -0
  127. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.d.ts +11 -0
  128. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.d.ts.map +1 -0
  129. package/src/generation/foliage/skeleton/tree_skeleton_floor_girth.js +38 -0
  130. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts +4 -11
  131. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  132. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +8 -2034
  133. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.d.ts +22 -0
  134. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.d.ts.map +1 -0
  135. package/src/generation/foliage/skeleton/tree_skeleton_grow_framework.js +2050 -0
  136. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts +10 -0
  137. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts.map +1 -1
  138. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.js +27 -56
  139. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts +4 -0
  140. package/src/shade/descriptor/pipeline/render/DepthStencilState.d.ts.map +1 -1
  141. package/src/shade/descriptor/pipeline/render/DepthStencilState.js +170 -144
  142. package/src/shade/descriptor/pipeline/render/MultisampleState.d.ts +4 -0
  143. package/src/shade/descriptor/pipeline/render/MultisampleState.d.ts.map +1 -1
  144. package/src/shade/descriptor/pipeline/render/MultisampleState.js +78 -65
  145. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.d.ts.map +1 -1
  146. package/src/shade/descriptor/pipeline/render/RenderPipelineDescriptor.js +176 -172
  147. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts +4 -0
  148. package/src/shade/descriptor/pipeline/render/StencilFaceState.d.ts.map +1 -1
  149. package/src/shade/descriptor/pipeline/render/StencilFaceState.js +107 -88
  150. package/src/shade/playground/particle_ecs/README.md +9 -8
  151. package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
  152. package/src/shade/playground/particle_ecs/bonfire_effects.d.ts +6 -6
  153. package/src/shade/playground/particle_ecs/bonfire_effects.js +6 -6
  154. package/src/shade/playground/particle_editor/README.md +14 -11
  155. package/src/shade/playground/particle_system/particle_prototype.js +18 -18
  156. package/src/shade/playground/particle_system/particle_scene.js +13 -13
  157. package/src/shade/playground/probe_clipmap/README.md +42 -0
  158. package/src/shade/playground/probe_clipmap/index.html +178 -0
  159. package/src/shade/playground/probe_clipmap/main.d.ts +8 -0
  160. package/src/shade/playground/probe_clipmap/main.d.ts.map +1 -0
  161. package/src/shade/playground/probe_clipmap/main.js +360 -0
  162. package/src/shade/renderer/Renderer.d.ts +3 -1
  163. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  164. package/src/shade/renderer/Renderer.js +94 -38
  165. package/src/shade/renderer/extension/ViewTextures.d.ts +2 -1
  166. package/src/shade/renderer/extension/ViewTextures.d.ts.map +1 -1
  167. package/src/shade/renderer/extension/ViewTextures.js +2 -1
  168. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  169. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  170. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  171. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  172. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  173. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +34 -12
  174. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  175. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +56 -15
  176. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts +2 -2
  177. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  178. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +13 -26
  179. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts +25 -2
  180. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.d.ts.map +1 -1
  181. package/src/shade/renderer/geometry/virtual/runtime/VGeoViewCut.js +54 -32
  182. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.d.ts +14 -0
  183. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/runtime/cut/VGEO_CUT_VERDICT.js +37 -0
  185. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -1
  186. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +16 -0
  187. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -1
  188. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +2 -6
  189. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.d.ts +131 -0
  190. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.d.ts.map +1 -0
  191. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_descent.js +467 -0
  192. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.d.ts +24 -0
  193. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.d.ts.map +1 -0
  194. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_instance.js +111 -0
  195. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.d.ts +42 -0
  196. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.d.ts.map +1 -0
  197. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_rule.js +404 -0
  198. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.d.ts +16 -0
  199. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.d.ts.map +1 -0
  200. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_stat.js +23 -0
  201. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.d.ts +17 -0
  202. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.d.ts.map +1 -0
  203. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_want.js +65 -0
  204. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.d.ts.map +1 -1
  205. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_collect.js +14 -70
  206. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  207. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +13 -773
  208. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.d.ts +55 -0
  209. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.d.ts.map +1 -0
  210. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_cut_descent.js +248 -0
  211. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.d.ts.map +1 -1
  212. package/src/shade/renderer/geometry/virtual/runtime/graph_vgeo_expand_instances_to_meshlets.js +15 -174
  213. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.d.ts.map +1 -1
  214. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_probe_meta_pick2.js +8 -24
  215. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.d.ts.map +1 -1
  216. package/src/shade/renderer/global_illumination/brick4/gpu/draw/chunk_brick4_sample_forward_indirect.js +1 -25
  217. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.d.ts.map +1 -1
  218. package/src/shade/renderer/global_illumination/lpv/deprecated/chunk_lpv_get_visibility_mask.js +5 -23
  219. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts +25 -4
  220. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  221. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +126 -8
  222. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +832 -4
  223. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts +7 -0
  224. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.d.ts.map +1 -1
  225. package/src/shade/renderer/global_illumination/probe_clipmap/brick/BRICK_CLIPMAP.js +8 -0
  226. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts +16 -0
  227. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.d.ts.map +1 -1
  228. package/src/shade/renderer/global_illumination/probe_clipmap/brick/GPUBrickClipmap.js +9 -0
  229. package/src/shade/renderer/global_illumination/probe_clipmap/brick/{mesh/chunk_mesh_brick_object.d.ts → chunk_brick_object.d.ts} +8 -8
  230. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_object.d.ts.map +1 -0
  231. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_object.js +42 -0
  232. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.d.ts +45 -0
  233. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.d.ts.map +1 -0
  234. package/src/shade/renderer/global_illumination/probe_clipmap/brick/chunk_brick_provider.js +93 -0
  235. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts +0 -7
  236. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.d.ts.map +1 -1
  237. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/MESH_BRICK_INSTANCE_STRUCT.js +0 -8
  238. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts +2 -4
  239. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.d.ts.map +1 -1
  240. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_instance.js +5 -8
  241. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.d.ts.map +1 -1
  242. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/shader_mesh_brick_provider.js +13 -22
  243. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts +99 -0
  244. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.d.ts.map +1 -0
  245. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGEO_BRICK.js +139 -0
  246. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts +65 -0
  247. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.d.ts.map +1 -0
  248. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/VGeoBrickProvider.js +393 -0
  249. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts +17 -0
  250. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.d.ts.map +1 -0
  251. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_box.js +36 -0
  252. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts +29 -0
  253. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.d.ts.map +1 -0
  254. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_pair.js +108 -0
  255. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts +31 -0
  256. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.d.ts.map +1 -0
  257. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_texel.js +113 -0
  258. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts +36 -0
  259. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.d.ts.map +1 -0
  260. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/chunk_vgeo_brick_triangle.js +85 -0
  261. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts +23 -0
  262. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.d.ts.map +1 -0
  263. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_distance.js +273 -0
  264. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts +13 -0
  265. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.d.ts.map +1 -0
  266. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_gather.js +151 -0
  267. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts +13 -0
  268. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.d.ts.map +1 -0
  269. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_traverse.js +133 -0
  270. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts +22 -0
  271. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.d.ts.map +1 -0
  272. package/src/shade/renderer/global_illumination/probe_clipmap/brick/vgeo/shader_vgeo_brick_wait.js +135 -0
  273. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +20 -6
  274. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  275. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +152 -10
  276. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts +7 -0
  277. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.d.ts.map +1 -1
  278. package/src/shade/renderer/global_illumination/probe_clipmap/probe/PROBE_CLIPMAP.js +8 -0
  279. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts +14 -2
  280. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.d.ts.map +1 -1
  281. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap.js +50 -5
  282. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts +19 -0
  283. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.d.ts.map +1 -0
  284. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_cage.js +40 -0
  285. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts +72 -0
  286. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.d.ts.map +1 -0
  287. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_pick.js +343 -0
  288. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts +29 -0
  289. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.d.ts.map +1 -0
  290. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_sample_radiance.js +188 -0
  291. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts +26 -0
  292. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.d.ts.map +1 -0
  293. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_want.js +132 -0
  294. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts +4 -0
  295. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.d.ts.map +1 -1
  296. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_accumulate.js +26 -3
  297. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts +3 -0
  298. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.d.ts.map +1 -1
  299. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_admit.js +8 -1
  300. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts +12 -0
  301. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.d.ts.map +1 -0
  302. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_diffuse.js +101 -0
  303. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.d.ts +1 -1
  304. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_due.js +1 -1
  305. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts +15 -0
  306. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.d.ts.map +1 -0
  307. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_indirect_lighting.js +175 -0
  308. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts +26 -0
  309. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.d.ts.map +1 -0
  310. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_light.js +210 -0
  311. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.d.ts +3 -3
  312. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_retire.js +3 -3
  313. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +2 -1
  314. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  315. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +5 -1
  316. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.d.ts.map +1 -1
  317. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_trace.js +3 -10
  318. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts +5 -9
  319. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.d.ts.map +1 -1
  320. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want.js +9 -110
  321. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts +27 -0
  322. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.d.ts.map +1 -0
  323. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_want_hits.js +110 -0
  324. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts +13 -0
  325. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts.map +1 -1
  326. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.js +40 -0
  327. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +11 -6
  328. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -1
  329. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +15 -8
  330. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts +9 -2
  331. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -1
  332. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +25 -11
  333. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  334. package/src/shade/renderer/particles/DESIGN.md +151 -42
  335. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +283 -0
  336. package/src/shade/renderer/particles/GPUParticleSystem.d.ts +10 -2
  337. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  338. package/src/shade/renderer/particles/GPUParticleSystem.js +46 -8
  339. package/src/shade/renderer/particles/ParticleConstants.d.ts +23 -6
  340. package/src/shade/renderer/particles/ParticleConstants.d.ts.map +1 -1
  341. package/src/shade/renderer/particles/ParticleConstants.js +25 -6
  342. package/src/shade/renderer/particles/bounds/chunk_particle_bounds.js +5 -5
  343. package/src/shade/renderer/particles/bounds/shader_particle_bounds.js +187 -187
  344. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts +20 -9
  345. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.d.ts.map +1 -1
  346. package/src/shade/renderer/particles/data/PARTICLE_DATABASE_SPEC.js +36 -10
  347. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts +8 -7
  348. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.d.ts.map +1 -1
  349. package/src/shade/renderer/particles/data/PARTICLE_EMITTER_STRUCT.js +25 -16
  350. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.d.ts +51 -0
  351. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.d.ts.map +1 -0
  352. package/src/shade/renderer/particles/data/PARTICLE_FIELD_BINDING.js +56 -0
  353. package/src/shade/renderer/particles/data/particle_emitter_record.d.ts.map +1 -1
  354. package/src/shade/renderer/particles/data/particle_emitter_record.js +2 -0
  355. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.d.ts +1 -1
  356. package/src/shade/renderer/particles/graph/ParticleGroupBuilder.js +1 -1
  357. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts +22 -11
  358. package/src/shade/renderer/particles/graph/ParticleNodeDescription.d.ts.map +1 -1
  359. package/src/shade/renderer/particles/graph/ParticleNodeDescription.js +14 -11
  360. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts +4 -4
  361. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.d.ts.map +1 -1
  362. package/src/shade/renderer/particles/graph/ParticleNodeRegistry.js +59 -24
  363. package/src/shade/renderer/particles/graph/ParticleValueType.d.ts +3 -3
  364. package/src/shade/renderer/particles/graph/ParticleValueType.js +287 -287
  365. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts +13 -6
  366. package/src/shade/renderer/particles/graph/compile_particle_graph.d.ts.map +1 -1
  367. package/src/shade/renderer/particles/graph/compile_particle_graph.js +46 -27
  368. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts +8 -2
  369. package/src/shade/renderer/particles/graph/infer_particle_graph_types.d.ts.map +1 -1
  370. package/src/shade/renderer/particles/graph/infer_particle_graph_types.js +240 -234
  371. package/src/shade/renderer/particles/graph/make_particle_group.d.ts +1 -1
  372. package/src/shade/renderer/particles/graph/make_particle_group.js +1 -1
  373. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts +3 -2
  374. package/src/shade/renderer/particles/graph/particle_graph_authoring.d.ts.map +1 -1
  375. package/src/shade/renderer/particles/graph/particle_graph_authoring.js +3 -2
  376. package/src/shade/renderer/particles/graph/particle_graph_distributions.js +170 -170
  377. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts +25 -16
  378. package/src/shade/renderer/particles/graph/particle_graph_json.d.ts.map +1 -1
  379. package/src/shade/renderer/particles/graph/particle_graph_json.js +16 -2
  380. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts +29 -15
  381. package/src/shade/renderer/particles/graph/particle_node_parameters.d.ts.map +1 -1
  382. package/src/shade/renderer/particles/graph/particle_node_parameters.js +54 -22
  383. package/src/shade/renderer/particles/graph/particle_node_presentation.d.ts.map +1 -1
  384. package/src/shade/renderer/particles/graph/particle_node_presentation.js +18 -8
  385. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts +9 -2
  386. package/src/shade/renderer/particles/graph/validate_particle_graph.d.ts.map +1 -1
  387. package/src/shade/renderer/particles/graph/validate_particle_graph.js +70 -32
  388. package/src/shade/renderer/particles/graph_particles.d.ts +9 -4
  389. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  390. package/src/shade/renderer/particles/graph_particles.js +27 -4
  391. package/src/shade/renderer/particles/isa/InstructionStream.d.ts +7 -6
  392. package/src/shade/renderer/particles/isa/InstructionStream.d.ts.map +1 -1
  393. package/src/shade/renderer/particles/isa/InstructionStream.js +17 -16
  394. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts +17 -0
  395. package/src/shade/renderer/particles/isa/ParticleAssembler.d.ts.map +1 -1
  396. package/src/shade/renderer/particles/isa/ParticleAssembler.js +35 -0
  397. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts +26 -6
  398. package/src/shade/renderer/particles/isa/ParticleProgram.d.ts.map +1 -1
  399. package/src/shade/renderer/particles/isa/ParticleProgram.js +61 -9
  400. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts +55 -4
  401. package/src/shade/renderer/particles/isa/ParticleVMISA.d.ts.map +1 -1
  402. package/src/shade/renderer/particles/isa/ParticleVMISA.js +79 -10
  403. package/src/shade/renderer/particles/isa/particle_assembly.d.ts +20 -6
  404. package/src/shade/renderer/particles/isa/particle_assembly.d.ts.map +1 -1
  405. package/src/shade/renderer/particles/isa/particle_assembly.js +136 -25
  406. package/src/shade/renderer/particles/isa/particle_link_global_fields.d.ts +20 -0
  407. package/src/shade/renderer/particles/isa/particle_link_global_fields.d.ts.map +1 -0
  408. package/src/shade/renderer/particles/isa/particle_link_global_fields.js +46 -0
  409. package/src/shade/renderer/particles/isa/validate_particle_program.js +8 -8
  410. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts +62 -28
  411. package/src/shade/renderer/particles/layout/ParticleLayout.d.ts.map +1 -1
  412. package/src/shade/renderer/particles/layout/ParticleLayout.js +102 -62
  413. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.d.ts.map +1 -1
  414. package/src/shade/renderer/particles/optimizer/dag/optimize_particle_program_vector.js +2 -0
  415. package/src/shade/renderer/particles/optimizer/dag/particle_vector_groups.js +1 -1
  416. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lift.js +4 -3
  417. package/src/shade/renderer/particles/optimizer/dag/particle_vector_lower.js +2 -2
  418. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.d.ts +3 -3
  419. package/src/shade/renderer/particles/optimizer/dag/particle_vector_pack.js +11 -11
  420. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts +4 -4
  421. package/src/shade/renderer/particles/optimizer/optimize_particle_program.d.ts.map +1 -1
  422. package/src/shade/renderer/particles/optimizer/optimize_particle_program.js +5 -4
  423. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.d.ts +1 -1
  424. package/src/shade/renderer/particles/optimizer/particle_integer_bounds.js +1 -1
  425. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts +4 -4
  426. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.d.ts.map +1 -1
  427. package/src/shade/renderer/particles/optimizer/particle_program_equivalence.js +13 -11
  428. package/src/shade/renderer/particles/optimizer/particle_program_fuzz.js +7 -7
  429. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts +3 -2
  430. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.d.ts.map +1 -1
  431. package/src/shade/renderer/particles/optimizer/particle_vm_semantics.js +5 -4
  432. package/src/shade/renderer/particles/optimizer/pass_allocate_registers.d.ts.map +1 -1
  433. package/src/shade/renderer/particles/optimizer/pass_dedup_constants.d.ts.map +1 -1
  434. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.d.ts.map +1 -1
  435. package/src/shade/renderer/particles/optimizer/pass_eliminate_dead_code.js +51 -51
  436. package/src/shade/renderer/particles/optimizer/pass_fold_constants.d.ts.map +1 -1
  437. package/src/shade/renderer/particles/optimizer/pass_fold_constants.js +5 -5
  438. package/src/shade/renderer/particles/optimizer/pass_inline_constants.d.ts.map +1 -1
  439. package/src/shade/renderer/particles/optimizer/pass_narrow_widths.d.ts.map +1 -1
  440. package/src/shade/renderer/particles/optimizer/pass_pack_registers.d.ts.map +1 -1
  441. package/src/shade/renderer/particles/optimizer/pass_peephole.d.ts.map +1 -1
  442. package/src/shade/renderer/particles/optimizer/pass_propagate_copies.d.ts.map +1 -1
  443. package/src/shade/renderer/particles/optimizer/pass_schedule.d.ts.map +1 -1
  444. package/src/shade/renderer/particles/optimizer/pass_schedule.js +2 -2
  445. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.d.ts.map +1 -1
  446. package/src/shade/renderer/particles/optimizer/pass_share_subexpressions.js +5 -4
  447. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +93 -22
  448. package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
  449. package/src/shade/renderer/particles/runtime/EmitterRegistry.js +336 -29
  450. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +43 -3
  451. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
  452. package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +43 -3
  453. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +56 -26
  454. package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
  455. package/src/shade/renderer/particles/runtime/ParticleEmitter.js +89 -33
  456. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.d.ts +85 -0
  457. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.d.ts.map +1 -0
  458. package/src/shade/renderer/particles/runtime/ParticleGlobalFields.js +221 -0
  459. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts +143 -18
  460. package/src/shade/renderer/particles/runtime/ProgramHeap.d.ts.map +1 -1
  461. package/src/shade/renderer/particles/runtime/ProgramHeap.js +378 -28
  462. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts +19 -7
  463. package/src/shade/renderer/particles/runtime/create_particle_effect.d.ts.map +1 -1
  464. package/src/shade/renderer/particles/runtime/create_particle_effect.js +22 -9
  465. package/src/shade/renderer/particles/shaders/chunk_particle_billboard_vertex.js +8 -8
  466. package/src/shade/renderer/particles/shaders/chunk_particle_render_math.js +1 -1
  467. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts +3 -0
  468. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.d.ts.map +1 -1
  469. package/src/shade/renderer/particles/shaders/chunk_particle_setup_context.js +4 -0
  470. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.d.ts +30 -0
  471. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.d.ts.map +1 -0
  472. package/src/shade/renderer/particles/shaders/shader_particle_field_bind.js +121 -0
  473. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.d.ts.map +1 -1
  474. package/src/shade/renderer/particles/vm/PARTICLE_VM_CONTEXT_STRUCT.js +3 -1
  475. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts +12 -4
  476. package/src/shade/renderer/particles/vm/ParticleVMReference.d.ts.map +1 -1
  477. package/src/shade/renderer/particles/vm/ParticleVMReference.js +48 -11
  478. package/src/shade/renderer/particles/vm/chunk_particle_vm.d.ts.map +1 -1
  479. package/src/shade/renderer/particles/vm/chunk_particle_vm.js +36 -14
  480. package/src/shade/renderer/postprocess/PostProcess.d.ts.map +1 -1
  481. package/src/shade/renderer/postprocess/PostProcess.js +2 -1
  482. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts +31 -19
  483. package/src/shade/renderer/postprocess/gtao/GTAO.d.ts.map +1 -1
  484. package/src/shade/renderer/postprocess/gtao/GTAO.js +44 -30
  485. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  486. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +16 -2
  487. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  488. package/src/shade/renderer/postprocess/nss/NSS.d.ts.map +1 -1
  489. package/src/shade/renderer/postprocess/nss/NSS.js +4 -3
  490. package/src/shade/renderer/postprocess/ssr/SSR.d.ts +7 -1
  491. package/src/shade/renderer/postprocess/ssr/SSR.d.ts.map +1 -1
  492. package/src/shade/renderer/postprocess/ssr/SSR.js +16 -0
  493. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts +20 -2
  494. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.d.ts.map +1 -1
  495. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_add_hit_irradiance.js +53 -3
  496. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts +10 -2
  497. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.d.ts.map +1 -1
  498. package/src/shade/renderer/postprocess/ssr/resolve/chunk_ssr_sample_radiance.js +31 -3
  499. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
  500. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +17 -11
  501. package/src/shade/renderer/postprocess/taa/TAA.d.ts +4 -2
  502. package/src/shade/renderer/postprocess/taa/TAA.d.ts.map +1 -1
  503. package/src/shade/renderer/postprocess/taa/TAA.js +6 -1
  504. package/src/shade/renderer/postprocess/taa/chunk_fsr2_compute_depth_clip.d.ts.map +1 -1
  505. package/src/shade/renderer/postprocess/taa/chunk_fsr2_compute_depth_clip.js +10 -5
  506. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  507. package/src/shade/renderer/postprocess/taa/shader_taa.js +15 -12
  508. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.d.ts.map +1 -1
  509. package/src/shade/renderer/postprocess/velocity/graph_add_per_object_velocity.js +26 -17
  510. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts +4 -3
  511. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.d.ts.map +1 -1
  512. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect.js +6 -4
  513. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts +12 -0
  514. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.d.ts.map +1 -0
  515. package/src/shade/renderer/rasterize/forward/chunk_forward_sample_indirect_probe_clipmap.js +57 -0
  516. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts +4 -2
  517. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.d.ts.map +1 -1
  518. package/src/shade/renderer/rasterize/native/avboit/AVBOITSideChannel.js +4 -2
  519. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts +8 -2
  520. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  521. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +28 -15
  522. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts +2 -1
  523. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.d.ts.map +1 -1
  524. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_draw.js +19 -3
  525. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.d.ts.map +1 -1
  526. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +4 -2
  527. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts +3 -1
  528. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  529. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +27 -14
  530. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts +2 -1
  531. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.d.ts.map +1 -1
  532. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +19 -3
  533. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.d.ts +2 -8
  534. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.d.ts.map +1 -1
  535. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_bounds.js +25 -52
  536. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.d.ts +15 -0
  537. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.d.ts.map +1 -0
  538. package/src/shade/renderer/shader/chunk/geometry/meshlet/chunk_read_meshlet_triangle_positions.js +52 -0
  539. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.d.ts +7 -0
  540. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.d.ts.map +1 -0
  541. package/src/shade/renderer/shader/chunk/geometry/triangle/TRIANGLE_POSITIONS_STRUCT.js +12 -0
  542. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.d.ts +22 -0
  543. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.d.ts.map +1 -0
  544. package/src/shade/renderer/shader/chunk/grid/chunk_index_to_grid2d_reciprocal.js +37 -0
  545. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.d.ts.map +1 -1
  546. package/src/shade/renderer/shader/chunk/light/lpv/depth/chunk_lpv_mask_weights_by_visibility.js +26 -60
  547. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts +23 -0
  548. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts.map +1 -0
  549. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.js +54 -0
  550. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts +25 -0
  551. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.d.ts.map +1 -0
  552. package/src/shade/renderer/shader/chunk/math/chunk_f16_round_stochastic.js +43 -0
  553. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.d.ts +14 -0
  554. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.d.ts.map +1 -0
  555. package/src/shade/renderer/shader/chunk/random/chunk_jitter_from_vectors.js +37 -0
  556. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.d.ts +27 -0
  557. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.d.ts.map +1 -0
  558. package/src/shade/renderer/shader/chunk/random/reservoir/chunk_pick2_wrs_mat2x4.js +61 -0
  559. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.d.ts +21 -0
  560. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.d.ts.map +1 -0
  561. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/chunk_resolve_irradiance_sh_to_specular.js +41 -0
  562. package/src/shade/renderer/texture/util/texture_fill_rectangle.d.ts.map +1 -1
  563. package/src/shade/renderer/texture/util/texture_fill_rectangle.js +282 -267
  564. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +8 -4
  565. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  566. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +36 -36
  567. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +6 -1
  568. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -1
  569. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +498 -484
  570. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +15 -2
  571. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -1
  572. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +57 -3
  573. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts.map +1 -1
  574. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js +197 -191
  575. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +4 -4
  576. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +2 -1
  577. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  578. package/src/shade/renderer/water/GPUWaterRenderer.js +5 -1
  579. package/src/shade/renderer/water/chunk_water_gi.d.ts +13 -3
  580. package/src/shade/renderer/water/chunk_water_gi.d.ts.map +1 -1
  581. package/src/shade/renderer/water/chunk_water_gi.js +47 -5
  582. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  583. package/src/shade/renderer/water/shader_water.d.ts +3 -2
  584. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  585. package/src/shade/renderer/water/shader_water.js +9 -3
  586. package/src/shade/renderer/geometry/sdf/SDF_BUILD_SETTINGS_STRUCT.d.ts +0 -3
  587. package/src/shade/renderer/geometry/sdf/SDF_BUILD_SETTINGS_STRUCT.d.ts.map +0 -1
  588. package/src/shade/renderer/geometry/sdf/SFD_BUILD_WORKGROUP_SIZE.d.ts +0 -2
  589. package/src/shade/renderer/geometry/sdf/SFD_BUILD_WORKGROUP_SIZE.d.ts.map +0 -1
  590. package/src/shade/renderer/geometry/sdf/chunk_blas_query_sdf.d.ts +0 -8
  591. package/src/shade/renderer/geometry/sdf/chunk_blas_query_sdf.d.ts.map +0 -1
  592. package/src/shade/renderer/geometry/sdf/chunk_blas_query_volume_sign.d.ts +0 -3
  593. package/src/shade/renderer/geometry/sdf/chunk_blas_query_volume_sign.d.ts.map +0 -1
  594. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts +0 -3
  595. package/src/shade/renderer/geometry/sdf/shader_build_sdf.d.ts.map +0 -1
  596. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_object.d.ts.map +0 -1
  597. package/src/shade/renderer/global_illumination/probe_clipmap/brick/mesh/chunk_mesh_brick_object.js +0 -42
  598. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts +0 -31
  599. package/src/shade/renderer/particles/shaders/shader_particle_init_free_list.d.ts.map +0 -1
  600. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts +0 -42
  601. package/src/shade/renderer/shadow/vsm/VSMMoverTracker.d.ts.map +0 -1
  602. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts +0 -54
  603. package/src/shade/renderer/shadow/vsm/VSM_MOVER_LAYOUT.d.ts.map +0 -1
  604. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts +0 -14
  605. package/src/shade/renderer/shadow/vsm/shader/chunk_vsm_append_mover.d.ts.map +0 -1
  606. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts +0 -30
  607. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_movers.d.ts.map +0 -1
  608. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts +0 -23
  609. package/src/shade/renderer/shadow/vsm/shader/shader_vsm_skinned_movers.d.ts.map +0 -1
@@ -1,16 +1,10 @@
1
1
  import { TREE_RENDER_COST_CEILING } from "../analysis/tree_render_cost.js";
2
- import { TREE_LOD_ERROR_FINEST } from "../config/TreeLODConfig.js";
2
+ import { TREE_LOD_ERROR_FINEST, TREE_LOD_ERROR_STEP } from "../config/TreeLODConfig.js";
3
3
  import { CUTOUT_HULL_VERTEX_COUNT } from "../material/FoliageAtlasCutout.js";
4
4
  import { tree_clusters } from "../mesh/tree_clusters.js";
5
5
  import { tree_mesh_compute_branch_rings } from "../mesh/tree_mesh_build_bark.js";
6
6
  import { tree_skeleton_assign_skin_joints } from "../skeleton/tree_skeleton_assign_skin_joints.js";
7
7
 
8
- /**
9
- * Ratio between consecutive errors the search tries: each a half-octave coarser than the last.
10
- * @type {number}
11
- */
12
- const ERROR_STEP = Math.SQRT2;
13
-
14
8
  /**
15
9
  * Triangles the bark `rings` and the cluster cards of the wood they leave out cost.
16
10
  *
@@ -19,7 +13,7 @@ const ERROR_STEP = Math.SQRT2;
19
13
  * @param {Map<number, Array<{m: number}>>} rings
20
14
  * @returns {number}
21
15
  */
22
- function triangles_of(skeleton, attachments, rings) {
16
+ function triangles_of(skeleton, attachments, rings, cards) {
23
17
  let triangles = 0;
24
18
  for (const list of rings.values()) {
25
19
  for (let i = 1; i < list.length; i++) {
@@ -28,7 +22,9 @@ function triangles_of(skeleton, attachments, rings) {
28
22
  // the tip's cap
29
23
  triangles += list[list.length - 1].m;
30
24
  }
31
- if (attachments.count > 0 || rings.size < skeleton.branch_count) {
25
+ if (cards !== null) {
26
+ triangles += cards(rings) * CUTOUT_HULL_VERTEX_COUNT;
27
+ } else if (attachments.count > 0 || rings.size < skeleton.branch_count) {
32
28
  // a card per cluster
33
29
  triangles += tree_clusters(skeleton, attachments, rings).length * CUTOUT_HULL_VERTEX_COUNT;
34
30
  }
@@ -46,7 +42,7 @@ function triangles_of(skeleton, attachments, rings) {
46
42
  * @returns {number}
47
43
  */
48
44
  export function tree_triangles_at_error(skeleton, species, attachments, error) {
49
- return triangles_of(skeleton, attachments, tree_mesh_compute_branch_rings(skeleton, species, { error }));
45
+ return triangles_of(skeleton, attachments, tree_mesh_compute_branch_rings(skeleton, species, { error }), null);
50
46
  }
51
47
 
52
48
  /**
@@ -62,7 +58,7 @@ export function tree_triangles_at_error(skeleton, species, attachments, error) {
62
58
  * `TREE_RENDER_COST_CEILING` over `side_area` (`tree_grown_side_area`), its bark and cluster cards in triangles and,
63
59
  * when it is rigged for wind, its joints, no finer than the LOD before it and no finer than `TREE_LOD_ERROR_FINEST`:
64
60
  * each halving of the error quadruples the cluster cards' texels, which no ceiling yet bounds. Errors are tried a
65
- * half-octave apart ({@link ERROR_STEP}), up from the finest until the tree fits, or until it draws no wood at all.
61
+ * half-octave apart ({@link TREE_LOD_ERROR_STEP}), up from the finest until the tree fits, or until it draws no wood at all.
66
62
  *
67
63
  * An LOD's rig (`tree_skeleton_assign_skin_joints`) is on the wood it draws, at a tolerance no finer than its error
68
64
  * (a sway smaller than the shape's error cannot be seen), and its joints are a subset of the finer LOD's. The
@@ -76,9 +72,11 @@ export function tree_triangles_at_error(skeleton, species, attachments, error) {
76
72
  * @param {Map<number, ReturnType<typeof tree_mesh_compute_branch_rings>>} [planned] the bark's rings the caller has
77
73
  * already planned (`tree_mesh_compute_branch_rings`), by error: the search takes them rather than planning them
78
74
  * again
75
+ * @param {((error: number) => number)|null} [cards] how many cards the tree draws at an error, where they are not its
76
+ * own cuts (`tree_shoot_instance_card_count`); its own clusters (`tree_clusters`) by default
79
77
  * @returns {TreeLODPlan[]}
80
78
  */
81
- export function tree_lod_plan(skeleton, species, attachments, side_area, lod_count, planned = new Map()) {
79
+ export function tree_lod_plan(skeleton, species, attachments, side_area, lod_count, planned = new Map(), cards = null) {
82
80
  const ceiling = TREE_RENDER_COST_CEILING;
83
81
  const rigged = species.wind.enabled;
84
82
  const drawn = new Map();
@@ -86,7 +84,7 @@ export function tree_lod_plan(skeleton, species, attachments, side_area, lod_cou
86
84
  let d = drawn.get(error);
87
85
  if (d === undefined) {
88
86
  const rings = planned.get(error) ?? tree_mesh_compute_branch_rings(skeleton, species, { error });
89
- d = { rings, density: triangles_of(skeleton, attachments, rings) / side_area };
87
+ d = { rings, density: triangles_of(skeleton, attachments, rings, cards === null ? null : () => cards(error)) / side_area };
90
88
  drawn.set(error, d);
91
89
  }
92
90
  return d;
@@ -112,7 +110,7 @@ export function tree_lod_plan(skeleton, species, attachments, side_area, lod_cou
112
110
  break;
113
111
  }
114
112
  }
115
- error *= ERROR_STEP;
113
+ error *= TREE_LOD_ERROR_STEP;
116
114
  }
117
115
  }
118
116
  return plan;
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @typedef {Object} TreeShootInstance
3
+ * @property {number} prototype index into `TreeShootPrototypes.prototypes`
4
+ * @property {number} carrier the tree's branch it is drawn on
5
+ * @property {number} scale `TREE_LOD_ERROR_STEP ^ shift`: wood, girth, leaves and cards alike
6
+ * @property {number} shift the steps of the error ladder its scale is: at the tree's error, the prototype's cuts `shift`
7
+ * steps finer are drawn, as large
8
+ * @property {Float64Array} turn row-major 3x3, a turn about the vertical: the prototype's carrier's heading onto the tree's
9
+ * @property {Int32Array} branch_of per branch of the prototype in the sheet (from its `first`), its branch in the tree,
10
+ * or -1 for wood no LOD draws, which the prototype's cuts alone draw
11
+ * @property {Array<import("../skeleton/tree_skeleton_copy_branches.js").TreeBranchPlacement>} placement_of per branch
12
+ * of the prototype, where it is carried onto the tree: grafted as, or, undrawn, drawn as
13
+ */
14
+ /**
15
+ * Draws a species' shoot prototypes on a tree grown by its generator graph (TWO_FRONT_ENDS_BRIEF_2026_10_28.md, G3).
16
+ * Every living carrier of a shoot rule's `source` takes the prototype of its generator whose carrier's length is nearest
17
+ * its own, in ratio (`tree_shoot_prototypes`).
18
+ *
19
+ * - **Scaled by the ladder.** The ratio is drawn as the nearest power of the error ladder's step: within the spread the
20
+ * species' leaves grow to, 1, so the prototype is drawn as it grew. Wood, girth, leaves and cards are scaled alike,
21
+ * so at the tree's error the tree draws as wood exactly what the prototype's cuts that many steps finer leave to wood.
22
+ * - **Turned about the vertical only**, from the prototype's carrier's heading to the tree's: up stays up, as the
23
+ * prototype's leaves were lit and baked.
24
+ * - **The carrier** keeps its own course in the tree. It takes the prototype's growth past its framework's tip, turned
25
+ * to carry on from the tree's carrier's tip, its annual units and its girth.
26
+ * - **The wood any LOD draws** (`TreeShootPrototypes.drawn`) is grafted onto it, each shoot system hung on the tree's
27
+ * carrier where it hangs on the prototype's (`tree_skeleton_copy_branch`): the rig, the bark and the LOD plan take it
28
+ * as the tree's own. Its leaf the tree holds by its annual units, as the prototype's wood held it.
29
+ * - **The rest** the prototype's cuts draw (`tree_shoot_instance_cards`); its leaf loads the segment it hangs from
30
+ * (`TreeSkeleton.segment_carried_leaf_area`). Every branch of an instance is marked (`TreeSkeleton.branch_instance`),
31
+ * so the tree's own leaves leave it to the prototype.
32
+ * - **Its girth holds together**: every branch is at least as thick as what grows from it (`tree_skeleton_floor_girth`).
33
+ *
34
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton the tree's framework, grafted onto in place
35
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
36
+ * @returns {TreeShootInstance[]}
37
+ */
38
+ export function tree_shoot_instances(skeleton: import("../skeleton/TreeSkeleton.js").TreeSkeleton, prototypes: import("./tree_shoot_prototypes.js").TreeShootPrototypes): TreeShootInstance[];
39
+ /**
40
+ * The cards of every instance on the tree at `error`: each prototype's cuts at the step of its error ladder `error` is
41
+ * (`TreeShootPrototypes.errors`, the LOD plan's own steps) less the instance's `shift`, carried as its instance carries
42
+ * them: from where they hang on the prototype to the same place on the tree, and skinned as the tree's drawn bark is
43
+ * there, or where the nearest drawn wood holds it (`tree_cluster_hang`).
44
+ *
45
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton bound to the rig `rings` were planned with
46
+ * @param {Map<number, Array<{t_norm: number, cx: number, cy: number, cz: number}>>} rings the tree's at `error`
47
+ * @param {TreeShootInstance[]} instances
48
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
49
+ * @param {number} error m, a step of the error ladder
50
+ * @returns {{clusters: import("../mesh/tree_clusters.js").TreeCluster[], cards: Array<{cluster: number}>, placement: {rep: Int32Array, frames: Float64Array}}}
51
+ */
52
+ export function tree_shoot_instance_cards(skeleton: import("../skeleton/TreeSkeleton.js").TreeSkeleton, rings: Map<number, Array<{
53
+ t_norm: number;
54
+ cx: number;
55
+ cy: number;
56
+ cz: number;
57
+ }>>, instances: TreeShootInstance[], prototypes: import("./tree_shoot_prototypes.js").TreeShootPrototypes, error: number): {
58
+ clusters: import("../mesh/tree_clusters.js").TreeCluster[];
59
+ cards: Array<{
60
+ cluster: number;
61
+ }>;
62
+ placement: {
63
+ rep: Int32Array;
64
+ frames: Float64Array;
65
+ };
66
+ };
67
+ /**
68
+ * How many cards the instances draw at `error` (`tree_shoot_instance_cards`), for the LOD plan.
69
+ *
70
+ * @param {TreeShootInstance[]} instances
71
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
72
+ * @param {number} error m, a step of the error ladder
73
+ * @returns {number}
74
+ */
75
+ export function tree_shoot_instance_card_count(instances: TreeShootInstance[], prototypes: import("./tree_shoot_prototypes.js").TreeShootPrototypes, error: number): number;
76
+ /**
77
+ * Every leaf's card the instances draw, carried onto the tree as they are (for `tree_grown_side_area`): positions,
78
+ * `3` per vertex. A leaf on a carrier lands where the carrier runs on the tree.
79
+ *
80
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton the tree the instances are on
81
+ * @param {TreeShootInstance[]} instances
82
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
83
+ * @returns {Float32Array}
84
+ */
85
+ export function tree_shoot_instance_leaves(skeleton: import("../skeleton/TreeSkeleton.js").TreeSkeleton, instances: TreeShootInstance[], prototypes: import("./tree_shoot_prototypes.js").TreeShootPrototypes): Float32Array;
86
+ export type TreeShootInstance = {
87
+ /**
88
+ * index into `TreeShootPrototypes.prototypes`
89
+ */
90
+ prototype: number;
91
+ /**
92
+ * the tree's branch it is drawn on
93
+ */
94
+ carrier: number;
95
+ /**
96
+ * `TREE_LOD_ERROR_STEP ^ shift`: wood, girth, leaves and cards alike
97
+ */
98
+ scale: number;
99
+ /**
100
+ * the steps of the error ladder its scale is: at the tree's error, the prototype's cuts `shift`
101
+ * steps finer are drawn, as large
102
+ */
103
+ shift: number;
104
+ /**
105
+ * row-major 3x3, a turn about the vertical: the prototype's carrier's heading onto the tree's
106
+ */
107
+ turn: Float64Array;
108
+ /**
109
+ * per branch of the prototype in the sheet (from its `first`), its branch in the tree,
110
+ * or -1 for wood no LOD draws, which the prototype's cuts alone draw
111
+ */
112
+ branch_of: Int32Array;
113
+ /**
114
+ * per branch
115
+ * of the prototype, where it is carried onto the tree: grafted as, or, undrawn, drawn as
116
+ */
117
+ placement_of: Array<import("../skeleton/tree_skeleton_copy_branches.js").TreeBranchPlacement>;
118
+ };
119
+ //# sourceMappingURL=tree_shoot_instances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree_shoot_instances.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/asset/tree_shoot_instances.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,+CAJW,OAAO,6BAA6B,EAAE,YAAY,cAClD,OAAO,4BAA4B,EAAE,mBAAmB,GACtD,iBAAiB,EAAE,CA6B/B;AA2GD;;;;;;;;;;;;GAYG;AACH,oDAPW,OAAO,6BAA6B,EAAE,YAAY,SAClD,IAAI,MAAM,EAAE,MAAM;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC,aACxE,iBAAiB,EAAE,cACnB,OAAO,4BAA4B,EAAE,mBAAmB,SACxD,MAAM,GACJ;IAAC,QAAQ,EAAE,OAAO,0BAA0B,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAAC,SAAS,EAAE;QAAC,GAAG,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,YAAY,CAAA;KAAC,CAAA;CAAC,CA2D7J;AAED;;;;;;;GAOG;AACH,0DALW,iBAAiB,EAAE,cACnB,OAAO,4BAA4B,EAAE,mBAAmB,SACxD,MAAM,GACJ,MAAM,CAclB;AAED;;;;;;;;GAQG;AACH,qDALW,OAAO,6BAA6B,EAAE,YAAY,aAClD,iBAAiB,EAAE,cACnB,OAAO,4BAA4B,EAAE,mBAAmB,GACtD,YAAY,CAyCxB;;;;;eAxTa,MAAM;;;;aACN,MAAM;;;;WACN,MAAM;;;;;WACN,MAAM;;;;UAEN,YAAY;;;;;eACZ,UAAU;;;;;kBAEV,MAAM,OAAO,4CAA4C,EAAE,mBAAmB,CAAC"}
@@ -0,0 +1,410 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import { StandardAttributes } from "../../../shade/renderer/geometry/StandardAttributes.js";
3
+ import { TREE_LOD_ERROR_FINEST, TREE_LOD_ERROR_STEP } from "../config/TreeLODConfig.js";
4
+ import { tree_cluster_hang } from "../mesh/tree_clusters.js";
5
+ import { shoot_locate_on_chain } from "../skeleton/shoot_geometry.js";
6
+ import { tree_branch_placement_apply, tree_branch_turn, tree_skeleton_copy_branch } from "../skeleton/tree_skeleton_copy_branches.js";
7
+ import { tree_skeleton_extend_branch } from "../skeleton/tree_skeleton_extend_branch.js";
8
+ import { tree_skeleton_floor_girth } from "../skeleton/tree_skeleton_floor_girth.js";
9
+ import { tree_skeleton_read_joint_motion } from "../skeleton/tree_skeleton_read_joint_motion.js";
10
+
11
+ const SCRATCH_A = new Float64Array(3);
12
+ const SCRATCH_B = new Float64Array(3);
13
+ const SCRATCH_V = new Float64Array(3);
14
+ const SCRATCH_NODES = [];
15
+ const SCRATCH_EDGES = [];
16
+
17
+ /**
18
+ * @typedef {Object} TreeShootInstance
19
+ * @property {number} prototype index into `TreeShootPrototypes.prototypes`
20
+ * @property {number} carrier the tree's branch it is drawn on
21
+ * @property {number} scale `TREE_LOD_ERROR_STEP ^ shift`: wood, girth, leaves and cards alike
22
+ * @property {number} shift the steps of the error ladder its scale is: at the tree's error, the prototype's cuts `shift`
23
+ * steps finer are drawn, as large
24
+ * @property {Float64Array} turn row-major 3x3, a turn about the vertical: the prototype's carrier's heading onto the tree's
25
+ * @property {Int32Array} branch_of per branch of the prototype in the sheet (from its `first`), its branch in the tree,
26
+ * or -1 for wood no LOD draws, which the prototype's cuts alone draw
27
+ * @property {Array<import("../skeleton/tree_skeleton_copy_branches.js").TreeBranchPlacement>} placement_of per branch
28
+ * of the prototype, where it is carried onto the tree: grafted as, or, undrawn, drawn as
29
+ */
30
+
31
+ /**
32
+ * Draws a species' shoot prototypes on a tree grown by its generator graph (TWO_FRONT_ENDS_BRIEF_2026_10_28.md, G3).
33
+ * Every living carrier of a shoot rule's `source` takes the prototype of its generator whose carrier's length is nearest
34
+ * its own, in ratio (`tree_shoot_prototypes`).
35
+ *
36
+ * - **Scaled by the ladder.** The ratio is drawn as the nearest power of the error ladder's step: within the spread the
37
+ * species' leaves grow to, 1, so the prototype is drawn as it grew. Wood, girth, leaves and cards are scaled alike,
38
+ * so at the tree's error the tree draws as wood exactly what the prototype's cuts that many steps finer leave to wood.
39
+ * - **Turned about the vertical only**, from the prototype's carrier's heading to the tree's: up stays up, as the
40
+ * prototype's leaves were lit and baked.
41
+ * - **The carrier** keeps its own course in the tree. It takes the prototype's growth past its framework's tip, turned
42
+ * to carry on from the tree's carrier's tip, its annual units and its girth.
43
+ * - **The wood any LOD draws** (`TreeShootPrototypes.drawn`) is grafted onto it, each shoot system hung on the tree's
44
+ * carrier where it hangs on the prototype's (`tree_skeleton_copy_branch`): the rig, the bark and the LOD plan take it
45
+ * as the tree's own. Its leaf the tree holds by its annual units, as the prototype's wood held it.
46
+ * - **The rest** the prototype's cuts draw (`tree_shoot_instance_cards`); its leaf loads the segment it hangs from
47
+ * (`TreeSkeleton.segment_carried_leaf_area`). Every branch of an instance is marked (`TreeSkeleton.branch_instance`),
48
+ * so the tree's own leaves leave it to the prototype.
49
+ * - **Its girth holds together**: every branch is at least as thick as what grows from it (`tree_skeleton_floor_girth`).
50
+ *
51
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton the tree's framework, grafted onto in place
52
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
53
+ * @returns {TreeShootInstance[]}
54
+ */
55
+ export function tree_shoot_instances(skeleton, prototypes) {
56
+ const by_generator = new Map();
57
+ prototypes.prototypes.forEach((q, i) => {
58
+ let list = by_generator.get(q.generator);
59
+ if (list === undefined) by_generator.set(q.generator, list = []);
60
+ list.push(i);
61
+ });
62
+ /** @type {TreeShootInstance[]} */
63
+ const instances = [];
64
+ const framework_count = skeleton.branch_count;
65
+ for (let c = 0; c < framework_count; c++) {
66
+ const of_generator = by_generator.get(skeleton.branch_generator[c]);
67
+ const length = skeleton.branch_length[c];
68
+ if (of_generator === undefined || skeleton.branch_dead[c] || !(length > 0)) continue;
69
+ // the nearest in ratio
70
+ let best = -1, best_d = Infinity;
71
+ for (const i of of_generator) {
72
+ const d = Math.abs(Math.log(length / prototypes.prototypes[i].length));
73
+ if (d < best_d) {
74
+ best = i;
75
+ best_d = d;
76
+ }
77
+ }
78
+ instances.push(graft(skeleton, prototypes, best, c, instances.length));
79
+ }
80
+ tree_skeleton_floor_girth(skeleton);
81
+ return instances;
82
+ }
83
+
84
+ /**
85
+ * Places prototype `index` on carrier `carrier` of `skeleton`.
86
+ *
87
+ * @returns {TreeShootInstance}
88
+ */
89
+ function graft(skeleton, prototypes, index, carrier, instance) {
90
+ const sheet = prototypes.sheet;
91
+ const q = prototypes.prototypes[index];
92
+ const shift = Math.round(Math.log(skeleton.branch_length[carrier] / q.length) / Math.log(TREE_LOD_ERROR_STEP));
93
+ const scale = Math.pow(TREE_LOD_ERROR_STEP, shift);
94
+
95
+ // turned about the vertical, its carrier's heading onto the tree's
96
+ const from = new Float64Array(3), to = new Float64Array(3);
97
+ sheet.node_read_position(from, 0, sheet.branch_root_vertex[q.first]);
98
+ skeleton.node_read_position(to, 0, skeleton.branch_root_vertex[carrier]);
99
+ const yaw = heading(skeleton, skeleton.branch_root_vertex[carrier]) - heading(sheet, sheet.branch_root_vertex[q.first]);
100
+ const cos = Math.cos(yaw), sin = Math.sin(yaw);
101
+ const turn = Float64Array.of(cos, 0, sin, 0, 1, 0, -sin, 0, cos);
102
+ const carry = { turn, scale, from, to };
103
+
104
+ // the carrier's growth past its framework's tip, carried on from the tree's carrier's tip and turned to continue it
105
+ sheet.collect_branch_chain(q.first, SCRATCH_NODES, SCRATCH_EDGES);
106
+ const nodes = SCRATCH_NODES.slice(), edges = SCRATCH_EDGES.slice();
107
+ const tip_t = q.length / sheet.branch_length[q.first];
108
+ let k0 = 0;
109
+ while (k0 + 1 < nodes.length && sheet.node_t_norm(nodes[k0 + 1]) <= tip_t + 1e-6) k0++;
110
+ if (k0 + 1 < nodes.length) {
111
+ const n = nodes.length - 1 - k0;
112
+ const points = new Float64Array((n + 1) * 3), radii = new Float64Array(n + 1), lengths = new Float64Array(n);
113
+ const host_tip = skeleton.branch_tip_vertex[carrier];
114
+ skeleton.node_read_position(SCRATCH_B, 0, host_tip);
115
+ skeleton.node_read_tangent(SCRATCH_V, 0, host_tip);
116
+ // the turn that takes the extension's own heading at the tip onto the tree's carrier's
117
+ sheet.node_read_tangent(SCRATCH_A, 0, nodes[k0]);
118
+ tree_branch_turn(SCRATCH_A, turn);
119
+ const onto = turn_onto(SCRATCH_A, SCRATCH_V);
120
+ sheet.node_read_position(SCRATCH_A, 0, nodes[k0]);
121
+ const tip = Float64Array.from(SCRATCH_A);
122
+ points.set(SCRATCH_B, 0);
123
+ radii[0] = skeleton.node_read_radius(host_tip);
124
+ for (let k = 1; k <= n; k++) {
125
+ sheet.node_read_position(SCRATCH_A, 0, nodes[k0 + k]);
126
+ for (let d = 0; d < 3; d++) SCRATCH_A[d] -= tip[d];
127
+ tree_branch_turn(SCRATCH_A, turn);
128
+ tree_branch_turn(SCRATCH_A, onto);
129
+ for (let d = 0; d < 3; d++) points[k * 3 + d] = SCRATCH_B[d] + scale * SCRATCH_A[d];
130
+ radii[k] = sheet.node_read_radius(nodes[k0 + k]) * scale;
131
+ lengths[k - 1] = sheet.segment_length(edges[k0 + k - 1]) * scale;
132
+ }
133
+ tree_skeleton_extend_branch(skeleton, carrier, points, radii, lengths);
134
+ }
135
+ // its units and its girth: at the same t, as the prototype's carrier has them
136
+ const unit_count = sheet.branch_unit_count[q.first];
137
+ if (unit_count > 0) {
138
+ const offset = sheet.branch_unit_offset[q.first];
139
+ skeleton.set_branch_units(carrier, sheet.unit_start_t.subarray(offset, offset + unit_count));
140
+ }
141
+ skeleton.collect_branch_chain(carrier, SCRATCH_NODES, SCRATCH_EDGES);
142
+ const host_nodes = SCRATCH_NODES.slice(), host_edges = SCRATCH_EDGES.slice();
143
+ for (const v of host_nodes) {
144
+ skeleton.node_write_radius(v, radius_at(sheet, nodes, skeleton.node_t_norm(v)) * scale);
145
+ }
146
+ skeleton.branch_base_radius[carrier] = sheet.branch_base_radius[q.first] * scale;
147
+ skeleton.branch_instance[carrier] = instance;
148
+
149
+ // where a shoot system hanging from the carrier at `t` lands: on the tree's carrier, wherever its course leaves it
150
+ const on_carrier = (t) => {
151
+ point_on(skeleton, host_nodes, host_edges, t, SCRATCH_B);
152
+ point_on(sheet, nodes, edges, t, SCRATCH_A);
153
+ tree_branch_placement_apply(SCRATCH_A, carry);
154
+ return { turn, scale, from, to: Float64Array.of(to[0] + SCRATCH_B[0] - SCRATCH_A[0], to[1] + SCRATCH_B[1] - SCRATCH_A[1], to[2] + SCRATCH_B[2] - SCRATCH_A[2]) };
155
+ };
156
+
157
+ // the wood any LOD draws, hung on the tree's carrier where it hangs on the prototype's
158
+ const branch_of = new Int32Array(q.branch_count).fill(-1);
159
+ const placement_of = new Array(q.branch_count).fill(carry);
160
+ branch_of[0] = carrier;
161
+ const edge_of = new Map();
162
+ for (let b = q.first + 1; b < q.first + q.branch_count; b++) {
163
+ const i = b - q.first;
164
+ const pb = sheet.branch_parent[b];
165
+ const t = sheet.branch_parent_attach_t[b];
166
+ const placement = pb === q.first ? on_carrier(t) : placement_of[pb - q.first];
167
+ placement_of[i] = placement;
168
+ if (!prototypes.drawn[b]) continue;
169
+ const parent = branch_of[pb - q.first];
170
+ skeleton.collect_branch_chain(parent, SCRATCH_NODES, SCRATCH_EDGES);
171
+ const edge = shoot_locate_on_chain(skeleton, SCRATCH_NODES, SCRATCH_EDGES, t).edge;
172
+ const level = skeleton.branch_level[carrier] + sheet.branch_level[b] - sheet.branch_level[q.first];
173
+ const id = tree_skeleton_copy_branch(sheet, b, skeleton, parent, edge, t, skeleton.segment_v0(edge), level, placement, edge_of);
174
+ skeleton.branch_instance[id] = instance;
175
+ branch_of[i] = id;
176
+ }
177
+
178
+ // what it carries without the tree holding it loads the segment it hangs from
179
+ for (const carried of q.carried) {
180
+ const host = branch_of[carried.parent - q.first];
181
+ skeleton.collect_branch_chain(host, SCRATCH_NODES, SCRATCH_EDGES);
182
+ const edge = shoot_locate_on_chain(skeleton, SCRATCH_NODES, SCRATCH_EDGES, carried.t).edge;
183
+ skeleton.segment_carried_leaf_area[edge] += carried.leaf_area * scale * scale;
184
+ skeleton.segment_carried_reach[edge] = Math.max(skeleton.segment_carried_reach[edge], carried.reach * scale);
185
+ }
186
+ return { prototype: index, carrier, scale, shift, turn, branch_of, placement_of };
187
+ }
188
+
189
+ /**
190
+ * The cards of every instance on the tree at `error`: each prototype's cuts at the step of its error ladder `error` is
191
+ * (`TreeShootPrototypes.errors`, the LOD plan's own steps) less the instance's `shift`, carried as its instance carries
192
+ * them: from where they hang on the prototype to the same place on the tree, and skinned as the tree's drawn bark is
193
+ * there, or where the nearest drawn wood holds it (`tree_cluster_hang`).
194
+ *
195
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton bound to the rig `rings` were planned with
196
+ * @param {Map<number, Array<{t_norm: number, cx: number, cy: number, cz: number}>>} rings the tree's at `error`
197
+ * @param {TreeShootInstance[]} instances
198
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
199
+ * @param {number} error m, a step of the error ladder
200
+ * @returns {{clusters: import("../mesh/tree_clusters.js").TreeCluster[], cards: Array<{cluster: number}>, placement: {rep: Int32Array, frames: Float64Array}}}
201
+ */
202
+ export function tree_shoot_instance_cards(skeleton, rings, instances, prototypes, error) {
203
+ const step = ladder_step(error);
204
+ const count = tree_shoot_instance_card_count(instances, prototypes, error);
205
+ const clusters = new Array(count);
206
+ const cards = new Array(count);
207
+ const rep = new Int32Array(count);
208
+ const frames = new Float64Array(count * 12);
209
+ if (count === 0) return { clusters, cards, placement: { rep, frames } };
210
+ const joint_motion = tree_skeleton_read_joint_motion(skeleton);
211
+ const at = new Float64Array(3);
212
+ let n = 0;
213
+ for (const instance of instances) {
214
+ const k = clamp_step(prototypes, step - instance.shift);
215
+ const { clusters: cut, cards: cut_cards } = prototypes.atlas.lods[k];
216
+ const source = prototypes.atlas.representatives.placements[k];
217
+ const owners = prototypes.owners[k];
218
+ const q = prototypes.prototypes[instance.prototype];
219
+ for (let i = 0; i < cut_cards.length; i++) {
220
+ if (owners[i] !== instance.prototype) continue;
221
+ const from = cut[cut_cards[i].cluster];
222
+ // where it hangs on the tree: on the copy of its branch, or for a whole prototype where its carrier starts
223
+ let branch, t;
224
+ if (from.branch >= 0) {
225
+ branch = instance.branch_of[from.branch - q.first];
226
+ t = from.t;
227
+ skeleton.collect_branch_chain(branch, SCRATCH_NODES, SCRATCH_EDGES);
228
+ point_on(skeleton, SCRATCH_NODES, SCRATCH_EDGES, t, at);
229
+ } else {
230
+ skeleton.node_read_position(at, 0, skeleton.branch_root_vertex[instance.carrier]);
231
+ branch = skeleton.branch_parent[instance.carrier];
232
+ t = skeleton.branch_parent_attach_t[instance.carrier];
233
+ }
234
+ // skinned as the nearest drawn wood holds it
235
+ while (branch >= 0 && !rings.has(branch)) {
236
+ t = skeleton.branch_parent_attach_t[branch];
237
+ branch = skeleton.branch_parent[branch];
238
+ }
239
+ const cluster = { branch, t, root: branch < 0 ? 0 : -1, leaves: [], wood: [], position: new Float64Array(3), joints: new Uint16Array(4), weights: new Float32Array(4) };
240
+ tree_cluster_hang(skeleton, rings, joint_motion, cluster);
241
+ clusters[n] = cluster;
242
+ cards[n] = { cluster: n };
243
+ rep[n] = source.rep[i];
244
+ // its tile on the prototype's card, turned and scaled as the instance is, from where it hangs on the tree
245
+ const f = i * 12, g = n * 12;
246
+ for (let d = 0; d < 3; d++) SCRATCH_A[d] = source.frames[f + d] - from.position[d];
247
+ tree_branch_turn(SCRATCH_A, instance.turn);
248
+ for (let d = 0; d < 3; d++) frames[g + d] = at[d] + instance.scale * SCRATCH_A[d];
249
+ for (let axis = 1; axis < 4; axis++) {
250
+ for (let d = 0; d < 3; d++) SCRATCH_A[d] = source.frames[f + axis * 3 + d];
251
+ tree_branch_turn(SCRATCH_A, instance.turn);
252
+ const s = axis < 3 ? instance.scale : 1;
253
+ for (let d = 0; d < 3; d++) frames[g + axis * 3 + d] = s * SCRATCH_A[d];
254
+ }
255
+ n++;
256
+ }
257
+ }
258
+ return { clusters, cards, placement: { rep, frames } };
259
+ }
260
+
261
+ /**
262
+ * How many cards the instances draw at `error` (`tree_shoot_instance_cards`), for the LOD plan.
263
+ *
264
+ * @param {TreeShootInstance[]} instances
265
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
266
+ * @param {number} error m, a step of the error ladder
267
+ * @returns {number}
268
+ */
269
+ export function tree_shoot_instance_card_count(instances, prototypes, error) {
270
+ // prototypes without leaves draw no cards
271
+ if (prototypes.atlas === null) return 0;
272
+ const step = ladder_step(error);
273
+ let count = 0;
274
+ for (const instance of instances) {
275
+ const owners = prototypes.owners[clamp_step(prototypes, step - instance.shift)];
276
+ for (let i = 0; i < owners.length; i++) {
277
+ if (owners[i] === instance.prototype) count++;
278
+ }
279
+ }
280
+ return count;
281
+ }
282
+
283
+ /**
284
+ * Every leaf's card the instances draw, carried onto the tree as they are (for `tree_grown_side_area`): positions,
285
+ * `3` per vertex. A leaf on a carrier lands where the carrier runs on the tree.
286
+ *
287
+ * @param {import("../skeleton/TreeSkeleton.js").TreeSkeleton} skeleton the tree the instances are on
288
+ * @param {TreeShootInstance[]} instances
289
+ * @param {import("./tree_shoot_prototypes.js").TreeShootPrototypes} prototypes
290
+ * @returns {Float32Array}
291
+ */
292
+ export function tree_shoot_instance_leaves(skeleton, instances, prototypes) {
293
+ const { attachments, leaves, sheet } = prototypes;
294
+ if (leaves === null) return new Float32Array(0);
295
+ const positions = leaves.getAttribute(StandardAttributes.Position).data;
296
+ const per_leaf = positions.length / 3 / attachments.count;
297
+ const of_prototype = prototypes.prototypes.map(() => []);
298
+ for (const instance of instances) of_prototype[instance.prototype].push(instance);
299
+ let count = 0;
300
+ for (let a = 0; a < attachments.count; a++) count += of_prototype[prototypes.prototype_of[attachments.carriers[a]]].length;
301
+ const out = new Float32Array(count * per_leaf * 3);
302
+ const proto_nodes = [], proto_edges = [], host_nodes = [], host_edges = [];
303
+ let o = 0;
304
+ for (let a = 0; a < attachments.count; a++) {
305
+ const b = attachments.carriers[a];
306
+ const q = prototypes.prototypes[prototypes.prototype_of[b]];
307
+ const on_carrier = b === q.first;
308
+ if (on_carrier) sheet.collect_branch_chain(b, proto_nodes, proto_edges);
309
+ for (const instance of of_prototype[prototypes.prototype_of[b]]) {
310
+ let placement = instance.placement_of[b - q.first];
311
+ if (on_carrier) {
312
+ // where the carrier runs on the tree, at the leaf's place along it
313
+ skeleton.collect_branch_chain(instance.carrier, host_nodes, host_edges);
314
+ point_on(skeleton, host_nodes, host_edges, attachments.attach_t[a], SCRATCH_B);
315
+ point_on(sheet, proto_nodes, proto_edges, attachments.attach_t[a], SCRATCH_A);
316
+ tree_branch_placement_apply(SCRATCH_A, placement);
317
+ placement = { ...placement, to: Float64Array.of(placement.to[0] + SCRATCH_B[0] - SCRATCH_A[0], placement.to[1] + SCRATCH_B[1] - SCRATCH_A[1], placement.to[2] + SCRATCH_B[2] - SCRATCH_A[2]) };
318
+ }
319
+ for (let v = a * per_leaf; v < (a + 1) * per_leaf; v++) {
320
+ SCRATCH_V[0] = positions[v * 3];
321
+ SCRATCH_V[1] = positions[v * 3 + 1];
322
+ SCRATCH_V[2] = positions[v * 3 + 2];
323
+ tree_branch_placement_apply(SCRATCH_V, placement);
324
+ out[o++] = SCRATCH_V[0];
325
+ out[o++] = SCRATCH_V[1];
326
+ out[o++] = SCRATCH_V[2];
327
+ }
328
+ }
329
+ }
330
+ return out;
331
+ }
332
+
333
+ /**
334
+ * The step of the error ladder `error` is.
335
+ * @param {number} error
336
+ * @returns {number}
337
+ */
338
+ function ladder_step(error) {
339
+ const exact = Math.log(error / TREE_LOD_ERROR_FINEST) / Math.log(TREE_LOD_ERROR_STEP);
340
+ const k = Math.round(exact);
341
+ assert.lessThan(Math.abs(exact - k), 1e-6, 'error is a step of the ladder');
342
+ return k;
343
+ }
344
+
345
+ /**
346
+ * A step of the prototypes' cuts: theirs, or the nearest they were cut at.
347
+ * @returns {number}
348
+ */
349
+ function clamp_step(prototypes, k) {
350
+ return Math.max(0, Math.min(prototypes.errors.length - 1, k));
351
+ }
352
+
353
+ /**
354
+ * Azimuth of node `v`'s heading about the vertical, rad: of its tangent, or of its frame's radial where it stands
355
+ * upright.
356
+ * @returns {number}
357
+ */
358
+ function heading(skeleton, v) {
359
+ skeleton.node_read_tangent(SCRATCH_A, 0, v);
360
+ if (Math.hypot(SCRATCH_A[0], SCRATCH_A[2]) < 1e-3) skeleton.node_read_frame_r(SCRATCH_A, 0, v);
361
+ return Math.atan2(SCRATCH_A[0], SCRATCH_A[2]);
362
+ }
363
+
364
+ /**
365
+ * The point at `t` along the chain `nodes`, `edges` into `out` (`shoot_locate_on_chain`).
366
+ */
367
+ function point_on(skeleton, nodes, edges, t, out) {
368
+ const { edge, u } = shoot_locate_on_chain(skeleton, nodes, edges, t);
369
+ skeleton.evaluate_segment_position(out, 0, edge, u);
370
+ }
371
+
372
+ /**
373
+ * The radius of the branch whose chain is `nodes` at `t`.
374
+ * @returns {number}
375
+ */
376
+ function radius_at(skeleton, nodes, t) {
377
+ for (let i = 0; i + 1 < nodes.length; i++) {
378
+ const t0 = skeleton.node_t_norm(nodes[i]), t1 = skeleton.node_t_norm(nodes[i + 1]);
379
+ if (t <= t1) {
380
+ const u = Math.min(1, Math.max(0, (t - t0) / Math.max(1e-9, t1 - t0)));
381
+ return skeleton.node_read_radius(nodes[i]) + u * (skeleton.node_read_radius(nodes[i + 1]) - skeleton.node_read_radius(nodes[i]));
382
+ }
383
+ }
384
+ return skeleton.node_read_radius(nodes[nodes.length - 1]);
385
+ }
386
+
387
+ /**
388
+ * The least turn (row-major 3x3) taking direction `a` onto direction `b`.
389
+ * @returns {Float64Array}
390
+ */
391
+ function turn_onto(a, b) {
392
+ const la = Math.hypot(a[0], a[1], a[2]), lb = Math.hypot(b[0], b[1], b[2]);
393
+ const ax = a[0] / la, ay = a[1] / la, az = a[2] / la, bx = b[0] / lb, by = b[1] / lb, bz = b[2] / lb;
394
+ const vx = ay * bz - az * by, vy = az * bx - ax * bz, vz = ax * by - ay * bx;
395
+ const c = ax * bx + ay * by + az * bz;
396
+ if (c < -1 + 1e-9) {
397
+ // opposite: half a turn about an axis across them
398
+ const px = Math.abs(ax) < 0.9 ? 1 : 0, py = Math.abs(ax) < 0.9 ? 0 : 1;
399
+ const kx = -az * py, ky = az * px, kz = ax * py - ay * px;
400
+ const l = Math.hypot(kx, ky, kz);
401
+ const x = kx / l, y = ky / l, z = kz / l;
402
+ return Float64Array.of(2 * x * x - 1, 2 * x * y, 2 * x * z, 2 * x * y, 2 * y * y - 1, 2 * y * z, 2 * x * z, 2 * y * z, 2 * z * z - 1);
403
+ }
404
+ const k = 1 / (1 + c);
405
+ return Float64Array.of(
406
+ c + vx * vx * k, vx * vy * k - vz, vx * vz * k + vy,
407
+ vx * vy * k + vz, c + vy * vy * k, vy * vz * k - vx,
408
+ vx * vz * k - vy, vy * vz * k + vx, c + vz * vz * k
409
+ );
410
+ }