@woosh/meep-engine 3.60.4 → 3.60.5

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 (379) hide show
  1. package/CHANGELOG.md +2602 -0
  2. package/CONTRIBUTING.md +7 -0
  3. package/MIGRATION_2_TO_3.md +136 -0
  4. package/SECURITY.md +4 -0
  5. package/editor/EditorCameraNavigation.d.ts +2 -1
  6. package/editor/EditorCameraNavigation.d.ts.map +1 -1
  7. package/editor/EditorCameraNavigation.js +51 -57
  8. package/package.json +6 -2
  9. package/src/engine/EngineHarness.d.ts +3 -9
  10. package/src/engine/EngineHarness.d.ts.map +1 -1
  11. package/src/engine/EngineHarness.js +6 -8
  12. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts +9 -6
  13. package/src/engine/graphics/camera/makeOrbitalCameraController.d.ts.map +1 -1
  14. package/src/engine/graphics/camera/makeOrbitalCameraController.js +44 -71
  15. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts +64 -0
  16. package/src/engine/graphics/camera/orbital/MomentumAxis.d.ts.map +1 -0
  17. package/src/engine/graphics/camera/orbital/MomentumAxis.js +187 -0
  18. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts +86 -0
  19. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.d.ts.map +1 -0
  20. package/src/engine/graphics/camera/orbital/OrbitalCameraRig.js +319 -0
  21. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts +34 -10
  22. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.d.ts.map +1 -1
  23. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +116 -30
  24. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts +1 -7
  25. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.d.ts.map +1 -1
  26. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +1 -37
  27. package/src/engine/graphics/ecs/water/Water.d.ts +8 -0
  28. package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
  29. package/src/engine/graphics/ecs/water/Water.js +8 -0
  30. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  31. package/src/engine/graphics3/WaterSystem.js +731 -734
  32. package/src/engine/graphics3/decal/DecalTileShader.d.ts +61 -0
  33. package/src/engine/graphics3/decal/DecalTileShader.d.ts.map +1 -0
  34. package/src/engine/graphics3/decal/DecalTileShader.js +138 -0
  35. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts +10 -4
  36. package/src/engine/graphics3/decal/GPUDecalRenderer.d.ts.map +1 -1
  37. package/src/engine/graphics3/decal/GPUDecalRenderer.js +149 -44
  38. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts +25 -0
  39. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.d.ts.map +1 -0
  40. package/src/engine/graphics3/decal/chunk_decal_tile_vertex.js +55 -0
  41. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts +22 -0
  42. package/src/engine/graphics3/decal/graph_gather_decal_tiles.d.ts.map +1 -0
  43. package/src/engine/graphics3/decal/graph_gather_decal_tiles.js +70 -0
  44. package/src/engine/graphics3/decal/shader_decal_composite.d.ts +7 -5
  45. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  46. package/src/engine/graphics3/decal/shader_decal_composite.js +48 -44
  47. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts +12 -0
  48. package/src/engine/graphics3/decal/shader_decal_tile_copy.d.ts.map +1 -0
  49. package/src/engine/graphics3/decal/shader_decal_tile_copy.js +78 -0
  50. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts +11 -0
  51. package/src/engine/graphics3/decal/shader_gather_decal_tiles.d.ts.map +1 -0
  52. package/src/engine/graphics3/decal/shader_gather_decal_tiles.js +80 -0
  53. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts +13 -0
  54. package/src/engine/input/devices/mouse/MouseEventButtons.d.ts.map +1 -0
  55. package/src/engine/input/devices/mouse/MouseEventButtons.js +23 -0
  56. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts +4 -0
  57. package/src/engine/input/ecs/controllers/KeyboardCameraController.d.ts.map +1 -1
  58. package/src/engine/input/ecs/controllers/KeyboardCameraController.js +9 -45
  59. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  60. package/src/shade/playground/water_refraction/README.md +5 -6
  61. package/src/shade/playground/water_refraction/index.html +1 -1
  62. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  63. package/src/shade/renderer/Renderer.js +7 -5
  64. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts +40 -80
  65. package/src/shade/renderer/camera/orbital/OrbitalCameraController.d.ts.map +1 -1
  66. package/src/shade/renderer/camera/orbital/OrbitalCameraController.js +197 -147
  67. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  68. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  69. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  70. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  71. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  72. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts +2 -2
  73. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +2 -2
  74. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts +2 -1
  75. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.d.ts.map +1 -1
  76. package/src/shade/renderer/geometry/sdf/cards/GPUMeshCardSets.js +18 -1
  77. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts +31 -0
  78. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.d.ts.map +1 -0
  79. package/src/shade/renderer/geometry/virtual/proxy/vgeo_to_proxy_mesh.js +343 -0
  80. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts +17 -0
  81. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.d.ts.map +1 -0
  82. package/src/shade/renderer/geometry/virtual/runtime/vgeo_meshlet_metadata_write.js +29 -0
  83. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_meshlet_batch.js +7 -13
  85. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.d.ts.map +1 -1
  86. package/src/shade/renderer/global_illumination/probe_clipmap/GPUProbeClipmapGI.js +1 -8
  87. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts +5 -5
  88. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.d.ts.map +1 -1
  89. package/src/shade/renderer/global_illumination/probe_clipmap/ProbeClipmapSceneHolds.js +10 -10
  90. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts +1 -4
  91. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.d.ts.map +1 -1
  92. package/src/shade/renderer/global_illumination/probe_clipmap/probe/GPUProbeClipmap.js +1 -10
  93. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts +5 -15
  94. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/probe_clipmap/probe/chunk_probe_clipmap_hit_surface.js +6 -34
  96. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +1 -7
  98. package/src/shade/renderer/hiz/HZBFootprint.d.ts +14 -0
  99. package/src/shade/renderer/hiz/HZBFootprint.d.ts.map +1 -0
  100. package/src/shade/renderer/hiz/HZBFootprint.js +16 -0
  101. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts +10 -0
  102. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.d.ts.map +1 -0
  103. package/src/shade/renderer/hiz/HZB_FOOTPRINT_X.js +11 -0
  104. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts +10 -0
  105. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.d.ts.map +1 -0
  106. package/src/shade/renderer/hiz/HZB_FOOTPRINT_Y.js +11 -0
  107. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +0 -7
  108. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  109. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +405 -350
  110. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts +12 -0
  111. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.d.ts.map +1 -0
  112. package/src/shade/renderer/hiz/chunk_hzb_footprint_x.js +27 -0
  113. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts +12 -0
  114. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.d.ts.map +1 -0
  115. package/src/shade/renderer/hiz/chunk_hzb_footprint_y.js +27 -0
  116. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts +14 -0
  117. package/src/shade/renderer/hiz/hzb_footprint_texels.d.ts.map +1 -0
  118. package/src/shade/renderer/hiz/hzb_footprint_texels.js +34 -0
  119. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +0 -5
  120. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  121. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +37 -57
  122. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts +11 -0
  123. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0.d.ts.map +1 -0
  124. package/src/shade/renderer/hiz/{shader_hzb_reduce_mip0_clip.js → shader_hzb_reduce_mip0.js} +120 -111
  125. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  126. package/src/shade/renderer/material/GPUMaterialManager.d.ts +7 -0
  127. package/src/shade/renderer/material/GPUMaterialManager.d.ts.map +1 -1
  128. package/src/shade/renderer/material/GPUMaterialManager.js +11 -0
  129. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +12 -12
  130. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  131. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +17 -118
  132. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  133. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +7 -2
  134. package/src/shade/renderer/water/GPUWaterRenderer.d.ts +0 -6
  135. package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
  136. package/src/shade/renderer/water/GPUWaterRenderer.js +12 -17
  137. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts +35 -0
  138. package/src/shade/renderer/water/medium/graph_water_meshlets.d.ts.map +1 -0
  139. package/src/shade/renderer/water/medium/graph_water_meshlets.js +89 -0
  140. package/src/shade/renderer/water/query/GPUWaterQueries.d.ts +1 -1
  141. package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
  142. package/src/shade/renderer/water/shader_water.js +22 -13
  143. package/src/shade/renderer/water/shader_water_avboit.d.ts.map +1 -1
  144. package/src/shade/renderer/water/shader_water_avboit.js +7 -7
  145. package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +1 -1
  146. package/src/shade/renderer/water/surface/graph_water_tessellation.js +1 -1
  147. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +9 -1
  148. package/editor/REWORK_PLAN_2026_08.md +0 -692
  149. package/src/CODEC_LAYOUT_VERIFICATION.md +0 -419
  150. package/src/CORRECTNESS_HUNT_2026_07_24.md +0 -142
  151. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +0 -738
  152. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +0 -79
  153. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +0 -93
  154. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +0 -80
  155. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +0 -164
  156. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +0 -69
  157. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +0 -110
  158. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +0 -129
  159. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +0 -72
  160. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +0 -74
  161. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +0 -169
  162. package/src/DUPLICATION_AUDIT_2026_08_07.md +0 -254
  163. package/src/DUPLICATION_AUDIT_REMEDIATION.md +0 -250
  164. package/src/DUPLICATION_REVIEW_2026_10_24.md +0 -1072
  165. package/src/REVIEW_2026_08_06/adv-core.md +0 -511
  166. package/src/REVIEW_2026_08_06/adv-gfx.md +0 -480
  167. package/src/REVIEW_2026_08_06/adv-view.md +0 -446
  168. package/src/REVIEW_2026_08_06/api-core.md +0 -296
  169. package/src/REVIEW_2026_08_06/api-engine.md +0 -195
  170. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +0 -507
  171. package/src/REVIEW_2026_08_06/core-binary.md +0 -348
  172. package/src/REVIEW_2026_08_06/core-collection.md +0 -376
  173. package/src/REVIEW_2026_08_06/core-math.md +0 -221
  174. package/src/REVIEW_2026_08_06/core-process.md +0 -266
  175. package/src/REVIEW_2026_08_06/core-science.md +0 -223
  176. package/src/REVIEW_2026_08_06/engine-ai-nav.md +0 -279
  177. package/src/REVIEW_2026_08_06/engine-animation.md +0 -167
  178. package/src/REVIEW_2026_08_06/engine-asset.md +0 -166
  179. package/src/REVIEW_2026_08_06/engine-ecs.md +0 -920
  180. package/src/REVIEW_2026_08_06/engine-input.md +0 -197
  181. package/src/REVIEW_2026_08_06/engine-misc.md +0 -248
  182. package/src/REVIEW_2026_08_06/engine-terrain.md +0 -52
  183. package/src/REVIEW_2026_08_06/generation.md +0 -176
  184. package/src/REVIEW_2026_08_06/geom-2d.md +0 -434
  185. package/src/REVIEW_2026_08_06/geom-3d.md +0 -117
  186. package/src/REVIEW_2026_08_06/gfx-gi.md +0 -143
  187. package/src/REVIEW_2026_08_06/gfx-render.md +0 -740
  188. package/src/REVIEW_2026_08_06/gfx-texture.md +0 -690
  189. package/src/REVIEW_2026_08_06/prior-criticals.md +0 -49
  190. package/src/REVIEW_2026_08_06/prior-highs.md +0 -138
  191. package/src/REVIEW_2026_08_06/test-gaps.md +0 -364
  192. package/src/REVIEW_2026_08_06/view.md +0 -667
  193. package/src/REVIEW_2026_08_06.md +0 -610
  194. package/src/core/binary/lz4/LZ4_HIGH_COMPRESSION_PLAN_2026_09_14.md +0 -542
  195. package/src/core/bvh2/bvh3/NOTES.md +0 -2
  196. package/src/core/bvh8/NOTES.md +0 -63
  197. package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +0 -243
  198. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +0 -417
  199. package/src/core/color/COLOR_REVIEW_2026_08_28.md +0 -779
  200. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +0 -433
  201. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +0 -486
  202. package/src/core/geom/3d/atlas/BFF_PLAN.md +0 -174
  203. package/src/core/geom/3d/atlas/REVIEW_02.md +0 -392
  204. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +0 -146
  205. package/src/core/geom/3d/gjk/NOTES.md +0 -8
  206. package/src/core/geom/3d/topology/TOPO_MESH_RETIREMENT_PLAN.md +0 -135
  207. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +0 -381
  208. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +0 -684
  209. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +0 -554
  210. package/src/core/model/reactive/evaluation/PREDICATE_APPLICABILITY_PROPOSAL.md +0 -446
  211. package/src/engine/REVIEW_2026_07_03.md +0 -211
  212. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +0 -815
  213. package/src/engine/control/first-person/DESIGN.md +0 -658
  214. package/src/engine/control/first-person/DESIGN_COLLISION.md +0 -382
  215. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +0 -563
  216. package/src/engine/control/first-person/TODO.md +0 -160
  217. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +0 -531
  218. package/src/engine/ecs/HIERARCHY_REVIEW.md +0 -717
  219. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +0 -262
  220. package/src/engine/ecs/ik/PLAN.md +0 -179
  221. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +0 -272
  222. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +0 -199
  223. package/src/engine/ecs/transform/TRANSFORM64_MIGRATION_PLAN_2026_09_04.md +0 -521
  224. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +0 -463
  225. package/src/engine/graphics/ecs/camera/pp/NOTES.md +0 -48
  226. package/src/engine/graphics/render/frame_graph/CORRECTNESS_FIXES_2026_09_04.md +0 -659
  227. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +0 -235
  228. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +0 -490
  229. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +0 -466
  230. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +0 -717
  231. package/src/engine/input/ecs/ism/ISM_DESIGN.md +0 -1523
  232. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +0 -627
  233. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +0 -661
  234. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +0 -229
  235. package/src/engine/network/CONGESTION_CONTROL.md +0 -87
  236. package/src/engine/network/MESSAGE_TRANSPORT.md +0 -364
  237. package/src/engine/network/SMOOTHNESS_DESIGN.md +0 -400
  238. package/src/engine/physics/cloth/MEASUREMENTS.md +0 -5304
  239. package/src/engine/physics/cloth/PLAN.md +0 -3056
  240. package/src/engine/physics/fluid/GPU_FLUID_CASCADES_PROPOSAL_2026_10_16.md +0 -1382
  241. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +0 -243
  242. package/src/engine/physics/fluid/solver/NOTES.md +0 -46
  243. package/src/engine/sound/SOUND_EMITTER_RETIREMENT_PLAN.md +0 -536
  244. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +0 -432
  245. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +0 -250
  246. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +0 -322
  247. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +0 -261
  248. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +0 -121
  249. package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +0 -999
  250. package/src/format/image/avif/DECISIONS.md +0 -545
  251. package/src/format/image/jpeg/NOTES.md +0 -3
  252. package/src/format/scene/gltf/MESHOPT_COMPRESSION_PLAN.md +0 -814
  253. package/src/generation/COORDINATES.md +0 -54
  254. package/src/generation/REVIEW_01_ACTION_PLAN.md +0 -628
  255. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +0 -220
  256. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +0 -172
  257. package/src/generation/foliage/CROWN_FULLNESS_BRIEF_2026_10_26.md +0 -86
  258. package/src/generation/foliage/FOLIAGE_DESIGN.md +0 -547
  259. package/src/generation/foliage/FOLIAGE_PLAN.md +0 -198
  260. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +0 -158
  261. package/src/generation/foliage/LOD_REWORK_BRIEF_2026_10_27.md +0 -521
  262. package/src/generation/foliage/REAL_TIME_TREES_BRIEF_2026_10_27.md +0 -86
  263. package/src/generation/foliage/SELF_ORGANIZING_FRAMEWORK_BRIEF_2026_10_26.md +0 -347
  264. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +0 -248
  265. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +0 -694
  266. package/src/generation/foliage/TWO_FRONT_ENDS_BRIEF_2026_10_28.md +0 -552
  267. package/src/shade/RENDERER_CONTRACT.md +0 -697
  268. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +0 -263
  269. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +0 -569
  270. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +0 -755
  271. package/src/shade/device/mock/EXTENSION_PROPOSAL_2026_08_22.md +0 -458
  272. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +0 -255
  273. package/src/shade/device/mock/REVIEW_2026_08_22.md +0 -527
  274. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +0 -894
  275. package/src/shade/device/timing/profile/SGPT_FORMAT.md +0 -345
  276. package/src/shade/renderer/NOTES.md +0 -78
  277. package/src/shade/renderer/PLAN.md +0 -8
  278. package/src/shade/renderer/animation/ADDITIVE_BLENDING_PLAN.md +0 -145
  279. package/src/shade/renderer/animation/SKINNING_FRAME_PLAN.md +0 -357
  280. package/src/shade/renderer/atmosphere/NOTES.md +0 -6
  281. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts +0 -76
  282. package/src/shade/renderer/camera/orbital/MomentumAxis.d.ts.map +0 -1
  283. package/src/shade/renderer/camera/orbital/MomentumAxis.js +0 -164
  284. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts +0 -45
  285. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.d.ts.map +0 -1
  286. package/src/shade/renderer/camera/orbital/OrbitalCameraConfig.js +0 -66
  287. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +0 -98
  288. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +0 -1
  289. package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +0 -184
  290. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +0 -175
  291. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +0 -1
  292. package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +0 -411
  293. package/src/shade/renderer/camera/orbital/README.md +0 -81
  294. package/src/shade/renderer/camera/orbital/index.d.ts +0 -6
  295. package/src/shade/renderer/camera/orbital/index.d.ts.map +0 -1
  296. package/src/shade/renderer/camera/orbital/index.js +0 -9
  297. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +0 -964
  298. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +0 -361
  299. package/src/shade/renderer/geometry/bvh/BLAS_REFIT_BATCH_PLAN.md +0 -619
  300. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +0 -674
  301. package/src/shade/renderer/geometry/sdf/NOTES.md +0 -6
  302. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +0 -540
  303. package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +0 -305
  304. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +0 -913
  305. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +0 -787
  306. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +0 -481
  307. package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +0 -301
  308. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +0 -448
  309. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +0 -385
  310. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +0 -656
  311. package/src/shade/renderer/geometry/virtual/runtime/REVIEW_LEDGER.md +0 -308
  312. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +0 -657
  313. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN_2026_09_14.md +0 -551
  314. package/src/shade/renderer/geometry/virtual/runtime/SHADOW_PLAN_2026_09_28.md +0 -529
  315. package/src/shade/renderer/global_illumination/lpv/NOTES.md +0 -3
  316. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +0 -4306
  317. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_RAYS_VARIABLE_AND_SORTED_SCOPE_2026_10_30.md +0 -410
  318. package/src/shade/renderer/global_illumination/sharc/NOTES.md +0 -8
  319. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +0 -1369
  320. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +0 -202
  321. package/src/shade/renderer/gpu_primitive/indirect/NOTES.md +0 -94
  322. package/src/shade/renderer/hiz/NOTES.md +0 -3
  323. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +0 -8
  324. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +0 -1
  325. package/src/shade/renderer/light/cluster/NOTES.md +0 -11
  326. package/src/shade/renderer/light/cluster/PROPOSAL_ALGORITHM_2026_10_16.md +0 -524
  327. package/src/shade/renderer/light/cluster/PROPOSAL_HIERARCHICAL_2026_10_16.md +0 -1101
  328. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts +0 -24
  329. package/src/shade/renderer/material/resident/shader_resident_texture_means.d.ts.map +0 -1
  330. package/src/shade/renderer/material/resident/shader_resident_texture_means.js +0 -120
  331. package/src/shade/renderer/particles/DESIGN.md +0 -1011
  332. package/src/shade/renderer/particles/EMITTER_GLOBAL_STATE_PLAN_2026_10_29.md +0 -280
  333. package/src/shade/renderer/particles/ORIENTATION_PLAN_2026_10_15.md +0 -453
  334. package/src/shade/renderer/path_tracer/PATH_TRACED_MEDIA_PLAN_2026_10_02.md +0 -520
  335. package/src/shade/renderer/postprocess/bloom/NOTES.md +0 -6
  336. package/src/shade/renderer/postprocess/fsr/NOTES.md +0 -4
  337. package/src/shade/renderer/postprocess/gtao/NOTES.md +0 -6
  338. package/src/shade/renderer/postprocess/nss/NOTES.md +0 -332
  339. package/src/shade/renderer/postprocess/perspective/NOTES.md +0 -3
  340. package/src/shade/renderer/postprocess/sscs/NOTES.md +0 -5
  341. package/src/shade/renderer/postprocess/ssr/NOTES.md +0 -14
  342. package/src/shade/renderer/postprocess/ssr/REPROJECTION_PROPOSAL.md +0 -286
  343. package/src/shade/renderer/postprocess/ssr/prefilter/NOTES.md +0 -39
  344. package/src/shade/renderer/postprocess/taa/NOTES.md +0 -11
  345. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +0 -78
  346. package/src/shade/renderer/postprocess/vrs/NOTES.md +0 -4
  347. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +0 -1218
  348. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +0 -600
  349. package/src/shade/renderer/restir/reservoir/NOTES.md +0 -6
  350. package/src/shade/renderer/shader/chunk/atmosphere/NOTES.md +0 -6
  351. package/src/shade/renderer/shader/chunk/brdf/FRESNEL_BRIEF_2026_10_16.md +0 -391
  352. package/src/shade/renderer/shader/chunk/color/tonemap/ACES_TONE_MAPPING_BRIEF_2026_10_17.md +0 -153
  353. package/src/shade/renderer/shader/chunk/color/tonemap/HDR_TONE_MAPPING_FORMS_BRIEF_2026_10_16.md +0 -322
  354. package/src/shade/renderer/shader/chunk/color/tonemap/SDR_TONE_MAPPING_BRIEF_2026_10_16.md +0 -247
  355. package/src/shade/renderer/shader/chunk/fsr/NOTES.md +0 -3
  356. package/src/shade/renderer/shader/chunk/fsr/spd/NOTES.md +0 -4
  357. package/src/shade/renderer/shader/chunk/geometry/ray/NOTES.md +0 -4
  358. package/src/shade/renderer/shader/chunk/material/MULTISCATTER.md +0 -159
  359. package/src/shade/renderer/shader/chunk/mboit/NOTES.md +0 -38
  360. package/src/shade/renderer/shader/chunk/spherical_harmonics/l1i/NOTES.md +0 -3
  361. package/src/shade/renderer/shader/chunk/spherical_harmonics/sampling/NOTES.md +0 -8
  362. package/src/shade/renderer/shader/compiler/SHADER_SWITCH_PROPOSAL_2026_10_16.md +0 -927
  363. package/src/shade/renderer/shadow/contact/FINDINGS.md +0 -413
  364. package/src/shade/renderer/shadow/map/csm/NOTES.md +0 -5
  365. package/src/shade/renderer/shadow/ray/NOTES.md +0 -31
  366. package/src/shade/renderer/shadow/sdf/NOTES.md +0 -9
  367. package/src/shade/renderer/shadow/sdf/brixelizer/NOTES.md +0 -5
  368. package/src/shade/renderer/shadow/sdf/cascade/NOTES.md +0 -9
  369. package/src/shade/renderer/shadow/vsm/NOTES.md +0 -12
  370. package/src/shade/renderer/shadow/vsm/PLAN.md +0 -442
  371. package/src/shade/renderer/shadow/vsm/REVIEW_LEDGER.md +0 -43
  372. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +0 -2444
  373. package/src/shade/renderer/texture/mipmaps/NOTES.md +0 -3
  374. package/src/shade/renderer/volumetrics/NOTES.md +0 -1329
  375. package/src/shade/renderer/volumetrics/VOLUMETRIC_NOISE_PLAN_2026_10_15.md +0 -336
  376. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +0 -23
  377. package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +0 -1
  378. package/src/shade/renderer/water/medium/GPUWaterBodies.js +0 -75
  379. package/src/shade/wgsl/NOTES.md +0 -4
@@ -1,198 +0,0 @@
1
- # Meep Procedural Foliage & Tree Generation System — Implementation Plan
2
-
3
- This implementation plan translates `FOLIAGE_DESIGN.md` (including all §9 adversarial review resolutions) into concrete, verifiable phases with exact file paths, function signatures, invariants, and co-located Vitest unit test suites.
4
-
5
- ---
6
-
7
- ## Phase 1: Core Engine Primitives Leveraged (`Graph`, `Transform64`, `Attribute`)
8
-
9
- The foliage system directly composes Meep's existing primitives without modifying `BinaryTopology`:
10
- 1. **`Graph` & `Edge` (`src/core/graph/v2/Graph.js`, `src/core/graph/Edge.js`)**: Directed skeletal graph (`EdgeDirectionType.Forward`).
11
- 2. **`Transform64` & `t64_look_rotation` (`src/engine/ecs/transform/Transform64.js`, `t64_look_rotation.js`)**: Per-node and per-attachment 3D position, RMF quaternion orientation (`[R, S, T]`), and radius scale.
12
- 3. **`Attribute` (`src/shade/renderer/geometry/Attribute.js`)**: Typed-array per-node, per-segment, and per-attachment data channels.
13
-
14
- ---
15
-
16
- ## Phase 2: Species Configuration, Enums, Curves, & Botanical Presets
17
- Location: `packages/meep-engine/src/generation/foliage/config/` & `presets/`
18
-
19
- ### Files & Signatures
20
- 1. **`config/CrownEnvelopeType.js`**
21
- - Enum: `Conical = 0`, `Spherical = 1`, `Hemispherical = 2`, `Cylindrical = 3`, `TaperedCylindrical = 4`, `Flame = 5`, `InverseConical = 6`, `TendFlame = 7`, `Weeping = 8`.
22
- 2. **`config/PhyllotaxisMode.js`**
23
- - Enum: `SpiralGolden = 0`, `AlternateDistichous = 1`, `Tristichous = 2`, `Opposite = 3`, `OppositeDecussate = 4`, `Whorled = 5`.
24
- 3. **`config/FoliageCardType.js`**
25
- - Enum: `FoldedVCard = 0`, `CrossCard = 1`, `TriStarCluster = 2`, `RibbedFrond = 3`, `OctagonalCutoutHull = 4`.
26
- 4. **`config/TreePreset.js`**
27
- - Enum: `Oak = "oak"`, `Pine = "pine"`, `Birch = "birch"`, `Willow = "willow"`, `Maple = "maple"`, `Spruce = "spruce"`, `Palm = "palm"`, `Shrub = "shrub"`, `Fern = "fern"`.
28
- 5. **`config/BranchLevelConfig.js`**
29
- - Fields:
30
- - `level = 0`
31
- - `segments = 8` (Hermite segments along branch spine)
32
- - `radial_segments_max = 12` ($\ge 3$), `radial_segments_min = 4` ($\ge 3$)
33
- - `length = 8.0`, `length_variance = 0.1`
34
- - `length_profile: AnimationCurve` (scales child length along parent $t \in [0, 1]$)
35
- - `radius_ratio = 0.06` (base radius relative to length, or pipe-model tip floor)
36
- - `taper = 0.85`, `radius_profile: AnimationCurve`
37
- - `bare_length_ratio = 0.25` (bare zone at base of this branch before children spawn)
38
- - `child_count = 12` (number of lateral child nodes spawned along this branch)
39
- - `phyllotaxis_mode = PhyllotaxisMode.SpiralGolden`, `whorl_count = 3`, `azimuth_jitter = 0.15`
40
- - `insertion_angle = 0.75` (radians from parent tangent), `insertion_angle_variation = 0.2`, `insertion_angle_profile: AnimationCurve`
41
- - `curvature = 0.15` (total pitch bend in radians), `curve_back = 0.0`, `spiral_twist = 0.0`
42
- - `gravitropism = 0.1` (positive bends toward $-Y$, negative bends toward $+Y$), `phototropism = 0.15`
43
- - `gnarl_strength = 0.1`, `gnarl_frequency = 0.35`
44
- - `split_probability = 0.0`, `split_count = 2`, `split_angle = 0.4`
45
- - `flare_amplitude = 0.0`, `flare_height_ratio = 0.18`, `flare_lobes = 5`, `flare_sharpness = 4.0`
46
- - `flute_amplitude = 0.0`, `flute_frequency = 6`
47
- - `collar_weld_rings = 2`, `collar_length_ratio = 0.08`, `collar_spread_upper = 0.25`, `collar_spread_lower = 0.45`, `collar_normal_blend = 0.85`
48
- - Methods: `static from(options)`, `copy(other)`, `clone()`, `equals(other)`, `hash()`.
49
- 6. **`config/CrownConfig.js`**
50
- - Fields: `envelope_type = CrownEnvelopeType.Spherical`, `height = 10.0`, `radius = 4.5`, `base_height = 2.0`, `prune_ratio = 0.35`, `space_colonization_weight = 0.25`, `attraction_point_count = 160`, `attraction_radius = 2.5`, `kill_radius = 0.6`, `pipe_model_exponent = 2.3`, `pipe_model_weight = 0.65`, `sky_phototropism_mix = 0.6`.
51
- - Methods: `static from(options)`, `copy(other)`, `clone()`, `equals(other)`, `hash()`.
52
- 7. **`config/FoliageConfig.js`**
53
- - Fields: `enabled = true`, `card_type = FoliageCardType.FoldedVCard`, `attach_min_level = 2`, `cards_per_branch = 10`, `terminal_rosette_count = 3`, `bare_ratio = 0.2`, `phyllotaxis_mode = PhyllotaxisMode.SpiralGolden`, `whorl_count = 2`, `insertion_angle = 0.85`, `card_width = 0.85`, `card_length = 0.95`, `size_variance = 0.2`, `fold_angle = 0.28`, `arch_height = 0.08`, `camber_droop = 0.1`, `frond_segments = 5`, `phototropism = 0.6`, `gravitropism = 0.25`, `angular_jitter = 0.25`, `normal_puffiness = 0.35`, `ao_core_darkening = 0.35`, `color_variation = 0.08`.
54
- - Methods: `static from(options)`, `copy(other)`, `clone()`, `equals(other)`, `hash()`.
55
- 8. **`config/BarkMaterialConfig.js` & `config/FoliageMaterialConfig.js`**
56
- - `BarkMaterialConfig`: `resolution = 128`, `primary_color: Color`, `secondary_color: Color`, `moss_color: Color`, `moss_amount = 0.1`, `fissure_frequency = 8`, `fissure_depth = 0.65`, `lenticel_amount = 0.0` (birch horizontal marks), `roughness = 0.85`, `texel_density = 1.5`, `twist_uv = 0.0`.
57
- - `FoliageMaterialConfig`: `resolution = 128`, `primary_color: Color`, `secondary_color: Color`, `autumn_tint = 0.0`, `leaf_shape = "lobed"` (`"ovate" | "lobed" | "serrated" | "palmate" | "needle" | "frond"`), `leaflets_per_cluster = 5`, `roughness = 0.58`, `vein_strength = 0.5`.
58
- 9. **`config/TreeWindConfig.js` & `config/TreeLODConfig.js`**
59
- - `TreeWindConfig`: `enabled = true`, `max_joints = 32`, `trunk_compliance = 0.012`, `branch_compliance = 0.045`, `natural_frequency = 2.8`, `damping_ratio = 0.32`, `turbulence = 0.28`, `max_bend_angle = 0.65`.
60
- - `TreeLODConfig`: `level = 0`, `radial_scale = 1.0`, `longitudinal_scale = 1.0`, `max_branch_level = 3`, `min_branch_radius = 0.0`, `foliage_keep_ratio = 1.0`, `foliage_area_compensation_exponent = 0.42`, `simplify_cards = false`.
61
- 10. **`config/TreeSpeciesConfig.js` + `config/TreeSpeciesConfig.spec.js`**
62
- - Combines `name`, `preset`, `seed`, `crown: CrownConfig`, `levels: BranchLevelConfig[]`, `foliage: FoliageConfig`, `bark_material: BarkMaterialConfig`, `foliage_material: FoliageMaterialConfig`, `wind: TreeWindConfig`, `lods: TreeLODConfig[]`.
63
- - Methods: `static from(options)`, `applyOverrides(overrides)`, `copy(other)`, `clone()`, `equals(other)`, `hash()`.
64
- 11. **`presets/make_tree_species_preset.js` + `presets/make_tree_species_preset.spec.js`**
65
- - `export function make_tree_species_preset(preset = TreePreset.Oak, overrides = {}): TreeSpeciesConfig`
66
- - Botanically tuned configurations for `Oak`, `Pine`, `Birch`, `Willow`, `Maple`, `Spruce`, `Palm`, `Shrub`, `Fern`.
67
-
68
- ---
69
-
70
- ## Phase 3: Skeleton Topology, Rotation-Minimizing Frames, & Hybrid Growth
71
- Location: `packages/meep-engine/src/generation/foliage/skeleton/`
72
-
73
- ### Files & Signatures
74
- 1. **`skeleton/TreeSkeleton.js` + `skeleton/TreeSkeleton.spec.js`**
75
- - Wraps `graph = new Graph()`, `node_transforms: Transform64[]`, 3 per-node `Attribute`s (`attr_node_branch_info`, `attr_node_spine_param`, `attr_node_joint`), and 4 per-segment `Attribute`s (`attr_segment_endpoints`, `attr_segment_hermite_m0`, `attr_segment_hermite_m1`, `attr_segment_metrics`).
76
- - Also holds flat branch metadata table (`branch_count`, `branch_root_vertex: Int32Array`, `branch_tip_vertex: Int32Array`, `branch_level: Uint8Array`, `branch_parent: Int32Array`, `branch_parent_edge: Int32Array`, `branch_length: Float32Array`, `branch_base_radius: Float32Array`, `crown_center: Float32Array(3)`, `crown_radii: Float32Array(3)`).
77
- - `add_node(px, py, pz, tx, ty, tz, rx, ry, rz, radius, branch_id, level, parent_branch_id, t_norm, arc_s, phase_hash): number`
78
- - Adds node `v` to `this.graph`, populates `this.node_transforms[v]` (`Transform64` with `setTranslation`, `t64_look_rotation`, `setScaleScalar(radius)`, `updateMatrix()`), and writes per-node `Attribute`s.
79
- - `add_segment(v0, v1, m0x, m0y, m0z, m1x, m1y, m1z, length, parent_attach_t): number`
80
- - Creates a directed `EdgeDirectionType.Forward` edge `v0 -> v1` in `this.graph` and writes per-segment `Attribute`s.
81
- - `evaluate_segment_position(out, out_offset, edge_id, u)` & `evaluate_segment_tangent(out, out_offset, edge_id, u)`:
82
- - Evaluates 3D cubic Hermite position/derivative via `spline3_hermite` / `spline3_hermite_derivative`.
83
- - `copy(other)` & `clone()`:
84
- - Deep-copies `this.graph`, `this.node_transforms`, and all `Attribute` buffers.
85
- 2. **`skeleton/crown_envelope_evaluate.js` + `skeleton/crown_envelope_evaluate.spec.js`**
86
- - `export function crown_envelope_evaluate(envelope_type, h_norm, prune_width_peak = 0.6, power_low = 1.5, power_high = 1.5): number`
87
- - Evaluates the normalized radial envelope $S_{\text{env}}(h_{\text{norm}}) \in [0.05, 1.0]$ for all 9 `CrownEnvelopeType` modes.
88
- - `export function crown_envelope_sdf(px, py, pz, crown_config): number` — signed distance to the 3D crown envelope around `+Y` trunk axis.
89
- 3. **`skeleton/spine_frame_double_reflection.js` + `skeleton/spine_frame_double_reflection.spec.js`**
90
- - `export function spine_frame_double_reflection(out, out_offset, x0, y0, z0, tx0, ty0, tz0, rx0, ry0, rz0, x1, y1, z1, tx1, ty1, tz1): void`
91
- - Computes Wang et al. (2008) fourth-order Rotation-Minimizing Frame `[Rx1, Ry1, Rz1, Sx1, Sy1, Sz1]` at `(x1, y1, z1)` with full guards for $c_1 \le 10^{-12}$ (`tube_frame_transport` fallback), $c_2 \le 10^{-12}$ (identity second reflection), and Gram-Schmidt re-orthonormalization.
92
- 4. **`skeleton/tree_skeleton_grow.js` + `skeleton/tree_skeleton_grow.spec.js`**
93
- - `export function tree_skeleton_grow(config, out = new TreeSkeleton()): TreeSkeleton`
94
- - Seeds `seededRandom(config.seed)` and computes a seed-derived 3D noise offset $\mathbf{o}_{\text{seed}}$.
95
- - Populates space colonization attraction points in the crown envelope and builds `PointHashGrid3` once with `cell_size = config.crown.attraction_radius` and an external `Uint8Array` `alive` mask.
96
- - Generates trunk ($l=0$) and recursive branch levels ($l=1 \dots L_{\max}$), handling phyllotaxis, `AnimationCurve` profiles, gravitropism (along $-Y$), phototropism (toward $+Y$ and radial crown exterior), `curl_noise_3d` gnarl, dichotomous/sympodial splitting, RMF transport, and Hermite tangent fitting.
97
- 5. **`skeleton/tree_skeleton_compute_pipe_radii.js` + `skeleton/tree_skeleton_compute_pipe_radii.spec.js`**
98
- - `export function tree_skeleton_compute_pipe_radii(skeleton, config): void`
99
- - Post-order bottom-up pass over `skeleton.topology` vertices, accumulating $R_{\text{pipe}}(v) = (R_{\text{tip}}^\alpha + \sum_{e=(v\to u)} R_{\text{pipe}}(u)^\alpha)^{1/\alpha}$ and blending with parametric taper `radius_profile.evaluate(t)` via `config.crown.pipe_model_weight`.
100
- 6. **`skeleton/tree_skeleton_assign_skin_joints.js` + `skeleton/tree_skeleton_assign_skin_joints.spec.js`**
101
- - `export function tree_skeleton_assign_skin_joints(skeleton, max_joints = 32): { joint_count: number, joint_vertex_ids: Int32Array, joint_parents: Int32Array, joint_positions: Float32Array, joint_levels: Uint8Array, joint_phases: Float32Array }`
102
- - Selects up to `max_joints` structural skeleton nodes in topological pre-order (`joint_parents[j] < j`) and assigns every skeleton vertex its `[primary_joint, parent_joint]` indices in `layer_node_joint`.
103
-
104
- ---
105
-
106
- ## Phase 4: Bark & Foliage Mesh Synthesis, Collar Welding, & Canopy AO
107
- Location: `packages/meep-engine/src/generation/foliage/mesh/`
108
-
109
- ### Files & Signatures
110
- 1. **`mesh/branch_collar_project.js` + `mesh/branch_collar_project.spec.js`**
111
- - `export function branch_collar_project(out_pos, out_pos_offset, out_norm, out_norm_offset, ring_x, ring_y, ring_z, tube_nx, tube_ny, tube_nz, child_tx, child_ty, child_tz, parent_px, parent_py, parent_pz, parent_tx, parent_ty, parent_tz, parent_radius, weld_factor, normal_blend): void`
112
- - Projects lateral branch collar vertices onto the parent branch cylinder surface with bounded axial pullback ($|\tau| \le 1.25 R_p$) and interpolates vertex normals from the parent cylinder normal $\mathbf{n}_{\text{parent}}$ to $\mathbf{n}_{\text{child}}$.
113
- 2. **`mesh/branch_ring_triangulate.js` + `mesh/branch_ring_triangulate.spec.js`**
114
- - `export function branch_ring_triangulate(indices, index_cursor, ring0_start, m0, ring1_start, m1): number`
115
- - `export function branch_apex_triangulate(indices, index_cursor, ring_start, m, apex_start): number`
116
- - Enforces $m_0 \ge 3, m_1 \ge 3$, zippers unequal rings using exact integer cross-multiplication `(j0 + 1) * m1 <= (j1 + 1) * m0` with outward CCW winding, and guarantees **zero repeated vertex indices** (`i0 !== i1 && i1 !== i2 && i2 !== i0`).
117
- 3. **`mesh/tree_mesh_build_bark.js` + `mesh/tree_mesh_build_bark.spec.js`**
118
- - `export function tree_mesh_build_bark(skeleton, config, lod_config, skin_info = null, out = new Geometry()): Geometry`
119
- - Sweeps all retained branches ($l \le \text{lod\_config.max\_branch\_level}$ and $R_0 \ge \text{lod\_config.min\_branch\_radius}$) using `spline3_hermite`, `spine_frame_double_reflection`, root buttress lobes, bark flutes, lateral collar welding (for `parent_attach_t < 0.95`), terminal fork blending (for `parent_attach_t >= 0.95`), quantized seamless bark UVs (`uv0`), wind weights (`uv1`), canopy/collar AO (`color`), and 4-joint skinning attributes (`joints`, `weights`).
120
- - Calls `out.ensureBounds()` and `out.ensureTangents()`.
121
- 4. **`mesh/foliage_collect_attachments.js` + `mesh/foliage_collect_attachments.spec.js`**
122
- - `export function foliage_collect_attachments(skeleton, config): FoliageAttachmentSet`
123
- - Generates phyllotactic attachment points, heliotropic/gravitropic orthonormal bases $(\mathbf{F}, \mathbf{U}, \mathbf{W})$ with outward hemisphere alignment ($\mathbf{U} \cdot \mathbf{n}_{\text{canopy}} \ge 0$), golden-ratio decimation rank $h_i = (i \cdot \varphi^{-1}) \bmod 1$, and inherited skin joint indices/weights.
124
- 5. **`mesh/tree_mesh_build_foliage.js` + `mesh/tree_mesh_build_foliage.spec.js`**
125
- - `export function tree_mesh_build_foliage(skeleton, attachments, config, lod_config, out = new Geometry()): Geometry`
126
- - Filters attachments by $h_i < k_{\text{keep}}$, applies area compensation scaling $s_{\text{comp}} = k_{\text{keep}}^{-\eta}$, and emits the selected `FoliageCardType` (`FoldedVCard`, `CrossCard`, `TriStarCluster`, `RibbedFrond`, `OctagonalCutoutHull`) with `position`, `normal`, `uv0`, `uv1` (wind weights), `color` (AO + color jitter), and `joints`/`weights`.
127
- 6. **`mesh/tree_mesh_apply_canopy_ao.js` + `mesh/tree_mesh_apply_canopy_ao.spec.js`**
128
- - `export function tree_mesh_apply_canopy_ao(geometry, crown_center, crown_radii, options): void`
129
- - Computes analytic crown ellipsoid + sky-exposure AO into `StandardAttributes.Color` and applies hemisphere-safe normal puffing ($\mathbf{n}_{\text{vertex}} \cdot \mathbf{n}_{\text{face}} \ge 0.55$) before `geometry.ensureTangents()`.
130
-
131
- ---
132
-
133
- ## Phase 5: Procedural PBR Materials, Wind Clips, & Turn-Key Asset Pipeline
134
- Location: `packages/meep-engine/src/generation/foliage/material/`, `animation/`, `asset/`
135
-
136
- ### Files & Signatures
137
- 1. **`material/make_bark_material.js` + `material/make_bark_material.spec.js`**
138
- - `export function make_bark_material(config = new BarkMaterialConfig(), seed = 1): StandardShadeMaterial`
139
- - Synthesizes tileable `Sampler2D` $\to$ `ShadeImage` $\to$ `ShadeTexture` for bark Albedo (`ColorSpace.SRGB`), 2-channel Normal (`ColorSpace.None` / `LinearSRGB`, `TextureFilterType.LinearNormal`), and ORM (`ColorSpace.None` / `LinearSRGB`), sets `material.ambient_factors.set(1, 0)`, `TransparencyMode.Opaque`, `ShadeDrawSide.Front`.
140
- 2. **`material/make_foliage_material.js` + `material/make_foliage_material.spec.js`**
141
- - `export function make_foliage_material(config = new FoliageMaterialConfig(), seed = 1): StandardShadeMaterial`
142
- - Synthesizes botanical leaf/needle cluster Albedo + Alpha mask (dilated straight RGB into $A=0$ texels with `AlphaMode.Straight` so GPU upload premultiplies cleanly once), Normal map (vein relief), and ORM map, sets `material.ambient_factors.set(1, 0)`, `TransparencyMode.AlphaTested`, `ShadeDrawSide.Double`, `transmission_factor = 0`.
143
- 3. **`animation/build_tree_wind_rig.js` + `animation/build_tree_wind_rig.spec.js`**
144
- - `export function build_tree_wind_rig(skin_info, wind_config = new TreeWindConfig()): FoliageWindRig|null`
145
- - Generates a GPU fluid-driven `FoliageWindRig` (`name: "foliage_wind"`) whose joints (`2..J`, with joint `0` / `SceneNode` `1` anchored at the trunk base) carry physical Euler-Bernoulli cantilever `compliance`, `natural_frequency`, `damping_ratio`, `max_angle`, `turbulence`, `branch_axis`, and `flutter_phase`. At runtime, `GPUAnimationManager` dispatches `shader_foliage_wind_apply` to sample `GPUSceneWind` (`chunk_wind_field_sample`) at each bone's world position and step a 2nd-order damped oscillator into `pose_accumulator`.
146
- 4. **`asset/TreeLODAsset.js` & `asset/TreeAsset.js`**
147
- - `TreeLODAsset`: holds `level`, `bark_geometry: Geometry`, `foliage_geometry: Geometry|null`, `bark_material: StandardShadeMaterial`, `foliage_material: StandardShadeMaterial`, `wind_rig: FoliageWindRig|null`, and **lazy memoized getters** `.bark_meshlet_geometry`, `.foliage_meshlet_geometry`, `.scene_bundle`, `.prefab`.
148
- - `TreeAsset`: holds `config: TreeSpeciesConfig`, `skeleton: TreeSkeleton`, `attachments: FoliageAttachmentSet`, `skin_info`, `wind_rig: FoliageWindRig|null`, `bark_material: StandardShadeMaterial`, `foliage_material: StandardShadeMaterial`, `lods: TreeLODAsset[]`, plus convenience getters `.bark_geometry`, `.foliage_geometry`, `.bark_meshlet_geometry`, `.foliage_meshlet_geometry`, `.scene_bundle`, `.prefab` aliasing `lods[0]`.
149
- 5. **`asset/generate_tree.js` + `asset/generate_tree.spec.js`**
150
- - `export function generate_tree(options = {}): TreeAsset`
151
- - Turn-key entry point accepting zero arguments (`generate_tree()`), a `TreeSpeciesConfig`, or `{ preset, seed, crown, levels, foliage, bark_material, foliage_material, wind, lod_count, eager_meshlets }`.
152
- 6. **`asset/place_tree.js` + `asset/place_tree.spec.js`**
153
- - `export function place_tree(scene_context, dataset, options = {}): PlacedTree`
154
- - `export function unplace_tree(scene_context, dataset, placed): void`
155
- - Accepts either an existing `tree` (`TreeAsset`) / `prefab` (`Prefab`) or generation options, constructs `Transform64` from `placement` or `{ position, rotation, rotation_y, scale }`, calls `prefab_place`, registers `FoliageWindRig`s on `scene_context.animation_manager` with position-derived phase offsets, and provides `unplace_tree` for complete cleanup.
156
-
157
- ---
158
-
159
- ## Adversarial Review of the Implementation Plan
160
-
161
- Before beginning implementation, each phase of this plan was audited against the exact runtime contracts in `packages/meep-engine/src`:
162
-
163
- 1. **`StandardAttributes.SkinningJoints` TypedArray Contract**:
164
- - `geometry_obtain_attribute` always allocates a `Float32Array`, whereas `meshlet_encode_attribute` expects `StandardAttributes.SkinningJoints` (`'joints'`) to be backed by a `Uint16Array(vertex_count * 4)`.
165
- - *Plan Adjustment*: `tree_mesh_build_bark` and `tree_mesh_build_foliage` will obtain `'joints'` via a dedicated `Uint16Array` attribute helper (`Attribute.from(new Uint16Array(vertex_count * 4), 4, StandardAttributes.SkinningJoints)`) and `'weights'` via `geometry_obtain_attribute(geometry, StandardAttributes.SkinningWeights, 4, vertex_count)`.
166
- 2. **`Sampler2D.uint8(itemSize, width, height)` Parameter Order & Direct Buffer Writes**:
167
- - `Sampler2D.uint8` takes `(itemSize, width, height)` with `itemSize` first.
168
- - *Plan Adjustment*: `make_bark_material` and `make_foliage_material` will construct `Sampler2D.uint8(channels, resolution, resolution)` and write directly into `sampler.data` (`Uint8Array`) for fast zero-overhead texture synthesis.
169
- 3. **`GPUAnimationManager` Clip Registration & Unregistration Order in `place_tree` / `unplace_tree`**:
170
- - `GPUAnimationManager` methods are `register_clip(clip)`, `set_flags(clip_id, AnimationClipFlags.Playing | AnimationClipFlags.Loop)`, `set_time(clip_id, time)`, `set_playback_rate(clip_id, rate)`, `set_playback_weight(clip_id, weight)`, and `unregister_clip(clip_id)`.
171
- - `register_clip` grants `GPUStateAuthorityFlags.TransformAttachment | GPUStateAuthorityFlags.Transform64` on target entities and registers an entity event listener on `dataset`.
172
- - *Plan Adjustment*: In `unplace_tree(scene_context, dataset, placed)`, `animation_manager.unregister_clip(clip_id)` **must** be called **before** `prefab_unplace(scene_context, dataset, placed)` so target entities and their `GPUStateAuthority` components still exist in `dataset` when `unregister_clip` revokes GPU authority and removes the event listener.
173
- 4. **Root Joint Binding for Unassigned / Root Vertices**:
174
- - In `tree_skeleton_assign_skin_joints`, joint `0` (`SceneNode` index `1`) is placed at the trunk base `(0, 0, 0)`. Any vertex at the very base of the trunk (`t = 0`) binds with weight `1.0` to joint `0` (`joints = [0, 0, 0, 0]`, `weights = [1, 0, 0, 0]`), and `build_tree_wind_clip` keeps joint `0` stationary (or applies only micro-base flex) so the base of the trunk stays anchored to the ground during wind sway.
175
-
176
- ---
177
-
178
- ## Step 7: Adversarial Review of the Implementation & Resolutions
179
-
180
- Following completion of Phases 1–5, a comprehensive adversarial review of the implementation was conducted across `src/core/geom/3d/topology/struct/binary/query/` and `src/generation/foliage/`. Every identified edge case and mathematical hazard was resolved and covered with regression unit tests:
181
-
182
- 1. **Adaxial Crotch Root Selection in `branch_collar_project.js`**:
183
- - *Finding*: For the upper (adaxial/crotch) half of a tilted lateral branch ($\alpha \in (0, \pi/2)$) originating on the parent spine axis, the ring offset $\mathbf{q}$ has a negative projection onto the emerging direction $\mathbf{u}$ ($b_{\text{half}} = \mathbf{q} \cdot \mathbf{u} < 0$). Selecting `Math.abs(t_plus) < Math.abs(t_minus)` caused $b_{\text{half}} < 0$ vertices to select $t_{\text{minus}} = \frac{-b_{\text{half}} - \sqrt{\Delta}}{\|\mathbf{u}\|^2}$, which satisfies $(\mathbf{q} + t_{\text{minus}}\mathbf{u})\cdot\mathbf{u} = -\sqrt{\Delta} < 0$ (the opposite back wall of the parent trunk!).
184
- - *Resolution*: Always select the emerging ($+\mathbf{u}$) cylinder root $\tau = t_{\text{plus}} = \frac{-b_{\text{half}} + \sqrt{\Delta}}{\|\mathbf{u}\|^2}$, which algebraically guarantees $(\mathbf{q} + t_{\text{plus}}\mathbf{u})\cdot\mathbf{u} = +\sqrt{\Delta} \ge 0$ for all collar vertices regardless of the sign of $b_{\text{half}}$, and bias steep-angle radial projection into the $+\mathbf{u}$ hemisphere.
185
- 2. **Parent RMF Transport & Singularity-Free Child RMF Initialization in `tree_skeleton_grow.js` and `foliage_collect_attachments.js`**:
186
- - *Finding*: When interpolating the parent branch's Rotation-Minimizing Frame at `local_u` along `parent_e`, `spine_frame_double_reflection` was called with `SCRATCH_POS` for both start and end points (`c1 === 0`), skipping the spatial chord reflection from `p_v0` to `SCRATCH_POS`. Additionally, initializing the child branch RMF radial vector from `D_rad` when $\alpha \approx \pi/2$ caused near-collinearity with `T_c`.
187
- - *Resolution*: Pass `p_v0`'s actual position and tangent as `(x0, y0, z0, tx0, ty0, tz0)` into `spine_frame_double_reflection`, and initialize the child branch's radial vector using the exact orthonormal vector in the $(\mathbf{T}_p, \mathbf{D}_{\text{rad}})$ plane: $\mathbf{R}_c = \cos(\alpha)\mathbf{D}_{\text{rad}} - \sin(\alpha)\mathbf{T}_p$, which has unit length and zero singularity across all $\alpha \in [0, \pi]$.
188
- 3. **Dichotomous Split Frame Preservation & Interior Hermite Tangent Smoothing in `tree_skeleton_grow.js`**:
189
- - *Finding*: During a dichotomous split, rotating `next_t` for fork 0 without rotating `next_r` broke frame orthogonality, and re-writing `m0` from `vertex_read_normal(branch_vertices[0])` overwrote continuation fork `f`'s departure tangent with fork 0's tangent at the shared split vertex.
190
- - *Resolution*: Preserve the pre-split orthonormal triad `(pre_t, pre_r, pre_s)`, rotate both `T` and `R` around each fork's bend axis so every fork maintains an exact right-handed orthonormal triad, and smooth only interior vertices (`1 <= k < branch_edges.length`) so continuation forks retain their exact departure Hermite tangent `m0`.
191
- 4. **Longitudinal Hermite Spline Resampling (`longitudinal_scale`), Watertight Apex Cones (`branch_apex_triangulate`), Collar Tip Guard, & Empty Skeleton Fallback in `tree_mesh_build_bark.js`**:
192
- - *Finding*: `tree_mesh_build_bark.js` iterated over raw skeleton nodes without resampling by `lod_config.longitudinal_scale`, left branch tips uncapped, could pull short branch tips (`sample_steps <= collar_weld_rings`) back onto the parent trunk, and left the 4-vertex empty-skeleton fallback buffer zero-filled.
193
- - *Resolution*: Resample each branch's Cubic Hermite spline chain into `sample_steps = Math.max(1, Math.round(E * long_scale))` longitudinal rings using `evaluate_segment_position`, `evaluate_segment_tangent`, and `spine_frame_double_reflection`; cap all branch tips into watertight cones via `branch_apex_triangulate`; guard collar welding with `i < sample_steps && t_norm < 0.65` using exact parent Hermite evaluation at `parent_local_u`; and populate a valid non-degenerate quad when `branch_plans.length === 0`.
194
- 5. **Single-Joint Wind Clips (`max_joints: 1`), Static Trees (`wind: false`), & Foliage Texture Clamping**:
195
- - *Finding*: `build_tree_wind_clip` returned a 0-channel clip when `joint_count === 1`; boolean shorthand `{ wind: false }` / `{ foliage: false }` was ignored by `applyOverrides`; `generate_tree` with `wind.enabled === false` still attached a `Skin` to `TreeLODAsset`; and foliage `ShadeTexture`s defaulted to `Repeat` wrapping along $V \in [0, 1]$.
196
- - *Resolution*: Animate joint `0` (`SceneNode` index `1`) when `joint_count === 1`; support boolean shorthand in `TreeWindConfig.applyOverrides` and `FoliageConfig.applyOverrides`; omit `Skin` on `TreeLODAsset` when `wind.enabled === false`; bind rest-pose skins cleanly in `place_tree` when `wind: false`; and set `TextureWrapType.ClampToEdge` on foliage textures in `make_foliage_material.js`.
197
-
198
-
@@ -1,158 +0,0 @@
1
- # Leaf Architecture
2
-
3
- ## Problem
4
-
5
- The oak's cards did not look like oak leaves (Alex, 2026-10-26: "What the fuck is that?"). Two causes, both hacks:
6
-
7
- - **The leaf outline was code, not botany.** `foliage_leaf_silhouette.js` switched on a string, `"lobed"` (a ±28% sine
8
- ripple, "oak-like"), `"serrated"` (a sawtooth), `"palmate"` (a cosine), each with hand-picked constants. The oak's
9
- `"lobed"` blade was widest near its base, with shallow wavy edges: a Christmas tree.
10
- - **A whole shoot was painted flat into one texture.** The `"rosette"` arrangement drew 11 leaves from one point,
11
- fanned over ±83°, each three-quarters as wide as long. They merged into one blob with 11 tips. A `TriStarCluster`
12
- stood three of those on crossing planes, which is the star in the screenshot. Meanwhile the simulation grows the
13
- real shoots, so the tile duplicated the shoot geometry and contradicted it.
14
-
15
- Fixing the oak's outline alone would have kept both hacks.
16
-
17
- ## Principle
18
-
19
- - **A leaf is data, described as floras describe it.** Ellis et al. (2009), *Manual of Leaf Architecture*, gives the
20
- vocabulary; each preset cites its flora.
21
- - **A card is one leaf, on its shoot.** Each leaf is a card at its own node, leaving the shoot at the rule's insertion
22
- angle and turned by its phyllotaxis.
23
- - **Needles stay shoot cards.** Pine bears 1,560 needles per metre and spruce 2,450 (sourced in the presets). A card
24
- per needle is out of reach, and the needle shoot is the unit those papers measure.
25
-
26
- ## Design
27
-
28
- - **`LeafArchitecture`** (`FoliageMaterialConfig.leaf`):
29
- - blade length, length/width ratio, where it is widest;
30
- - apex and base angle and shape (`LeafApexShape`, `LeafBaseShape`; the angles measured as Ellis et al. define them,
31
- a quarter of the blade's length from the tip or the base);
32
- - lobation (`LeafLobation`), lobes, sinus depth, palmate spread and lateral lobe length;
33
- - teeth per cm, tooth depth and order;
34
- - secondary veins and their angle;
35
- - petiole length;
36
- - a compound leaf's leaflets and rachis.
37
- - **`leaf_geometry`** turns that into outline contours, veins and stems in metres:
38
- - **Envelope:** a monotone cubic Hermite (Fritsch-Carlson) through the base, the base angle's point, the widest point,
39
- the apex angle's point and the apex. The shapes set the end slopes. A rounded end is an elliptic arc; an acuminate
40
- one is shallow, so the margin is concave near the tip.
41
- - **Pinnate lobes:** the blade reaches only to the sinus floor, `1 - sinus_depth` of the outline's width. Each lateral
42
- lobe is a rounded blade of its own along its secondary vein (so it leans by the vein's angle), out to the outline.
43
- The veins leave the midvein evenly spaced.
44
- - **Palmate lobes:** a blade per primary lobe, radiating across `lobe_spread`, over a body to the sinus floors.
45
- - **Base lobes:** cordate and lobate bases are a cubic Bezier from the petiole sinus round the basal lobe, solved to
46
- reach exactly `base_lobe_depth` below the petiole.
47
- - **Teeth:** offset along the outline's normal, spaced along the untoothed margin, with a second order a third the
48
- size.
49
- - **Union:** every contour winds the same way, so the union of lobes, leaflets and petiole is filled by the nonzero
50
- rule (`polygon2_rasterize_coverage`, exact across each row, 4 samples down it).
51
- - **`foliage_tile_layout`** (one place for every consumer):
52
- - The mature leaf fills the tile within a 2% margin, attached at the bottom middle. Every tile draws at that scale,
53
- so the card's size in metres is the leaf's (`card_size`).
54
- - **Resolution:** the finest feature (a tooth, a sinus) is drawn 4 texels across. The narrowest stem is drawn 2
55
- texels across, so wherever it falls it covers a whole texel and survives the alpha test.
56
- - **Needle shoots:** a stretch of shoot as long as a needle, with the needles the shoot bears there
57
- (`leaves_per_metre`), shared among the card's planes. Each plane draws the needles in its sector round the shoot,
58
- foreshortened by their azimuth.
59
- - **`foliage_tile_raster`:**
60
- - Coverage, veins stamped near each segment, distance to the margin and to the midvein by chamfer, camber,
61
- bullation, and the petiole.
62
- - The pigment, senescence and normal code of `make_foliage_material` is unchanged. It now skips the texels the leaf
63
- leaves empty, which keep the dilated fill.
64
- - **Cards:**
65
- - **Broadleaves:** a card per leaf. A short shoot's `leaves_per_short_shoot` sit at its tip. The presets draw
66
- `CutoutHull` cards.
67
- - **Needle cards** lie along the shoot.
68
- - **Density path:** branches not grown by annual units keep it, on the layout's card size and anchor.
69
-
70
- ## Sources per species
71
-
72
- | preset | leaf | sources | estimated, not found |
73
- | :--- | :--- | :--- | :--- |
74
- | oak (*Quercus robur*) | mean blade 10.6 and 12.0 cm; L/W 1.8, 1.64; width 0.81-0.85 of max at 0.5 L, 0.47-0.50 at 0.9 L; petiole 7.4-8.0% of blade | Boratyński et al. 2008, *Silva Fennica* 42: 115-124, Table 4. Fitted: widest at 0.675, apex angle 1.2, base 0.8 rad (both widths within 0.01) | auricle size, secondary angle |
75
- | | obovate; apex broadly rounded; sinuses 1/3-7/8 to midrib; entire; 5-7 secondaries | FNA vol. 3 | |
76
- | | 5-7 lobes a side | Flora of China | |
77
- | | up to 5 pairs; auricles usually strong | BSBI Plant Crib | |
78
- | birch (*Betula pendula*) | 3-7 × 2.5-5 cm, ovate-rhombic, acuminate, cuneate, doubly serrate | FNA | apex and base angles, teeth (1.3 a cm, 1.5 mm), widest point |
79
- | | 6-8 lateral veins; petiole 2-3 cm | FoC | |
80
- | | 2 leaves a short shoot | Maillette 1982 | |
81
- | willow (*Salix babylonica*) | 90-160 × 5-20 mm, L/W 5.5-10.5, acuminate, cuneate, serrulate; petiole 7-9 mm | FNA vol. 7 | angles, teeth (5 a cm, 0.3 mm), veins |
82
- | maple (*Acer rubrum*) | 6.8 cm, 39 cm² | Wilson 1966 | lobe outline, lateral lobe length 0.85, teeth (3 a cm, 1.5 mm) |
83
- | | 3 lobes; lateral axes 73-86° apart; midlobe 46-56% of blade; petiole 60-114% of blade; 2 leaf pairs a short shoot | Critchfield 1971 | |
84
- | | doubly serrate | Gleason & Cronquist | |
85
- | | base truncate to cordate | Trees and Shrubs Online | |
86
- | shrub (*Corylus avellana*) | 5-12 × 4-12 cm, abruptly acuminate, narrowly cordate, doubly serrate, ≤ 8 vein pairs | FNA | angles, base lobe depth, teeth (0.7 a cm, 2.5 mm) |
87
- | | petiole 6-12 mm | Trees and Shrubs Online | |
88
- | | 8 cm gives the 41 cm² of a sun leaf | Catoni et al. 2015 | |
89
- | pine, spruce needles | 52 mm [Niinemets & Lukjanova 2003]; spruce's 18 mm was already chosen | | widths 1.6 and 1 mm; needle angle 0.6 rad |
90
- | palm, fern | no species named: the old frond's sizes are kept | | everything |
91
-
92
- The botanical data was gathered by a research subagent from efloras.org (FNA, FoC), BSBI, VicFlora, Go Botany, Trees
93
- and Shrubs Online, SEINet and the papers above. Its quotes and URLs are in the session's scratchpad (`leaf/`).
94
- floranorthamerica.org refused access, and HAL (Kremer et al. 2002) is behind a bot check.
95
-
96
- ## Measured
97
-
98
- *Seed 1337 unless noted; the "before" figures are from 49845ff00.*
99
-
100
- **Atlas, from the drawn tiles:**
101
-
102
- | preset | resolution | card | coverage | one leaf |
103
- | :--- | ---: | ---: | ---: | ---: |
104
- | oak | 128 | 12.7 cm | 0.208 | 33 cm² |
105
- | birch | 256 | 7.8 cm | 0.174 | 10.6 cm² |
106
- | willow | 512 | 13.9 cm | 0.073 | 14 cm² |
107
- | maple | 512 | 13.2 cm | 0.213 | 37 cm² |
108
- | shrub | 128 | 9.3 cm | 0.522 | 45 cm² |
109
- | pine | 256 | 9.8 cm (81 needles) | | |
110
- | spruce | 256 | 3.4 cm (44 needles) | | |
111
- | palm | 128 | | | |
112
- | fern | 128 | | | |
113
-
114
- Leaf areas against the sources:
115
- - maple: 37 cm² against Wilson's 39;
116
- - hazel: 45 cm² against Catoni's 41;
117
- - birch: 10.6 cm² against about 11 from FNA's sizes.
118
-
119
- **Cost:** cards, LOD0 triangles, and `generate_tree` time with the LOD0 meshes.
120
-
121
- | preset | cards | foliage tris | bark tris | generate + LOD0 |
122
- | :--- | ---: | ---: | ---: | ---: |
123
- | oak | 25,622 | 153,732 | 81,587 | 0.77 + 0.06 s |
124
- | pine | 3,554 | 21,324 | 39,817 | 0.71 + 0.03 s |
125
- | birch | 63,909 | 383,454 | 454,735 | 1.73 + 0.56 s |
126
- | willow | 113,001 | 678,006 | 410,091 | 1.81 + 0.46 s |
127
- | maple | 13,008 | 78,048 | 37,774 | 1.16 + 0.05 s |
128
- | spruce | 176,311 | 705,244 | 1,085,114 | 3.12 + 1.23 s |
129
- | shrub | 16,976 | 101,856 | 62,817 | 0.52 + 0.05 s |
130
-
131
- **Crowns,** measured with `foliage_measure_leaf_area` and `tree_crown_opacity`; "before" is 49845ff00:
132
-
133
- | preset | leaf m² (before) | crown LAI | side density | side transparency | below density | below transparency |
134
- | :--- | ---: | ---: | ---: | ---: | ---: | ---: |
135
- | oak | 89.4 (90.9) | 3.11 | 0.50 | 0.42 | 0.58 | 0.27 |
136
- | pine | 15.7 (35.0) | 0.74 | 0.34 | 0.64 | 0.35 | 0.62 |
137
- | birch | 70.4 (64.5) | 6.77 | 0.56 | 0.33 | 0.75 | 0.12 |
138
- | willow | 232.6 (136.3) | 6.43 | 0.75 | 0.18 | 0.74 | 0.19 |
139
- | maple | 50.7 (36.3) | 1.97 | 0.41 | 0.42 | 0.42 | 0.32 |
140
- | spruce | 78.4 (117.8) | 3.03 | 0.33 | 0.31 | 0.42 | 0.29 |
141
- | shrub | 62.5 (57.8) | 4.52 | 0.63 | 0.22 | 0.64 | 0.16 |
142
-
143
- - **Pine and spruce lost leaf area** because their old tiles overdrew. Every plane of a card drew all of its needles,
144
- three times over on pine, and wider than the needles are. Now each needle is drawn once at its width.
145
- - **Willow gained,** its lanceolate leaves replacing a frond drawing. Its transparency, 0.18, is near FIA's 15%.
146
-
147
- ## Open (measured, not argued)
148
-
149
- - **Card counts rose where a card used to hold several leaves:** birch 5×, willow 9×, oak 11×. Pine and spruce rose
150
- 2.4×, because a needle card now covers one needle length of shoot, not 2.4. That stretch is chosen, not sourced.
151
- - **Estimates:** the angles, tooth sizes and widest points the floras do not give are marked in each preset.
152
- - **Palm and fern** name no species, so their leaves are not sourced.
153
- - **Wind sail:**
154
- - `TreeWindConfig.elastic_modulus` is fitted to the oak, whose leaf area moved by 2% (90.9 to 89.4 m²); it was not
155
- refit.
156
- - Pine's and spruce's sails fell with their leaf area (to 0.45 and 0.67), so they will sway less. That sway is not
157
- measured.
158
- - **Transparency:** every crown but willow's is still far above FIA's 15% transparency.