@woosh/meep-engine 2.138.19 → 2.139.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/package.json +2 -1
- package/src/core/collection/PairUint32Map.d.ts +100 -0
- package/src/core/collection/PairUint32Map.d.ts.map +1 -0
- package/src/core/collection/PairUint32Map.js +321 -0
- package/src/core/collection/Uint32Map.d.ts +119 -0
- package/src/core/collection/Uint32Map.d.ts.map +1 -0
- package/src/core/collection/Uint32Map.js +345 -0
- package/src/core/collection/array/array_shuffle.d.ts +10 -3
- package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
- package/src/core/collection/array/array_shuffle.js +27 -22
- package/src/core/collection/heap/FibonacciHeap.d.ts +195 -0
- package/src/core/collection/heap/FibonacciHeap.d.ts.map +1 -0
- package/src/core/collection/heap/FibonacciHeap.js +586 -0
- package/src/core/collection/heap/Uint32Heap.js +1 -1
- package/src/core/collection/heap/Uint32Heap4.d.ts +169 -0
- package/src/core/collection/heap/Uint32Heap4.d.ts.map +1 -0
- package/src/core/collection/heap/Uint32Heap4.js +490 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts +27 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.d.ts.map +1 -0
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +88 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts +61 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/BoxShape3D.js +158 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +11 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CapsuleShape3D.js +12 -0
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts +37 -9
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -98
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts +10 -0
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitSphereShape3D.js +11 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts +61 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -0
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +148 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts +39 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +147 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts +15 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +22 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts +2 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +673 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts +26 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +222 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts +34 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts +36 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts +33 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts +68 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +365 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +31 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +112 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +22 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +55 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts +32 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +49 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +134 -0
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +276 -3
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts +17 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +135 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts +14 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +177 -0
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +20 -4
- 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 +5 -3
- 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 +9 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -45
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.js +7 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts +8 -6
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +8 -6
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts +22 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +73 -0
- 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 +51 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts +10 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts +28 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +227 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts +13 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts +11 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.d.ts.map +1 -0
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +20 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts +20 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +38 -0
- package/src/core/graph/csr/CSRGraph.d.ts +168 -0
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -0
- package/src/core/graph/csr/CSRGraph.js +319 -0
- package/src/core/graph/metis/cluster_mesh_metis.d.ts +12 -0
- package/src/core/graph/metis/cluster_mesh_metis.d.ts.map +1 -1
- package/src/core/graph/metis/cluster_mesh_metis.js +12 -0
- package/src/core/graph/metis/metis.d.ts +19 -0
- package/src/core/graph/metis/metis.d.ts.map +1 -1
- package/src/core/graph/metis/metis.js +20 -0
- package/src/core/graph/metis/metis_cluster_bs.d.ts +11 -0
- package/src/core/graph/metis/metis_cluster_bs.d.ts.map +1 -1
- package/src/core/graph/metis/metis_cluster_bs.js +11 -0
- package/src/core/graph/metis/metis_options.d.ts +17 -2
- package/src/core/graph/metis/metis_options.d.ts.map +1 -1
- package/src/core/graph/metis/metis_options.js +17 -2
- package/src/core/graph/metis/native/MetisGraph.d.ts +144 -0
- package/src/core/graph/metis/native/MetisGraph.d.ts.map +1 -0
- package/src/core/graph/metis/native/MetisGraph.js +212 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts +72 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/BisectionScratch.js +101 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.d.ts +37 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts +15 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/compute_2way_params.js +84 -0
- package/src/core/graph/metis/native/bisection/fm_2way.d.ts +30 -0
- package/src/core/graph/metis/native/bisection/fm_2way.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/fm_2way.js +290 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.d.ts +23 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts +28 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.d.ts.map +1 -0
- package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts +20 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts +24 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -0
- package/src/core/graph/metis/native/coarsen/match_shem.d.ts +41 -0
- package/src/core/graph/metis/native/coarsen/match_shem.d.ts.map +1 -0
- package/src/core/graph/metis/native/coarsen/match_shem.js +175 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts +24 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.d.ts.map +1 -0
- package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts +29 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.d.ts.map +1 -0
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -0
- package/src/core/graph/metis/native/metis_partition_kway.d.ts +41 -0
- package/src/core/graph/metis/native/metis_partition_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/metis_partition_kway.js +126 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts +62 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/IndexedFloatMaxHeap.js +261 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts +45 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.d.ts +18 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/compute_kway_params.js +138 -0
- package/src/core/graph/metis/native/refine/fm_kway.d.ts +63 -0
- package/src/core/graph/metis/native/refine/fm_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/fm_kway.js +462 -0
- package/src/core/graph/metis/native/refine/project_kway.d.ts +22 -0
- package/src/core/graph/metis/native/refine/project_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/project_kway.js +43 -0
- package/src/core/graph/metis/native/refine/refine_kway.d.ts +34 -0
- package/src/core/graph/metis/native/refine/refine_kway.d.ts.map +1 -0
- package/src/core/graph/metis/native/refine/refine_kway.js +43 -0
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts +2 -2
- package/src/core/math/linalg/eigen/matrix_householder_in_place.js +2 -2
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +6 -4
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_qr_in_place.js +69 -23
- package/src/engine/EngineHarness.d.ts +3 -1
- package/src/engine/EngineHarness.d.ts.map +1 -1
- package/src/engine/EngineHarness.js +6 -4
- package/src/engine/control/first-person/DESIGN.md +30 -6
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +102 -9
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.js +38 -3
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +533 -4
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +315 -6
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +220 -22
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +858 -241
- package/src/engine/control/first-person/TODO.md +127 -0
- package/src/engine/control/first-person/abilities/Ability.d.ts +101 -0
- package/src/engine/control/first-person/abilities/Ability.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Ability.js +119 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts +86 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/AbilitySet.js +185 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +62 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.js +199 -0
- package/src/engine/control/first-person/abilities/Mantle.d.ts +45 -0
- package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Mantle.js +188 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts +33 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/Slide.js +158 -0
- package/src/engine/control/first-person/abilities/WallJump.d.ts +45 -0
- package/src/engine/control/first-person/abilities/WallJump.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/WallJump.js +131 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts +44 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/WallRun.js +180 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts +49 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.d.ts.map +1 -0
- package/src/engine/control/first-person/composer/EyeOffsetStack.js +60 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts +100 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/BreathRhythmEvaluator.js +133 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.d.ts +10 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts +61 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/FootAsymmetryTurnEvaluator.js +109 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts +40 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasteryEvaluator.js +45 -0
- package/src/engine/control/first-person/mastery/MasteryScore.d.ts +68 -0
- package/src/engine/control/first-person/mastery/MasteryScore.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasteryScore.js +100 -0
- package/src/engine/control/first-person/mastery/MasterySet.d.ts +60 -0
- package/src/engine/control/first-person/mastery/MasterySet.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/MasterySet.js +86 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +58 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +83 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +69 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -0
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +109 -0
- package/src/engine/control/first-person/math/Spring.d.ts +56 -0
- package/src/engine/control/first-person/math/Spring.d.ts.map +1 -0
- package/src/engine/control/first-person/math/Spring.js +71 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts +26 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.d.ts.map +1 -0
- package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -0
- package/src/engine/control/first-person/math/computeMassRatios.d.ts +35 -0
- package/src/engine/control/first-person/math/computeMassRatios.d.ts.map +1 -0
- package/src/engine/control/first-person/math/computeMassRatios.js +44 -0
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts +31 -1
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts.map +1 -1
- package/src/engine/control/first-person/pose/FirstPersonPose.js +49 -3
- package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts +7 -0
- package/src/engine/control/first-person/pose/FirstPersonPosture.d.ts.map +1 -0
- package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -0
- package/src/engine/control/first-person/prototype_first_person_controller.js +550 -119
- package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts +58 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensors.d.ts.map +1 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensors.js +77 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts +80 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -0
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +196 -0
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts +20 -0
- package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -0
- package/src/engine/control/first-person/test/buildTestPlayer.js +28 -0
- package/src/engine/ecs/EntityManager.d.ts +2 -2
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +13 -8
- package/src/engine/ecs/System.d.ts.map +1 -1
- package/src/engine/ecs/System.js +2 -2
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -2
- package/src/engine/graphics/ecs/light/Light.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/Light.js +27 -0
- package/src/engine/graphics/ecs/light/LightSystem.js +1 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +0 -2
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -2
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -2
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -2
- package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts.map +1 -1
- package/src/engine/navigation/grid/find_path_on_grid_astar.js +11 -2
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -1
- package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +11 -1
- package/src/engine/physics/PLAN.md +236 -0
- package/src/engine/physics/body/BodyStorage.d.ts +187 -0
- package/src/engine/physics/body/BodyStorage.d.ts.map +1 -0
- package/src/engine/physics/body/BodyStorage.js +427 -0
- package/src/engine/physics/broadphase/PairList.d.ts +62 -0
- package/src/engine/physics/broadphase/PairList.d.ts.map +1 -0
- package/src/engine/physics/broadphase/PairList.js +97 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts +30 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +1 -0
- package/src/engine/physics/broadphase/aabb_transform_oriented.js +93 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts +16 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.d.ts.map +1 -0
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +61 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts +38 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -0
- package/src/engine/physics/broadphase/generate_pairs.js +101 -0
- package/src/engine/physics/contact/ManifoldStore.d.ts +226 -0
- package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -0
- package/src/engine/physics/contact/ManifoldStore.js +499 -0
- package/src/engine/physics/ecs/BodyKind.d.ts +23 -0
- package/src/engine/physics/ecs/BodyKind.d.ts.map +1 -0
- package/src/engine/physics/ecs/BodyKind.js +24 -0
- package/src/engine/physics/ecs/Collider.d.ts +98 -0
- package/src/engine/physics/ecs/Collider.d.ts.map +1 -0
- package/src/engine/physics/ecs/Collider.js +136 -0
- package/src/engine/physics/ecs/ColliderFlags.d.ts +14 -0
- package/src/engine/physics/ecs/ColliderFlags.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderFlags.js +15 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +58 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderObserverSystem.js +103 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts +25 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -0
- package/src/engine/physics/ecs/PhysicsEvents.d.ts +15 -0
- package/src/engine/physics/ecs/PhysicsEvents.d.ts.map +1 -0
- package/src/engine/physics/ecs/PhysicsEvents.js +16 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +520 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/PhysicsSystem.js +1159 -0
- package/src/engine/physics/ecs/RigidBody.d.ts +197 -0
- package/src/engine/physics/ecs/RigidBody.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBody.js +240 -0
- package/src/engine/physics/ecs/RigidBodyFlags.d.ts +21 -0
- package/src/engine/physics/ecs/RigidBodyFlags.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBodyFlags.js +22 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts +28 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.d.ts.map +1 -0
- package/src/engine/physics/ecs/RigidBodySerializationAdapter.js +81 -0
- package/src/engine/physics/ecs/SleepState.d.ts +11 -0
- package/src/engine/physics/ecs/SleepState.d.ts.map +1 -0
- package/src/engine/physics/ecs/SleepState.js +12 -0
- package/src/engine/physics/events/ContactEventBuffer.d.ts +46 -0
- package/src/engine/physics/events/ContactEventBuffer.d.ts.map +1 -0
- package/src/engine/physics/events/ContactEventBuffer.js +83 -0
- package/src/engine/physics/events/diff_manifolds.d.ts +25 -0
- package/src/engine/physics/events/diff_manifolds.d.ts.map +1 -0
- package/src/engine/physics/events/diff_manifolds.js +50 -0
- package/src/engine/physics/fluid/FluidField.d.ts +294 -16
- package/src/engine/physics/fluid/FluidField.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidField.js +510 -66
- package/src/engine/physics/fluid/FluidSimulator.d.ts +188 -5
- package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
- package/src/engine/physics/fluid/FluidSimulator.js +455 -95
- package/src/engine/physics/fluid/SliceVisualiser.d.ts +29 -6
- package/src/engine/physics/fluid/SliceVisualiser.d.ts.map +1 -1
- package/src/engine/physics/fluid/SliceVisualiser.js +190 -165
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +154 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.js +238 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts +45 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +107 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts.map +1 -0
- package/src/engine/physics/fluid/ecs/FluidSystem.js +278 -0
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts +62 -1
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -6
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts +17 -4
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +105 -12
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts +43 -0
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.d.ts.map +1 -0
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +210 -0
- package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts +62 -1
- package/src/engine/physics/fluid/effector/WakeFluidEffector.d.ts.map +1 -1
- package/src/engine/physics/fluid/effector/WakeFluidEffector.js +302 -8
- package/src/engine/physics/fluid/prototype.js +102 -91
- package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts +33 -0
- package/src/engine/physics/fluid/solver/optimal_sor_omega.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/optimal_sor_omega.js +41 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts +20 -5
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_forward.js +60 -38
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts +25 -4
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_diffusion.js +93 -73
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts +23 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_apply_scalar_advection.js +60 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts +23 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_divergence.js +68 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts +30 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +66 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts +26 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts +30 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts +49 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +126 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts +93 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +424 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +20 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +83 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +26 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -0
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +70 -0
- package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
- package/src/engine/physics/gjk/expanding_polytope_algorithm.js +8 -10
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts +29 -0
- package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -0
- package/src/engine/physics/inertia/world_inverse_inertia.js +79 -0
- package/src/engine/physics/integration/integrate_position.d.ts +16 -0
- package/src/engine/physics/integration/integrate_position.d.ts.map +1 -0
- package/src/engine/physics/integration/integrate_position.js +48 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts +25 -0
- package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -0
- package/src/engine/physics/integration/integrate_velocity.js +79 -0
- package/src/engine/physics/integration/quat_integrate.d.ts +27 -0
- package/src/engine/physics/integration/quat_integrate.d.ts.map +1 -0
- package/src/engine/physics/integration/quat_integrate.js +62 -0
- package/src/engine/physics/island/IslandBuilder.d.ts +167 -0
- package/src/engine/physics/island/IslandBuilder.d.ts.map +1 -0
- package/src/engine/physics/island/IslandBuilder.js +411 -0
- package/src/engine/physics/island/union_find.d.ts +51 -0
- package/src/engine/physics/island/union_find.d.ts.map +1 -0
- package/src/engine/physics/island/union_find.js +76 -0
- package/src/engine/physics/narrowphase/PosedShape.d.ts +59 -0
- package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/PosedShape.js +110 -0
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts +32 -0
- package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/box_box_manifold.js +543 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts +122 -0
- package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/capsule_contacts.js +508 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts +11 -0
- package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/narrowphase_step.js +382 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts +38 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_box_contact.js +130 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts +26 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.d.ts.map +1 -0
- package/src/engine/physics/narrowphase/sphere_sphere_contact.js +51 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts +83 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.d.ts.map +1 -0
- package/src/engine/physics/queries/PhysicsSurfacePoint.js +100 -0
- package/src/engine/physics/queries/raycast.d.ts +20 -0
- package/src/engine/physics/queries/raycast.d.ts.map +1 -0
- package/src/engine/physics/queries/raycast.js +249 -0
- package/src/engine/physics/solver/friction_cone.d.ts +16 -0
- package/src/engine/physics/solver/friction_cone.d.ts.map +1 -0
- package/src/engine/physics/solver/friction_cone.js +37 -0
- package/src/engine/physics/solver/solve_contacts.d.ts +36 -0
- package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -0
- package/src/engine/physics/solver/solve_contacts.js +598 -0
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts +0 -34
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.js +0 -66
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.js +0 -54
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts.map +0 -1
- package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.js +0 -26
- package/src/engine/ecs/components/Motion.d.ts +0 -21
- package/src/engine/ecs/components/Motion.d.ts.map +0 -1
- package/src/engine/ecs/components/Motion.js +0 -27
- package/src/engine/ecs/components/MotionSerializationAdapter.d.ts +0 -20
- package/src/engine/ecs/components/MotionSerializationAdapter.d.ts.map +0 -1
- package/src/engine/ecs/components/MotionSerializationAdapter.js +0 -26
- package/src/engine/ecs/systems/MotionSystem.d.ts +0 -9
- package/src/engine/ecs/systems/MotionSystem.d.ts.map +0 -1
- package/src/engine/ecs/systems/MotionSystem.js +0 -29
- package/src/engine/physics/fluid/Fluid.d.ts +0 -26
- package/src/engine/physics/fluid/Fluid.d.ts.map +0 -1
- package/src/engine/physics/fluid/Fluid.js +0 -221
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts +0 -7
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.d.ts.map +0 -1
- package/src/engine/physics/fluid/solver/v3_grid_apply_advection_reverse.js +0 -8
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# First-person controller — TODO
|
|
2
|
+
|
|
3
|
+
Working notes. Things we've identified as worth doing but haven't pulled
|
|
4
|
+
the trigger on yet. Companion to DESIGN.md (base) and DESIGN_EXTENSIONS.md
|
|
5
|
+
(abilities + mastery roadmap).
|
|
6
|
+
|
|
7
|
+
## Mastery evaluators — additional
|
|
8
|
+
|
|
9
|
+
We ship StrideTimingJump, FootAsymmetryTurn, BreathRhythm, and
|
|
10
|
+
SlideInitiationTiming today. The remaining ones from the
|
|
11
|
+
DESIGN_EXTENSIONS Phase 10 list, ordered by what would give the most
|
|
12
|
+
texture per unit of work:
|
|
13
|
+
|
|
14
|
+
### WallRunEntryTimingEvaluator
|
|
15
|
+
Decision point: `WallRunGravity` (currently un-wired — Wall-run reads
|
|
16
|
+
`cfg.wallRun.gravityFactor` straight, no mastery hook). Wire it.
|
|
17
|
+
|
|
18
|
+
Input: angle-of-attack against the wall at activation. Lower angle of
|
|
19
|
+
attack (entering near-parallel) is the canonical "good" entry — converts
|
|
20
|
+
forward momentum into the run smoothly. High angle of attack (entering
|
|
21
|
+
near-perpendicular) is "bad" — you're crashing into the wall.
|
|
22
|
+
|
|
23
|
+
Curve shape: peak at small angle (1.0 → 0.8, less effective gravity =
|
|
24
|
+
more hang time); penalty at high angle (1.0 → 1.15, gravity ramped =
|
|
25
|
+
shorter run). Symmetric in behaviour, asymmetric in magnitude.
|
|
26
|
+
|
|
27
|
+
Estimated effort: 0.5 day. Capture entry angle in WallRun.onActivate,
|
|
28
|
+
stash it on the evaluator's per-instance state OR on a new
|
|
29
|
+
`runtime.wallRunEntryAngle` field. Curve + spec.
|
|
30
|
+
|
|
31
|
+
### WallRunTakeoffTimingEvaluator
|
|
32
|
+
Decision point: `WallJumpImpulse` (already wired — base WallJump runs
|
|
33
|
+
mastery on it).
|
|
34
|
+
|
|
35
|
+
Input: how late in the wall-run the wall-jump is fired. Late in the
|
|
36
|
+
run (near the timer expiry) is the "explosive last-second push-off"
|
|
37
|
+
— bonus. Right at activation is "panicked early jump" — penalty.
|
|
38
|
+
|
|
39
|
+
Curve shape: time-based, normalized to [0, 1] over wall-run duration.
|
|
40
|
+
Peak at 0.6–0.9 (committed but not desperate). Trough near 0.0
|
|
41
|
+
(panicked).
|
|
42
|
+
|
|
43
|
+
Estimated effort: 0.5 day. WallJump needs to read how long WallRun was
|
|
44
|
+
active when it preempted. Simplest: track `runtime.wallRunElapsedAt
|
|
45
|
+
Takeoff` in WallRun.onDeactivate (or via a signal).
|
|
46
|
+
|
|
47
|
+
### WallJumpEntryAngleEvaluator
|
|
48
|
+
Decision point: `WallJumpImpulse`.
|
|
49
|
+
|
|
50
|
+
Input: angle between the player's velocity vector and the wall normal
|
|
51
|
+
at the moment of jump press. A near-perpendicular push-off (velocity
|
|
52
|
+
along normal at impact) converts the most into the impulse — bonus.
|
|
53
|
+
A near-tangent push (sliding along) is "weak push-off" — penalty.
|
|
54
|
+
|
|
55
|
+
Curve shape: peak at dot(velocity, normal) approaching 1.0 (head-on);
|
|
56
|
+
penalty near 0 (parallel skim).
|
|
57
|
+
|
|
58
|
+
Composes multiplicatively with the takeoff-timing evaluator above —
|
|
59
|
+
both fire on `WallJumpImpulse`. That's the point of the multiplicative
|
|
60
|
+
composition rule.
|
|
61
|
+
|
|
62
|
+
Estimated effort: 0.5 day.
|
|
63
|
+
|
|
64
|
+
### LedgeCatchTimingEvaluator
|
|
65
|
+
Decision point: NEW — would need `LedgeCatchExertionScale` or similar.
|
|
66
|
+
Currently LedgeGrab uses a flat `cfg.ledgeGrab.exertionRiseRate`.
|
|
67
|
+
|
|
68
|
+
Input: |velocityY| at the moment of catch. A gentle catch (low vy) is
|
|
69
|
+
forgiving — low exertion rise (longer hang). A desperate save (high
|
|
70
|
+
|vy|) is harder — higher exertion rise (shorter hang).
|
|
71
|
+
|
|
72
|
+
Curve shape: identity 1.0 at low |vy| (≤ 2 m/s), ramping up to ~1.5×
|
|
73
|
+
at high |vy| (≥ 8 m/s).
|
|
74
|
+
|
|
75
|
+
Estimated effort: 0.5 day, plus adding the new decision point.
|
|
76
|
+
|
|
77
|
+
### MantleExitSpeedEvaluator
|
|
78
|
+
Decision point: `MantleExitSpeed` (currently un-wired).
|
|
79
|
+
|
|
80
|
+
Input: stride-phase at the moment of mantle completion. Landing on a
|
|
81
|
+
midstance push-off bonus the exit velocity (player runs off the mantle
|
|
82
|
+
into the next surface); landing on footfall takes a small penalty.
|
|
83
|
+
|
|
84
|
+
Currently Mantle's exit doesn't set any forward velocity — the player
|
|
85
|
+
lands at rest. To make this evaluator meaningful, we'd also need
|
|
86
|
+
Mantle to apply a small forward push on completion, which the
|
|
87
|
+
evaluator then scales. Two-step change.
|
|
88
|
+
|
|
89
|
+
Estimated effort: 1 day (more wiring than the others).
|
|
90
|
+
|
|
91
|
+
## Other open notes
|
|
92
|
+
|
|
93
|
+
### Refactor `pose.crouchAmount` away
|
|
94
|
+
Now redundant with `pose.postureAmount`. Leave for one or two builds so
|
|
95
|
+
any external consumers can migrate, then delete.
|
|
96
|
+
|
|
97
|
+
### Stride-mastery score telemetry
|
|
98
|
+
`MasterySet` records EMA scores per decision point. We never surface
|
|
99
|
+
these to the HUD or any feedback system. A simple debug overlay
|
|
100
|
+
showing the running scores (a sparkline per decision point?) would be
|
|
101
|
+
helpful when tuning curves.
|
|
102
|
+
|
|
103
|
+
### Tune the slide bob fade-out
|
|
104
|
+
`bobIntensityHalfLife` controls how fast the lateral bob fades when
|
|
105
|
+
posture changes to Prone. May be too slow — feels like a brief wobble
|
|
106
|
+
before the slide settles into "pure motion". Worth play-test tuning.
|
|
107
|
+
|
|
108
|
+
### Posture-aware footstep audio
|
|
109
|
+
Surface tag is on `state.surfaceTag`. The footstep signal carries
|
|
110
|
+
side + speed + surfaceTag, but emission is gated on
|
|
111
|
+
`feetStriking` (Stand or Crouch posture). When other postures want
|
|
112
|
+
audio cues (a slide-along-pavement sound, a hang-grip creak), they
|
|
113
|
+
need their own signal channels — not piggyback on `onFootStep`.
|
|
114
|
+
|
|
115
|
+
### WallRun direction sense (push-back behaviour)
|
|
116
|
+
Currently WallRun projects velocity onto the wall tangent each tick.
|
|
117
|
+
If the player turns AWAY from the wall mid-run, the wall-tangent
|
|
118
|
+
projection still keeps them pinned. Might want a "lean-away exits the
|
|
119
|
+
run" condition: if `intent.move` rotates more than X degrees from the
|
|
120
|
+
wall tangent, exit the wall-run.
|
|
121
|
+
|
|
122
|
+
### Animation track for Hang posture
|
|
123
|
+
The eye stays at body height while hanging (we don't drop the eye
|
|
124
|
+
height in Hang because the body root is already below the ledge). But
|
|
125
|
+
the rig should probably show arms reaching up. That's a skeleton
|
|
126
|
+
concern, not a controller one — just flagging that `pose.posture =
|
|
127
|
+
Hang` is the signal the rig should branch on.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for movement abilities (wall-run, mantle, slide, ledge-grab,
|
|
3
|
+
* wall-jump, etc.). Each ability is a small state machine that:
|
|
4
|
+
*
|
|
5
|
+
* 1. Reports whether it wants to activate ({@link canActivate})
|
|
6
|
+
* 2. Owns the player's motion while active ({@link tick})
|
|
7
|
+
* 3. Reports whether it can be preempted right now ({@link canInterrupt})
|
|
8
|
+
* 4. Cleans up when control is released ({@link onDeactivate})
|
|
9
|
+
*
|
|
10
|
+
* Abilities are owned by an {@link AbilitySet}. At most one ability is
|
|
11
|
+
* active at a time. Preemption and queueing are handled by the set — see
|
|
12
|
+
* its docs for the hybrid policy.
|
|
13
|
+
*
|
|
14
|
+
* Subclasses should set:
|
|
15
|
+
* - `priority` — used to order preemption attempts
|
|
16
|
+
* - `name` — for telemetry / debugging
|
|
17
|
+
*
|
|
18
|
+
* @author Alex Goldring
|
|
19
|
+
* @copyright Company Named Limited (c) 2026
|
|
20
|
+
*/
|
|
21
|
+
export class Ability {
|
|
22
|
+
/**
|
|
23
|
+
* Higher priority preempts lower. Defaults:
|
|
24
|
+
* slide=10, mantle=30, ledgeGrab=40, wallRun=50, wallJump=60.
|
|
25
|
+
* Wall-jump is highest because it's the most input-direct response
|
|
26
|
+
* (button press) and should fire reliably regardless of what else
|
|
27
|
+
* is going on.
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
priority: number;
|
|
31
|
+
/**
|
|
32
|
+
* Stable string identifier for telemetry / debugging overlays.
|
|
33
|
+
* @type {string}
|
|
34
|
+
*/
|
|
35
|
+
name: string;
|
|
36
|
+
/**
|
|
37
|
+
* Ask: do you want to take control RIGHT NOW?
|
|
38
|
+
*
|
|
39
|
+
* Read controller state and sensor data; return true iff conditions
|
|
40
|
+
* are met. Side-effect-free; called every tick when no ability is
|
|
41
|
+
* active, and once on each tick when this ability is queued behind
|
|
42
|
+
* another.
|
|
43
|
+
*
|
|
44
|
+
* @param {*} controller FirstPersonPlayerController
|
|
45
|
+
* @param {*} runtime per-entity runtime
|
|
46
|
+
* @param {*} sensors FirstPersonSensors (may be null in stub mode)
|
|
47
|
+
* @returns {boolean}
|
|
48
|
+
*/
|
|
49
|
+
canActivate(controller: any, runtime: any, sensors: any): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Called once when this ability acquires control. Use for one-shot
|
|
52
|
+
* setup (kicking impulses, capturing entry velocity, etc.).
|
|
53
|
+
*
|
|
54
|
+
* @param {*} controller
|
|
55
|
+
* @param {*} runtime
|
|
56
|
+
*/
|
|
57
|
+
onActivate(controller: any, runtime: any): void;
|
|
58
|
+
/**
|
|
59
|
+
* Runs each fixed step while active. The ability OWNS body motion
|
|
60
|
+
* during this window — writes directly to runtime.velocity*, the body
|
|
61
|
+
* Transform position, springs, etc. Returning false releases control
|
|
62
|
+
* back to the AbilitySet (which will run base locomotion or the next
|
|
63
|
+
* queued ability in the same tick).
|
|
64
|
+
*
|
|
65
|
+
* The `system` parameter is the {@link FirstPersonPlayerControllerSystem}
|
|
66
|
+
* itself, passed through so abilities can call shared helpers like
|
|
67
|
+
* vertical-integration-and-ground-resolution without re-implementing
|
|
68
|
+
* them. Use it sparingly — the cleaner the ability's tick is, the
|
|
69
|
+
* easier it is to reason about ownership.
|
|
70
|
+
*
|
|
71
|
+
* @param {*} controller
|
|
72
|
+
* @param {*} runtime
|
|
73
|
+
* @param {*} bodyTransform
|
|
74
|
+
* @param {number} dt
|
|
75
|
+
* @param {*} system the FirstPersonPlayerControllerSystem instance
|
|
76
|
+
* @returns {boolean} true = stay active; false = release control
|
|
77
|
+
*/
|
|
78
|
+
tick(controller: any, runtime: any, bodyTransform: any, dt: number, system: any): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Ask: can a higher-priority ability preempt you right now?
|
|
81
|
+
*
|
|
82
|
+
* Defaults to true (interruptible). Override to declare windows where
|
|
83
|
+
* this ability *must* finish what it's doing — e.g. mantle returns
|
|
84
|
+
* false while on its scripted path; slide returns false for the
|
|
85
|
+
* first ~150ms after entry.
|
|
86
|
+
*
|
|
87
|
+
* @param {*} controller
|
|
88
|
+
* @param {*} runtime
|
|
89
|
+
* @returns {boolean}
|
|
90
|
+
*/
|
|
91
|
+
canInterrupt(controller: any, runtime: any): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Called once when control is released (either tick returned false,
|
|
94
|
+
* or a higher-priority ability preempted). Clean up internal state.
|
|
95
|
+
*
|
|
96
|
+
* @param {*} controller
|
|
97
|
+
* @param {*} runtime
|
|
98
|
+
*/
|
|
99
|
+
onDeactivate(controller: any, runtime: any): void;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=Ability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ability.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/Ability.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IAEQ;;;;;;;OAOG;IACH,UAFU,MAAM,CAEC;IAEjB;;;OAGG;IACH,MAFU,MAAM,CAEK;IAGzB;;;;;;;;;;;;OAYG;IAEH,0DAHa,OAAO,CAKnB;IAED;;;;;;OAMG;IAEH,gDAAkC;IAElC;;;;;;;;;;;;;;;;;;;OAmBG;IAEH,4DALW,MAAM,gBAEJ,OAAO,CAKnB;IAED;;;;;;;;;;;OAWG;IAEH,6CAHa,OAAO,CAKnB;IAED;;;;;;OAMG;IAEH,kDAAoC;CACvC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for movement abilities (wall-run, mantle, slide, ledge-grab,
|
|
3
|
+
* wall-jump, etc.). Each ability is a small state machine that:
|
|
4
|
+
*
|
|
5
|
+
* 1. Reports whether it wants to activate ({@link canActivate})
|
|
6
|
+
* 2. Owns the player's motion while active ({@link tick})
|
|
7
|
+
* 3. Reports whether it can be preempted right now ({@link canInterrupt})
|
|
8
|
+
* 4. Cleans up when control is released ({@link onDeactivate})
|
|
9
|
+
*
|
|
10
|
+
* Abilities are owned by an {@link AbilitySet}. At most one ability is
|
|
11
|
+
* active at a time. Preemption and queueing are handled by the set — see
|
|
12
|
+
* its docs for the hybrid policy.
|
|
13
|
+
*
|
|
14
|
+
* Subclasses should set:
|
|
15
|
+
* - `priority` — used to order preemption attempts
|
|
16
|
+
* - `name` — for telemetry / debugging
|
|
17
|
+
*
|
|
18
|
+
* @author Alex Goldring
|
|
19
|
+
* @copyright Company Named Limited (c) 2026
|
|
20
|
+
*/
|
|
21
|
+
export class Ability {
|
|
22
|
+
constructor() {
|
|
23
|
+
/**
|
|
24
|
+
* Higher priority preempts lower. Defaults:
|
|
25
|
+
* slide=10, mantle=30, ledgeGrab=40, wallRun=50, wallJump=60.
|
|
26
|
+
* Wall-jump is highest because it's the most input-direct response
|
|
27
|
+
* (button press) and should fire reliably regardless of what else
|
|
28
|
+
* is going on.
|
|
29
|
+
* @type {number}
|
|
30
|
+
*/
|
|
31
|
+
this.priority = 0;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Stable string identifier for telemetry / debugging overlays.
|
|
35
|
+
* @type {string}
|
|
36
|
+
*/
|
|
37
|
+
this.name = "Ability";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Ask: do you want to take control RIGHT NOW?
|
|
42
|
+
*
|
|
43
|
+
* Read controller state and sensor data; return true iff conditions
|
|
44
|
+
* are met. Side-effect-free; called every tick when no ability is
|
|
45
|
+
* active, and once on each tick when this ability is queued behind
|
|
46
|
+
* another.
|
|
47
|
+
*
|
|
48
|
+
* @param {*} controller FirstPersonPlayerController
|
|
49
|
+
* @param {*} runtime per-entity runtime
|
|
50
|
+
* @param {*} sensors FirstPersonSensors (may be null in stub mode)
|
|
51
|
+
* @returns {boolean}
|
|
52
|
+
*/
|
|
53
|
+
// eslint-disable-next-line no-unused-vars
|
|
54
|
+
canActivate(controller, runtime, sensors) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Called once when this ability acquires control. Use for one-shot
|
|
60
|
+
* setup (kicking impulses, capturing entry velocity, etc.).
|
|
61
|
+
*
|
|
62
|
+
* @param {*} controller
|
|
63
|
+
* @param {*} runtime
|
|
64
|
+
*/
|
|
65
|
+
// eslint-disable-next-line no-unused-vars
|
|
66
|
+
onActivate(controller, runtime) {}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Runs each fixed step while active. The ability OWNS body motion
|
|
70
|
+
* during this window — writes directly to runtime.velocity*, the body
|
|
71
|
+
* Transform position, springs, etc. Returning false releases control
|
|
72
|
+
* back to the AbilitySet (which will run base locomotion or the next
|
|
73
|
+
* queued ability in the same tick).
|
|
74
|
+
*
|
|
75
|
+
* The `system` parameter is the {@link FirstPersonPlayerControllerSystem}
|
|
76
|
+
* itself, passed through so abilities can call shared helpers like
|
|
77
|
+
* vertical-integration-and-ground-resolution without re-implementing
|
|
78
|
+
* them. Use it sparingly — the cleaner the ability's tick is, the
|
|
79
|
+
* easier it is to reason about ownership.
|
|
80
|
+
*
|
|
81
|
+
* @param {*} controller
|
|
82
|
+
* @param {*} runtime
|
|
83
|
+
* @param {*} bodyTransform
|
|
84
|
+
* @param {number} dt
|
|
85
|
+
* @param {*} system the FirstPersonPlayerControllerSystem instance
|
|
86
|
+
* @returns {boolean} true = stay active; false = release control
|
|
87
|
+
*/
|
|
88
|
+
// eslint-disable-next-line no-unused-vars
|
|
89
|
+
tick(controller, runtime, bodyTransform, dt, system) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Ask: can a higher-priority ability preempt you right now?
|
|
95
|
+
*
|
|
96
|
+
* Defaults to true (interruptible). Override to declare windows where
|
|
97
|
+
* this ability *must* finish what it's doing — e.g. mantle returns
|
|
98
|
+
* false while on its scripted path; slide returns false for the
|
|
99
|
+
* first ~150ms after entry.
|
|
100
|
+
*
|
|
101
|
+
* @param {*} controller
|
|
102
|
+
* @param {*} runtime
|
|
103
|
+
* @returns {boolean}
|
|
104
|
+
*/
|
|
105
|
+
// eslint-disable-next-line no-unused-vars
|
|
106
|
+
canInterrupt(controller, runtime) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Called once when control is released (either tick returned false,
|
|
112
|
+
* or a higher-priority ability preempted). Clean up internal state.
|
|
113
|
+
*
|
|
114
|
+
* @param {*} controller
|
|
115
|
+
* @param {*} runtime
|
|
116
|
+
*/
|
|
117
|
+
// eslint-disable-next-line no-unused-vars
|
|
118
|
+
onDeactivate(controller, runtime) {}
|
|
119
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds a set of {@link Ability} instances and runs the activation +
|
|
3
|
+
* preemption + queueing policy:
|
|
4
|
+
*
|
|
5
|
+
* 1. If an ability is active, tick it first.
|
|
6
|
+
* - If its tick returns false → it's done. Falls through to step 2
|
|
7
|
+
* in the SAME tick (no wasted frame).
|
|
8
|
+
*
|
|
9
|
+
* 2. If a queued ability exists (from a previous tick that was blocked),
|
|
10
|
+
* check its canActivate() again. If still wants in → activate.
|
|
11
|
+
*
|
|
12
|
+
* 3. If no ability is active, poll all abilities in DESCENDING priority.
|
|
13
|
+
* First that canActivate() becomes active.
|
|
14
|
+
*
|
|
15
|
+
* 4. If an active ability is still running but a higher-priority one
|
|
16
|
+
* wants in: check the active one's canInterrupt(). If yes → preempt
|
|
17
|
+
* now. If no → queue the higher-priority candidate; it will re-check
|
|
18
|
+
* every tick until the current ability releases (or canInterrupt
|
|
19
|
+
* flips to true).
|
|
20
|
+
*
|
|
21
|
+
* Returns whether base-locomotion should run this tick (true iff no
|
|
22
|
+
* ability owns motion).
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
export class AbilitySet {
|
|
28
|
+
/**
|
|
29
|
+
* Registered abilities. Order does not matter — sorted by priority
|
|
30
|
+
* on demand when polling. Set is small (typically <10) so we don't
|
|
31
|
+
* pre-sort.
|
|
32
|
+
* @type {Ability[]}
|
|
33
|
+
*/
|
|
34
|
+
abilities: Ability[];
|
|
35
|
+
/**
|
|
36
|
+
* Currently-active ability, or null if base locomotion is running.
|
|
37
|
+
* @type {Ability|null}
|
|
38
|
+
*/
|
|
39
|
+
active: Ability | null;
|
|
40
|
+
/**
|
|
41
|
+
* Ability waiting for the current one to release. Cleared when it
|
|
42
|
+
* activates OR when its canActivate() returns false on re-check
|
|
43
|
+
* (the conditions that wanted it might have passed).
|
|
44
|
+
* @type {Ability|null}
|
|
45
|
+
*/
|
|
46
|
+
queued: Ability | null;
|
|
47
|
+
/**
|
|
48
|
+
* Add an ability.
|
|
49
|
+
* @param {Ability} ability
|
|
50
|
+
*/
|
|
51
|
+
add(ability: Ability): void;
|
|
52
|
+
/**
|
|
53
|
+
* Remove an ability if present. If it's currently active or queued,
|
|
54
|
+
* deactivates / clears it first.
|
|
55
|
+
* @param {Ability} ability
|
|
56
|
+
*/
|
|
57
|
+
remove(ability: Ability): void;
|
|
58
|
+
/**
|
|
59
|
+
* Execute one tick. Returns true if base locomotion should run this
|
|
60
|
+
* fixed step (no ability owns motion).
|
|
61
|
+
*
|
|
62
|
+
* @param {*} controller
|
|
63
|
+
* @param {*} runtime
|
|
64
|
+
* @param {*} bodyTransform
|
|
65
|
+
* @param {*} sensors
|
|
66
|
+
* @param {number} dt
|
|
67
|
+
* @param {*} [system] FirstPersonPlayerControllerSystem instance,
|
|
68
|
+
* passed through to ability.tick() so abilities
|
|
69
|
+
* can delegate to shared helpers.
|
|
70
|
+
* @returns {boolean} true = run base locomotion; false = ability owned
|
|
71
|
+
*/
|
|
72
|
+
tick(controller: any, runtime: any, bodyTransform: any, sensors: any, dt: number, system?: any): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
private _findHighestPriorityActivatable;
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
private _activate;
|
|
81
|
+
/**
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
private _deactivate;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=AbilitySet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbilitySet.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/AbilitySet.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;IAEQ;;;;;OAKG;IACH,WAFU,SAAS,CAEA;IAEnB;;;OAGG;IACH,QAFU,UAAQ,IAAI,CAEJ;IAElB;;;;;OAKG;IACH,QAFU,UAAQ,IAAI,CAEJ;IAGtB;;;OAGG;IACH,4BAEC;IAED;;;;OAIG;IACH,+BAQC;IAED;;;;;;;;;;;;;OAaG;IACH,0EANW,MAAM,iBAIJ,OAAO,CA4DnB;IAED;;OAEG;IACH,wCAcC;IAED;;OAEG;IACH,kBAGC;IAED;;OAEG;IACH,oBAKC;CACJ"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds a set of {@link Ability} instances and runs the activation +
|
|
3
|
+
* preemption + queueing policy:
|
|
4
|
+
*
|
|
5
|
+
* 1. If an ability is active, tick it first.
|
|
6
|
+
* - If its tick returns false → it's done. Falls through to step 2
|
|
7
|
+
* in the SAME tick (no wasted frame).
|
|
8
|
+
*
|
|
9
|
+
* 2. If a queued ability exists (from a previous tick that was blocked),
|
|
10
|
+
* check its canActivate() again. If still wants in → activate.
|
|
11
|
+
*
|
|
12
|
+
* 3. If no ability is active, poll all abilities in DESCENDING priority.
|
|
13
|
+
* First that canActivate() becomes active.
|
|
14
|
+
*
|
|
15
|
+
* 4. If an active ability is still running but a higher-priority one
|
|
16
|
+
* wants in: check the active one's canInterrupt(). If yes → preempt
|
|
17
|
+
* now. If no → queue the higher-priority candidate; it will re-check
|
|
18
|
+
* every tick until the current ability releases (or canInterrupt
|
|
19
|
+
* flips to true).
|
|
20
|
+
*
|
|
21
|
+
* Returns whether base-locomotion should run this tick (true iff no
|
|
22
|
+
* ability owns motion).
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
export class AbilitySet {
|
|
28
|
+
constructor() {
|
|
29
|
+
/**
|
|
30
|
+
* Registered abilities. Order does not matter — sorted by priority
|
|
31
|
+
* on demand when polling. Set is small (typically <10) so we don't
|
|
32
|
+
* pre-sort.
|
|
33
|
+
* @type {Ability[]}
|
|
34
|
+
*/
|
|
35
|
+
this.abilities = [];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Currently-active ability, or null if base locomotion is running.
|
|
39
|
+
* @type {Ability|null}
|
|
40
|
+
*/
|
|
41
|
+
this.active = null;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Ability waiting for the current one to release. Cleared when it
|
|
45
|
+
* activates OR when its canActivate() returns false on re-check
|
|
46
|
+
* (the conditions that wanted it might have passed).
|
|
47
|
+
* @type {Ability|null}
|
|
48
|
+
*/
|
|
49
|
+
this.queued = null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Add an ability.
|
|
54
|
+
* @param {Ability} ability
|
|
55
|
+
*/
|
|
56
|
+
add(ability) {
|
|
57
|
+
this.abilities.push(ability);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Remove an ability if present. If it's currently active or queued,
|
|
62
|
+
* deactivates / clears it first.
|
|
63
|
+
* @param {Ability} ability
|
|
64
|
+
*/
|
|
65
|
+
remove(ability) {
|
|
66
|
+
if (this.active === ability) {
|
|
67
|
+
// Best-effort: caller-side cleanup is their responsibility.
|
|
68
|
+
this.active = null;
|
|
69
|
+
}
|
|
70
|
+
if (this.queued === ability) this.queued = null;
|
|
71
|
+
const i = this.abilities.indexOf(ability);
|
|
72
|
+
if (i !== -1) this.abilities.splice(i, 1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Execute one tick. Returns true if base locomotion should run this
|
|
77
|
+
* fixed step (no ability owns motion).
|
|
78
|
+
*
|
|
79
|
+
* @param {*} controller
|
|
80
|
+
* @param {*} runtime
|
|
81
|
+
* @param {*} bodyTransform
|
|
82
|
+
* @param {*} sensors
|
|
83
|
+
* @param {number} dt
|
|
84
|
+
* @param {*} [system] FirstPersonPlayerControllerSystem instance,
|
|
85
|
+
* passed through to ability.tick() so abilities
|
|
86
|
+
* can delegate to shared helpers.
|
|
87
|
+
* @returns {boolean} true = run base locomotion; false = ability owned
|
|
88
|
+
*/
|
|
89
|
+
tick(controller, runtime, bodyTransform, sensors, dt, system) {
|
|
90
|
+
// Step 1: tick the active ability if any. May release control.
|
|
91
|
+
if (this.active !== null) {
|
|
92
|
+
const stillActive = this.active.tick(controller, runtime, bodyTransform, dt, system);
|
|
93
|
+
if (!stillActive) {
|
|
94
|
+
this._deactivate(controller, runtime);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Step 2: if something is queued, see if it can activate now (the
|
|
99
|
+
// current ability may have released in step 1, OR may be
|
|
100
|
+
// interruptible now even though it wasn't before).
|
|
101
|
+
if (this.queued !== null) {
|
|
102
|
+
if (this.active === null) {
|
|
103
|
+
if (this.queued.canActivate(controller, runtime, sensors)) {
|
|
104
|
+
this._activate(this.queued, controller, runtime);
|
|
105
|
+
}
|
|
106
|
+
this.queued = null; // cleared whether or not it activated
|
|
107
|
+
} else if (this.queued.priority > this.active.priority
|
|
108
|
+
&& this.active.canInterrupt(controller, runtime)) {
|
|
109
|
+
if (this.queued.canActivate(controller, runtime, sensors)) {
|
|
110
|
+
const next = this.queued;
|
|
111
|
+
this.queued = null;
|
|
112
|
+
this._deactivate(controller, runtime);
|
|
113
|
+
this._activate(next, controller, runtime);
|
|
114
|
+
} else {
|
|
115
|
+
// Queued candidate no longer wants in — drop it.
|
|
116
|
+
this.queued = null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// else: still waiting on a non-interruptible current ability
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Step 3: if nothing active, poll candidates (highest priority first).
|
|
123
|
+
if (this.active === null) {
|
|
124
|
+
const best = this._findHighestPriorityActivatable(controller, runtime, sensors, -Infinity);
|
|
125
|
+
if (best !== null) {
|
|
126
|
+
this._activate(best, controller, runtime);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
// Step 4: existing ability active — check if a higher-priority
|
|
130
|
+
// candidate wants in.
|
|
131
|
+
const challenger = this._findHighestPriorityActivatable(
|
|
132
|
+
controller, runtime, sensors, this.active.priority,
|
|
133
|
+
);
|
|
134
|
+
if (challenger !== null) {
|
|
135
|
+
if (this.active.canInterrupt(controller, runtime)) {
|
|
136
|
+
this._deactivate(controller, runtime);
|
|
137
|
+
this._activate(challenger, controller, runtime);
|
|
138
|
+
} else {
|
|
139
|
+
// Queue it — will re-poll each tick until current releases
|
|
140
|
+
// or becomes interruptible.
|
|
141
|
+
this.queued = challenger;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return this.active === null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
_findHighestPriorityActivatable(controller, runtime, sensors, minPriorityExclusive) {
|
|
153
|
+
let best = null;
|
|
154
|
+
let bestPriority = minPriorityExclusive;
|
|
155
|
+
const list = this.abilities;
|
|
156
|
+
for (let i = 0; i < list.length; i++) {
|
|
157
|
+
const a = list[i];
|
|
158
|
+
if (a === this.active) continue;
|
|
159
|
+
if (a.priority <= bestPriority) continue;
|
|
160
|
+
if (a.canActivate(controller, runtime, sensors)) {
|
|
161
|
+
best = a;
|
|
162
|
+
bestPriority = a.priority;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return best;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
_activate(ability, controller, runtime) {
|
|
172
|
+
this.active = ability;
|
|
173
|
+
ability.onActivate(controller, runtime);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @private
|
|
178
|
+
*/
|
|
179
|
+
_deactivate(controller, runtime) {
|
|
180
|
+
if (this.active === null) return;
|
|
181
|
+
const prev = this.active;
|
|
182
|
+
this.active = null;
|
|
183
|
+
prev.onDeactivate(controller, runtime);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ledge-grab ability — snap to a forward ledge while descending and hang
|
|
3
|
+
* from it until the player chooses (or is forced) to release.
|
|
4
|
+
*
|
|
5
|
+
* Activation:
|
|
6
|
+
* - `sensors.ledgeAhead.hit` (a forward+up obstacle probe found a grab-
|
|
7
|
+
* able edge — typically the same probe mantle uses).
|
|
8
|
+
* - `runtime.velocityY <= 0` — the player is descending or static. We
|
|
9
|
+
* don't auto-catch ledges on the way UP — that would feel like the
|
|
10
|
+
* world is grabbing the player mid-jump.
|
|
11
|
+
* - `state.airborneTime >= minAirborneTime` — leaves a small window
|
|
12
|
+
* after takeoff where ledge-grab can't fire, even if the player is
|
|
13
|
+
* instantly at apex (which would otherwise satisfy `velocityY <= 0`).
|
|
14
|
+
* - Forward intent (`intent.move.y > 0.1`) — the player must be
|
|
15
|
+
* committing into the ledge. Walking backwards off an edge shouldn't
|
|
16
|
+
* auto-catch the lip.
|
|
17
|
+
*
|
|
18
|
+
* Behaviour:
|
|
19
|
+
* - Body position snaps to a "hang from edge" pose: at the ledge edge
|
|
20
|
+
* X/Z (with a small back-offset so the body is pulled against the
|
|
21
|
+
* wall below), and Y offset down by ~bodyHeight so the hands grip
|
|
22
|
+
* the edge with the body suspended below.
|
|
23
|
+
* - Velocity is zeroed each tick — the body is parked.
|
|
24
|
+
* - Exertion rises at `cfg.exertionRiseRate` per second, scaled by
|
|
25
|
+
* mass. Climbing fatigue: hang too long and the next exit is
|
|
26
|
+
* forced (a slip).
|
|
27
|
+
* - Grounded stays false (the player is hanging in air).
|
|
28
|
+
*
|
|
29
|
+
* Exit:
|
|
30
|
+
* - Jump pressed (rising edge) → mantle-up. Release with a small
|
|
31
|
+
* upward velocity so mantle's ledgeAhead probe still hits next
|
|
32
|
+
* tick; mantle (priority 30) then takes over and animates the
|
|
33
|
+
* climb-onto-surface path.
|
|
34
|
+
* - Back-intent (`intent.move.y < -0.1`) → drop. Release with zero
|
|
35
|
+
* velocity; the player falls under base gravity.
|
|
36
|
+
* - Crouch pressed → drop. Same as back-intent.
|
|
37
|
+
* - Exertion saturates (`>= 1`) → slip. Release with zero velocity.
|
|
38
|
+
* - `sensors.ledgeAhead.hit` becomes false → shuffled off the edge.
|
|
39
|
+
* Release with zero velocity.
|
|
40
|
+
*
|
|
41
|
+
* Priority 40 — above mantle (30), below wall-run (50). Mantle CAN'T
|
|
42
|
+
* preempt an active ledge-grab — that's the point of placing ledge
|
|
43
|
+
* higher. Otherwise mantle would fire mid-hang and snap the body away.
|
|
44
|
+
* Wall-run and wall-jump can preempt — but in practice they need lateral
|
|
45
|
+
* walls + speed (wall-run) or a jump press near a side wall (wall-jump),
|
|
46
|
+
* conditions which rarely hold while hanging.
|
|
47
|
+
*
|
|
48
|
+
* @author Alex Goldring
|
|
49
|
+
* @copyright Company Named Limited (c) 2026
|
|
50
|
+
*/
|
|
51
|
+
export class LedgeGrab extends Ability {
|
|
52
|
+
/** @private World-space ledge edge position captured at onActivate. */
|
|
53
|
+
private _edgeX;
|
|
54
|
+
_edgeY: number;
|
|
55
|
+
_edgeZ: number;
|
|
56
|
+
canActivate(controller: any, runtime: any, sensors: any): boolean;
|
|
57
|
+
onActivate(controller: any, runtime: any): void;
|
|
58
|
+
canInterrupt(): boolean;
|
|
59
|
+
tick(controller: any, runtime: any, bodyTransform: any, dt: any, _system: any): boolean;
|
|
60
|
+
}
|
|
61
|
+
import { Ability } from "./Ability.js";
|
|
62
|
+
//# sourceMappingURL=LedgeGrab.d.ts.map
|