@woosh/meep-engine 3.55.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/ecs/transform/Transform64.d.ts +21 -0
- package/src/engine/ecs/transform/Transform64.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform64.js +26 -0
- 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/Renderer.d.ts +5 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +25 -2
- 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/GPUParticleSystem.d.ts +2 -1
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts +2 -2
- package/src/shade/renderer/particles/graph_particles_avboit.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles_avboit.js +4 -9
- 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/NSS.d.ts +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/view/GPUViewContext.d.ts +0 -14
- package/src/shade/renderer/view/GPUViewContext.d.ts.map +1 -1
- package/src/shade/renderer/view/GPUViewContext.js +0 -29
- package/src/shade/renderer/view/ViewManager.d.ts +1 -1
- package/src/shade/renderer/view/ViewManager.js +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts +40 -3
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +660 -583
- 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/renderer/wind/GPUSceneWind.d.ts +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
- package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.d.ts +0 -2
- package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.d.ts.map +0 -1
- package/src/shade/renderer/volumetrics/VOLUMETRICS_RESOLUTION_Z.js +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
|
+
}
|