@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.
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/DUPLICATION_REVIEW_2026_10_24.md +1072 -0
- package/src/core/binary/BitSet.js +1 -1
- package/src/core/binary/FLOAT16_MAX.d.ts +2 -0
- package/src/core/binary/FLOAT16_MAX.d.ts.map +1 -0
- package/src/core/binary/FLOAT16_MAX.js +1 -0
- package/src/core/binary/base58/base58_encode.js +2 -2
- package/src/core/binary/type/TypeBuilder.js +1 -1
- package/src/core/bvh2/bvh3/BVH.js +1 -1
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +7 -3
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +5 -1
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +195 -246
- package/src/core/collection/CuckooFilter.js +1 -1
- package/src/core/collection/array/isArrayEqual.d.ts.map +1 -1
- package/src/core/collection/array/isArrayEqual.js +33 -58
- package/src/core/collection/array/typed/array_buffer_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/array_buffer_hash.js +41 -39
- package/src/core/collection/array/typed/float32_array_hash.js +38 -38
- package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -1
- package/src/core/collection/array/typed/uint16_array_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/uint16_array_hash.js +30 -29
- package/src/core/collection/array/typed/uint32_array_hash.d.ts +2 -1
- package/src/core/collection/array/typed/uint32_array_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/uint32_array_hash.js +21 -20
- package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -1
- package/src/core/collection/array/typed/uint8_array_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/uint8_array_hash.js +37 -36
- package/src/core/collection/array/typed/uint_array_for_count.js +2 -2
- package/src/core/collection/list/List.d.ts.map +1 -1
- package/src/core/collection/list/List.js +3 -19
- package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
- package/src/core/collection/table/RowFirstTable.js +4 -28
- package/src/core/debug/matchers/DescribeAs.d.ts.map +1 -1
- package/src/core/debug/matchers/DescribeAs.js +62 -64
- package/src/core/function/FunctionCompiler.js +4 -4
- package/src/core/function/objectsEqual.d.ts.map +1 -1
- package/src/core/function/objectsEqual.js +3 -2
- package/src/core/geom/2d/bvh/BVH2D.d.ts.map +1 -1
- package/src/core/geom/2d/bvh/BVH2D.js +4 -3
- package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts +5 -2
- package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.d.ts.map +1 -1
- package/src/core/geom/2d/convex-hull/convex_hull_fixed_count_2d_relaxation.js +49 -11
- package/src/core/geom/2d/hash-grid/shg_query_elements_circle.d.ts.map +1 -1
- package/src/core/geom/2d/hash-grid/shg_query_elements_circle.js +122 -159
- package/src/core/geom/2d/hash-grid/shg_query_elements_line.d.ts.map +1 -1
- package/src/core/geom/2d/hash-grid/shg_query_elements_line.js +8 -5
- package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts +18 -0
- package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.d.ts.map +1 -0
- package/src/core/geom/2d/polygon/polygon2_rasterize_coverage.js +97 -0
- package/src/core/geom/2d/r-tree/StaticR2Tree.js +2 -2
- package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts +21 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_coverage.d.ts.map +1 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_coverage.js +54 -0
- package/src/core/geom/3d/aabb/aabb3_build_frustum.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_build_frustum.js +20 -53
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts +1 -1
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -42
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -1
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +30 -32
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -1
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +1 -5
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -1
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +1 -15
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -1
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +105 -116
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.d.ts.map +1 -1
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.js +36 -54
- package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts +5 -10
- package/src/core/geom/3d/plane/plane3_compute_intersection_objects.d.ts.map +1 -1
- package/src/core/geom/3d/plane/plane3_compute_intersection_objects.js +20 -82
- package/src/core/geom/3d/plane/plane3_slerp.d.ts.map +1 -1
- package/src/core/geom/3d/plane/plane3_slerp.js +87 -102
- package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts +12 -0
- package/src/core/geom/3d/polygon/polygon3_compute_normal.d.ts.map +1 -1
- package/src/core/geom/3d/polygon/polygon3_compute_normal.js +107 -60
- package/src/core/geom/3d/ray/ray3_compute_closest_point.d.ts.map +1 -1
- package/src/core/geom/3d/ray/ray3_compute_closest_point.js +37 -43
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/ConvexHullShape3D.js +5 -16
- package/src/core/geom/3d/shape/MeshShape3D.js +2 -56
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +10 -7
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnionShape3D.js +9 -3
- package/src/core/geom/3d/shape/json/shape_to_type.js +2 -2
- package/src/core/geom/3d/sphere/harmonics/SH3_COEFFICIENTS.js +17 -17
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +6 -2
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +3 -2
- package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts +20 -2
- package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/tetrahedron_contains_point.js +52 -37
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +40 -56
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +251 -260
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +104 -113
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_resolve_t_junctions.js +227 -238
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +15 -24
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +31 -115
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +142 -150
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +151 -194
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.js +60 -85
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.js +156 -171
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +8 -44
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +2 -7
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +3 -2
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +128 -133
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts +8 -14
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +36 -82
- package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
- package/src/core/geom/3d/triangle/tri3_ray_intersection.js +7 -144
- package/src/core/geom/ConicRay.d.ts.map +1 -1
- package/src/core/geom/ConicRay.js +230 -237
- package/src/core/localization/LocaleDataset.d.ts +6 -0
- package/src/core/localization/LocaleDataset.d.ts.map +1 -1
- package/src/core/localization/LocaleDataset.js +48 -37
- package/src/core/localization/LocalizationEngine.d.ts.map +1 -1
- package/src/core/localization/LocalizationEngine.js +3 -2
- package/src/core/math/lookup/ParameterLookupTable.d.ts.map +1 -1
- package/src/core/math/lookup/ParameterLookupTable.js +3 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +330 -400
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -0
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.js +134 -167
- package/src/core/model/DebouncedObservedBoolean.d.ts +1 -2
- package/src/core/model/DebouncedObservedBoolean.d.ts.map +1 -1
- package/src/core/model/DebouncedObservedBoolean.js +1 -1
- package/src/core/model/node-graph/node/NodeInstance.d.ts.map +1 -1
- package/src/core/model/node-graph/node/NodeInstance.js +2 -7
- package/src/core/model/node-graph/node/parameter/NodeParameterDescription.js +1 -1
- package/src/core/model/object/optional_equality.d.ts +3 -3
- package/src/core/model/object/optional_equality.d.ts.map +1 -1
- package/src/core/model/object/optional_equality.js +10 -27
- package/src/core/model/object/write_property.js +1 -1
- package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +2 -2
- package/src/core/primitives/strings/string_compute_byte_size.d.ts +3 -3
- package/src/core/primitives/strings/string_compute_byte_size.d.ts.map +1 -1
- package/src/core/primitives/strings/string_compute_byte_size.js +8 -21
- package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
- package/src/core/process/executor/ConcurrentExecutor.js +14 -2
- package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts +6 -3
- package/src/engine/achievements/gateway/StorageAchievementGateway.d.ts.map +1 -1
- package/src/engine/achievements/gateway/StorageAchievementGateway.js +31 -75
- package/src/engine/asset/loaders/SVGAssetLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/SVGAssetLoader.js +33 -31
- package/src/engine/control/first-person/math/criticallyDampedSpring.d.ts.map +1 -1
- package/src/engine/control/first-person/math/criticallyDampedSpring.js +3 -14
- package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +4 -1
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts +0 -2
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.js +3 -3
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/geometry/sort_triangles_by_distance_to_point.js +1 -1
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +1 -1
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +2 -1
- package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -1
- package/src/engine/graphics3/prefab/prefab_skin_frame.js +1 -12
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +1 -1
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.js +141 -137
- package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
- package/src/engine/input/ecs/systems/InputControllerSystem.js +13 -3
- package/src/engine/input/ecs/systems/InputSystem.d.ts.map +1 -1
- package/src/engine/input/ecs/systems/InputSystem.js +2 -1
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +4 -1
- package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.js +3 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +3 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +39 -33
- package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts +5 -0
- package/src/engine/intelligence/behavior/util/ConditionalBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/util/ConditionalBehavior.js +93 -75
- package/src/engine/intelligence/behavior/util/RotationBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/util/RotationBehavior.js +79 -76
- package/src/engine/intelligence/blackboard/BlackboardStack.d.ts +1 -0
- package/src/engine/intelligence/blackboard/BlackboardStack.d.ts.map +1 -1
- package/src/engine/intelligence/blackboard/BlackboardStack.js +159 -123
- package/src/engine/intelligence/mcts/StateNode.d.ts.map +1 -1
- package/src/engine/intelligence/mcts/StateNode.js +366 -364
- package/src/engine/intelligence/resource/ResourceAllocationSolver.js +1 -1
- package/src/engine/navigation/ecs/components/Path.d.ts.map +1 -1
- package/src/engine/navigation/ecs/components/Path.js +2 -1
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.d.ts.map +1 -1
- package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +5 -2
- package/src/engine/physics/body/SolverBodyState.d.ts.map +1 -1
- package/src/engine/physics/body/SolverBodyState.js +2 -6
- package/src/engine/physics/ccd/linear_sweep.d.ts.map +1 -1
- package/src/engine/physics/ccd/linear_sweep.js +3 -16
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +2 -16
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +13 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +15 -4
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +2 -5
- package/src/engine/physics/inertia/locked_inverse_inertia.d.ts +12 -0
- package/src/engine/physics/inertia/locked_inverse_inertia.d.ts.map +1 -0
- package/src/engine/physics/inertia/locked_inverse_inertia.js +22 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
- package/src/engine/physics/integration/integrate_velocity.js +3 -18
- package/src/engine/physics/mls-mpm/MLS_MPM.d.ts +1 -0
- package/src/engine/physics/mls-mpm/MLS_MPM.d.ts.map +1 -1
- package/src/engine/physics/mls-mpm/MLS_MPM.js +5 -4
- package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/convex_decomposition.js +7 -16
- package/src/engine/physics/vehicle/RaycastVehicle.d.ts.map +1 -1
- package/src/engine/physics/vehicle/RaycastVehicle.js +15 -5
- package/src/engine/save/StorageBackedList.d.ts +5 -0
- package/src/engine/save/StorageBackedList.d.ts.map +1 -1
- package/src/engine/save/StorageBackedList.js +161 -144
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +394 -391
- package/src/engine/sound/simulation/probe/AcousticProbeField.d.ts.map +1 -1
- package/src/engine/sound/simulation/probe/AcousticProbeField.js +6 -19
- package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts +15 -0
- package/src/engine/sound/simulation/probe/probe_edge_visible.d.ts.map +1 -1
- package/src/engine/sound/simulation/probe/probe_edge_visible.js +59 -41
- package/src/engine/sound/simulation/probe/probe_refine_connectivity.d.ts.map +1 -1
- package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +164 -181
- package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.d.ts.map +1 -1
- package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +20 -5
- package/src/format/image/avif/av1/decode/Av1FrameContext.d.ts.map +1 -1
- package/src/format/image/avif/av1/decode/Av1FrameContext.js +3 -10
- package/src/format/image/avif/av1/decode/reconstruct.d.ts +20 -0
- package/src/format/image/avif/av1/decode/reconstruct.d.ts.map +1 -1
- package/src/format/image/avif/av1/decode/reconstruct.js +22 -9
- package/src/format/image/avif/av1/encode/choose_restoration.js +2 -18
- package/src/format/image/avif/av1/encode/quantise.d.ts.map +1 -1
- package/src/format/image/avif/av1/encode/quantise.js +1 -55
- package/src/format/image/avif/av1/filter/loop_restoration.d.ts +9 -0
- package/src/format/image/avif/av1/filter/loop_restoration.d.ts.map +1 -1
- package/src/format/image/avif/av1/filter/loop_restoration.js +1 -1
- package/src/format/texture/basis/transcode/etc1s_to_bc7.js +2 -33
- package/src/format/texture/basis/transcode/fit_endpoints.d.ts +11 -0
- package/src/format/texture/basis/transcode/fit_endpoints.d.ts.map +1 -1
- package/src/format/texture/basis/transcode/fit_endpoints.js +1 -1
- package/src/format/texture/basis/uastc/uastc_decode_block.d.ts.map +1 -1
- package/src/format/texture/basis/uastc/uastc_decode_block.js +2 -19
- package/src/generation/foliage/ANNUAL_SHOOTS_BRIEF_2026_10_25.md +220 -0
- package/src/generation/foliage/CROWN_FILLING_BRIEF_2026_10_26.md +172 -0
- package/src/generation/foliage/FOLIAGE_DESIGN.md +165 -15
- package/src/generation/foliage/LEAF_ARCHITECTURE_BRIEF_2026_10_26.md +158 -0
- package/src/generation/foliage/SHOOT_SYSTEMS_ALL_SPECIES_BRIEF_2026_10_26.md +248 -0
- package/src/generation/foliage/SPEEDTREE_COMPARISON_2026_10_24.md +694 -0
- package/src/generation/foliage/analysis/CrownOpacity.d.ts +118 -0
- package/src/generation/foliage/analysis/CrownOpacity.d.ts.map +1 -0
- package/src/generation/foliage/analysis/CrownOpacity.js +182 -0
- package/src/generation/foliage/analysis/crown_opacity_frames.d.ts +10 -0
- package/src/generation/foliage/analysis/crown_opacity_frames.d.ts.map +1 -0
- package/src/generation/foliage/analysis/crown_opacity_frames.js +132 -0
- package/src/generation/foliage/analysis/crown_opacity_measure.d.ts +51 -0
- package/src/generation/foliage/analysis/crown_opacity_measure.d.ts.map +1 -0
- package/src/generation/foliage/analysis/crown_opacity_measure.js +649 -0
- package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts +66 -0
- package/src/generation/foliage/analysis/foliage_measure_leaf_area.d.ts.map +1 -0
- package/src/generation/foliage/analysis/foliage_measure_leaf_area.js +192 -0
- package/src/generation/foliage/analysis/tree_crown_opacity.d.ts +27 -0
- package/src/generation/foliage/analysis/tree_crown_opacity.d.ts.map +1 -0
- package/src/generation/foliage/analysis/tree_crown_opacity.js +58 -0
- package/src/generation/foliage/animation/build_tree_wind_rig.d.ts +3 -2
- package/src/generation/foliage/animation/build_tree_wind_rig.d.ts.map +1 -1
- package/src/generation/foliage/animation/build_tree_wind_rig.js +12 -30
- package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts +12 -0
- package/src/generation/foliage/animation/tree_wind_bend_limit.d.ts.map +1 -0
- package/src/generation/foliage/animation/tree_wind_bend_limit.js +13 -0
- package/src/generation/foliage/asset/TreeAsset.d.ts +5 -0
- package/src/generation/foliage/asset/TreeAsset.d.ts.map +1 -1
- package/src/generation/foliage/asset/TreeAsset.js +6 -0
- package/src/generation/foliage/asset/generate_tree.d.ts.map +1 -1
- package/src/generation/foliage/asset/generate_tree.js +23 -6
- package/src/generation/foliage/config/{BranchLevelConfig.d.ts → BranchGeneratorConfig.d.ts} +61 -75
- package/src/generation/foliage/config/BranchGeneratorConfig.d.ts.map +1 -0
- package/src/generation/foliage/config/{BranchLevelConfig.js → BranchGeneratorConfig.js} +83 -126
- package/src/generation/foliage/config/BranchSpawnRule.d.ts +118 -0
- package/src/generation/foliage/config/BranchSpawnRule.d.ts.map +1 -0
- package/src/generation/foliage/config/BranchSpawnRule.js +217 -0
- package/src/generation/foliage/config/FoliageCardType.d.ts +1 -1
- package/src/generation/foliage/config/FoliageCardType.js +2 -2
- package/src/generation/foliage/config/FoliageConfig.d.ts +23 -45
- package/src/generation/foliage/config/FoliageConfig.d.ts.map +1 -1
- package/src/generation/foliage/config/FoliageConfig.js +47 -93
- package/src/generation/foliage/config/FoliageMaterialConfig.d.ts +12 -20
- package/src/generation/foliage/config/FoliageMaterialConfig.d.ts.map +1 -1
- package/src/generation/foliage/config/FoliageMaterialConfig.js +261 -279
- package/src/generation/foliage/config/FoliageSpawnRule.d.ts +77 -0
- package/src/generation/foliage/config/FoliageSpawnRule.d.ts.map +1 -0
- package/src/generation/foliage/config/FoliageSpawnRule.js +135 -0
- package/src/generation/foliage/config/FoliageTileContent.d.ts +9 -0
- package/src/generation/foliage/config/FoliageTileContent.d.ts.map +1 -0
- package/src/generation/foliage/config/FoliageTileContent.js +12 -0
- package/src/generation/foliage/config/LeafApexShape.d.ts +12 -0
- package/src/generation/foliage/config/LeafApexShape.d.ts.map +1 -0
- package/src/generation/foliage/config/LeafApexShape.js +17 -0
- package/src/generation/foliage/config/LeafArchitecture.d.ts +155 -0
- package/src/generation/foliage/config/LeafArchitecture.d.ts.map +1 -0
- package/src/generation/foliage/config/LeafArchitecture.js +288 -0
- package/src/generation/foliage/config/LeafBaseShape.d.ts +14 -0
- package/src/generation/foliage/config/LeafBaseShape.d.ts.map +1 -0
- package/src/generation/foliage/config/LeafBaseShape.js +21 -0
- package/src/generation/foliage/config/LeafLobation.d.ts +10 -0
- package/src/generation/foliage/config/LeafLobation.d.ts.map +1 -0
- package/src/generation/foliage/config/LeafLobation.js +14 -0
- package/src/generation/foliage/config/PhyllotaxisMode.d.ts +11 -0
- package/src/generation/foliage/config/PhyllotaxisMode.d.ts.map +1 -1
- package/src/generation/foliage/config/PhyllotaxisMode.js +36 -0
- package/src/generation/foliage/config/ShootBudZone.d.ts +105 -0
- package/src/generation/foliage/config/ShootBudZone.d.ts.map +1 -0
- package/src/generation/foliage/config/ShootBudZone.js +219 -0
- package/src/generation/foliage/config/ShootGrowthConfig.d.ts +84 -0
- package/src/generation/foliage/config/ShootGrowthConfig.d.ts.map +1 -0
- package/src/generation/foliage/config/ShootGrowthConfig.js +146 -0
- package/src/generation/foliage/config/ShootSystemRule.d.ts +144 -0
- package/src/generation/foliage/config/ShootSystemRule.d.ts.map +1 -0
- package/src/generation/foliage/config/ShootSystemRule.js +316 -0
- package/src/generation/foliage/config/TreeLODConfig.d.ts +1 -1
- package/src/generation/foliage/config/TreeLODConfig.js +1 -1
- package/src/generation/foliage/config/TreeSpeciesConfig.d.ts +40 -8
- package/src/generation/foliage/config/TreeSpeciesConfig.d.ts.map +1 -1
- package/src/generation/foliage/config/TreeSpeciesConfig.js +124 -68
- package/src/generation/foliage/config/TreeWindConfig.d.ts +23 -10
- package/src/generation/foliage/config/TreeWindConfig.d.ts.map +1 -1
- package/src/generation/foliage/config/TreeWindConfig.js +34 -25
- package/src/generation/foliage/index.d.ts +19 -2
- package/src/generation/foliage/index.js +63 -44
- package/src/generation/foliage/material/FoliageAtlasCutout.d.ts +59 -0
- package/src/generation/foliage/material/FoliageAtlasCutout.d.ts.map +1 -0
- package/src/generation/foliage/material/FoliageAtlasCutout.js +93 -0
- package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts +26 -0
- package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.d.ts.map +1 -0
- package/src/generation/foliage/material/compute_foliage_variant_atlas_layout.js +63 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.d.ts +34 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.d.ts.map +1 -0
- package/src/generation/foliage/material/foliage_atlas_cutout.js +174 -0
- package/src/generation/foliage/material/foliage_tile.d.ts +110 -0
- package/src/generation/foliage/material/foliage_tile.d.ts.map +1 -0
- package/src/generation/foliage/material/foliage_tile.js +286 -0
- package/src/generation/foliage/material/leaf_geometry.d.ts +103 -0
- package/src/generation/foliage/material/leaf_geometry.d.ts.map +1 -0
- package/src/generation/foliage/material/leaf_geometry.js +528 -0
- package/src/generation/foliage/material/make_foliage_material.d.ts +13 -33
- package/src/generation/foliage/material/make_foliage_material.d.ts.map +1 -1
- package/src/generation/foliage/material/make_foliage_material.js +356 -605
- package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts +39 -4
- package/src/generation/foliage/mesh/foliage_collect_attachments.d.ts.map +1 -1
- package/src/generation/foliage/mesh/foliage_collect_attachments.js +637 -569
- package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts +48 -0
- package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.d.ts.map +1 -0
- package/src/generation/foliage/mesh/interpolate_ring_skin_weights4.js +232 -0
- package/src/generation/foliage/mesh/tree_mesh_build_bark.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_mesh_build_bark.js +1023 -1049
- package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts +9 -2
- package/src/generation/foliage/mesh/tree_mesh_build_foliage.d.ts.map +1 -1
- package/src/generation/foliage/mesh/tree_mesh_build_foliage.js +467 -454
- package/src/generation/foliage/presets/make_tree_species_preset.d.ts.map +1 -1
- package/src/generation/foliage/presets/make_tree_species_preset.js +1648 -870
- package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts +35 -0
- package/src/generation/foliage/skeleton/ShootFrameworkHash.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/ShootFrameworkHash.js +129 -0
- package/src/generation/foliage/skeleton/ShootGirth.d.ts +51 -0
- package/src/generation/foliage/skeleton/ShootGirth.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/ShootGirth.js +212 -0
- package/src/generation/foliage/skeleton/ShootLightField.d.ts +73 -0
- package/src/generation/foliage/skeleton/ShootLightField.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/ShootLightField.js +197 -0
- package/src/generation/foliage/skeleton/TreeSkeleton.d.ts +106 -3
- package/src/generation/foliage/skeleton/TreeSkeleton.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/TreeSkeleton.js +217 -39
- package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts +13 -0
- package/src/generation/foliage/skeleton/flare_lobe_phase_offset.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/flare_lobe_phase_offset.js +16 -0
- package/src/generation/foliage/skeleton/foliage_card_density.d.ts +71 -0
- package/src/generation/foliage/skeleton/foliage_card_density.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/foliage_card_density.js +101 -0
- package/src/generation/foliage/skeleton/foliage_senescence.d.ts +101 -0
- package/src/generation/foliage/skeleton/foliage_senescence.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/foliage_senescence.js +149 -0
- package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts +76 -0
- package/src/generation/foliage/skeleton/foliage_unit_cards.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/foliage_unit_cards.js +95 -0
- package/src/generation/foliage/skeleton/shoot_demography.d.ts +22 -0
- package/src/generation/foliage/skeleton/shoot_demography.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/shoot_demography.js +96 -0
- package/src/generation/foliage/skeleton/shoot_geometry.d.ts +66 -0
- package/src/generation/foliage/skeleton/shoot_geometry.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/shoot_geometry.js +109 -0
- package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts +166 -0
- package/src/generation/foliage/skeleton/shoot_systems_simulate.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/shoot_systems_simulate.js +588 -0
- package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts +28 -12
- package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.js +137 -102
- package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts +112 -0
- package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/tree_skeleton_compute_joint_mechanics.js +408 -0
- package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/tree_skeleton_compute_pipe_radii.js +208 -206
- package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts +5 -2
- package/src/generation/foliage/skeleton/tree_skeleton_grow.d.ts.map +1 -1
- package/src/generation/foliage/skeleton/tree_skeleton_grow.js +2048 -1871
- package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts +17 -0
- package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/tree_skeleton_grow_shoots.js +231 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts +14 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_motion.js +26 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts +10 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.d.ts.map +1 -0
- package/src/generation/foliage/skeleton/tree_skeleton_read_joint_parents.js +20 -0
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.d.ts.map +1 -1
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +4 -1
- package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts +1 -0
- package/src/generation/markers/GridCellActionPlaceMarkerGroup.d.ts.map +1 -1
- package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +98 -86
- package/src/shade/SHADER_F16_PROPOSAL_2026_10_24.md +263 -0
- package/src/shade/descriptor/WebGPUExtensionType.d.ts +17 -0
- package/src/shade/descriptor/WebGPUExtensionType.d.ts.map +1 -1
- package/src/shade/descriptor/WebGPUExtensionType.js +31 -1
- package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts +37 -0
- package/src/shade/playground/foliage_wind/FoliageRigOverlay.d.ts.map +1 -0
- package/src/shade/playground/foliage_wind/FoliageRigOverlay.js +491 -0
- package/src/shade/playground/foliage_wind/foliage_world.d.ts.map +1 -1
- package/src/shade/playground/foliage_wind/foliage_world.js +600 -602
- package/src/shade/playground/foliage_wind/index.html +6 -0
- package/src/shade/playground/foliage_wind/main.js +14 -0
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +2 -1
- package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts +2 -1
- package/src/shade/renderer/animation/foliage/FoliageWindJoint.d.ts.map +1 -1
- package/src/shade/renderer/animation/foliage/FoliageWindJoint.js +2 -1
- package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.d.ts.map +1 -1
- package/src/shade/renderer/animation/foliage/chunk_foliage_wind_step.js +4 -2
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +403 -401
- package/src/shade/renderer/camera/OrbitalCameraController.d.ts +1 -62
- package/src/shade/renderer/camera/OrbitalCameraController.d.ts.map +1 -1
- package/src/shade/renderer/camera/OrbitalCameraController.js +1 -374
- package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/deferred/indirect/chunk_lpv_2d_cache_sample_irradiance.js +3 -0
- package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.d.ts.map +1 -1
- package/src/shade/renderer/deferred/indirect/chunk_lpv_sample_light.js +6 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts +2 -2
- package/src/shade/renderer/fluid/GPUFluidCascade.d.ts.map +1 -1
- package/src/shade/renderer/fluid/GPUFluidCascade.js +6 -3
- package/src/shade/renderer/fluid/GPU_FLUID_OCCUPANCY_AND_SOTA_REVIEW_2026_10_26.md +361 -0
- package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.d.ts.map +1 -1
- package/src/shade/renderer/fluid/coupling/chunk_fluid_cascade_parent.js +335 -241
- package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.d.ts.map +1 -1
- package/src/shade/renderer/fluid/coupling/shader_fluid_cascade_ghosts.js +108 -101
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/chunk_fluid_forcing_query_select.js +69 -67
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts +7 -6
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.d.ts.map +1 -1
- package/src/shade/renderer/fluid/forcing/shader_fluid_forcing_apply.js +341 -287
- package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts +6 -4
- package/src/shade/renderer/fluid/mac/FluidMacPasses.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/FluidMacPasses.js +427 -400
- package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts +10 -5
- package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/chunk_fluid_mac_seams.js +532 -190
- package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/chunk_v3_mac_lattice_corners.js +231 -237
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts +2 -2
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_correct.js +282 -245
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts +1 -3
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_advect_predict.js +139 -109
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts +6 -6
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_curl.js +257 -222
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts +8 -7
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_divergence.js +119 -92
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts +6 -9
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.d.ts.map +1 -1
- package/src/shade/renderer/fluid/mac/shader_fluid_mac_gradient.js +229 -181
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts +17 -7
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/GPUFluidPressureSolve.js +634 -621
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts +8 -6
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_residual_restrict.js +166 -149
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts +8 -6
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.d.ts.map +1 -1
- package/src/shade/renderer/fluid/pressure/shader_fluid_mg_smooth.js +219 -183
- package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.d.ts.map +1 -1
- package/src/shade/renderer/fluid/publish/shader_fluid_wind_publish.js +142 -122
- package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +674 -663
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +63 -29
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +77 -87
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/meshopt_clusterizer.js +4 -3
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +11 -11
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +17 -19
- package/src/shade/renderer/global_illumination/lpv/graph_bake_irradiance_lookup_2d.js +4 -4
- package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/sample/chunk_lpv_mesh_interpolate_radiance_via_atlas.js +5 -1
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +11 -35
- package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/load_usd.js +6 -19
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_draw.js +199 -193
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_avboit_splat.js +151 -143
- package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/bloom/chunk_karis_blur4x4_sample.js +11 -5
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +6 -18
- package/src/shade/renderer/postprocess/gtao/GTAO.js +1 -1
- package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/ao_reproject_shader.js +3 -5
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +1 -1
- package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/chunk_nss_luma_derivative.js +7 -3
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +4 -2
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +4 -1
- package/src/shade/renderer/postprocess/ssr/downsample_karis.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/downsample_karis.js +6 -3
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/chunk_ssr_temporal_accumulate.js +4 -3
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader.js +4 -1
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
- package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap.js +35 -39
- package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/taa/chunk_taa_tonemap_inv.js +20 -17
- package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/taa/shader_taa.js +6 -3
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +3 -1
- package/src/shade/renderer/rasterize/native/avboit/avboit_draw_fragment_body.js +1 -1
- package/src/shade/renderer/rasterize/native/avboit/chunk_avboit_splat_slice.js +2 -2
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_integrate.js +92 -83
- package/src/shade/renderer/rasterize/native/avboit/shader_avboit_splat.js +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.js +12 -4
- package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/bvh/chunk_bvh_query_aabb_cooperative.js +294 -286
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_interpolate_probe_irradiance8.js +5 -5
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe.js +5 -3
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_mesh_interpolate_probe_irradiance.js +9 -6
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/lpv/chunk_lpv_sample_sh3_at.js +33 -38
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +690 -675
- package/src/shade/renderer/shader/type/WebGPUArray.d.ts +3 -0
- package/src/shade/renderer/shader/type/WebGPUArray.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUArray.js +185 -167
- package/src/shade/renderer/shader/type/WebGPUStruct.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/WebGPUStruct.js +461 -455
- package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/serde/read_gpu_typed_buffer.js +335 -211
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js +329 -221
- package/src/shade/renderer/shader/type/type_has_f16.d.ts +12 -0
- package/src/shade/renderer/shader/type/type_has_f16.d.ts.map +1 -0
- package/src/shade/renderer/shader/type/type_has_f16.js +66 -0
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +16 -2
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +5 -2
- package/src/shade/renderer/water/shader_water_avboit.js +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +260 -23
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts +6 -7
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +269 -69
- package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
- package/src/shade/wgsl/validate_wgsl_source.js +27 -1
- package/src/view/controller/controls/ListController.d.ts.map +1 -1
- package/src/view/controller/controls/ListController.js +118 -113
- package/src/view/controller/controls/Vector1Control.js +97 -97
- package/src/view/elements/image/SvgImageView.d.ts +1 -0
- package/src/view/elements/image/SvgImageView.d.ts.map +1 -1
- package/src/view/elements/image/SvgImageView.js +92 -90
- package/src/view/minimap/dom/MinimapTerrainView.d.ts +1 -0
- package/src/view/minimap/dom/MinimapTerrainView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapTerrainView.js +151 -147
- package/src/view/tooltip/gml/TooltipParser.js +2 -2
- package/src/engine/network/PriorityFetch.d.ts +0 -59
- package/src/engine/network/PriorityFetch.d.ts.map +0 -1
- package/src/engine/network/PriorityFetch.js +0 -193
- package/src/generation/foliage/config/BranchLevelConfig.d.ts.map +0 -1
|
@@ -0,0 +1,588 @@
|
|
|
1
|
+
import { GOLDEN_RATIO } from "../../../core/math/GOLDEN_RATIO.js";
|
|
2
|
+
import { PI2 } from "../../../core/math/PI2.js";
|
|
3
|
+
import { clamp } from "../../../core/math/clamp.js";
|
|
4
|
+
import { phyllotaxis_sample_angle } from "../config/PhyllotaxisMode.js";
|
|
5
|
+
import { shoot_order_value } from "../config/ShootBudZone.js";
|
|
6
|
+
import { foliage_atlas_cutout } from "../material/foliage_atlas_cutout.js";
|
|
7
|
+
import { foliage_tile_layout } from "../material/foliage_tile.js";
|
|
8
|
+
import { foliage_card_leaf_area } from "./foliage_card_density.js";
|
|
9
|
+
import { foliage_unit_leaf_count } from "./foliage_unit_cards.js";
|
|
10
|
+
import { ShootFrameworkHash } from "./ShootFrameworkHash.js";
|
|
11
|
+
import { ShootGirth } from "./ShootGirth.js";
|
|
12
|
+
import { ShootLightField } from "./ShootLightField.js";
|
|
13
|
+
import { shoot_expected_yield, shoot_sample_unit_length } from "./shoot_demography.js";
|
|
14
|
+
import { shoot_locate_on_chain, shoot_normalize3, shoot_outward3, shoot_perpendicular3, shoot_radius } from "./shoot_geometry.js";
|
|
15
|
+
|
|
16
|
+
const GOLDEN_ANGLE = PI2 / (GOLDEN_RATIO * GOLDEN_RATIO);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Room (m) the light field leaves around the framework for the twig systems to grow into; leaf past it shades nothing
|
|
20
|
+
* and sees open sky. Chosen.
|
|
21
|
+
* @type {number}
|
|
22
|
+
*/
|
|
23
|
+
const LIGHT_FIELD_MARGIN = 2.0;
|
|
24
|
+
|
|
25
|
+
const SCRATCH_P = new Float32Array(3);
|
|
26
|
+
const SCRATCH_T = new Float32Array(3);
|
|
27
|
+
const SCRATCH_R = new Float64Array(3);
|
|
28
|
+
const SCRATCH_O = new Float64Array(3);
|
|
29
|
+
const SCRATCH_H = new Float64Array(3);
|
|
30
|
+
const SCRATCH_A = new Float64Array(3);
|
|
31
|
+
const SCRATCH_B = new Float64Array(3);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {Object} ShootCarrier
|
|
35
|
+
* @property {import("../config/ShootSystemRule.js").ShootSystemRule} rule
|
|
36
|
+
* @property {number} carrier framework branch
|
|
37
|
+
* @property {number} length metres
|
|
38
|
+
* @property {number[]} nodes the carrier's chain
|
|
39
|
+
* @property {number[]} edges
|
|
40
|
+
* @property {number[]} units lengths (m) of its last annual units, oldest first, ending at its tip
|
|
41
|
+
* @property {Float64Array} starts arc length (m) from its base where each unit starts
|
|
42
|
+
* @property {Float64Array} points world position of each unit boundary, `(units + 1) * 3`, the last its tip
|
|
43
|
+
* @property {number} first_season season its oldest unit grew in
|
|
44
|
+
* @property {Float64Array} [carrier_area] pipe area of what grows on each unit, after the simulation
|
|
45
|
+
* @property {Float64Array} [carrier_demand] radius each unit needs where its laterals join, after the simulation
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @typedef {Object} ShootAxis
|
|
50
|
+
* @property {number} system index of its carrier
|
|
51
|
+
* @property {number} parent mother axis, `-1` for the carrier
|
|
52
|
+
* @property {number} parent_unit unit of the mother it grew from, oldest first
|
|
53
|
+
* @property {number} u where along that unit, 0 base to 1 tip
|
|
54
|
+
* @property {number} node bud index on that unit, for the leaf spiral
|
|
55
|
+
* @property {number} order branching order, the carrier being `rule.carrier_order`
|
|
56
|
+
* @property {boolean} short a short shoot
|
|
57
|
+
* @property {number} generator its branch generator
|
|
58
|
+
* @property {number} phase random phase in [0, 1)
|
|
59
|
+
* @property {number[]} units lengths (m), oldest first
|
|
60
|
+
* @property {number[]} unit_seasons season each unit grew in
|
|
61
|
+
* @property {number[]} points world position of each unit boundary, `(units + 1) * 3`
|
|
62
|
+
* @property {number[]} radii radius (m) of the wood at each unit boundary, `units + 1`
|
|
63
|
+
* @property {number} anchor_edge carrier segment a first-order axis grows from, else -1
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Grows the twig systems of every carrier together, season by season, in the light their leaves make for each other,
|
|
68
|
+
* for `seasons` seasons: the tree's age, so every unit of every carrier has had the time since it grew to grow its
|
|
69
|
+
* twigs.
|
|
70
|
+
*
|
|
71
|
+
* Each season:
|
|
72
|
+
* 1. **Light.** The leaves alive last season are put in a {@link ShootLightField}, and each shoot reads the relative
|
|
73
|
+
* irradiance where it grows.
|
|
74
|
+
* 2. **Extension.** Every living long axis grows a terminal unit, bent from its last by the generator's phototropism,
|
|
75
|
+
* gravitropism and zigzag, `terminal_length + terminal_length_slope *` its last unit long on average.
|
|
76
|
+
* 3. **Short shoots** live on at `short_shoot_survival`, less in light too dim for a shoot to replace itself.
|
|
77
|
+
* 4. **Buds.** Last season's units burst their buds: by zone and mother order, a `long` share grow long shoots and a
|
|
78
|
+
* `short` share short shoots. A `sylleptic` share of this season's units' buds grow at once.
|
|
79
|
+
* 5. **Shedding.** A new shoot in relative light `Q` survives at `p = net_yield(Q) / yield`. That is the species'
|
|
80
|
+
* net shoots per shoot at that light, over the gross new shoots its mother makes. Of a season's new shoots the
|
|
81
|
+
* sum of their `p` survive, with a carried-over remainder so the count is exact on average. They are ranked by
|
|
82
|
+
* `log p` plus the rank of oak's shedding: the highest orders, the youngest axes and the shortest shoots go first
|
|
83
|
+
* (Buck-Sorlin & Bell 1998, Bot. J. Linn. Soc. 127: 371-391, p. 388). So the shaded go before the lit, and among
|
|
84
|
+
* equally lit shoots an established axis outlasts a new lateral. A shed terminal sheds its whole axis with
|
|
85
|
+
* everything on it, as oak sheds only at an axis's base (p. 388). So a branch in deep shade, whose terminals are
|
|
86
|
+
* shed, dies.
|
|
87
|
+
*
|
|
88
|
+
* The wood thickens season by season with what it carries (`ShootGirth`): twigs, carriers, and the framework above
|
|
89
|
+
* them. A shoot whose path would run into framework wood as thick as it is that season is a blocked bud and does not
|
|
90
|
+
* grow; its mother's junction is the one exception. A blocked terminal leaves its axis without a unit that season. A
|
|
91
|
+
* shoot whose wood the framework, or its own girth, has grown into by the end of a season is engulfed and dies with
|
|
92
|
+
* everything on it.
|
|
93
|
+
*
|
|
94
|
+
* @param {import("./TreeSkeleton.js").TreeSkeleton} skeleton
|
|
95
|
+
* @param {import("../config/TreeSpeciesConfig.js").TreeSpeciesConfig} species
|
|
96
|
+
* @param {ShootCarrier[]} carriers
|
|
97
|
+
* @param {number} seasons
|
|
98
|
+
* @param {function():number} rng
|
|
99
|
+
* @returns {ShootAxis[]} the living axes, a mother before its laterals
|
|
100
|
+
*/
|
|
101
|
+
export function shoot_systems_simulate(skeleton, species, carriers, seasons, rng) {
|
|
102
|
+
const growth = species.shoot_growth;
|
|
103
|
+
// everything in the skeleton now is framework
|
|
104
|
+
const framework_segments = skeleton.segment_count;
|
|
105
|
+
const girth = new ShootGirth(skeleton, carriers, skeleton.branch_count, species.crown.pipe_model_exponent);
|
|
106
|
+
let framework = new ShootFrameworkHash(skeleton, framework_segments);
|
|
107
|
+
const leaf_survival = species.foliage.leaf_survival;
|
|
108
|
+
const yields = carriers.map(c => shoot_expected_yield(c.rule));
|
|
109
|
+
|
|
110
|
+
// Leaf area of one leaf, as the cards draw it
|
|
111
|
+
const leafy = new Map();
|
|
112
|
+
for (const rule of species.foliage_rules) {
|
|
113
|
+
leafy.set(rule.source, rule.short_shoot);
|
|
114
|
+
}
|
|
115
|
+
let leaf_area_each = 0;
|
|
116
|
+
if (leafy.size > 0) {
|
|
117
|
+
const layout = foliage_tile_layout(species);
|
|
118
|
+
const coverage = foliage_atlas_cutout(species).mean_coverage();
|
|
119
|
+
leaf_area_each = foliage_card_leaf_area(layout, species.foliage.card_type, coverage, 1.0) / layout.leaves_per_card;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const field = make_light_field(skeleton, growth.light_cell);
|
|
123
|
+
|
|
124
|
+
/** @type {Array<ShootAxis & {alive: boolean, birth: number, heading: number[], taken: Array<number[]|null>, exempt_branch: number, key: number}>} */
|
|
125
|
+
const axes = [];
|
|
126
|
+
/** buds spent on sylleptic shoots per carrier unit, by zone */
|
|
127
|
+
const carrier_taken = carriers.map(c => new Array(c.units.length).fill(null));
|
|
128
|
+
let remainder = 0.5;
|
|
129
|
+
|
|
130
|
+
const survival_at = (light, system) => clamp(growth.net_yield(light) / yields[system], 0, 1);
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Where a bud on unit `k` of a mother sits, and the mother's tangent there, into SCRATCH_P / SCRATCH_T.
|
|
134
|
+
* @returns {{edge: number, u: number}|null} the carrier segment, for a carrier's bud
|
|
135
|
+
*/
|
|
136
|
+
const bud_site = (system, mother, k, u) => {
|
|
137
|
+
if (mother < 0) {
|
|
138
|
+
const c = carriers[system];
|
|
139
|
+
const located = shoot_locate_on_chain(skeleton, c.nodes, c.edges, (c.starts[k] + u * c.units[k]) / c.length);
|
|
140
|
+
skeleton.evaluate_segment_position(SCRATCH_P, 0, located.edge, located.u);
|
|
141
|
+
skeleton.evaluate_segment_tangent(SCRATCH_T, 0, located.edge, located.u);
|
|
142
|
+
shoot_normalize3(SCRATCH_T, SCRATCH_T[0], SCRATCH_T[1], SCRATCH_T[2]);
|
|
143
|
+
return located;
|
|
144
|
+
}
|
|
145
|
+
const p = axes[mother].points;
|
|
146
|
+
const a = k * 3, b = (k + 1) * 3;
|
|
147
|
+
SCRATCH_P[0] = p[a] + (p[b] - p[a]) * u;
|
|
148
|
+
SCRATCH_P[1] = p[a + 1] + (p[b + 1] - p[a + 1]) * u;
|
|
149
|
+
SCRATCH_P[2] = p[a + 2] + (p[b + 2] - p[a + 2]) * u;
|
|
150
|
+
shoot_normalize3(SCRATCH_T, p[b] - p[a], p[b + 1] - p[a + 1], p[b + 2] - p[a + 2]);
|
|
151
|
+
return null;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A lateral from bud `node` at `u` on unit `k` of `mother` (`-1` for the carrier), or -1 when the bud cannot grow:
|
|
156
|
+
* knocked out on a plagiotropic mother, or blocked by framework wood.
|
|
157
|
+
*/
|
|
158
|
+
const spawn = (system, mother, k, u, node, order, mean_length, short, season, candidates) => {
|
|
159
|
+
const c = carriers[system];
|
|
160
|
+
const rule = c.rule;
|
|
161
|
+
const located = bud_site(system, mother, k, u);
|
|
162
|
+
const px = SCRATCH_P[0], py = SCRATCH_P[1], pz = SCRATCH_P[2];
|
|
163
|
+
const mtx = SCRATCH_T[0], mty = SCRATCH_T[1], mtz = SCRATCH_T[2];
|
|
164
|
+
const mother_phase = mother < 0 ? skeleton.branch_phase_hash[c.carrier] : axes[mother].phase;
|
|
165
|
+
const mother_generator = mother < 0 ? rule.source : axes[mother].generator;
|
|
166
|
+
|
|
167
|
+
// radial direction at the bud: a frame around the mother's tangent turned by the leaf spiral
|
|
168
|
+
shoot_perpendicular3(SCRATCH_R, mtx, mty, mtz);
|
|
169
|
+
const rx0 = SCRATCH_R[0], ry0 = SCRATCH_R[1], rz0 = SCRATCH_R[2];
|
|
170
|
+
const sx0 = mty * rz0 - mtz * ry0;
|
|
171
|
+
const sy0 = mtz * rx0 - mtx * rz0;
|
|
172
|
+
const sz0 = mtx * ry0 - mty * rx0;
|
|
173
|
+
const ins = shoot_order_value(rule.insertion_angle, order - 1) * (0.85 + 0.3 * rng());
|
|
174
|
+
const cos_i = Math.cos(ins), sin_i = Math.sin(ins);
|
|
175
|
+
// a plagiotropic mother breaks no bud into the downward cone (its ventral knockout): the bud turns by the golden
|
|
176
|
+
// angle until it clears it, or does not break
|
|
177
|
+
const plagio = species.branches[mother_generator].plagiotropism;
|
|
178
|
+
const ventral_cos = plagio > 0 ? Math.cos(plagio * Math.PI * 0.5) : Infinity;
|
|
179
|
+
let phi = phyllotaxis_sample_angle(rule.phyllotaxis_mode, node, 1, mother_phase * PI2) + (rng() - 0.5) * 0.4;
|
|
180
|
+
let tx = 0, ty = 0, tz = 0;
|
|
181
|
+
let cleared = false;
|
|
182
|
+
for (let attempt = 0; attempt < 5 && !cleared; attempt++, phi += GOLDEN_ANGLE) {
|
|
183
|
+
const drx = Math.cos(phi) * rx0 + Math.sin(phi) * sx0;
|
|
184
|
+
const dry = Math.cos(phi) * ry0 + Math.sin(phi) * sy0;
|
|
185
|
+
const drz = Math.cos(phi) * rz0 + Math.sin(phi) * sz0;
|
|
186
|
+
tx = cos_i * mtx + sin_i * drx;
|
|
187
|
+
ty = cos_i * mty + sin_i * dry;
|
|
188
|
+
tz = cos_i * mtz + sin_i * drz;
|
|
189
|
+
cleared = -ty / Math.max(1e-9, Math.hypot(tx, ty, tz)) <= ventral_cos;
|
|
190
|
+
}
|
|
191
|
+
if (!cleared) return -1;
|
|
192
|
+
shoot_normalize3(SCRATCH_H, tx, ty, tz);
|
|
193
|
+
|
|
194
|
+
const len = short ? rule.short_shoot_growth : shoot_sample_unit_length(rng, mean_length, order, rule);
|
|
195
|
+
SCRATCH_A[0] = px;
|
|
196
|
+
SCRATCH_A[1] = py;
|
|
197
|
+
SCRATCH_A[2] = pz;
|
|
198
|
+
SCRATCH_B[0] = px + SCRATCH_H[0] * len;
|
|
199
|
+
SCRATCH_B[1] = py + SCRATCH_H[1] * len;
|
|
200
|
+
SCRATCH_B[2] = pz + SCRATCH_H[2] * len;
|
|
201
|
+
const exempt_branch = mother < 0 ? c.carrier : -1;
|
|
202
|
+
const exempt_edge = located !== null ? located.edge : -1;
|
|
203
|
+
// a shoot does not grow through wood that was there first, its own junction aside
|
|
204
|
+
if (framework.hits(SCRATCH_A, SCRATCH_B, shoot_radius(len, 0), exempt_branch, exempt_edge)) return -1;
|
|
205
|
+
|
|
206
|
+
const light = field.irradiance_at(px, py, pz);
|
|
207
|
+
axes.push({
|
|
208
|
+
system, parent: mother, parent_unit: k, u, node, order, short,
|
|
209
|
+
generator: short ? rule.short_target : rule.target,
|
|
210
|
+
phase: rng(),
|
|
211
|
+
units: [len],
|
|
212
|
+
unit_seasons: [season],
|
|
213
|
+
points: [px, py, pz, SCRATCH_B[0], SCRATCH_B[1], SCRATCH_B[2]],
|
|
214
|
+
radii: [],
|
|
215
|
+
anchor_edge: located !== null ? located.edge : -1,
|
|
216
|
+
exempt_branch,
|
|
217
|
+
heading: [SCRATCH_H[0], SCRATCH_H[1], SCRATCH_H[2]],
|
|
218
|
+
taken: [null],
|
|
219
|
+
birth: season,
|
|
220
|
+
alive: true,
|
|
221
|
+
key: 0
|
|
222
|
+
});
|
|
223
|
+
const m = axes.length - 1;
|
|
224
|
+
if (!short) {
|
|
225
|
+
const p = survival_at(light, system);
|
|
226
|
+
candidates.push({ axis: m, p, key: shed_rank(p, order, len, 0, rule, rng) });
|
|
227
|
+
axes[m].taken[0] = sylleptic(system, m, 0, len, order, season, candidates);
|
|
228
|
+
}
|
|
229
|
+
return m;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/** Buds of a unit grown this season that grow out at once; the buds they spent, by zone */
|
|
233
|
+
const sylleptic = (system, mother, k, unit_length, order, season, candidates) => {
|
|
234
|
+
const rule = carriers[system].rule;
|
|
235
|
+
if (order + 1 > rule.max_order) return null;
|
|
236
|
+
let taken = null;
|
|
237
|
+
let node = 0;
|
|
238
|
+
for (let z = 0; z < rule.zones.length; z++) {
|
|
239
|
+
const zone = rule.zones[z];
|
|
240
|
+
const n = zone.bud_count(unit_length, order);
|
|
241
|
+
const p = shoot_order_value(zone.sylleptic, order);
|
|
242
|
+
if (p > 0) {
|
|
243
|
+
const count = binomial(rng, n, p);
|
|
244
|
+
if (taken === null) taken = new Array(rule.zones.length).fill(0);
|
|
245
|
+
taken[z] = count;
|
|
246
|
+
const mean = lateral_mean(zone, order, unit_length);
|
|
247
|
+
for (let j = 0; j < count; j++) {
|
|
248
|
+
const u = lerp_u(zone.u_max, zone.u_min, (j + rng()) / Math.max(1, count));
|
|
249
|
+
spawn(system, mother, k, u, node + j, order + 1, mean, false, season, candidates);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
node += n;
|
|
253
|
+
}
|
|
254
|
+
return taken;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/** Unit `k` of a mother, grown last season, bursts its buds */
|
|
258
|
+
const burst = (system, mother, k, unit_length, order, taken, season, candidates) => {
|
|
259
|
+
const rule = carriers[system].rule;
|
|
260
|
+
if (order + 1 > rule.max_order) return;
|
|
261
|
+
let node = 0;
|
|
262
|
+
for (let z = 0; z < rule.zones.length; z++) {
|
|
263
|
+
const zone = rule.zones[z];
|
|
264
|
+
const all = zone.bud_count(unit_length, order);
|
|
265
|
+
const n = all - (taken !== null ? taken[z] : 0);
|
|
266
|
+
const p_long = shoot_order_value(zone.long, order);
|
|
267
|
+
const p_short = shoot_order_value(zone.short, order);
|
|
268
|
+
let n_long = 0;
|
|
269
|
+
let n_short = 0;
|
|
270
|
+
if (p_short > 0) {
|
|
271
|
+
for (let i = 0; i < n; i++) {
|
|
272
|
+
const r = rng();
|
|
273
|
+
if (r < p_long) n_long++;
|
|
274
|
+
else if (r < p_long + p_short) n_short++;
|
|
275
|
+
}
|
|
276
|
+
} else {
|
|
277
|
+
n_long = binomial(rng, n, p_long);
|
|
278
|
+
}
|
|
279
|
+
const mean = lateral_mean(zone, order, unit_length);
|
|
280
|
+
for (let j = 0; j < n_long; j++) {
|
|
281
|
+
spawn(system, mother, k, lerp_u(zone.u_max, zone.u_min, (j + rng()) / Math.max(1, n_long)), node + j, order + 1, mean, false, season, candidates);
|
|
282
|
+
}
|
|
283
|
+
for (let j = 0; j < n_short; j++) {
|
|
284
|
+
spawn(system, mother, k, lerp_u(zone.u_max, zone.u_min, (j + rng()) / Math.max(1, n_short)), node + n_long + j, order + 1, 0, true, season, candidates);
|
|
285
|
+
}
|
|
286
|
+
node += all;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
for (let season = 0; season < seasons; season++) {
|
|
291
|
+
// 1. Light from last season's leaves
|
|
292
|
+
if (season > 0) {
|
|
293
|
+
field.clear();
|
|
294
|
+
deposit_leaves(field, species, carriers, axes, season - 1, leafy, leaf_area_each, leaf_survival);
|
|
295
|
+
field.solve(growth.leaf_clumping);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** @type {Array<{axis: number, p: number, key: number}>} key: the shedding rank, the highest kept */
|
|
299
|
+
const candidates = [];
|
|
300
|
+
|
|
301
|
+
// 2. Every living long axis extends by a terminal unit, a candidate for shedding with its whole axis
|
|
302
|
+
const extended = [];
|
|
303
|
+
const count_before = axes.length;
|
|
304
|
+
for (let m = 0; m < count_before; m++) {
|
|
305
|
+
const axis = axes[m];
|
|
306
|
+
if (!axis.alive || axis.short || axis.birth >= season) continue;
|
|
307
|
+
const rule = carriers[axis.system].rule;
|
|
308
|
+
const cfg = species.branches[axis.generator];
|
|
309
|
+
const n = axis.units.length;
|
|
310
|
+
const pts = axis.points;
|
|
311
|
+
const tip = n * 3;
|
|
312
|
+
const light = field.irradiance_at(pts[tip], pts[tip + 1], pts[tip + 2]);
|
|
313
|
+
shoot_outward3(SCRATCH_O, skeleton, pts[tip], pts[tip + 1], pts[tip + 2]);
|
|
314
|
+
const zig = cfg.internode_zigzag;
|
|
315
|
+
const h = axis.heading;
|
|
316
|
+
shoot_normalize3(
|
|
317
|
+
SCRATCH_H,
|
|
318
|
+
h[0] + cfg.phototropism * 0.5 * SCRATCH_O[0] + (rng() * 2 - 1) * zig,
|
|
319
|
+
h[1] + cfg.phototropism * 0.5 * SCRATCH_O[1] - cfg.gravitropism * 0.5 + (rng() * 2 - 1) * zig,
|
|
320
|
+
h[2] + cfg.phototropism * 0.5 * SCRATCH_O[2] + (rng() * 2 - 1) * zig
|
|
321
|
+
);
|
|
322
|
+
const prev = axis.units[n - 1];
|
|
323
|
+
const mean = shoot_order_value(rule.terminal_length, axis.order) + shoot_order_value(rule.terminal_length_slope, axis.order) * prev;
|
|
324
|
+
const len = shoot_sample_unit_length(rng, mean, axis.order, rule);
|
|
325
|
+
SCRATCH_A[0] = pts[tip];
|
|
326
|
+
SCRATCH_A[1] = pts[tip + 1];
|
|
327
|
+
SCRATCH_A[2] = pts[tip + 2];
|
|
328
|
+
SCRATCH_B[0] = pts[tip] + SCRATCH_H[0] * len;
|
|
329
|
+
SCRATCH_B[1] = pts[tip + 1] + SCRATCH_H[1] * len;
|
|
330
|
+
SCRATCH_B[2] = pts[tip + 2] + SCRATCH_H[2] * len;
|
|
331
|
+
if (framework.hits(SCRATCH_A, SCRATCH_B, shoot_radius(len, 0), axis.exempt_branch, axis.anchor_edge)) continue;
|
|
332
|
+
axis.units.push(len);
|
|
333
|
+
axis.unit_seasons.push(season);
|
|
334
|
+
axis.taken.push(null);
|
|
335
|
+
pts.push(SCRATCH_B[0], SCRATCH_B[1], SCRATCH_B[2]);
|
|
336
|
+
h[0] = SCRATCH_H[0];
|
|
337
|
+
h[1] = SCRATCH_H[1];
|
|
338
|
+
h[2] = SCRATCH_H[2];
|
|
339
|
+
const p_ext = survival_at(light, axis.system);
|
|
340
|
+
candidates.push({ axis: m, p: p_ext, key: shed_rank(p_ext, axis.order, len, season - axis.birth, rule, rng) });
|
|
341
|
+
extended.push(m);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// 3. Short shoots live on, a year's growth each, or die
|
|
345
|
+
for (let m = 0; m < count_before; m++) {
|
|
346
|
+
const axis = axes[m];
|
|
347
|
+
if (!axis.alive || !axis.short || axis.birth >= season) continue;
|
|
348
|
+
const rule = carriers[axis.system].rule;
|
|
349
|
+
const pts = axis.points;
|
|
350
|
+
const tip = axis.units.length * 3;
|
|
351
|
+
const light = field.irradiance_at(pts[tip], pts[tip + 1], pts[tip + 2]);
|
|
352
|
+
if (rng() < rule.short_shoot_survival * Math.min(1, growth.net_yield(light))) {
|
|
353
|
+
const g = rule.short_shoot_growth;
|
|
354
|
+
axis.units.push(g);
|
|
355
|
+
axis.unit_seasons.push(season);
|
|
356
|
+
pts.push(pts[tip] + axis.heading[0] * g, pts[tip + 1] + axis.heading[1] * g, pts[tip + 2] + axis.heading[2] * g);
|
|
357
|
+
} else {
|
|
358
|
+
axis.alive = false;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// 4. Units grown last season burst their buds: on the carriers and on every living long axis
|
|
363
|
+
for (let s = 0; s < carriers.length; s++) {
|
|
364
|
+
const c = carriers[s];
|
|
365
|
+
const k = season - 1 - c.first_season;
|
|
366
|
+
if (k >= 0 && k < c.units.length) {
|
|
367
|
+
burst(s, -1, k, c.units[k], c.rule.carrier_order, carrier_taken[s][k], season, candidates);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
for (let m = 0; m < count_before; m++) {
|
|
371
|
+
const axis = axes[m];
|
|
372
|
+
if (!axis.alive || axis.short || axis.birth >= season) continue;
|
|
373
|
+
const k = axis.unit_seasons.lastIndexOf(season - 1);
|
|
374
|
+
if (k >= 0) {
|
|
375
|
+
burst(axis.system, m, k, axis.units[k], axis.order, axis.taken[k], season, candidates);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// 5. This season's units branch at once where their buds are sylleptic: the carriers' and the extensions'
|
|
380
|
+
for (let s = 0; s < carriers.length; s++) {
|
|
381
|
+
const c = carriers[s];
|
|
382
|
+
const k = season - c.first_season;
|
|
383
|
+
if (k >= 0 && k < c.units.length) {
|
|
384
|
+
carrier_taken[s][k] = sylleptic(s, -1, k, c.units[k], c.rule.carrier_order, season, candidates);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
for (let i = 0; i < extended.length; i++) {
|
|
388
|
+
const m = extended[i];
|
|
389
|
+
const axis = axes[m];
|
|
390
|
+
const k = axis.units.length - 1;
|
|
391
|
+
axis.taken[k] = sylleptic(axis.system, m, k, axis.units[k], axis.order, season, candidates);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// 6. Shedding: the best-lit share of this season's new shoots survives
|
|
395
|
+
let expected = remainder;
|
|
396
|
+
for (let i = 0; i < candidates.length; i++) expected += candidates[i].p;
|
|
397
|
+
const keep = Math.floor(expected);
|
|
398
|
+
remainder = expected - keep;
|
|
399
|
+
candidates.sort((a, b) => b.key - a.key);
|
|
400
|
+
for (let i = keep; i < candidates.length; i++) {
|
|
401
|
+
axes[candidates[i].axis].alive = false;
|
|
402
|
+
}
|
|
403
|
+
// a dead mother takes everything on it; mothers come first
|
|
404
|
+
cascade(axes);
|
|
405
|
+
|
|
406
|
+
// 7. The wood thickens with what it now carries, and what it has grown into dies
|
|
407
|
+
girth.update(axes, season);
|
|
408
|
+
framework = new ShootFrameworkHash(skeleton, framework_segments);
|
|
409
|
+
for (let m = 0; m < axes.length; m++) {
|
|
410
|
+
const axis = axes[m];
|
|
411
|
+
if (!axis.alive) continue;
|
|
412
|
+
if (axis.parent >= 0 && !axes[axis.parent].alive) {
|
|
413
|
+
axis.alive = false;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
const pts = axis.points;
|
|
417
|
+
const r = axis.radii;
|
|
418
|
+
for (let k = 0; k < axis.units.length; k++) {
|
|
419
|
+
SCRATCH_A[0] = pts[k * 3];
|
|
420
|
+
SCRATCH_A[1] = pts[k * 3 + 1];
|
|
421
|
+
SCRATCH_A[2] = pts[k * 3 + 2];
|
|
422
|
+
SCRATCH_B[0] = pts[k * 3 + 3];
|
|
423
|
+
SCRATCH_B[1] = pts[k * 3 + 4];
|
|
424
|
+
SCRATCH_B[2] = pts[k * 3 + 5];
|
|
425
|
+
if (framework.hits(SCRATCH_A, SCRATCH_B, Math.max(r[k], r[k + 1]), axis.exempt_branch, axis.anchor_edge)) {
|
|
426
|
+
axis.alive = false;
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// The living axes, a mother before its laterals
|
|
434
|
+
const index = new Int32Array(axes.length).fill(-1);
|
|
435
|
+
/** @type {ShootAxis[]} */
|
|
436
|
+
const living = [];
|
|
437
|
+
for (let m = 0; m < axes.length; m++) {
|
|
438
|
+
const axis = axes[m];
|
|
439
|
+
if (!axis.alive) continue;
|
|
440
|
+
index[m] = living.length;
|
|
441
|
+
living.push({
|
|
442
|
+
system: axis.system,
|
|
443
|
+
parent: axis.parent < 0 ? -1 : index[axis.parent],
|
|
444
|
+
parent_unit: axis.parent_unit,
|
|
445
|
+
u: axis.u,
|
|
446
|
+
node: axis.node,
|
|
447
|
+
order: axis.order,
|
|
448
|
+
short: axis.short,
|
|
449
|
+
generator: axis.generator,
|
|
450
|
+
phase: axis.phase,
|
|
451
|
+
units: axis.units,
|
|
452
|
+
unit_seasons: axis.unit_seasons,
|
|
453
|
+
points: axis.points,
|
|
454
|
+
radii: axis.radii,
|
|
455
|
+
anchor_edge: axis.anchor_edge
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
return living;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Kills every axis whose mother has died; mothers come before their laterals.
|
|
463
|
+
* @param {Array<{parent: number, alive: boolean}>} axes
|
|
464
|
+
*/
|
|
465
|
+
function cascade(axes) {
|
|
466
|
+
for (let m = 0; m < axes.length; m++) {
|
|
467
|
+
const parent = axes[m].parent;
|
|
468
|
+
if (axes[m].alive && parent >= 0 && !axes[parent].alive) axes[m].alive = false;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* A light field over the framework and {@link LIGHT_FIELD_MARGIN} around it.
|
|
474
|
+
* @param {import("./TreeSkeleton.js").TreeSkeleton} skeleton
|
|
475
|
+
* @param {number} cell
|
|
476
|
+
* @returns {ShootLightField}
|
|
477
|
+
*/
|
|
478
|
+
function make_light_field(skeleton, cell) {
|
|
479
|
+
const min = [Infinity, Infinity, Infinity];
|
|
480
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
481
|
+
const p = new Float32Array(3);
|
|
482
|
+
for (let v = 0; v < skeleton.node_count; v++) {
|
|
483
|
+
skeleton.node_read_position(p, 0, v);
|
|
484
|
+
for (let i = 0; i < 3; i++) {
|
|
485
|
+
min[i] = Math.min(min[i], p[i]);
|
|
486
|
+
max[i] = Math.max(max[i], p[i]);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
for (let i = 0; i < 3; i++) {
|
|
490
|
+
min[i] -= LIGHT_FIELD_MARGIN;
|
|
491
|
+
max[i] += LIGHT_FIELD_MARGIN;
|
|
492
|
+
}
|
|
493
|
+
return new ShootLightField(min, max, cell);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Puts the leaves alive in `season` into `field`: on each leaf-bearing unit young enough to keep them, the unit's leaves
|
|
498
|
+
* times the share of that age still alive, spread along it; a short shoot's at its tip. `leaf_area_each` is one leaf's
|
|
499
|
+
* area (m^2).
|
|
500
|
+
*/
|
|
501
|
+
function deposit_leaves(field, species, carriers, axes, season, leafy, leaf_area_each, leaf_survival) {
|
|
502
|
+
const L = leaf_survival.length;
|
|
503
|
+
for (let s = 0; s < carriers.length; s++) {
|
|
504
|
+
const c = carriers[s];
|
|
505
|
+
if (!leafy.has(c.rule.source)) continue;
|
|
506
|
+
for (let k = 0; k < c.units.length; k++) {
|
|
507
|
+
const age = season - (c.first_season + k);
|
|
508
|
+
if (age < 0 || age >= L) continue;
|
|
509
|
+
const area = foliage_unit_leaf_count(species, false, c.units[k]) * leaf_area_each * leaf_survival[age];
|
|
510
|
+
field.deposit_segment(c.points.subarray(k * 3, k * 3 + 3), c.points.subarray(k * 3 + 3, k * 3 + 6), area);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
for (let m = 0; m < axes.length; m++) {
|
|
514
|
+
const axis = axes[m];
|
|
515
|
+
if (!axis.alive || !leafy.has(axis.generator)) continue;
|
|
516
|
+
const pts = axis.points;
|
|
517
|
+
if (axis.short) {
|
|
518
|
+
const tip = axis.units.length * 3;
|
|
519
|
+
field.deposit(pts[tip], pts[tip + 1], pts[tip + 2], foliage_unit_leaf_count(species, true, 0) * leaf_area_each);
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
for (let k = 0; k < axis.units.length; k++) {
|
|
523
|
+
const age = season - axis.unit_seasons[k];
|
|
524
|
+
if (age < 0 || age >= L) continue;
|
|
525
|
+
const area = foliage_unit_leaf_count(species, false, axis.units[k]) * leaf_area_each * leaf_survival[age];
|
|
526
|
+
SCRATCH_A[0] = pts[k * 3];
|
|
527
|
+
SCRATCH_A[1] = pts[k * 3 + 1];
|
|
528
|
+
SCRATCH_A[2] = pts[k * 3 + 2];
|
|
529
|
+
SCRATCH_B[0] = pts[k * 3 + 3];
|
|
530
|
+
SCRATCH_B[1] = pts[k * 3 + 4];
|
|
531
|
+
SCRATCH_B[2] = pts[k * 3 + 5];
|
|
532
|
+
field.deposit_segment(SCRATCH_A, SCRATCH_B, area);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Rank of a new shoot for surviving, the highest kept: the log of its chance in the light it has, plus oak's shedding
|
|
539
|
+
* rank, by which older axes, lower orders and longer units hold on, and the highest orders and short shoots are shed
|
|
540
|
+
* first [Buck-Sorlin & Bell 1998 p. 388]. The rank's weights are chosen.
|
|
541
|
+
*
|
|
542
|
+
* @param {number} p chance of surviving in its light
|
|
543
|
+
* @param {number} order
|
|
544
|
+
* @param {number} length metres
|
|
545
|
+
* @param {number} age seasons its axis has lived
|
|
546
|
+
* @param {import("../config/ShootSystemRule.js").ShootSystemRule} rule
|
|
547
|
+
* @param {function():number} rng
|
|
548
|
+
* @returns {number}
|
|
549
|
+
*/
|
|
550
|
+
function shed_rank(p, order, length, age, rule, rng) {
|
|
551
|
+
return Math.log(Math.max(1e-6, p)) + 1.5 * age - 0.5 * order + Math.log(length / rule.mean_unit_length) + 0.5 * rng();
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Mean length (m) of the first unit of a long lateral from `zone`, grown on a mother of `order` from a unit
|
|
556
|
+
* `unit_length` long.
|
|
557
|
+
* @param {import("../config/ShootBudZone.js").ShootBudZone} zone
|
|
558
|
+
* @param {number} order
|
|
559
|
+
* @param {number} unit_length
|
|
560
|
+
* @returns {number}
|
|
561
|
+
*/
|
|
562
|
+
function lateral_mean(zone, order, unit_length) {
|
|
563
|
+
return shoot_order_value(zone.length, order) + shoot_order_value(zone.length_slope, order) * unit_length;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* @param {function():number} rng
|
|
568
|
+
* @param {number} n
|
|
569
|
+
* @param {number} p
|
|
570
|
+
* @returns {number}
|
|
571
|
+
*/
|
|
572
|
+
function binomial(rng, n, p) {
|
|
573
|
+
let k = 0;
|
|
574
|
+
for (let i = 0; i < n; i++) {
|
|
575
|
+
if (rng() < p) k++;
|
|
576
|
+
}
|
|
577
|
+
return k;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* @param {number} a
|
|
582
|
+
* @param {number} b
|
|
583
|
+
* @param {number} t
|
|
584
|
+
* @returns {number}
|
|
585
|
+
*/
|
|
586
|
+
function lerp_u(a, b, t) {
|
|
587
|
+
return a + (b - a) * clamp(t, 0, 1);
|
|
588
|
+
}
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* (`joint_parents[j] < j`)
|
|
4
|
-
*
|
|
2
|
+
* Derives the wind joints of a tree for GPU skeletal wind animation (`Skin`) from how its wood bends, in strict
|
|
3
|
+
* topological pre-order (`joint_parents[j] < j`), and writes `[primary_joint_index, parent_joint_index]` into
|
|
4
|
+
* `skeleton.attr_node_joint` for every node, and each joint's pivot and turn in the reference wind into the skeleton
|
|
5
|
+
* (`TreeSkeleton.set_joints`).
|
|
6
|
+
*
|
|
7
|
+
* Joints go where the rig would otherwise hide visible sway. Every segment bends by its share of its branch's bend in a
|
|
8
|
+
* `TREE_WIND_REFERENCE_SPEED` wind (beam elements, `tree_skeleton_compute_segment_mechanics`), saturated as the rig
|
|
9
|
+
* shows it (`tree_wind_bend_limit`). Walking each branch from its base:
|
|
10
|
+
*
|
|
11
|
+
* - while the branch has no joint, its bending is lost: a bend `theta` moves what the segment carries by up to
|
|
12
|
+
* `theta * reach`, so the branch gets a joint at the first node past which that sum is still over the tolerance;
|
|
13
|
+
* - a joint rotates its whole span about its own pivot, so a bend `theta` at a distance `x` along the span lands
|
|
14
|
+
* `theta * x` off, and a new joint starts where that error would pass the tolerance.
|
|
15
|
+
*
|
|
16
|
+
* The tolerance is `species.wind.deflection_tolerance`, a distance in metres. So stiff or bare wood takes few joints,
|
|
17
|
+
* slender leafy wood many, and a tall tree, whose bends move more, more than a small one. Node 0, the trunk
|
|
18
|
+
* base, is always joint 0 and stays anchored. Branches of a `root` generator never get a joint, so surface roots stay
|
|
19
|
+
* bound to their parent's stationary base joint and do not lift out of the soil in wind. `species.wind.max_joints` is
|
|
20
|
+
* only a safety net: past it, the joints that would hide the least sway are dropped.
|
|
5
21
|
*
|
|
6
22
|
* @param {import("./TreeSkeleton.js").TreeSkeleton} skeleton
|
|
7
|
-
* @param {
|
|
23
|
+
* @param {TreeSpeciesConfig} species
|
|
8
24
|
* @returns {{
|
|
9
25
|
* joint_count: number,
|
|
10
26
|
* joint_vertex_ids: Int32Array,
|
|
@@ -13,12 +29,12 @@
|
|
|
13
29
|
* joint_tangents: Float32Array,
|
|
14
30
|
* joint_levels: Uint8Array,
|
|
15
31
|
* joint_phases: Float32Array,
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
32
|
+
* joint_compliance: Float32Array,
|
|
33
|
+
* joint_natural_frequency: Float32Array
|
|
34
|
+
* }} `joint_compliance` (rad / (m/s)^2) and `joint_natural_frequency` (rad/s) are each joint's cantilever
|
|
35
|
+
* wind mechanics, see `tree_skeleton_compute_joint_mechanics`
|
|
20
36
|
*/
|
|
21
|
-
export function tree_skeleton_assign_skin_joints(skeleton: import("./TreeSkeleton.js").TreeSkeleton,
|
|
37
|
+
export function tree_skeleton_assign_skin_joints(skeleton: import("./TreeSkeleton.js").TreeSkeleton, species: TreeSpeciesConfig): {
|
|
22
38
|
joint_count: number;
|
|
23
39
|
joint_vertex_ids: Int32Array;
|
|
24
40
|
joint_parents: Int32Array;
|
|
@@ -26,8 +42,8 @@ export function tree_skeleton_assign_skin_joints(skeleton: import("./TreeSkeleto
|
|
|
26
42
|
joint_tangents: Float32Array;
|
|
27
43
|
joint_levels: Uint8Array;
|
|
28
44
|
joint_phases: Float32Array;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
joint_lengths: Float32Array;
|
|
45
|
+
joint_compliance: Float32Array;
|
|
46
|
+
joint_natural_frequency: Float32Array;
|
|
32
47
|
};
|
|
48
|
+
import { TreeSpeciesConfig } from "../config/TreeSpeciesConfig.js";
|
|
33
49
|
//# sourceMappingURL=tree_skeleton_assign_skin_joints.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree_skeleton_assign_skin_joints.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tree_skeleton_assign_skin_joints.d.ts","sourceRoot":"","sources":["../../../../../src/generation/foliage/skeleton/tree_skeleton_assign_skin_joints.js"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,2DAfW,OAAO,mBAAmB,EAAE,YAAY,WACxC,iBAAiB,GACf;IACZ,WAAe,EAAE,MAAM,CAAC;IACxB,gBAAoB,EAAE,UAAU,CAAC;IACjC,aAAiB,EAAE,UAAU,CAAC;IAC9B,eAAmB,EAAE,YAAY,CAAC;IAClC,cAAkB,EAAE,YAAY,CAAC;IACjC,YAAgB,EAAE,UAAU,CAAC;IAC7B,YAAgB,EAAE,YAAY,CAAC;IAC/B,gBAAoB,EAAE,YAAY,CAAC;IACnC,uBAA2B,EAAE,YAAY,CAAA;CACtC,CAiMH;kCA9OiC,gCAAgC"}
|