@woosh/meep-engine 3.56.0 → 3.57.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 (625) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/DUPLICATION_REVIEW_2026_10_24.md +1072 -0
  4. package/src/core/binary/BitSet.js +1 -1
  5. package/src/core/binary/FLOAT16_MAX.d.ts +2 -0
  6. package/src/core/binary/FLOAT16_MAX.d.ts.map +1 -0
  7. package/src/core/binary/FLOAT16_MAX.js +1 -0
  8. package/src/core/binary/base58/base58_encode.js +2 -2
  9. package/src/core/binary/type/TypeBuilder.js +1 -1
  10. package/src/core/bvh2/bvh3/BVH.js +1 -1
  11. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
  12. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +7 -3
  13. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts.map +1 -1
  14. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +5 -1
  15. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.d.ts.map +1 -1
  16. package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +195 -246
  17. package/src/core/collection/CuckooFilter.js +1 -1
  18. package/src/core/collection/array/isArrayEqual.d.ts.map +1 -1
  19. package/src/core/collection/array/isArrayEqual.js +33 -58
  20. package/src/core/collection/array/typed/array_buffer_hash.d.ts.map +1 -1
  21. package/src/core/collection/array/typed/array_buffer_hash.js +41 -39
  22. package/src/core/collection/array/typed/float32_array_hash.js +38 -38
  23. package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -1
  24. package/src/core/collection/array/typed/uint16_array_hash.d.ts.map +1 -1
  25. package/src/core/collection/array/typed/uint16_array_hash.js +30 -29
  26. package/src/core/collection/array/typed/uint32_array_hash.d.ts +2 -1
  27. package/src/core/collection/array/typed/uint32_array_hash.d.ts.map +1 -1
  28. package/src/core/collection/array/typed/uint32_array_hash.js +21 -20
  29. package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -1
  30. package/src/core/collection/array/typed/uint8_array_hash.d.ts.map +1 -1
  31. package/src/core/collection/array/typed/uint8_array_hash.js +37 -36
  32. package/src/core/collection/array/typed/uint_array_for_count.js +2 -2
  33. package/src/core/collection/list/List.d.ts.map +1 -1
  34. package/src/core/collection/list/List.js +3 -19
  35. package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
  36. package/src/core/collection/table/RowFirstTable.js +4 -28
  37. package/src/core/debug/matchers/DescribeAs.d.ts.map +1 -1
  38. package/src/core/debug/matchers/DescribeAs.js +62 -64
  39. package/src/core/function/FunctionCompiler.js +4 -4
  40. package/src/core/function/objectsEqual.d.ts.map +1 -1
  41. package/src/core/function/objectsEqual.js +3 -2
  42. package/src/core/geom/2d/bvh/BVH2D.d.ts.map +1 -1
  43. package/src/core/geom/2d/bvh/BVH2D.js +4 -3
  44. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts +5 -2
  45. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts.map +1 -1
  46. package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.js +49 -11
  47. package/src/core/geom/2d/hash-grid/shg_query_elements_circle.d.ts.map +1 -1
  48. package/src/core/geom/2d/hash-grid/shg_query_elements_circle.js +122 -159
  49. package/src/core/geom/2d/hash-grid/shg_query_elements_line.d.ts.map +1 -1
  50. package/src/core/geom/2d/hash-grid/shg_query_elements_line.js +8 -5
  51. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts +18 -0
  52. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts.map +1 -0
  53. package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.js +97 -0
  54. package/src/core/geom/2d/r-tree/StaticR2Tree.js +2 -2
  55. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts +21 -0
  56. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts.map +1 -0
  57. package/src/core/geom/2d/triangle/tri2_rasterize_coverage.js +54 -0
  58. package/src/core/geom/3d/aabb/aabb3_build_frustum.d.ts.map +1 -1
  59. package/src/core/geom/3d/aabb/aabb3_build_frustum.js +20 -53
  60. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts +1 -1
  61. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts.map +1 -1
  62. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -42
  63. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -1
  64. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +30 -32
  65. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -1
  66. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +1 -5
  67. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -1
  68. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +1 -15
  69. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -1
  70. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +105 -116
  71. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.d.ts.map +1 -1
  72. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.js +36 -54
  73. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts +5 -10
  74. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts.map +1 -1
  75. package/src/core/geom/3d/plane/plane3_compute_intersection_objects.js +20 -82
  76. package/src/core/geom/3d/plane/plane3_slerp.d.ts.map +1 -1
  77. package/src/core/geom/3d/plane/plane3_slerp.js +87 -102
  78. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts +12 -0
  79. package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts.map +1 -1
  80. package/src/core/geom/3d/polygon/polygon3_compute_normal.js +107 -60
  81. package/src/core/geom/3d/ray/ray3_compute_closest_point.d.ts.map +1 -1
  82. package/src/core/geom/3d/ray/ray3_compute_closest_point.js +37 -43
  83. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  84. package/src/core/geom/3d/shape/ConvexHullShape3D.js +5 -16
  85. package/src/core/geom/3d/shape/MeshShape3D.js +2 -56
  86. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  87. package/src/core/geom/3d/shape/TransformedShape3D.js +10 -7
  88. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  89. package/src/core/geom/3d/shape/UnionShape3D.js +9 -3
  90. package/src/core/geom/3d/shape/json/shape_to_type.js +2 -2
  91. package/src/core/geom/3d/sphere/harmonics/SH3_COEFFICIENTS.js +17 -17
  92. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.d.ts.map +1 -1
  93. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +6 -2
  94. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -1
  95. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +3 -2
  96. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts +20 -2
  97. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts.map +1 -1
  98. package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.js +52 -37
  99. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.d.ts.map +1 -1
  100. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +40 -56
  101. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
  102. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +251 -260
  103. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -1
  104. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +104 -113
  105. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.d.ts.map +1 -1
  106. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.js +227 -238
  107. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  108. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +15 -24
  109. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
  110. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +31 -115
  111. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.d.ts.map +1 -1
  112. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +142 -150
  113. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
  114. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +151 -194
  115. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.d.ts.map +1 -1
  116. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.js +60 -85
  117. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.d.ts.map +1 -1
  118. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.js +156 -171
  119. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.d.ts.map +1 -1
  120. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +8 -44
  121. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  122. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +2 -7
  123. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -1
  124. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +3 -2
  125. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.d.ts.map +1 -1
  126. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +128 -133
  127. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts +8 -14
  128. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts.map +1 -1
  129. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +36 -82
  130. package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
  131. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +7 -144
  132. package/src/core/geom/ConicRay.d.ts.map +1 -1
  133. package/src/core/geom/ConicRay.js +230 -237
  134. package/src/core/localization/LocaleDataset.d.ts +6 -0
  135. package/src/core/localization/LocaleDataset.d.ts.map +1 -1
  136. package/src/core/localization/LocaleDataset.js +48 -37
  137. package/src/core/localization/LocalizationEngine.d.ts.map +1 -1
  138. package/src/core/localization/LocalizationEngine.js +3 -2
  139. package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
  140. package/src/core/math/lookup/ParameterLookupTable.js +3 -1
  141. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
  142. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +330 -400
  143. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -0
  144. package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
  145. package/src/core/math/spline/spline3_hermite_nearest_point.js +134 -167
  146. package/src/core/model/DebouncedObservedBoolean.d.ts +1 -2
  147. package/src/core/model/DebouncedObservedBoolean.d.ts.map +1 -1
  148. package/src/core/model/DebouncedObservedBoolean.js +1 -1
  149. package/src/core/model/node-graph/node/NodeInstance.d.ts.map +1 -1
  150. package/src/core/model/node-graph/node/NodeInstance.js +2 -7
  151. package/src/core/model/node-graph/node/parameter/NodeParameterDescription.js +1 -1
  152. package/src/core/model/object/optional_equality.d.ts +3 -3
  153. package/src/core/model/object/optional_equality.d.ts.map +1 -1
  154. package/src/core/model/object/optional_equality.js +10 -27
  155. package/src/core/model/object/write_property.js +1 -1
  156. package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +2 -2
  157. package/src/core/primitives/strings/string_compute_byte_size.d.ts +3 -3
  158. package/src/core/primitives/strings/string_compute_byte_size.d.ts.map +1 -1
  159. package/src/core/primitives/strings/string_compute_byte_size.js +8 -21
  160. package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
  161. package/src/core/process/executor/ConcurrentExecutor.js +14 -2
  162. package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts +6 -3
  163. package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts.map +1 -1
  164. package/src/engine/achievements/gateway/StorageAchievementGateway.js +31 -75
  165. package/src/engine/asset/loaders/SVGAssetLoader.d.ts.map +1 -1
  166. package/src/engine/asset/loaders/SVGAssetLoader.js +33 -31
  167. package/src/engine/control/first-person/math/criticallyDampedSpring.d.ts.map +1 -1
  168. package/src/engine/control/first-person/math/criticallyDampedSpring.js +3 -14
  169. package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
  170. package/src/engine/ecs/EntityComponentDataset.js +4 -1
  171. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts +0 -2
  172. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts.map +1 -1
  173. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.js +3 -3
  174. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +2 -2
  175. package/src/engine/graphics/sh3/path_tracer/geometry/sort_triangles_by_distance_to_point.js +1 -1
  176. package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +1 -1
  177. package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
  178. package/src/engine/graphics3/WaterSystem.js +2 -1
  179. package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -1
  180. package/src/engine/graphics3/prefab/prefab_skin_frame.js +1 -12
  181. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +1 -1
  182. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  183. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +141 -137
  184. package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
  185. package/src/engine/input/ecs/systems/InputControllerSystem.js +13 -3
  186. package/src/engine/input/ecs/systems/InputSystem.d.ts.map +1 -1
  187. package/src/engine/input/ecs/systems/InputSystem.js +2 -1
  188. package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts +1 -1
  189. package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts.map +1 -1
  190. package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +4 -1
  191. package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.d.ts.map +1 -1
  192. package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.js +3 -1
  193. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.d.ts.map +1 -1
  194. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +3 -1
  195. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.d.ts.map +1 -1
  196. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +39 -33
  197. package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts +5 -0
  198. package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts.map +1 -1
  199. package/src/engine/intelligence/behavior/util/ConditionalBehavior.js +93 -75
  200. package/src/engine/intelligence/behavior/util/RotationBehavior.d.ts.map +1 -1
  201. package/src/engine/intelligence/behavior/util/RotationBehavior.js +79 -76
  202. package/src/engine/intelligence/blackboard/BlackboardStack.d.ts +1 -0
  203. package/src/engine/intelligence/blackboard/BlackboardStack.d.ts.map +1 -1
  204. package/src/engine/intelligence/blackboard/BlackboardStack.js +159 -123
  205. package/src/engine/intelligence/mcts/StateNode.d.ts.map +1 -1
  206. package/src/engine/intelligence/mcts/StateNode.js +366 -364
  207. package/src/engine/intelligence/resource/ResourceAllocationSolver.js +1 -1
  208. package/src/engine/navigation/ecs/components/Path.d.ts.map +1 -1
  209. package/src/engine/navigation/ecs/components/Path.js +2 -1
  210. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
  211. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +5 -2
  212. package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
  213. package/src/engine/physics/body/SolverBodyState.js +2 -6
  214. package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
  215. package/src/engine/physics/ccd/linear_sweep.js +3 -16
  216. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
  217. package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +2 -16
  218. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +13 -1
  219. package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
  220. package/src/engine/physics/cloth/ecs/cloth_build_rows.js +15 -4
  221. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  222. package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
  223. package/src/engine/physics/inertia/locked_inverse_inertia.d.ts +12 -0
  224. package/src/engine/physics/inertia/locked_inverse_inertia.d.ts.map +1 -0
  225. package/src/engine/physics/inertia/locked_inverse_inertia.js +22 -0
  226. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  227. package/src/engine/physics/integration/integrate_velocity.js +3 -18
  228. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts +1 -0
  229. package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
  230. package/src/engine/physics/mls-mpm/MLS_MPM.js +5 -4
  231. package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
  232. package/src/engine/physics/narrowphase/convex_decomposition.js +7 -16
  233. package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
  234. package/src/engine/physics/vehicle/RaycastVehicle.js +15 -5
  235. package/src/engine/save/StorageBackedList.d.ts +5 -0
  236. package/src/engine/save/StorageBackedList.d.ts.map +1 -1
  237. package/src/engine/save/StorageBackedList.js +161 -144
  238. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  239. package/src/engine/simulation/Ticker.js +394 -391
  240. package/src/engine/sound/simulation/probe/AcousticProbeField.d.ts.map +1 -1
  241. package/src/engine/sound/simulation/probe/AcousticProbeField.js +6 -19
  242. package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts +15 -0
  243. package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts.map +1 -1
  244. package/src/engine/sound/simulation/probe/probe_edge_visible.js +59 -41
  245. package/src/engine/sound/simulation/probe/probe_refine_connectivity.d.ts.map +1 -1
  246. package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +164 -181
  247. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.d.ts.map +1 -1
  248. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +20 -5
  249. package/src/format/image/avif/av1/decode/Av1FrameContext.d.ts.map +1 -1
  250. package/src/format/image/avif/av1/decode/Av1FrameContext.js +3 -10
  251. package/src/format/image/avif/av1/decode/reconstruct.d.ts +20 -0
  252. package/src/format/image/avif/av1/decode/reconstruct.d.ts.map +1 -1
  253. package/src/format/image/avif/av1/decode/reconstruct.js +22 -9
  254. package/src/format/image/avif/av1/encode/choose_restoration.js +2 -18
  255. package/src/format/image/avif/av1/encode/quantise.d.ts.map +1 -1
  256. package/src/format/image/avif/av1/encode/quantise.js +1 -55
  257. package/src/format/image/avif/av1/filter/loop_restoration.d.ts +9 -0
  258. package/src/format/image/avif/av1/filter/loop_restoration.d.ts.map +1 -1
  259. package/src/format/image/avif/av1/filter/loop_restoration.js +1 -1
  260. package/src/format/texture/basis/transcode/etc1s_to_bc7.js +2 -33
  261. package/src/format/texture/basis/transcode/fit_endpoints.d.ts +11 -0
  262. package/src/format/texture/basis/transcode/fit_endpoints.d.ts.map +1 -1
  263. package/src/format/texture/basis/transcode/fit_endpoints.js +1 -1
  264. package/src/format/texture/basis/uastc/uastc_decode_block.d.ts.map +1 -1
  265. package/src/format/texture/basis/uastc/uastc_decode_block.js +2 -19
  266. package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +220 -0
  267. package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +172 -0
  268. package/src/generation/foliage/FOLIAGE_DESIGN.md +165 -15
  269. package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +158 -0
  270. package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +248 -0
  271. package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +694 -0
  272. package/src/generation/foliage/analysis/CrownOpacity.d.ts +118 -0
  273. package/src/generation/foliage/analysis/CrownOpacity.d.ts.map +1 -0
  274. package/src/generation/foliage/analysis/CrownOpacity.js +182 -0
  275. package/src/generation/foliage/analysis/crown_opacity_frames.d.ts +10 -0
  276. package/src/generation/foliage/analysis/crown_opacity_frames.d.ts.map +1 -0
  277. package/src/generation/foliage/analysis/crown_opacity_frames.js +132 -0
  278. package/src/generation/foliage/analysis/crown_opacity_measure.d.ts +51 -0
  279. package/src/generation/foliage/analysis/crown_opacity_measure.d.ts.map +1 -0
  280. package/src/generation/foliage/analysis/crown_opacity_measure.js +649 -0
  281. package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts +66 -0
  282. package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts.map +1 -0
  283. package/src/generation/foliage/analysis/foliage_measure_leaf_area.js +192 -0
  284. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts +27 -0
  285. package/src/generation/foliage/analysis/tree_crown_opacity.d.ts.map +1 -0
  286. package/src/generation/foliage/analysis/tree_crown_opacity.js +58 -0
  287. package/src/generation/foliage/animation/build_tree_wind_rig.d.ts +3 -2
  288. package/src/generation/foliage/animation/build_tree_wind_rig.d.ts.map +1 -1
  289. package/src/generation/foliage/animation/build_tree_wind_rig.js +12 -30
  290. package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts +12 -0
  291. package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts.map +1 -0
  292. package/src/generation/foliage/animation/tree_wind_bend_limit.js +13 -0
  293. package/src/generation/foliage/asset/TreeAsset.d.ts +5 -0
  294. package/src/generation/foliage/asset/TreeAsset.d.ts.map +1 -1
  295. package/src/generation/foliage/asset/TreeAsset.js +6 -0
  296. package/src/generation/foliage/asset/generate_tree.d.ts.map +1 -1
  297. package/src/generation/foliage/asset/generate_tree.js +23 -6
  298. package/src/generation/foliage/config/{BranchLevelConfig.d.ts → BranchGeneratorConfig.d.ts} +61 -75
  299. package/src/generation/foliage/config/BranchGeneratorConfig.d.ts.map +1 -0
  300. package/src/generation/foliage/config/{BranchLevelConfig.js → BranchGeneratorConfig.js} +83 -126
  301. package/src/generation/foliage/config/BranchSpawnRule.d.ts +118 -0
  302. package/src/generation/foliage/config/BranchSpawnRule.d.ts.map +1 -0
  303. package/src/generation/foliage/config/BranchSpawnRule.js +217 -0
  304. package/src/generation/foliage/config/FoliageCardType.d.ts +1 -1
  305. package/src/generation/foliage/config/FoliageCardType.js +2 -2
  306. package/src/generation/foliage/config/FoliageConfig.d.ts +23 -45
  307. package/src/generation/foliage/config/FoliageConfig.d.ts.map +1 -1
  308. package/src/generation/foliage/config/FoliageConfig.js +47 -93
  309. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts +12 -20
  310. package/src/generation/foliage/config/FoliageMaterialConfig.d.ts.map +1 -1
  311. package/src/generation/foliage/config/FoliageMaterialConfig.js +261 -279
  312. package/src/generation/foliage/config/FoliageSpawnRule.d.ts +77 -0
  313. package/src/generation/foliage/config/FoliageSpawnRule.d.ts.map +1 -0
  314. package/src/generation/foliage/config/FoliageSpawnRule.js +135 -0
  315. package/src/generation/foliage/config/FoliageTileContent.d.ts +9 -0
  316. package/src/generation/foliage/config/FoliageTileContent.d.ts.map +1 -0
  317. package/src/generation/foliage/config/FoliageTileContent.js +12 -0
  318. package/src/generation/foliage/config/LeafApexShape.d.ts +12 -0
  319. package/src/generation/foliage/config/LeafApexShape.d.ts.map +1 -0
  320. package/src/generation/foliage/config/LeafApexShape.js +17 -0
  321. package/src/generation/foliage/config/LeafArchitecture.d.ts +155 -0
  322. package/src/generation/foliage/config/LeafArchitecture.d.ts.map +1 -0
  323. package/src/generation/foliage/config/LeafArchitecture.js +288 -0
  324. package/src/generation/foliage/config/LeafBaseShape.d.ts +14 -0
  325. package/src/generation/foliage/config/LeafBaseShape.d.ts.map +1 -0
  326. package/src/generation/foliage/config/LeafBaseShape.js +21 -0
  327. package/src/generation/foliage/config/LeafLobation.d.ts +10 -0
  328. package/src/generation/foliage/config/LeafLobation.d.ts.map +1 -0
  329. package/src/generation/foliage/config/LeafLobation.js +14 -0
  330. package/src/generation/foliage/config/PhyllotaxisMode.d.ts +11 -0
  331. package/src/generation/foliage/config/PhyllotaxisMode.d.ts.map +1 -1
  332. package/src/generation/foliage/config/PhyllotaxisMode.js +36 -0
  333. package/src/generation/foliage/config/ShootBudZone.d.ts +105 -0
  334. package/src/generation/foliage/config/ShootBudZone.d.ts.map +1 -0
  335. package/src/generation/foliage/config/ShootBudZone.js +219 -0
  336. package/src/generation/foliage/config/ShootGrowthConfig.d.ts +84 -0
  337. package/src/generation/foliage/config/ShootGrowthConfig.d.ts.map +1 -0
  338. package/src/generation/foliage/config/ShootGrowthConfig.js +146 -0
  339. package/src/generation/foliage/config/ShootSystemRule.d.ts +144 -0
  340. package/src/generation/foliage/config/ShootSystemRule.d.ts.map +1 -0
  341. package/src/generation/foliage/config/ShootSystemRule.js +316 -0
  342. package/src/generation/foliage/config/TreeLODConfig.d.ts +1 -1
  343. package/src/generation/foliage/config/TreeLODConfig.js +1 -1
  344. package/src/generation/foliage/config/TreeSpeciesConfig.d.ts +40 -8
  345. package/src/generation/foliage/config/TreeSpeciesConfig.d.ts.map +1 -1
  346. package/src/generation/foliage/config/TreeSpeciesConfig.js +124 -68
  347. package/src/generation/foliage/config/TreeWindConfig.d.ts +23 -10
  348. package/src/generation/foliage/config/TreeWindConfig.d.ts.map +1 -1
  349. package/src/generation/foliage/config/TreeWindConfig.js +34 -25
  350. package/src/generation/foliage/index.d.ts +19 -2
  351. package/src/generation/foliage/index.js +63 -44
  352. package/src/generation/foliage/material/FoliageAtlasCutout.d.ts +59 -0
  353. package/src/generation/foliage/material/FoliageAtlasCutout.d.ts.map +1 -0
  354. package/src/generation/foliage/material/FoliageAtlasCutout.js +93 -0
  355. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts +26 -0
  356. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts.map +1 -0
  357. package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.js +63 -0
  358. package/src/generation/foliage/material/foliage_atlas_cutout.d.ts +34 -0
  359. package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -0
  360. package/src/generation/foliage/material/foliage_atlas_cutout.js +174 -0
  361. package/src/generation/foliage/material/foliage_tile.d.ts +110 -0
  362. package/src/generation/foliage/material/foliage_tile.d.ts.map +1 -0
  363. package/src/generation/foliage/material/foliage_tile.js +286 -0
  364. package/src/generation/foliage/material/leaf_geometry.d.ts +103 -0
  365. package/src/generation/foliage/material/leaf_geometry.d.ts.map +1 -0
  366. package/src/generation/foliage/material/leaf_geometry.js +528 -0
  367. package/src/generation/foliage/material/make_foliage_material.d.ts +13 -33
  368. package/src/generation/foliage/material/make_foliage_material.d.ts.map +1 -1
  369. package/src/generation/foliage/material/make_foliage_material.js +356 -605
  370. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts +39 -4
  371. package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts.map +1 -1
  372. package/src/generation/foliage/mesh/foliage_collect_attachments.js +637 -569
  373. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts +48 -0
  374. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts.map +1 -0
  375. package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.js +232 -0
  376. package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
  377. package/src/generation/foliage/mesh/tree_mesh_build_bark.js +1023 -1049
  378. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts +9 -2
  379. package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts.map +1 -1
  380. package/src/generation/foliage/mesh/tree_mesh_build_foliage.js +467 -454
  381. package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
  382. package/src/generation/foliage/presets/make_tree_species_preset.js +1648 -870
  383. package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts +35 -0
  384. package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts.map +1 -0
  385. package/src/generation/foliage/skeleton/ShootFrameworkHash.js +129 -0
  386. package/src/generation/foliage/skeleton/ShootGirth.d.ts +51 -0
  387. package/src/generation/foliage/skeleton/ShootGirth.d.ts.map +1 -0
  388. package/src/generation/foliage/skeleton/ShootGirth.js +212 -0
  389. package/src/generation/foliage/skeleton/ShootLightField.d.ts +73 -0
  390. package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -0
  391. package/src/generation/foliage/skeleton/ShootLightField.js +197 -0
  392. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts +106 -3
  393. package/src/generation/foliage/skeleton/TreeSkeleton.d.ts.map +1 -1
  394. package/src/generation/foliage/skeleton/TreeSkeleton.js +217 -39
  395. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts +13 -0
  396. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts.map +1 -0
  397. package/src/generation/foliage/skeleton/flare_lobe_phase_offset.js +16 -0
  398. package/src/generation/foliage/skeleton/foliage_card_density.d.ts +71 -0
  399. package/src/generation/foliage/skeleton/foliage_card_density.d.ts.map +1 -0
  400. package/src/generation/foliage/skeleton/foliage_card_density.js +101 -0
  401. package/src/generation/foliage/skeleton/foliage_senescence.d.ts +101 -0
  402. package/src/generation/foliage/skeleton/foliage_senescence.d.ts.map +1 -0
  403. package/src/generation/foliage/skeleton/foliage_senescence.js +149 -0
  404. package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts +76 -0
  405. package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts.map +1 -0
  406. package/src/generation/foliage/skeleton/foliage_unit_cards.js +95 -0
  407. package/src/generation/foliage/skeleton/shoot_demography.d.ts +22 -0
  408. package/src/generation/foliage/skeleton/shoot_demography.d.ts.map +1 -0
  409. package/src/generation/foliage/skeleton/shoot_demography.js +96 -0
  410. package/src/generation/foliage/skeleton/shoot_geometry.d.ts +66 -0
  411. package/src/generation/foliage/skeleton/shoot_geometry.d.ts.map +1 -0
  412. package/src/generation/foliage/skeleton/shoot_geometry.js +109 -0
  413. package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts +166 -0
  414. package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts.map +1 -0
  415. package/src/generation/foliage/skeleton/shoot_systems_simulate.js +588 -0
  416. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts +28 -12
  417. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts.map +1 -1
  418. package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.js +137 -102
  419. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts +112 -0
  420. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts.map +1 -0
  421. package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.js +408 -0
  422. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts.map +1 -1
  423. package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js +208 -206
  424. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts +5 -2
  425. package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
  426. package/src/generation/foliage/skeleton/tree_skeleton_grow.js +2048 -1871
  427. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts +17 -0
  428. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts.map +1 -0
  429. package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.js +231 -0
  430. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts +14 -0
  431. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts.map +1 -0
  432. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.js +26 -0
  433. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts +10 -0
  434. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts.map +1 -0
  435. package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.js +20 -0
  436. package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
  437. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +4 -1
  438. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts +1 -0
  439. package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts.map +1 -1
  440. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +98 -86
  441. package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +263 -0
  442. package/src/shade/descriptor/WebGPUExtensionType.d.ts +17 -0
  443. package/src/shade/descriptor/WebGPUExtensionType.d.ts.map +1 -1
  444. package/src/shade/descriptor/WebGPUExtensionType.js +31 -1
  445. package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts +37 -0
  446. package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts.map +1 -0
  447. package/src/shade/playground/foliage_wind/FoliageRigOverlay.js +491 -0
  448. package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
  449. package/src/shade/playground/foliage_wind/foliage_world.js +600 -602
  450. package/src/shade/playground/foliage_wind/index.html +6 -0
  451. package/src/shade/playground/foliage_wind/main.js +14 -0
  452. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  453. package/src/shade/renderer/animation/GPUAnimationManager.js +2 -1
  454. package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts +2 -1
  455. package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts.map +1 -1
  456. package/src/shade/renderer/animation/foliage/FoliageWindJoint.js +2 -1
  457. package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.d.ts.map +1 -1
  458. package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.js +4 -2
  459. package/src/shade/renderer/buffer/table/GPUTypedTable.js +1 -1
  460. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  461. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +403 -401
  462. package/src/shade/renderer/camera/OrbitalCameraController.d.ts +1 -62
  463. package/src/shade/renderer/camera/OrbitalCameraController.d.ts.map +1 -1
  464. package/src/shade/renderer/camera/OrbitalCameraController.js +1 -374
  465. package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.d.ts.map +1 -1
  466. package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.js +3 -0
  467. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.d.ts.map +1 -1
  468. package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +6 -1
  469. package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +1 -1
  470. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +2 -2
  471. package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -1
  472. package/src/shade/renderer/fluid/GPUFluidCascade.js +6 -3
  473. package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +361 -0
  474. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -1
  475. package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +335 -241
  476. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -1
  477. package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +108 -101
  478. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts.map +1 -1
  479. package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.js +69 -67
  480. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +7 -6
  481. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
  482. package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +341 -287
  483. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +6 -4
  484. package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -1
  485. package/src/shade/renderer/fluid/mac/FluidMacPasses.js +427 -400
  486. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts +10 -5
  487. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts.map +1 -1
  488. package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.js +532 -190
  489. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts.map +1 -1
  490. package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.js +231 -237
  491. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +2 -2
  492. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
  493. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +282 -245
  494. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts +1 -3
  495. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts.map +1 -1
  496. package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.js +139 -109
  497. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts +6 -6
  498. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts.map +1 -1
  499. package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js +257 -222
  500. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts +8 -7
  501. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts.map +1 -1
  502. package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.js +119 -92
  503. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts +6 -9
  504. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts.map +1 -1
  505. package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js +229 -181
  506. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +17 -7
  507. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts.map +1 -1
  508. package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.js +634 -621
  509. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts +8 -6
  510. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -1
  511. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +166 -149
  512. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts +8 -6
  513. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -1
  514. package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +219 -183
  515. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -1
  516. package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +142 -122
  517. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +674 -663
  518. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +1 -1
  519. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  520. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +63 -29
  521. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
  522. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +77 -87
  523. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.d.ts.map +1 -1
  524. package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.js +4 -3
  525. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +11 -11
  526. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  527. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +17 -19
  528. package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.js +4 -4
  529. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.d.ts.map +1 -1
  530. package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.js +5 -1
  531. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  532. package/src/shade/renderer/loader/gltf/load_gltf.js +11 -35
  533. package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
  534. package/src/shade/renderer/loader/usd/load_usd.js +6 -19
  535. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
  536. package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +199 -193
  537. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
  538. package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +151 -143
  539. package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.d.ts.map +1 -1
  540. package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.js +11 -5
  541. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  542. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +6 -18
  543. package/src/shade/renderer/postprocess/gtao/GTAO.js +1 -1
  544. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
  545. package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +3 -5
  546. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +1 -1
  547. package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.d.ts.map +1 -1
  548. package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.js +7 -3
  549. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
  550. package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +4 -2
  551. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
  552. package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +4 -1
  553. package/src/shade/renderer/postprocess/ssr/downsample_karis.d.ts.map +1 -1
  554. package/src/shade/renderer/postprocess/ssr/downsample_karis.js +6 -3
  555. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
  556. package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +4 -3
  557. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
  558. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +4 -1
  559. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  560. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
  561. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.d.ts.map +1 -1
  562. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.js +35 -39
  563. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.d.ts.map +1 -1
  564. package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.js +20 -17
  565. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  566. package/src/shade/renderer/postprocess/taa/shader_taa.js +6 -3
  567. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  568. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -1
  569. package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +1 -1
  570. package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +2 -2
  571. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
  572. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -1
  573. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +92 -83
  574. package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +1 -1
  575. package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
  576. package/src/shade/renderer/shader/ShaderDescriptor.js +12 -4
  577. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
  578. package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +294 -286
  579. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_interpolate_probe_irradiance8.js +5 -5
  580. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.d.ts.map +1 -1
  581. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.js +5 -3
  582. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.d.ts.map +1 -1
  583. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.js +9 -6
  584. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.d.ts.map +1 -1
  585. package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.js +33 -38
  586. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  587. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +690 -675
  588. package/src/shade/renderer/shader/type/WebGPUArray.d.ts +3 -0
  589. package/src/shade/renderer/shader/type/WebGPUArray.d.ts.map +1 -1
  590. package/src/shade/renderer/shader/type/WebGPUArray.js +185 -167
  591. package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
  592. package/src/shade/renderer/shader/type/WebGPUStruct.js +461 -455
  593. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.d.ts.map +1 -1
  594. package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js +335 -211
  595. package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.d.ts.map +1 -1
  596. package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js +329 -221
  597. package/src/shade/renderer/shader/type/type_has_f16.d.ts +12 -0
  598. package/src/shade/renderer/shader/type/type_has_f16.d.ts.map +1 -0
  599. package/src/shade/renderer/shader/type/type_has_f16.js +66 -0
  600. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
  601. package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +16 -2
  602. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
  603. package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +5 -2
  604. package/src/shade/renderer/water/shader_water_avboit.js +1 -1
  605. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
  606. package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +260 -23
  607. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts +6 -7
  608. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  609. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +269 -69
  610. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  611. package/src/shade/wgsl/validate_wgsl_source.js +27 -1
  612. package/src/view/controller/controls/ListController.d.ts.map +1 -1
  613. package/src/view/controller/controls/ListController.js +118 -113
  614. package/src/view/controller/controls/Vector1Control.js +97 -97
  615. package/src/view/elements/image/SvgImageView.d.ts +1 -0
  616. package/src/view/elements/image/SvgImageView.d.ts.map +1 -1
  617. package/src/view/elements/image/SvgImageView.js +92 -90
  618. package/src/view/minimap/dom/MinimapTerrainView.d.ts +1 -0
  619. package/src/view/minimap/dom/MinimapTerrainView.d.ts.map +1 -1
  620. package/src/view/minimap/dom/MinimapTerrainView.js +151 -147
  621. package/src/view/tooltip/gml/TooltipParser.js +2 -2
  622. package/src/engine/network/PriorityFetch.d.ts +0 -59
  623. package/src/engine/network/PriorityFetch.d.ts.map +0 -1
  624. package/src/engine/network/PriorityFetch.js +0 -193
  625. package/src/generation/foliage/config/BranchLevelConfig.d.ts.map +0 -1
@@ -0,0 +1,649 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import { typed_array_value_denormalize } from "../../../core/collection/array/typed/typed_array_value_denormalize.js";
3
+ import { convex_hull_monotone_2d } from "../../../core/geom/2d/convex-hull/convex_hull_monotone_2d.js";
4
+ import { clamp } from "../../../core/math/clamp.js";
5
+ import {
6
+ computeUnsignedDistanceField_Chamfer
7
+ } from "../../../engine/graphics/texture/sampler/distance/computeUnsignedDistanceField_Chamfer.js";
8
+ import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
9
+ import { StandardAttributes } from "../../../shade/renderer/geometry/StandardAttributes.js";
10
+ import { CrownOpacity } from "./CrownOpacity.js";
11
+ import { crown_opacity_frames } from "./crown_opacity_frames.js";
12
+
13
+ /**
14
+ * The FIA five-foot rule (Schomaker et al. 2007, glossary): foliage more than this far below the crown above it is a
15
+ * straggler, not part of the live crown. 5 ft in metres.
16
+ * @type {number}
17
+ */
18
+ const FIVE_FOOT_RULE = 1.524;
19
+
20
+ /**
21
+ * Normal visual acuity, one minute of arc, as a tangent: the finest detail a rater sees, per metre of viewing distance.
22
+ * @type {number}
23
+ */
24
+ const OBSERVER_ACUITY = Math.tan(Math.PI / (180 * 60));
25
+
26
+ /**
27
+ * The raters' distance from the tree, in tree lengths. FIA crews "stay at least one-half tree length from the tree"
28
+ * and see the top better further out (Schomaker et al. 2007, §2.2); one length is where they rate from.
29
+ * @type {number}
30
+ */
31
+ const VIEWING_DISTANCE = 1;
32
+
33
+ /**
34
+ * A raster at the observer's acuity is a few thousand pixels across; past this the pixel size is wrong, not the tree.
35
+ * @type {number}
36
+ */
37
+ const MAX_PIXEL_COUNT = 1 << 27;
38
+
39
+ const FLAG_DRAWN = 1;
40
+ const FLAG_FOLIAGE = 2;
41
+ const FLAG_DILATED = 4;
42
+
43
+ const scratch_position = new Float64Array(2);
44
+ const scratch_sample = new Float64Array(1);
45
+
46
+ /**
47
+ * Raster state shared by every view of one measurement, grown to the largest view.
48
+ */
49
+ class CrownRaster {
50
+ width = 0;
51
+ height = 0;
52
+ /**
53
+ * Transmittance of everything drawn.
54
+ * @type {Float32Array}
55
+ */
56
+ transmittance = new Float32Array(0);
57
+ /**
58
+ * Transmittance of the foliage alone.
59
+ * @type {Float32Array}
60
+ */
61
+ foliage_transmittance = new Float32Array(0);
62
+ /**
63
+ * @type {Uint8Array}
64
+ */
65
+ flags = new Uint8Array(0);
66
+ /**
67
+ * Chamfer distance, in pixels, written in place over its own source mask.
68
+ * @type {Float32Array}
69
+ */
70
+ distance = new Float32Array(0);
71
+ /**
72
+ * Hull candidates, 2 per row.
73
+ * @type {Float64Array}
74
+ */
75
+ points = new Float64Array(0);
76
+ distance_sampler = new Sampler2D(new Float32Array(0), 1, 0, 0);
77
+
78
+ /**
79
+ * @param {number} width
80
+ * @param {number} height
81
+ */
82
+ reset(width, height) {
83
+ const n = width * height;
84
+ if (n > MAX_PIXEL_COUNT) {
85
+ throw new Error(`crown raster of ${width}x${height} pixels: the pixel size is too small for this crown`);
86
+ }
87
+ if (this.flags.length < n) {
88
+ this.transmittance = new Float32Array(n);
89
+ this.foliage_transmittance = new Float32Array(n);
90
+ this.flags = new Uint8Array(n);
91
+ this.distance = new Float32Array(n);
92
+ }
93
+ if (this.points.length < height * 4) {
94
+ this.points = new Float64Array(height * 4);
95
+ }
96
+ this.width = width;
97
+ this.height = height;
98
+ this.transmittance.fill(1.0, 0, n);
99
+ this.foliage_transmittance.fill(1.0, 0, n);
100
+ this.flags.fill(0, 0, n);
101
+
102
+ this.distance_sampler.data = this.distance.subarray(0, n);
103
+ this.distance_sampler.width = width;
104
+ this.distance_sampler.height = height;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Lowest foliage of the live crown, by the FIA five-foot rule: walking down from the top, foliage joins the crown
110
+ * while it is within `gap` of the foliage above it.
111
+ *
112
+ * The rule is written for branch attachments on the bole; the foliage heights stand in for them, since a branch whose
113
+ * leaves are within the gap of the crown above is attached within it too.
114
+ *
115
+ * @param {Float32Array} positions foliage vertex positions
116
+ * @param {number} gap
117
+ * @returns {number}
118
+ */
119
+ function compute_crown_base(positions, gap) {
120
+ const n = positions.length / 3;
121
+ const heights = new Float64Array(n);
122
+ for (let i = 0; i < n; i++) {
123
+ heights[i] = positions[i * 3 + 1];
124
+ }
125
+ heights.sort();
126
+
127
+ let base = heights[n - 1];
128
+ for (let i = n - 2; i >= 0; i--) {
129
+ if (base - heights[i] > gap) {
130
+ break;
131
+ }
132
+ base = heights[i];
133
+ }
134
+ return base;
135
+ }
136
+
137
+ /**
138
+ * @param {Float64Array} projected out, 2 pixel coordinates per vertex
139
+ * @param {Float32Array} positions
140
+ * @param {number} ax image x axis
141
+ * @param {number} ay
142
+ * @param {number} az
143
+ * @param {number} bx image y axis
144
+ * @param {number} by
145
+ * @param {number} bz
146
+ * @param {number} x0 world offset of pixel 0
147
+ * @param {number} y0
148
+ * @param {number} inv_pixel
149
+ */
150
+ function project_vertices(projected, positions, ax, ay, az, bx, by, bz, x0, y0, inv_pixel) {
151
+ const n = positions.length / 3;
152
+ for (let i = 0; i < n; i++) {
153
+ const px = positions[i * 3];
154
+ const py = positions[i * 3 + 1];
155
+ const pz = positions[i * 3 + 2];
156
+ projected[i * 2] = (px * ax + py * ay + pz * az - x0) * inv_pixel;
157
+ projected[i * 2 + 1] = (px * bx + py * by + pz * bz - y0) * inv_pixel;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * @param {Float64Array} bounds `[x_min, y_min, x_max, y_max]` of the view, grown in place
163
+ * @param {Float32Array} positions
164
+ * @param {number} ax image x axis
165
+ * @param {number} ay
166
+ * @param {number} az
167
+ * @param {number} bx image y axis
168
+ * @param {number} by
169
+ * @param {number} bz
170
+ */
171
+ function extend_view_bounds(bounds, positions, ax, ay, az, bx, by, bz) {
172
+ for (let i = 0; i < positions.length; i += 3) {
173
+ const x = positions[i] * ax + positions[i + 1] * ay + positions[i + 2] * az;
174
+ const y = positions[i] * bx + positions[i + 1] * by + positions[i + 2] * bz;
175
+ bounds[0] = Math.min(bounds[0], x);
176
+ bounds[1] = Math.min(bounds[1], y);
177
+ bounds[2] = Math.max(bounds[2], x);
178
+ bounds[3] = Math.max(bounds[3], y);
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Draws every triangle of a geometry into the raster. Pixel `(i, j)` is the point sample at `(i + 0.5, j + 0.5)`;
184
+ * an edge through a pixel centre belongs to one of the two triangles sharing it, so a mesh draws each point once.
185
+ *
186
+ * Bark is opaque. A card's coverage at a pixel is its atlas alpha there, bilinearly sampled: the renderer's hashed
187
+ * alpha test keeps a fragment with probability equal to that alpha, so this is the coverage it draws, in expectation.
188
+ * A covered leaf passes `leaf_transmittance` of the light it covers.
189
+ *
190
+ * @param {CrownRaster} raster
191
+ * @param {Float64Array} projected
192
+ * @param {Float32Array} positions
193
+ * @param {Float32Array|null} uvs `null` for opaque geometry
194
+ * @param {ArrayLike<number>|null} index
195
+ * @param {number} triangle_count
196
+ * @param {Sampler2D|null} atlas
197
+ * @param {number} alpha_channel
198
+ * @param {number} alpha_scale
199
+ * @param {number} leaf_transmittance
200
+ * @param {number} crown_base fragments below this height are not part of the crown
201
+ */
202
+ function raster_geometry(
203
+ raster, projected, positions, uvs, index, triangle_count,
204
+ atlas, alpha_channel, alpha_scale, leaf_transmittance, crown_base
205
+ ) {
206
+ const width = raster.width;
207
+ const height = raster.height;
208
+ const T = raster.transmittance;
209
+ const T_foliage = raster.foliage_transmittance;
210
+ const flags = raster.flags;
211
+ const is_foliage = uvs !== null;
212
+ const atlas_w = is_foliage ? atlas.width : 0;
213
+ const atlas_h = is_foliage ? atlas.height : 0;
214
+ const blocked = 1.0 - leaf_transmittance;
215
+
216
+ for (let t = 0; t < triangle_count; t++) {
217
+ let i0, i1, i2;
218
+ if (index !== null) {
219
+ i0 = index[t * 3];
220
+ i1 = index[t * 3 + 1];
221
+ i2 = index[t * 3 + 2];
222
+ } else {
223
+ i0 = t * 3;
224
+ i1 = t * 3 + 1;
225
+ i2 = t * 3 + 2;
226
+ }
227
+
228
+ let x0 = projected[i0 * 2], y0 = projected[i0 * 2 + 1];
229
+ let x1 = projected[i1 * 2], y1 = projected[i1 * 2 + 1];
230
+ let x2 = projected[i2 * 2], y2 = projected[i2 * 2 + 1];
231
+
232
+ let area = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0);
233
+ if (!(Math.abs(area) > 0)) {
234
+ // edge-on: a card has no thickness
235
+ continue;
236
+ }
237
+ if (area < 0) {
238
+ // counter-clockwise, so the interior is where all three edge functions are positive
239
+ let s = i1; i1 = i2; i2 = s;
240
+ s = x1; x1 = x2; x2 = s;
241
+ s = y1; y1 = y2; y2 = s;
242
+ area = -area;
243
+ }
244
+ const inv_area = 1.0 / area;
245
+
246
+ // a point on an edge belongs to the triangle that edge runs up through (or left along) in
247
+ const own_0 = (y2 - y1) > 0 || ((y2 - y1) === 0 && (x2 - x1) < 0);
248
+ const own_1 = (y0 - y2) > 0 || ((y0 - y2) === 0 && (x0 - x2) < 0);
249
+ const own_2 = (y1 - y0) > 0 || ((y1 - y0) === 0 && (x1 - x0) < 0);
250
+
251
+ const h0 = positions[i0 * 3 + 1];
252
+ const h1 = positions[i1 * 3 + 1];
253
+ const h2 = positions[i2 * 3 + 1];
254
+ if (Math.max(h0, h1, h2) < crown_base) {
255
+ continue;
256
+ }
257
+ // only a triangle across the crown base is cut per fragment: one wholly above keeps every fragment, where an
258
+ // interpolated height could round below a base it sits on
259
+ const cut_at_base = Math.min(h0, h1, h2) < crown_base;
260
+
261
+ const col_lo = Math.max(0, Math.ceil(Math.min(x0, x1, x2) - 0.5));
262
+ const col_hi = Math.min(width - 1, Math.floor(Math.max(x0, x1, x2) - 0.5));
263
+ const row_lo = Math.max(0, Math.ceil(Math.min(y0, y1, y2) - 0.5));
264
+ const row_hi = Math.min(height - 1, Math.floor(Math.max(y0, y1, y2) - 0.5));
265
+
266
+ for (let row = row_lo; row <= row_hi; row++) {
267
+ const cy = row + 0.5;
268
+
269
+ // Each edge function is linear along the row, `e(cx) = a - dy * cx`, and bounds cx on one side: the row's
270
+ // span, widened by a pixel each way so the exact tests below keep their say on the edges
271
+ let x_lower = -Infinity;
272
+ let x_upper = Infinity;
273
+ let dy = y2 - y1;
274
+ let a = (x2 - x1) * (cy - y1) + dy * x1;
275
+ if (dy > 0) x_upper = Math.min(x_upper, a / dy); else if (dy < 0) x_lower = Math.max(x_lower, a / dy); else if (a < 0) continue;
276
+ dy = y0 - y2;
277
+ a = (x0 - x2) * (cy - y2) + dy * x2;
278
+ if (dy > 0) x_upper = Math.min(x_upper, a / dy); else if (dy < 0) x_lower = Math.max(x_lower, a / dy); else if (a < 0) continue;
279
+ dy = y1 - y0;
280
+ a = (x1 - x0) * (cy - y0) + dy * x0;
281
+ if (dy > 0) x_upper = Math.min(x_upper, a / dy); else if (dy < 0) x_lower = Math.max(x_lower, a / dy); else if (a < 0) continue;
282
+
283
+ const span_lo = Math.max(col_lo, Math.ceil(x_lower - 0.5) - 1);
284
+ const span_hi = Math.min(col_hi, Math.floor(x_upper - 0.5) + 1);
285
+
286
+ for (let col = span_lo; col <= span_hi; col++) {
287
+ const cx = col + 0.5;
288
+
289
+ const e0 = (x2 - x1) * (cy - y1) - (y2 - y1) * (cx - x1);
290
+ if (e0 < 0 || (e0 === 0 && !own_0)) continue;
291
+ const e1 = (x0 - x2) * (cy - y2) - (y0 - y2) * (cx - x2);
292
+ if (e1 < 0 || (e1 === 0 && !own_1)) continue;
293
+ const e2 = (x1 - x0) * (cy - y0) - (y1 - y0) * (cx - x0);
294
+ if (e2 < 0 || (e2 === 0 && !own_2)) continue;
295
+
296
+ const l0 = e0 * inv_area;
297
+ const l1 = e1 * inv_area;
298
+ const l2 = e2 * inv_area;
299
+
300
+ if (cut_at_base && l0 * h0 + l1 * h1 + l2 * h2 < crown_base) continue;
301
+
302
+ const k = row * width + col;
303
+
304
+ if (!is_foliage) {
305
+ T[k] = 0.0;
306
+ flags[k] |= FLAG_DRAWN;
307
+ continue;
308
+ }
309
+
310
+ if (T_foliage[k] === 0.0) {
311
+ // an opaque leaf is already here: nothing behind or in front of it changes the pixel
312
+ continue;
313
+ }
314
+
315
+ const u = l0 * uvs[i0 * 2] + l1 * uvs[i1 * 2] + l2 * uvs[i2 * 2];
316
+ const v = l0 * uvs[i0 * 2 + 1] + l1 * uvs[i1 * 2 + 1] + l2 * uvs[i2 * 2 + 1];
317
+ scratch_position[0] = u * atlas_w - 0.5;
318
+ scratch_position[1] = v * atlas_h - 0.5;
319
+ atlas.sampleChannelBilinearArray(scratch_sample, 0, scratch_position, 0, alpha_channel);
320
+ const alpha = clamp(scratch_sample[0] * alpha_scale, 0.0, 1.0);
321
+ if (alpha <= 0.0) continue;
322
+
323
+ const pass = 1.0 - alpha * blocked;
324
+ T[k] *= pass;
325
+ T_foliage[k] *= pass;
326
+ flags[k] |= FLAG_DRAWN | FLAG_FOLIAGE;
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Marks the foliated part of the view: the morphological closing of the foliage's pixels by a ball of `radius_px`,
334
+ * so a gap narrower than the ball's diameter is a microhole within the foliage and a wider one is a large gap
335
+ * between foliage, outside. The ball is the 3x3 chamfer metric's (an octagon through the disc's axis and diagonal
336
+ * points, 90% of its area).
337
+ *
338
+ * @param {CrownRaster} raster
339
+ * @param {number} radius_px
340
+ */
341
+ function mark_foliated(raster, radius_px) {
342
+ const n = raster.width * raster.height;
343
+ const flags = raster.flags;
344
+ const distance = raster.distance;
345
+ const sampler = raster.distance_sampler;
346
+ const far = raster.width + raster.height;
347
+
348
+ // dilate; the chamfer reads each source pixel before it writes it, so the mask is its own output
349
+ for (let k = 0; k < n; k++) {
350
+ distance[k] = flags[k] & FLAG_FOLIAGE ? 1 : 0;
351
+ }
352
+ computeUnsignedDistanceField_Chamfer(sampler, sampler, 0, 1, Math.SQRT2, far);
353
+ for (let k = 0; k < n; k++) {
354
+ distance[k] = distance[k] <= radius_px ? 0 : 1;
355
+ }
356
+
357
+ // erode the dilation
358
+ computeUnsignedDistanceField_Chamfer(sampler, sampler, 0, 1, Math.SQRT2, far);
359
+ for (let k = 0; k < n; k++) {
360
+ if (distance[k] > radius_px) {
361
+ flags[k] |= FLAG_DILATED;
362
+ }
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Integrates one view over its crown outline: the convex hull of every pixel the crown draws.
368
+ *
369
+ * FIA's crown density outline is "a normal, expected crown that encompasses the branch tips", rated "as if [the
370
+ * crown is] full" with dieback and open areas inside it (Schomaker et al. 2007, §2.3.5.2). The convex hull is the
371
+ * smallest outline that encompasses every branch tip without the observer's judgement of which notches to bridge.
372
+ *
373
+ * @param {CrownRaster} raster
374
+ * @param {Float64Array} out `[outline pixels, density sum, foliated pixels, transparency sum]`
375
+ */
376
+ function integrate_view(raster, out) {
377
+ const width = raster.width;
378
+ const height = raster.height;
379
+ const flags = raster.flags;
380
+ const T = raster.transmittance;
381
+ const T_foliage = raster.foliage_transmittance;
382
+
383
+ // the hull of the drawn pixels' centres is the hull of each row's first and last drawn pixel
384
+ const points = raster.points;
385
+ let point_count = 0;
386
+ for (let row = 0; row < height; row++) {
387
+ const row_offset = row * width;
388
+ let first = -1;
389
+ let last = -1;
390
+ for (let col = 0; col < width; col++) {
391
+ if (flags[row_offset + col] & FLAG_DRAWN) {
392
+ if (first < 0) first = col;
393
+ last = col;
394
+ }
395
+ }
396
+ if (first < 0) continue;
397
+ points[point_count * 2] = first;
398
+ points[point_count * 2 + 1] = row;
399
+ point_count++;
400
+ if (last !== first) {
401
+ points[point_count * 2] = last;
402
+ points[point_count * 2 + 1] = row;
403
+ point_count++;
404
+ }
405
+ }
406
+
407
+ out.fill(0);
408
+ if (point_count === 0) {
409
+ return;
410
+ }
411
+
412
+ const hull = convex_hull_monotone_2d(points, point_count);
413
+ const hull_count = hull.length;
414
+
415
+ let row_lo = height;
416
+ let row_hi = -1;
417
+ for (let h = 0; h < hull_count; h++) {
418
+ const y = points[hull[h] * 2 + 1];
419
+ row_lo = Math.min(row_lo, y);
420
+ row_hi = Math.max(row_hi, y);
421
+ }
422
+
423
+ let outline = 0;
424
+ let density_sum = 0.0;
425
+ let foliated = 0;
426
+ let transparency_sum = 0.0;
427
+
428
+ for (let row = row_lo; row <= row_hi; row++) {
429
+ // the hull's span on this row
430
+ let x_lo = Infinity;
431
+ let x_hi = -Infinity;
432
+ for (let h = 0; h < hull_count; h++) {
433
+ const a = hull[h];
434
+ const b = hull[(h + 1) % hull_count];
435
+ const ax = points[a * 2], ay = points[a * 2 + 1];
436
+ const bx = points[b * 2], by = points[b * 2 + 1];
437
+ if (row < Math.min(ay, by) || row > Math.max(ay, by)) continue;
438
+ if (ay === by) {
439
+ x_lo = Math.min(x_lo, ax, bx);
440
+ x_hi = Math.max(x_hi, ax, bx);
441
+ } else {
442
+ const x = ax + (row - ay) * (bx - ax) / (by - ay);
443
+ x_lo = Math.min(x_lo, x);
444
+ x_hi = Math.max(x_hi, x);
445
+ }
446
+ }
447
+
448
+ const col_lo = Math.max(0, Math.ceil(x_lo - 1e-9));
449
+ const col_hi = Math.min(width - 1, Math.floor(x_hi + 1e-9));
450
+ const row_offset = row * width;
451
+ for (let col = col_lo; col <= col_hi; col++) {
452
+ const k = row_offset + col;
453
+ outline++;
454
+ density_sum += 1.0 - T[k];
455
+ if (flags[k] & FLAG_DILATED) {
456
+ foliated++;
457
+ transparency_sum += T_foliage[k];
458
+ }
459
+ }
460
+ }
461
+
462
+ out[0] = outline;
463
+ out[1] = density_sum;
464
+ out[2] = foliated;
465
+ out[3] = transparency_sum;
466
+ }
467
+
468
+ /**
469
+ * Measures how opaque a tree crown is, as the USDA Forest Inventory and Analysis program rates it in the field
470
+ * (Schomaker et al. 2007, GTR SRS-102), by rasterising what the renderer draws in orthographic views from every frame
471
+ * of a `frame_count` x `frame_count` hemi-octahedral impostor grid (`crown_opacity_frames`). A view and its opposite
472
+ * see mirrored images of the same transmittance, so the hemisphere holds every view once; the grid's rim is the
473
+ * horizon, where FIA rates from, and its centre the view from directly below. Rim frames come in opposite pairs, and
474
+ * each pair is measured once.
475
+ *
476
+ * - **Crown**: everything above the live crown base, which is the lowest foliage reached from the top without a
477
+ * vertical gap in foliage wider than the FIA five-foot rule's 1.524 m. Nothing below it is drawn.
478
+ * - **Crown outline**: the convex hull of every pixel the crown draws (bark or foliage), with every gap inside it.
479
+ * - **Crown density**: the mean of `1 - T` over the outline, `T` the transmittance of bark and foliage together.
480
+ * From below, over the footprint, this is the light the crown intercepts (Nowak 1996).
481
+ * - **Foliated part**: FIA rates transparency "where foliage or remnants of foliage occur", excluding macroholes
482
+ * and "the spaces between clumps of foliage" (§2.3.7). Here it is the morphological closing of the foliage's pixels
483
+ * by a ball of `microhole_radius`, inside the outline: gaps narrower than two radii are microholes, wider ones are
484
+ * large gaps and drop out.
485
+ * - **Foliage transparency**: the mean foliage-only transmittance over the foliated part. Bark does not count, as
486
+ * FIA's raters "exclude the branches from foliage ... as if the light were penetrating the branches".
487
+ *
488
+ * Each pixel is a point sample of what the renderer draws there. The outline and the foliated part are extremes over
489
+ * those samples, and grow as finer pixels catch thinner twigs and leaf stalks, so the pixel size is part of the
490
+ * definition: by default it is what a rater sees, one minute of arc (normal acuity) from one tree length away, the
491
+ * tree's length being the height of everything drawn.
492
+ *
493
+ * `leaf_transmittance` is the fraction of the light a leaf lets through where it covers. Our shading model has no
494
+ * leaf translucency, so it defaults to 0; it is the hook for when the shading model gains one.
495
+ *
496
+ * @param {import("../../../shade/renderer/geometry/Geometry.js").Geometry|null} bark opaque geometry
497
+ * @param {import("../../../shade/renderer/geometry/Geometry.js").Geometry|null} foliage cards, `uv0` into `atlas`
498
+ * @param {Sampler2D|null} atlas the cards' texture; required with `foliage`
499
+ * @param {Object} options
500
+ * @param {number} options.microhole_radius closing radius separating microholes from large gaps, m
501
+ * @param {number} [options.pixel_size] m, the tree's height times the tangent of one minute of arc by default
502
+ * @param {number} [options.frame_count=9] frames along each side of the grid; odd, so the vertical is a frame. At 9
503
+ * every preset's hemisphere means are within 0.2 points of 13's; 5 is off by up to 1.6, 3 by up to 5.8
504
+ * @param {number} [options.leaf_transmittance=0] fraction of light a leaf passes, in `[0, 1]`
505
+ * @param {number} [options.atlas_alpha_channel=3] channel of `atlas` holding the cards' coverage
506
+ * @param {CrownOpacity} [out]
507
+ * @returns {CrownOpacity}
508
+ */
509
+ export function crown_opacity_measure(bark, foliage, atlas, {
510
+ microhole_radius,
511
+ pixel_size,
512
+ frame_count = 9,
513
+ leaf_transmittance = 0,
514
+ atlas_alpha_channel = 3
515
+ }, out = new CrownOpacity()) {
516
+ assert.greaterThan(microhole_radius, 0, 'microhole_radius');
517
+ assert.isNonNegativeInteger(frame_count, 'frame_count');
518
+ assert.equal(frame_count % 2, 1, 'frame_count must be odd, so the vertical is a frame');
519
+ assert.greaterThanOrEqual(leaf_transmittance, 0, 'leaf_transmittance');
520
+ assert.lessThanOrEqual(leaf_transmittance, 1, 'leaf_transmittance');
521
+ if (foliage !== null) {
522
+ assert.defined(atlas, 'atlas');
523
+ assert.notNull(atlas, 'atlas');
524
+ assert.equal(atlas.isSampler2D, true, 'atlas.isSampler2D !== true');
525
+ }
526
+
527
+ const bark_positions = bark !== null ? bark.getAttribute(StandardAttributes.Position).data : null;
528
+ const foliage_positions = foliage !== null ? foliage.getAttribute(StandardAttributes.Position).data : null;
529
+ const foliage_uvs = foliage !== null ? foliage.getAttribute(StandardAttributes.TextureCoordinates0).data : null;
530
+ const alpha_scale = foliage !== null ? typed_array_value_denormalize(1, atlas.data) : 0;
531
+
532
+ const bounds = new Float64Array(4);
533
+ if (pixel_size === undefined) {
534
+ bounds[1] = Infinity;
535
+ bounds[3] = -Infinity;
536
+ if (bark_positions !== null) {
537
+ extend_view_bounds(bounds, bark_positions, 0, 1, 0, 0, 1, 0);
538
+ }
539
+ if (foliage_positions !== null) {
540
+ extend_view_bounds(bounds, foliage_positions, 0, 1, 0, 0, 1, 0);
541
+ }
542
+ pixel_size = (bounds[3] - bounds[1]) * VIEWING_DISTANCE * OBSERVER_ACUITY;
543
+ }
544
+ assert.greaterThan(pixel_size, 0, 'pixel_size');
545
+
546
+ const crown_base = foliage_positions !== null && foliage_positions.length > 0
547
+ ? compute_crown_base(foliage_positions, FIVE_FOOT_RULE)
548
+ : -Infinity;
549
+
550
+ out.resize(frame_count);
551
+ crown_opacity_frames(out);
552
+ out.crown_base = crown_base;
553
+ out.pixel_size = pixel_size;
554
+ out.microhole_radius = microhole_radius;
555
+
556
+ const inv_pixel = 1.0 / pixel_size;
557
+ const radius_px = microhole_radius * inv_pixel;
558
+ // the closing's dilation reaches radius_px past the outermost foliage, and has to stay inside the raster
559
+ const pad = Math.ceil(radius_px) + 2;
560
+
561
+ const bark_projected = new Float64Array(bark_positions !== null ? bark_positions.length / 3 * 2 : 0);
562
+ const foliage_projected = new Float64Array(foliage_positions !== null ? foliage_positions.length / 3 * 2 : 0);
563
+ const raster = new CrownRaster();
564
+ const sums = new Float64Array(4);
565
+ const pixel_area = pixel_size * pixel_size;
566
+
567
+ const frame_total = frame_count * frame_count;
568
+ for (let frame = 0; frame < frame_total; frame++) {
569
+ const i = frame % frame_count;
570
+ const j = (frame - i) / frame_count;
571
+ const on_rim = i === 0 || j === 0 || i === frame_count - 1 || j === frame_count - 1;
572
+ const opposite = (frame_count - 1 - j) * frame_count + (frame_count - 1 - i);
573
+ if (on_rim && opposite < frame) {
574
+ // its opposite on the horizon sees the mirror image
575
+ out.density[frame] = out.density[opposite];
576
+ out.transparency[frame] = out.transparency[opposite];
577
+ out.outline_area[frame] = out.outline_area[opposite];
578
+ out.foliated_area[frame] = out.foliated_area[opposite];
579
+ continue;
580
+ }
581
+
582
+ // image axes: x horizontal across the view, y the rest of the way up (on the horizon, the vertical)
583
+ const dx = out.directions[frame * 3];
584
+ const dy = out.directions[frame * 3 + 1];
585
+ const dz = out.directions[frame * 3 + 2];
586
+ let ax, ay, az, bx, by, bz;
587
+ if (dx === 0 && dz === 0) {
588
+ ax = 1; ay = 0; az = 0;
589
+ bx = 0; by = 0; bz = 1;
590
+ } else {
591
+ const m = 1 / Math.sqrt(dx * dx + dz * dz);
592
+ ax = dz * m; ay = 0; az = -dx * m;
593
+ bx = dy * az; by = dz * ax - dx * az; bz = -dy * ax;
594
+ }
595
+
596
+ bounds[0] = Infinity;
597
+ bounds[1] = Infinity;
598
+ bounds[2] = -Infinity;
599
+ bounds[3] = -Infinity;
600
+ if (bark_positions !== null) {
601
+ extend_view_bounds(bounds, bark_positions, ax, ay, az, bx, by, bz);
602
+ }
603
+ if (foliage_positions !== null) {
604
+ extend_view_bounds(bounds, foliage_positions, ax, ay, az, bx, by, bz);
605
+ }
606
+ const x_min = bounds[0], y_min = bounds[1], x_max = bounds[2], y_max = bounds[3];
607
+
608
+ sums.fill(0);
609
+ if (x_min <= x_max) {
610
+ const width = Math.ceil((x_max - x_min) * inv_pixel) + 2 * pad;
611
+ const height = Math.ceil((y_max - y_min) * inv_pixel) + 2 * pad;
612
+ raster.reset(width, height);
613
+ const x0 = x_min - pad * pixel_size;
614
+ const y0 = y_min - pad * pixel_size;
615
+
616
+ if (bark_positions !== null) {
617
+ project_vertices(bark_projected, bark_positions, ax, ay, az, bx, by, bz, x0, y0, inv_pixel);
618
+ raster_geometry(
619
+ raster, bark_projected, bark_positions, null,
620
+ bark.index !== null ? bark.index.data : null, bark.getPrimitiveCount(),
621
+ null, 0, 0, 0, crown_base
622
+ );
623
+ }
624
+ if (foliage_positions !== null) {
625
+ project_vertices(foliage_projected, foliage_positions, ax, ay, az, bx, by, bz, x0, y0, inv_pixel);
626
+ raster_geometry(
627
+ raster, foliage_projected, foliage_positions, foliage_uvs,
628
+ foliage.index !== null ? foliage.index.data : null, foliage.getPrimitiveCount(),
629
+ atlas, atlas_alpha_channel, alpha_scale, leaf_transmittance, crown_base
630
+ );
631
+ }
632
+
633
+ mark_foliated(raster, radius_px);
634
+ integrate_view(raster, sums);
635
+ }
636
+
637
+ const density = sums[1] / sums[0];
638
+ const transparency = sums[3] / sums[2];
639
+ const outline_area = sums[0] * pixel_area;
640
+ const foliated_area = sums[2] * pixel_area;
641
+
642
+ out.density[frame] = density;
643
+ out.transparency[frame] = transparency;
644
+ out.outline_area[frame] = outline_area;
645
+ out.foliated_area[frame] = foliated_area;
646
+ }
647
+
648
+ return out;
649
+ }