@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
|
@@ -1,391 +1,394 @@
|
|
|
1
|
-
import { assert } from "../../core/assert.js";
|
|
2
|
-
import Signal from "../../core/events/signal/Signal.js";
|
|
3
|
-
import { current_time_in_seconds } from "../../core/time/current_time_in_seconds.js";
|
|
4
|
-
import Clock from '../Clock.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Simulation tick generator
|
|
8
|
-
* Dispatches "tick" every animation frame or "maxDelay" time, whichever happens to be soonest
|
|
9
|
-
* This is essentially the timing bus that all the simulation systems subscribe to for their step advancement
|
|
10
|
-
*
|
|
11
|
-
* A tick taken in an animation frame runs inside that frame and is measured to the frame's timestamp,
|
|
12
|
-
* and {@link Ticker#onFrame} follows it, so whatever draws from `onFrame` draws the simulation as of
|
|
13
|
-
* that frame.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ticker.onTick.add(delta_s => {
|
|
18
|
-
* //do something every tick
|
|
19
|
-
* });
|
|
20
|
-
* ticker.start();
|
|
21
|
-
*
|
|
22
|
-
* @author Alex Goldring
|
|
23
|
-
* @copyright Company Named Limited (c) 2026
|
|
24
|
-
*/
|
|
25
|
-
class Ticker {
|
|
26
|
-
/**
|
|
27
|
-
* @readonly
|
|
28
|
-
* @type {Clock}
|
|
29
|
-
*/
|
|
30
|
-
clock = new Clock();
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* When `true`, ticking is suspended while the host document/tab is in the
|
|
34
|
-
* background (hidden, or stored in the back/forward cache) and resumes from
|
|
35
|
-
* the current moment once it returns to the foreground.
|
|
36
|
-
*
|
|
37
|
-
* This avoids dispatching a flood of catch-up ticks (or one huge delta) for
|
|
38
|
-
* the time spent suspended, which would otherwise destabilise the simulation.
|
|
39
|
-
*
|
|
40
|
-
* Has no effect in environments without document/visibility support (e.g.
|
|
41
|
-
* Node.js), where the relevant lifecycle events simply never fire.
|
|
42
|
-
*
|
|
43
|
-
* @type {boolean}
|
|
44
|
-
*/
|
|
45
|
-
suspend_in_background = true;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @private
|
|
49
|
-
* @type {boolean}
|
|
50
|
-
*/
|
|
51
|
-
#isRunning = false;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Whether ticking is currently suspended because the host page is in the background
|
|
55
|
-
* @private
|
|
56
|
-
* @type {boolean}
|
|
57
|
-
*/
|
|
58
|
-
#isSuspended = false;
|
|
59
|
-
|
|
60
|
-
#animationFrameHandle = -1;
|
|
61
|
-
#timeoutHandle = -1;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Incremented by {@link Ticker#stop}. The loop closures capture the value they were started
|
|
65
|
-
* with and refuse to schedule anything once it moves, so a callback already in flight when
|
|
66
|
-
* stop() ran cannot re-arm the loop behind it. Deliberately not keyed on #isRunning: pause()
|
|
67
|
-
* clears that while the loop is meant to keep cycling.
|
|
68
|
-
* @private
|
|
69
|
-
* @type {number}
|
|
70
|
-
*/
|
|
71
|
-
#generation = 0;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Time delta in seconds dispatched by the last tick
|
|
75
|
-
* @type {number}
|
|
76
|
-
*/
|
|
77
|
-
#last_tick_delta_s = 0;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Dispatches time delta in seconds since last tick
|
|
81
|
-
* @readonly
|
|
82
|
-
* @type {Signal<number>}
|
|
83
|
-
*/
|
|
84
|
-
onTick = new Signal();
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Dispatched once per animation frame, after that frame's tick - or with none, while paused or
|
|
88
|
-
* suspended. The place to draw: the simulation is at the frame's timestamp here.
|
|
89
|
-
* Not dispatched for the {@link start}'s `maxTimeout` fallback ticks, which are not frames.
|
|
90
|
-
* @readonly
|
|
91
|
-
* @type {Signal}
|
|
92
|
-
*/
|
|
93
|
-
onFrame = new Signal();
|
|
94
|
-
|
|
95
|
-
constructor() {
|
|
96
|
-
this.clock.pause();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Owned by {@link start} and {@link stop}; the two handles stay purely for cancellation.
|
|
101
|
-
*
|
|
102
|
-
* This used to be `#timeoutHandle !== -1 && #animationFrameHandle !== -1`, but `start()` only
|
|
103
|
-
* assigns the animation-frame handle - the timeout handle stays -1 until the first frame
|
|
104
|
-
* callback runs - so for the whole first frame the ticker reported itself inactive. `start()`'s
|
|
105
|
-
* own "Already running" guard therefore did not fire, and `pause()`/`resume()`, which throw
|
|
106
|
-
* when the loop is NOT active, did. A second `start()` inside that window installed a second
|
|
107
|
-
* rAF/timeout chain, and a graphics context lost and restored inside it left the simulation
|
|
108
|
-
* paused for ever, because Engine's restore path gates `resume()` on this.
|
|
109
|
-
*
|
|
110
|
-
* Unlike `#isRunning`, which `pause()` clears, this stays true across a pause.
|
|
111
|
-
*
|
|
112
|
-
* @type {boolean}
|
|
113
|
-
*/
|
|
114
|
-
#loop_started = false;
|
|
115
|
-
|
|
116
|
-
#isUpdateLoopActive() {
|
|
117
|
-
return this.#loop_started;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Whether the update loop is cycling. {@link Ticker#pause} and {@link Ticker#resume} require this,
|
|
122
|
-
* they throw otherwise.
|
|
123
|
-
* @returns {boolean}
|
|
124
|
-
*/
|
|
125
|
-
get is_active() {
|
|
126
|
-
return this.#isUpdateLoopActive();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Whether tick dispatch is currently stopped via {@link Ticker#pause}. Suspension caused by the host
|
|
131
|
-
* page going into the background is not reported here, see {@link Ticker#suspend_in_background}.
|
|
132
|
-
* @returns {boolean}
|
|
133
|
-
*/
|
|
134
|
-
get is_paused() {
|
|
135
|
-
return !this.#isRunning;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Stop dispatching ticks because the host page moved to the background.
|
|
140
|
-
* The clock is paused so no simulation time accrues while suspended. The
|
|
141
|
-
* update loop itself keeps cycling so it can pick back up cleanly, but
|
|
142
|
-
* {@link Ticker#onTick} stays silent until the page returns to the foreground.
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
|
-
#suspend() {
|
|
146
|
-
if (!this.suspend_in_background) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!this.#isRunning) {
|
|
151
|
-
// not actively ticking, nothing to suspend
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (this.#isSuspended) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
this.#isSuspended = true;
|
|
160
|
-
|
|
161
|
-
this.clock.pause();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Resume after the host page returned to the foreground.
|
|
166
|
-
*
|
|
167
|
-
* The clock is
|
|
168
|
-
* delta accumulated for the suspended period discarded so that time continues
|
|
169
|
-
* from the current moment rather than catching up all at once. Whether ticks
|
|
170
|
-
* actually flow afterwards is still governed by the running flag, so a manual
|
|
171
|
-
* {@link Ticker#pause} taken during suspension is preserved.
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
#resume() {
|
|
175
|
-
if (!this.#isSuspended) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this.#isSuspended = false;
|
|
180
|
-
|
|
181
|
-
this.clock.getDelta(); //discard time spent suspended
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
this
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
//
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
this.#
|
|
384
|
-
this.#
|
|
385
|
-
|
|
386
|
-
this.#
|
|
387
|
-
this.#
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
1
|
+
import { assert } from "../../core/assert.js";
|
|
2
|
+
import Signal from "../../core/events/signal/Signal.js";
|
|
3
|
+
import { current_time_in_seconds } from "../../core/time/current_time_in_seconds.js";
|
|
4
|
+
import Clock from '../Clock.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Simulation tick generator
|
|
8
|
+
* Dispatches "tick" every animation frame or "maxDelay" time, whichever happens to be soonest
|
|
9
|
+
* This is essentially the timing bus that all the simulation systems subscribe to for their step advancement
|
|
10
|
+
*
|
|
11
|
+
* A tick taken in an animation frame runs inside that frame and is measured to the frame's timestamp,
|
|
12
|
+
* and {@link Ticker#onFrame} follows it, so whatever draws from `onFrame` draws the simulation as of
|
|
13
|
+
* that frame.
|
|
14
|
+
*
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ticker.onTick.add(delta_s => {
|
|
18
|
+
* //do something every tick
|
|
19
|
+
* });
|
|
20
|
+
* ticker.start();
|
|
21
|
+
*
|
|
22
|
+
* @author Alex Goldring
|
|
23
|
+
* @copyright Company Named Limited (c) 2026
|
|
24
|
+
*/
|
|
25
|
+
class Ticker {
|
|
26
|
+
/**
|
|
27
|
+
* @readonly
|
|
28
|
+
* @type {Clock}
|
|
29
|
+
*/
|
|
30
|
+
clock = new Clock();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* When `true`, ticking is suspended while the host document/tab is in the
|
|
34
|
+
* background (hidden, or stored in the back/forward cache) and resumes from
|
|
35
|
+
* the current moment once it returns to the foreground.
|
|
36
|
+
*
|
|
37
|
+
* This avoids dispatching a flood of catch-up ticks (or one huge delta) for
|
|
38
|
+
* the time spent suspended, which would otherwise destabilise the simulation.
|
|
39
|
+
*
|
|
40
|
+
* Has no effect in environments without document/visibility support (e.g.
|
|
41
|
+
* Node.js), where the relevant lifecycle events simply never fire.
|
|
42
|
+
*
|
|
43
|
+
* @type {boolean}
|
|
44
|
+
*/
|
|
45
|
+
suspend_in_background = true;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @private
|
|
49
|
+
* @type {boolean}
|
|
50
|
+
*/
|
|
51
|
+
#isRunning = false;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Whether ticking is currently suspended because the host page is in the background
|
|
55
|
+
* @private
|
|
56
|
+
* @type {boolean}
|
|
57
|
+
*/
|
|
58
|
+
#isSuspended = false;
|
|
59
|
+
|
|
60
|
+
#animationFrameHandle = -1;
|
|
61
|
+
#timeoutHandle = -1;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Incremented by {@link Ticker#stop}. The loop closures capture the value they were started
|
|
65
|
+
* with and refuse to schedule anything once it moves, so a callback already in flight when
|
|
66
|
+
* stop() ran cannot re-arm the loop behind it. Deliberately not keyed on #isRunning: pause()
|
|
67
|
+
* clears that while the loop is meant to keep cycling.
|
|
68
|
+
* @private
|
|
69
|
+
* @type {number}
|
|
70
|
+
*/
|
|
71
|
+
#generation = 0;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Time delta in seconds dispatched by the last tick
|
|
75
|
+
* @type {number}
|
|
76
|
+
*/
|
|
77
|
+
#last_tick_delta_s = 0;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Dispatches time delta in seconds since last tick
|
|
81
|
+
* @readonly
|
|
82
|
+
* @type {Signal<number>}
|
|
83
|
+
*/
|
|
84
|
+
onTick = new Signal();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Dispatched once per animation frame, after that frame's tick - or with none, while paused or
|
|
88
|
+
* suspended. The place to draw: the simulation is at the frame's timestamp here.
|
|
89
|
+
* Not dispatched for the {@link start}'s `maxTimeout` fallback ticks, which are not frames.
|
|
90
|
+
* @readonly
|
|
91
|
+
* @type {Signal}
|
|
92
|
+
*/
|
|
93
|
+
onFrame = new Signal();
|
|
94
|
+
|
|
95
|
+
constructor() {
|
|
96
|
+
this.clock.pause();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Owned by {@link start} and {@link stop}; the two handles stay purely for cancellation.
|
|
101
|
+
*
|
|
102
|
+
* This used to be `#timeoutHandle !== -1 && #animationFrameHandle !== -1`, but `start()` only
|
|
103
|
+
* assigns the animation-frame handle - the timeout handle stays -1 until the first frame
|
|
104
|
+
* callback runs - so for the whole first frame the ticker reported itself inactive. `start()`'s
|
|
105
|
+
* own "Already running" guard therefore did not fire, and `pause()`/`resume()`, which throw
|
|
106
|
+
* when the loop is NOT active, did. A second `start()` inside that window installed a second
|
|
107
|
+
* rAF/timeout chain, and a graphics context lost and restored inside it left the simulation
|
|
108
|
+
* paused for ever, because Engine's restore path gates `resume()` on this.
|
|
109
|
+
*
|
|
110
|
+
* Unlike `#isRunning`, which `pause()` clears, this stays true across a pause.
|
|
111
|
+
*
|
|
112
|
+
* @type {boolean}
|
|
113
|
+
*/
|
|
114
|
+
#loop_started = false;
|
|
115
|
+
|
|
116
|
+
#isUpdateLoopActive() {
|
|
117
|
+
return this.#loop_started;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Whether the update loop is cycling. {@link Ticker#pause} and {@link Ticker#resume} require this,
|
|
122
|
+
* they throw otherwise.
|
|
123
|
+
* @returns {boolean}
|
|
124
|
+
*/
|
|
125
|
+
get is_active() {
|
|
126
|
+
return this.#isUpdateLoopActive();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Whether tick dispatch is currently stopped via {@link Ticker#pause}. Suspension caused by the host
|
|
131
|
+
* page going into the background is not reported here, see {@link Ticker#suspend_in_background}.
|
|
132
|
+
* @returns {boolean}
|
|
133
|
+
*/
|
|
134
|
+
get is_paused() {
|
|
135
|
+
return !this.#isRunning;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Stop dispatching ticks because the host page moved to the background.
|
|
140
|
+
* The clock is paused so no simulation time accrues while suspended. The
|
|
141
|
+
* update loop itself keeps cycling so it can pick back up cleanly, but
|
|
142
|
+
* {@link Ticker#onTick} stays silent until the page returns to the foreground.
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
#suspend() {
|
|
146
|
+
if (!this.suspend_in_background) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!this.#isRunning) {
|
|
151
|
+
// not actively ticking, nothing to suspend
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (this.#isSuspended) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
this.#isSuspended = true;
|
|
160
|
+
|
|
161
|
+
this.clock.pause();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Resume after the host page returned to the foreground.
|
|
166
|
+
*
|
|
167
|
+
* The clock is restarted here when not manually paused, with the
|
|
168
|
+
* delta accumulated for the suspended period discarded so that time continues
|
|
169
|
+
* from the current moment rather than catching up all at once. Whether ticks
|
|
170
|
+
* actually flow afterwards is still governed by the running flag, so a manual
|
|
171
|
+
* {@link Ticker#pause} taken during suspension is preserved.
|
|
172
|
+
* @private
|
|
173
|
+
*/
|
|
174
|
+
#resume() {
|
|
175
|
+
if (!this.#isSuspended) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this.#isSuspended = false;
|
|
180
|
+
|
|
181
|
+
this.clock.getDelta(); //discard time spent suspended
|
|
182
|
+
|
|
183
|
+
if (this.#isRunning) {
|
|
184
|
+
this.clock.start();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#handleVisibilityChange = () => {
|
|
189
|
+
const doc = globalThis.document;
|
|
190
|
+
|
|
191
|
+
if (doc === undefined) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (doc.visibilityState === 'hidden') {
|
|
196
|
+
this.#suspend();
|
|
197
|
+
} else {
|
|
198
|
+
this.#resume();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
#handlePageHide = () => {
|
|
203
|
+
this.#suspend();
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
#handlePageShow = () => {
|
|
207
|
+
this.#resume();
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Subscribe to page lifecycle events where the host environment provides them.
|
|
212
|
+
* Degrades gracefully where there is no DOM event target (e.g. Node.js).
|
|
213
|
+
* @private
|
|
214
|
+
*/
|
|
215
|
+
#addLifecycleListeners() {
|
|
216
|
+
const doc = globalThis.document;
|
|
217
|
+
if (doc !== undefined && typeof doc.addEventListener === 'function') {
|
|
218
|
+
doc.addEventListener('visibilitychange', this.#handleVisibilityChange);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (typeof globalThis.addEventListener === 'function') {
|
|
222
|
+
globalThis.addEventListener('pagehide', this.#handlePageHide);
|
|
223
|
+
globalThis.addEventListener('pageshow', this.#handlePageShow);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
#removeLifecycleListeners() {
|
|
231
|
+
const doc = globalThis.document;
|
|
232
|
+
if (doc !== undefined && typeof doc.removeEventListener === 'function') {
|
|
233
|
+
doc.removeEventListener('visibilitychange', this.#handleVisibilityChange);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (typeof globalThis.removeEventListener === 'function') {
|
|
237
|
+
globalThis.removeEventListener('pagehide', this.#handlePageHide);
|
|
238
|
+
globalThis.removeEventListener('pageshow', this.#handlePageShow);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
*
|
|
244
|
+
* @param {Object} [options]
|
|
245
|
+
* @param {number} [options.maxTimeout]
|
|
246
|
+
*/
|
|
247
|
+
start({ maxTimeout = 100 } = {}) {
|
|
248
|
+
assert.isNumber(maxTimeout, 'maxTimeout');
|
|
249
|
+
assert.greaterThan(maxTimeout, 0);
|
|
250
|
+
|
|
251
|
+
if (this.#isUpdateLoopActive()) {
|
|
252
|
+
throw new Error("Already running");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
this.#loop_started = true;
|
|
256
|
+
this.#isRunning = true;
|
|
257
|
+
this.#isSuspended = false;
|
|
258
|
+
|
|
259
|
+
const generation = this.#generation;
|
|
260
|
+
const is_current = () => this.#generation === generation;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* @param {number} time in seconds, on the {@link current_time_in_seconds} timeline
|
|
264
|
+
*/
|
|
265
|
+
const update = (time) => {
|
|
266
|
+
if (!this.#isRunning || this.#isSuspended) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const delta = this.clock.getDeltaAt(time);
|
|
271
|
+
|
|
272
|
+
this.#last_tick_delta_s = delta;
|
|
273
|
+
|
|
274
|
+
this.onTick.send1(delta);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const timeoutCallback = () => {
|
|
278
|
+
cancelAnimationFrame(this.#animationFrameHandle);
|
|
279
|
+
|
|
280
|
+
if (!is_current()) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
animate(current_time_in_seconds());
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @param {number} timestamp the frame's, in milliseconds
|
|
289
|
+
*/
|
|
290
|
+
const animationFrameCallback = (timestamp) => {
|
|
291
|
+
clearTimeout(this.#timeoutHandle);
|
|
292
|
+
|
|
293
|
+
if (!is_current()) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/*
|
|
298
|
+
Ticked here, on the frame's own timestamp, and before the frame is announced. This used to
|
|
299
|
+
be pushed to a setTimeout(0) "allowing draw to happen" first, which made every frame draw
|
|
300
|
+
the simulation as of the previous frame's timeout - and that fired whenever the previous
|
|
301
|
+
draw finished, so a steady motion was drawn at a different speed every frame.
|
|
302
|
+
*/
|
|
303
|
+
animate(timestamp * 1e-3);
|
|
304
|
+
|
|
305
|
+
//a tick listener is allowed to stop us
|
|
306
|
+
if (!is_current()) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
this.onFrame.send0();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* @param {number} time in seconds, on the {@link current_time_in_seconds} timeline
|
|
315
|
+
*/
|
|
316
|
+
const animate = (time) => {
|
|
317
|
+
if (!is_current()) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
this.#animationFrameHandle = requestAnimationFrame(animationFrameCallback);
|
|
322
|
+
|
|
323
|
+
update(time);
|
|
324
|
+
|
|
325
|
+
//update() dispatches onTick, and a listener is allowed to stop us from inside it
|
|
326
|
+
if (!is_current()) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
this.#timeoutHandle = setTimeout(timeoutCallback, maxTimeout);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
this.clock.getDelta(); //purge delta
|
|
334
|
+
this.clock.start();
|
|
335
|
+
|
|
336
|
+
this.#addLifecycleListeners();
|
|
337
|
+
|
|
338
|
+
//recorded, so a stop() taken before the first frame lands can cancel it. The generation guard
|
|
339
|
+
//already makes the callback a no-op, but an uncancelled frame request keeps the closures (and
|
|
340
|
+
//everything the tick listeners hold) alive until it fires
|
|
341
|
+
this.#animationFrameHandle = requestAnimationFrame(animationFrameCallback);
|
|
342
|
+
|
|
343
|
+
//if we are starting while the page is already in the background, suspend right away
|
|
344
|
+
const doc = globalThis.document;
|
|
345
|
+
if (doc !== undefined && doc.visibilityState === 'hidden') {
|
|
346
|
+
this.#suspend();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
pause() {
|
|
351
|
+
|
|
352
|
+
if (!this.#isUpdateLoopActive()) {
|
|
353
|
+
throw new Error("Not currently running");
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
this.#isRunning = false;
|
|
357
|
+
|
|
358
|
+
//freeze the clock so no simulation time accrues while paused; without this
|
|
359
|
+
//the first getDelta() after resume() returns the whole paused duration
|
|
360
|
+
this.clock.pause();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
resume() {
|
|
364
|
+
|
|
365
|
+
if (!this.#isUpdateLoopActive()) {
|
|
366
|
+
throw new Error("Not currently running");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
this.#isRunning = true;
|
|
371
|
+
|
|
372
|
+
//discard the time spent paused and restart from the current moment,
|
|
373
|
+
//mirroring #resume() for the background-suspend path
|
|
374
|
+
this.clock.getDelta();
|
|
375
|
+
this.clock.start();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
stop() {
|
|
379
|
+
this.#generation++;
|
|
380
|
+
|
|
381
|
+
this.#removeLifecycleListeners();
|
|
382
|
+
|
|
383
|
+
clearTimeout(this.#timeoutHandle);
|
|
384
|
+
cancelAnimationFrame(this.#animationFrameHandle);
|
|
385
|
+
this.#loop_started = false;
|
|
386
|
+
this.#isRunning = false;
|
|
387
|
+
this.#isSuspended = false;
|
|
388
|
+
|
|
389
|
+
this.#timeoutHandle = -1;
|
|
390
|
+
this.#animationFrameHandle = -1;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export default Ticker;
|