@woosh/meep-engine 3.53.0 → 3.54.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 (194) hide show
  1. package/package.json +1 -1
  2. package/src/core/math/noise/worley_noise_2d.d.ts +14 -0
  3. package/src/core/math/noise/worley_noise_2d.d.ts.map +1 -0
  4. package/src/core/math/noise/worley_noise_2d.js +74 -0
  5. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts +6 -1
  6. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.d.ts.map +1 -1
  7. package/src/engine/graphics/texture/atlas/CachingTextureAtlas.js +363 -325
  8. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.d.ts +93 -14
  9. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.d.ts.map +1 -1
  10. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.js +322 -183
  11. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.d.ts +9 -0
  12. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.d.ts.map +1 -1
  13. package/src/engine/graphics/texture/atlas/ReferencedTextureAtlas.js +110 -83
  14. package/src/engine/graphics/texture/atlas/SpriteAtlas.d.ts +42 -0
  15. package/src/engine/graphics/texture/atlas/SpriteAtlas.d.ts.map +1 -0
  16. package/src/engine/{graphics3/decal/DecalAtlas.js → graphics/texture/atlas/SpriteAtlas.js} +202 -194
  17. package/src/engine/graphics/texture/atlas/SpriteAtlasFill.d.ts +12 -0
  18. package/src/engine/graphics/texture/atlas/SpriteAtlasFill.d.ts.map +1 -0
  19. package/src/engine/graphics/texture/atlas/SpriteAtlasFill.js +30 -0
  20. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts +7 -0
  21. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  22. package/src/engine/graphics/texture/atlas/TextureAtlas.js +11 -1
  23. package/src/engine/graphics/texture/atlas/sprite_atlas_border.d.ts +52 -0
  24. package/src/engine/graphics/texture/atlas/sprite_atlas_border.d.ts.map +1 -0
  25. package/src/engine/{graphics3/decal/decal_atlas_border.js → graphics/texture/atlas/sprite_atlas_border.js} +69 -69
  26. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  27. package/src/engine/graphics3/DecalSystem.js +447 -450
  28. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +9 -22
  29. package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
  30. package/src/engine/graphics3/GPUParticleEmitterSystem.js +892 -951
  31. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  32. package/src/generation/foliage/FOLIAGE_DESIGN.md +2 -1
  33. package/src/generation/foliage/config/BarkMaterialConfig.d.ts +4 -3
  34. package/src/generation/foliage/config/BarkMaterialConfig.d.ts.map +1 -1
  35. package/src/generation/foliage/config/BarkMaterialConfig.js +6 -6
  36. package/src/generation/foliage/config/FoliageBarkType.d.ts +11 -0
  37. package/src/generation/foliage/config/FoliageBarkType.d.ts.map +1 -0
  38. package/src/generation/foliage/config/FoliageBarkType.js +16 -0
  39. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts +58 -5
  40. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts.map +1 -1
  41. package/src/generation/foliage/config/FoliageMaterialConfig.js +279 -181
  42. package/src/generation/foliage/index.d.ts +2 -1
  43. package/src/generation/foliage/index.js +44 -43
  44. package/src/generation/foliage/material/make_bark_material.d.ts.map +1 -1
  45. package/src/generation/foliage/material/make_bark_material.js +23 -95
  46. package/src/generation/foliage/material/make_foliage_material.d.ts +29 -3
  47. package/src/generation/foliage/material/make_foliage_material.d.ts.map +1 -1
  48. package/src/generation/foliage/material/make_foliage_material.js +605 -359
  49. package/src/generation/foliage/mesh/branch_collar_project.d.ts.map +1 -1
  50. package/src/generation/foliage/mesh/branch_collar_project.js +205 -203
  51. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts +15 -0
  52. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts.map +1 -1
  53. package/src/generation/foliage/mesh/foliage_collect_attachments.js +569 -502
  54. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  55. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +1049 -1047
  56. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts +2 -1
  57. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts.map +1 -1
  58. package/src/generation/foliage/mesh/tree_mesh_build_foliage.js +454 -415
  59. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  60. package/src/generation/foliage/presets/make_tree_species_preset.js +870 -837
  61. package/src/generation/foliage/skeleton/crown_envelope_evaluate.js +121 -121
  62. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts +10 -7
  63. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts.map +1 -1
  64. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js +206 -179
  65. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  66. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +1871 -1104
  67. package/src/shade/playground/foliage_wind/foliage_world.d.ts +6 -0
  68. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  69. package/src/shade/playground/foliage_wind/foliage_world.js +602 -593
  70. package/src/shade/playground/foliage_wind/index.html +260 -254
  71. package/src/shade/playground/foliage_wind/main.js +275 -263
  72. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +3 -3
  73. package/src/shade/renderer/fluid/GPUFluidCascadeStack.d.ts +1 -1
  74. package/src/shade/renderer/fluid/forcing/GPUFluidForcing.d.ts +6 -6
  75. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +1 -1
  76. package/src/shade/renderer/fluid/query/GPUFluidQueries.d.ts +1 -1
  77. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +1 -1
  78. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts +3 -3
  79. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  80. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +350 -294
  81. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts +0 -2
  82. package/src/shade/renderer/hiz/generate_downsampler_code.d.ts.map +1 -1
  83. package/src/shade/renderer/hiz/generate_downsampler_code.js +99 -100
  84. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts +15 -0
  85. package/src/shade/renderer/hiz/hzb_pick_alignment.d.ts.map +1 -0
  86. package/src/shade/renderer/hiz/hzb_pick_alignment.js +148 -0
  87. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts +28 -0
  88. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.d.ts.map +1 -0
  89. package/src/shade/renderer/hiz/hzb_plan_reduction_steps.js +58 -0
  90. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts +5 -5
  91. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  92. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +57 -67
  93. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts +3 -3
  94. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  95. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +111 -112
  96. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts +5 -0
  97. package/src/shade/renderer/hiz/shader_hzb_spd.d.ts.map +1 -0
  98. package/src/shade/renderer/hiz/shader_hzb_spd.js +160 -0
  99. package/src/shade/renderer/light/GPULightCollection.d.ts +8 -0
  100. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  101. package/src/shade/renderer/light/GPULightCollection.js +67 -0
  102. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts +7 -0
  103. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.d.ts.map +1 -0
  104. package/src/shade/renderer/light/environment/FAR_FIELD_IRRADIANCE_SH_RESOURCE.js +13 -0
  105. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts +10 -0
  106. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.d.ts.map +1 -0
  107. package/src/shade/renderer/light/environment/shader_project_far_field_irradiance_sh.js +72 -0
  108. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts +39 -0
  109. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.d.ts.map +1 -0
  110. package/src/shade/renderer/light/world_cluster/WORLD_LIGHT_CLUSTER.js +90 -0
  111. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts +12 -0
  112. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.d.ts.map +1 -0
  113. package/src/shade/renderer/light/world_cluster/chunk_world_light_cluster_lookup.js +56 -0
  114. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts +31 -0
  115. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.d.ts.map +1 -0
  116. package/src/shade/renderer/light/world_cluster/graph_build_world_light_clusters.js +196 -0
  117. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts +10 -0
  118. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.d.ts.map +1 -0
  119. package/src/shade/renderer/light/world_cluster/shader_world_cluster_assign_lights.js +163 -0
  120. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts +4 -0
  121. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.d.ts.map +1 -0
  122. package/src/shade/renderer/light/world_cluster/shader_world_cluster_cull_lights.js +137 -0
  123. package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
  124. package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
  125. package/src/shade/renderer/particles/GPUParticleSystem.js +4 -3
  126. package/src/shade/renderer/particles/graph_particles_avboit.d.ts +4 -3
  127. package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
  128. package/src/shade/renderer/particles/graph_particles_avboit.js +28 -11
  129. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts +9 -13
  130. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.d.ts.map +1 -1
  131. package/src/shade/renderer/particles/shaders/chunk_particle_lighting.js +25 -20
  132. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  133. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +21 -38
  134. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  135. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.d.ts.map +1 -1
  136. package/src/shade/renderer/shader/chunk/depth/chunk_query_depth_from_screen_space_bb.js +62 -62
  137. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts +6 -0
  138. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.d.ts.map +1 -0
  139. package/src/shade/renderer/shader/chunk/random/lowbias/chunk_hash_lowbias32_vec2u.js +19 -0
  140. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.d.ts.map +1 -1
  141. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_get_mip_resolution.js +16 -10
  142. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.d.ts.map +1 -1
  143. package/src/shade/renderer/shader/chunk/screen_space/chunk_ffx_sssr_hierarchical_raymarch.js +118 -117
  144. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts +41 -7
  145. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.d.ts.map +1 -1
  146. package/src/shade/renderer/texture/atlas/GPUTileAtlas3D.js +162 -58
  147. package/src/shade/renderer/volumetrics/GPUSceneVolumetrics.js +1 -1
  148. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +10 -12
  149. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
  150. package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +583 -606
  151. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts +24 -0
  152. package/src/shade/renderer/volumetrics/chunk_volumetrics_froxel_sample.d.ts.map +1 -0
  153. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.d.ts.map +1 -1
  154. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts +1 -1
  155. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +640 -640
  156. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts +113 -0
  157. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.d.ts.map +1 -0
  158. package/src/shade/renderer/volumetrics/irradiance_clipmap/GPUIrradianceClipmap.js +484 -0
  159. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts +50 -0
  160. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.d.ts.map +1 -0
  161. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP.js +60 -0
  162. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts +25 -0
  163. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.d.ts.map +1 -0
  164. package/src/shade/renderer/volumetrics/irradiance_clipmap/IRRADIANCE_CLIPMAP_STRUCT.js +47 -0
  165. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts +74 -0
  166. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.d.ts.map +1 -0
  167. package/src/shade/renderer/volumetrics/irradiance_clipmap/IrradianceCascadePlacement.js +173 -0
  168. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts +26 -0
  169. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.d.ts.map +1 -0
  170. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_gi_sample.js +83 -0
  171. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts +31 -0
  172. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.d.ts.map +1 -0
  173. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_local_light.js +113 -0
  174. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts +121 -0
  175. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.d.ts.map +1 -0
  176. package/src/shade/renderer/volumetrics/irradiance_clipmap/chunk_irradiance_clipmap_sample.js +356 -0
  177. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts +16 -0
  178. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.d.ts.map +1 -0
  179. package/src/shade/renderer/volumetrics/irradiance_clipmap/shader_irradiance_clipmap_build.js +191 -0
  180. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts +16 -0
  181. package/src/shade/renderer/volumetrics/shader_volumetrics_classify_froxels.d.ts.map +1 -0
  182. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts +23 -0
  183. package/src/shade/renderer/volumetrics/shader_volumetrics_lighting_regimes.d.ts.map +1 -0
  184. package/src/shade/renderer/wind/GPUSceneWind.d.ts +1 -1
  185. package/src/shade/renderer/wind/GPUSceneWind.js +1 -1
  186. package/src/engine/graphics3/decal/DecalAtlasFill.js +0 -32
  187. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_froxel_centre_ws.js +0 -49
  188. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi.js +0 -50
  189. package/src/shade/renderer/volumetrics/gi/chunk_volumetrics_gi_sample.js +0 -105
  190. package/src/shade/renderer/volumetrics/gi/graph_build_froxel_gi.js +0 -80
  191. package/src/shade/renderer/volumetrics/gi/shader_volumetrics_gi.js +0 -51
  192. package/src/shade/renderer/volumetrics/gi/volumetrics_gi_resources.js +0 -39
  193. package/src/shade/renderer/volumetrics/graph_build_froxel_irradiance.js +0 -121
  194. package/src/shade/renderer/volumetrics/shader_volumetrics_build_irradiance.js +0 -237
@@ -1,121 +1,121 @@
1
- import { clamp } from "../../../core/math/clamp.js";
2
- import { CrownEnvelopeType } from "../config/CrownEnvelopeType.js";
3
-
4
- /**
5
- * Evaluates the normalized radial crown envelope profile $S_{\text{env}}(h_{\text{norm}}) \in [0.05, 1.0]$
6
- * at normalized crown height $h_{\text{norm}} \in [0, 1]$ (0 = base of crown, 1 = apex of crown).
7
- *
8
- * Implements Weber & Penn (1995) / SpeedTree botanical crown envelope shapes.
9
- *
10
- * @param {CrownEnvelopeType|number} envelope_type
11
- * @param {number} h_norm normalized height in [0, 1]
12
- * @param {number} [prune_width_peak=0.6] normalized height of maximum crown width for asymmetric envelopes
13
- * @param {number} [power_low=1.5] lower envelope exponent
14
- * @param {number} [power_high=1.5] upper envelope exponent
15
- * @returns {number} radial envelope factor in [0.05, 1.0]
16
- */
17
- export function crown_envelope_evaluate(
18
- envelope_type,
19
- h_norm,
20
- prune_width_peak = 0.6,
21
- power_low = 1.5,
22
- power_high = 1.5
23
- ) {
24
- const h = clamp(h_norm, 0.0, 1.0);
25
- let val = 1.0;
26
-
27
- switch (envelope_type) {
28
- case CrownEnvelopeType.Conical:
29
- val = 0.2 + 0.8 * (1.0 - h);
30
- break;
31
-
32
- case CrownEnvelopeType.Spherical:
33
- val = 0.2 + 0.8 * Math.sin(Math.PI * h);
34
- break;
35
-
36
- case CrownEnvelopeType.Hemispherical:
37
- val = 0.2 + 0.8 * Math.sin(0.5 * Math.PI * (1.0 - h));
38
- break;
39
-
40
- case CrownEnvelopeType.Cylindrical:
41
- val = 1.0;
42
- break;
43
-
44
- case CrownEnvelopeType.TaperedCylindrical:
45
- val = 0.5 + 0.5 * (1.0 - h);
46
- break;
47
-
48
- case CrownEnvelopeType.Flame:
49
- if (h <= 0.7) {
50
- val = h / 0.7;
51
- } else {
52
- val = (1.0 - h) / 0.3;
53
- }
54
- val = 0.15 + 0.85 * val;
55
- break;
56
-
57
- case CrownEnvelopeType.InverseConical:
58
- val = 0.2 + 0.8 * h;
59
- break;
60
-
61
- case CrownEnvelopeType.TendFlame:
62
- if (h <= 0.7) {
63
- val = 0.5 + 0.5 * (h / 0.7);
64
- } else {
65
- val = 0.5 + 0.5 * ((1.0 - h) / 0.3);
66
- }
67
- break;
68
-
69
- case CrownEnvelopeType.Weeping: {
70
- const peak = clamp(prune_width_peak, 0.1, 0.9);
71
- if (h < peak) {
72
- const u = (peak - h) / peak;
73
- val = 1.0 - Math.pow(u, power_low);
74
- } else {
75
- const u = (h - peak) / (1.0 - peak);
76
- val = 1.0 - Math.pow(u, power_high);
77
- }
78
- val = 0.18 + 0.82 * Math.max(0.0, val);
79
- break;
80
- }
81
-
82
- default:
83
- val = 0.2 + 0.8 * Math.sin(Math.PI * h);
84
- break;
85
- }
86
-
87
- return clamp(val, 0.05, 1.0);
88
- }
89
-
90
- /**
91
- * Evaluates a signed distance approximation to the 3D crown envelope around the `+Y` trunk axis.
92
- * Negative inside the crown envelope, positive outside.
93
- *
94
- * @param {number} px
95
- * @param {number} py
96
- * @param {number} pz
97
- * @param {import("../config/CrownConfig.js").CrownConfig} crown_config
98
- * @returns {number}
99
- */
100
- export function crown_envelope_sdf(px, py, pz, crown_config) {
101
- const base_y = crown_config.base_height;
102
- const height = Math.max(0.1, crown_config.height);
103
- const max_r = Math.max(0.1, crown_config.radius);
104
-
105
- const h_norm = (py - base_y) / height;
106
- const r_horiz = Math.sqrt(px * px + pz * pz);
107
- const r_env = max_r * crown_envelope_evaluate(crown_config.envelope_type, clamp(h_norm, 0.0, 1.0));
108
-
109
- const d_radial = r_horiz - r_env;
110
- let d_vert = 0.0;
111
- if (py < base_y) {
112
- d_vert = base_y - py;
113
- } else if (py > base_y + height) {
114
- d_vert = py - (base_y + height);
115
- }
116
-
117
- if (d_vert > 0.0 && d_radial > 0.0) {
118
- return Math.sqrt(d_radial * d_radial + d_vert * d_vert);
119
- }
120
- return Math.max(d_radial, d_vert > 0.0 ? d_vert : (Math.abs(h_norm - 0.5) - 0.5) * height);
121
- }
1
+ import { clamp } from "../../../core/math/clamp.js";
2
+ import { CrownEnvelopeType } from "../config/CrownEnvelopeType.js";
3
+
4
+ /**
5
+ * Evaluates the normalized radial crown envelope profile $S_{\text{env}}(h_{\text{norm}}) \in [0.05, 1.0]$
6
+ * at normalized crown height $h_{\text{norm}} \in [0, 1]$ (0 = base of crown, 1 = apex of crown).
7
+ *
8
+ * Implements Weber & Penn (1995) / SpeedTree botanical crown envelope shapes.
9
+ *
10
+ * @param {CrownEnvelopeType|number} envelope_type
11
+ * @param {number} h_norm normalized height in [0, 1]
12
+ * @param {number} [prune_width_peak=0.6] normalized height of maximum crown width for asymmetric envelopes
13
+ * @param {number} [power_low=1.5] lower envelope exponent
14
+ * @param {number} [power_high=1.5] upper envelope exponent
15
+ * @returns {number} radial envelope factor in [0.05, 1.0]
16
+ */
17
+ export function crown_envelope_evaluate(
18
+ envelope_type,
19
+ h_norm,
20
+ prune_width_peak = 0.6,
21
+ power_low = 1.5,
22
+ power_high = 1.5
23
+ ) {
24
+ const h = clamp(h_norm, 0.0, 1.0);
25
+ let val = 1.0;
26
+
27
+ switch (envelope_type) {
28
+ case CrownEnvelopeType.Conical:
29
+ val = 0.06 + 0.94 * (1.0 - h);
30
+ break;
31
+
32
+ case CrownEnvelopeType.Spherical:
33
+ val = 0.2 + 0.8 * Math.sin(Math.PI * h);
34
+ break;
35
+
36
+ case CrownEnvelopeType.Hemispherical:
37
+ val = 0.2 + 0.8 * Math.sin(0.5 * Math.PI * (1.0 - h));
38
+ break;
39
+
40
+ case CrownEnvelopeType.Cylindrical:
41
+ val = 1.0;
42
+ break;
43
+
44
+ case CrownEnvelopeType.TaperedCylindrical:
45
+ val = 0.5 + 0.5 * (1.0 - h);
46
+ break;
47
+
48
+ case CrownEnvelopeType.Flame:
49
+ if (h <= 0.7) {
50
+ val = h / 0.7;
51
+ } else {
52
+ val = (1.0 - h) / 0.3;
53
+ }
54
+ val = 0.15 + 0.85 * val;
55
+ break;
56
+
57
+ case CrownEnvelopeType.InverseConical:
58
+ val = 0.2 + 0.8 * h;
59
+ break;
60
+
61
+ case CrownEnvelopeType.TendFlame:
62
+ if (h <= 0.7) {
63
+ val = 0.5 + 0.5 * (h / 0.7);
64
+ } else {
65
+ val = 0.5 + 0.5 * ((1.0 - h) / 0.3);
66
+ }
67
+ break;
68
+
69
+ case CrownEnvelopeType.Weeping: {
70
+ const peak = clamp(prune_width_peak, 0.1, 0.9);
71
+ if (h < peak) {
72
+ const u = (peak - h) / peak;
73
+ val = 1.0 - Math.pow(u, power_low);
74
+ } else {
75
+ const u = (h - peak) / (1.0 - peak);
76
+ val = 1.0 - Math.pow(u, power_high);
77
+ }
78
+ val = 0.18 + 0.82 * Math.max(0.0, val);
79
+ break;
80
+ }
81
+
82
+ default:
83
+ val = 0.2 + 0.8 * Math.sin(Math.PI * h);
84
+ break;
85
+ }
86
+
87
+ return clamp(val, 0.05, 1.0);
88
+ }
89
+
90
+ /**
91
+ * Evaluates a signed distance approximation to the 3D crown envelope around the `+Y` trunk axis.
92
+ * Negative inside the crown envelope, positive outside.
93
+ *
94
+ * @param {number} px
95
+ * @param {number} py
96
+ * @param {number} pz
97
+ * @param {import("../config/CrownConfig.js").CrownConfig} crown_config
98
+ * @returns {number}
99
+ */
100
+ export function crown_envelope_sdf(px, py, pz, crown_config) {
101
+ const base_y = crown_config.base_height;
102
+ const height = Math.max(0.1, crown_config.height);
103
+ const max_r = Math.max(0.1, crown_config.radius);
104
+
105
+ const h_norm = (py - base_y) / height;
106
+ const r_horiz = Math.sqrt(px * px + pz * pz);
107
+ const r_env = max_r * crown_envelope_evaluate(crown_config.envelope_type, clamp(h_norm, 0.0, 1.0));
108
+
109
+ const d_radial = r_horiz - r_env;
110
+ let d_vert = 0.0;
111
+ if (py < base_y) {
112
+ d_vert = base_y - py;
113
+ } else if (py > base_y + height) {
114
+ d_vert = py - (base_y + height);
115
+ }
116
+
117
+ if (d_vert > 0.0 && d_radial > 0.0) {
118
+ return Math.sqrt(d_radial * d_radial + d_vert * d_vert);
119
+ }
120
+ return Math.max(d_radial, d_vert > 0.0 ? d_vert : (Math.abs(h_norm - 0.5) - 0.5) * height);
121
+ }
@@ -1,14 +1,17 @@
1
1
  /**
2
- * Computes and blends botanical Pipe Model Theory (Shinozaki et al. 1964; Leonardo da Vinci / Murray's law)
3
- * cross-sectional radii $R_p^\alpha = \sum R_i^\alpha$ bottom-up across `skeleton.graph`,
4
- * blending with the parametric `radius_profile` curves according to `config.crown.pipe_model_weight`.
2
+ * Enforces Da Vinci's pipe-model cross-sectional area conservation across a `TreeSkeleton`
3
+ * in a bottom-up post-order pass:
5
4
  *
6
- * Also guarantees monotonic non-increasing radii along each branch from base to tip and updates
7
- * each node's {@link Transform64} scale and `skeleton.branch_base_radius`.
5
+ * $$r_{\text{parent}}^\alpha = \sum_{k} r_{\text{child}, k}^\alpha$$
6
+ *
7
+ * Blended with each node's initial parametric taper radius via `pipe_model_weight`, while
8
+ * preserving boundary conditions at both the branch base ($t = 0$) and terminal shoot apex ($t = 1$)
9
+ * so neither trunk nor branch tips inflate into blunt stubs.
8
10
  *
9
11
  * @param {import("./TreeSkeleton.js").TreeSkeleton} skeleton
10
- * @param {TreeSpeciesConfig|Object} [config]
12
+ * @param {TreeSpeciesConfig} [config]
13
+ * @returns {import("./TreeSkeleton.js").TreeSkeleton}
11
14
  */
12
- export function tree_skeleton_compute_pipe_radii(skeleton: import("./TreeSkeleton.js").TreeSkeleton, config?: TreeSpeciesConfig | any): void;
15
+ export function tree_skeleton_compute_pipe_radii(skeleton: import("./TreeSkeleton.js").TreeSkeleton, config?: TreeSpeciesConfig): import("./TreeSkeleton.js").TreeSkeleton;
13
16
  import { TreeSpeciesConfig } from "../config/TreeSpeciesConfig.js";
14
17
  //# sourceMappingURL=tree_skeleton_compute_pipe_radii.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tree_skeleton_compute_pipe_radii.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,2DAHW,OAAO,mBAAmB,EAAE,YAAY,WACxC,iBAAiB,MAAO,QAqKlC;kCAhLiC,gCAAgC"}
1
+ {"version":3,"file":"tree_skeleton_compute_pipe_radii.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,2DAJW,OAAO,mBAAmB,EAAE,YAAY,WACxC,iBAAiB,GACf,OAAO,mBAAmB,EAAE,YAAY,CA6LpD;kCA3MiC,gCAAgC"}