@woosh/meep-engine 2.154.0 → 2.156.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/README.md +1 -1
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/view/ecs/ComponentControlView.d.ts +0 -9
- package/editor/view/ecs/ComponentControlView.js +2 -98
- package/package.json +1 -1
- package/src/core/binary/32BitEncoder.js +1 -1
- package/src/core/binary/to_half_float_uint16.js +3 -3
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +275 -253
- package/src/core/cache/Cache.d.ts.map +1 -1
- package/src/core/cache/Cache.js +7 -0
- package/src/core/cache/FrequencySketch.d.ts.map +1 -1
- package/src/core/cache/FrequencySketch.js +8 -4
- package/src/core/clipboard/obtainClipBoard.d.ts +6 -0
- package/src/core/clipboard/obtainClipBoard.d.ts.map +1 -0
- package/src/core/clipboard/obtainClipBoard.js +29 -0
- package/src/core/clipboard/safeClipboardReadText.d.ts +6 -0
- package/src/core/clipboard/safeClipboardReadText.d.ts.map +1 -0
- package/src/core/clipboard/safeClipboardReadText.js +55 -0
- package/src/core/clipboard/safeClipboardWriteText.d.ts +8 -0
- package/src/core/clipboard/safeClipboardWriteText.d.ts.map +1 -0
- package/src/core/clipboard/safeClipboardWriteText.js +23 -0
- package/src/core/collection/array/array_quick_sort_by_lookup_map.js +1 -1
- package/src/core/collection/array/array_set_diff_sorting.d.ts.map +1 -1
- package/src/core/collection/array/array_set_diff_sorting.js +4 -1
- package/src/core/collection/array/array_shuffle.d.ts.map +1 -1
- package/src/core/collection/array/array_shuffle.js +30 -27
- package/src/core/collection/array/binarySearchLowIndex.d.ts.map +1 -1
- package/src/core/collection/array/binarySearchLowIndex.js +4 -3
- package/src/core/collection/array/typed/array_buffer_hash.js +1 -1
- package/src/core/collection/array/typed/is_typed_array_equals.d.ts.map +1 -1
- package/src/core/collection/array/typed/is_typed_array_equals.js +12 -2
- package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
- package/src/core/collection/heap/BinaryHeap.js +12 -2
- package/src/core/collection/queue/Deque.d.ts.map +1 -1
- package/src/core/collection/queue/Deque.js +10 -8
- package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
- package/src/core/collection/table/RowFirstTable.js +4 -2
- package/src/core/collection/table/RowFirstTableSpec.js +2 -2
- package/src/core/color/operations/color_lerp.d.ts.map +1 -1
- package/src/core/color/operations/color_lerp.js +10 -3
- package/src/core/color/rgb2uint32.js +1 -1
- package/src/core/color/rgbe9995_to_rgb.js +1 -1
- package/src/core/function/objectsEqual.d.ts.map +1 -1
- package/src/core/function/objectsEqual.js +2 -1
- package/src/core/geom/2d/aabb/AABB2.d.ts.map +1 -1
- package/src/core/geom/2d/aabb/AABB2.js +12 -11
- package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.d.ts.map +1 -1
- package/src/core/geom/2d/convex-hull/convex_hull_jarvis_2d.js +30 -4
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.d.ts.map +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +6 -2
- package/src/core/geom/2d/hash-grid/SpatialHashGrid.d.ts.map +1 -1
- package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +388 -386
- 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 -3
- package/src/core/geom/2d/quad-tree/QuadTreeDatum.d.ts.map +1 -1
- package/src/core/geom/2d/quad-tree/QuadTreeDatum.js +9 -1
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts +3 -1
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.d.ts.map +1 -1
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +3 -1
- package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
- package/src/core/geom/2d/r-tree/StaticR2Tree.d.ts.map +1 -1
- package/src/core/geom/2d/r-tree/StaticR2Tree.js +5 -4
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +33 -29
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +3 -1
- package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_signed_distance_to_aabb3.js +10 -7
- package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +30 -9
- package/src/core/geom/3d/aabb/compute_aabb_from_points.js +3 -3
- package/src/core/geom/3d/box/box3_raycast.d.ts +37 -0
- package/src/core/geom/3d/box/box3_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/box/box3_raycast.js +81 -0
- package/src/core/geom/3d/capsule/capsule_raycast.d.ts +35 -0
- package/src/core/geom/3d/capsule/capsule_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/capsule/capsule_raycast.js +93 -0
- package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.d.ts.map +1 -1
- package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +4 -0
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +3 -2
- package/src/core/geom/3d/mat4/decompose_matrix_4_array.d.ts.map +1 -1
- package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +12 -2
- package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +2 -2
- package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts +1 -1
- package/src/core/geom/3d/mat4/m4_multiply_alphatensor.d.ts.map +1 -1
- package/src/core/geom/3d/mat4/m4_multiply_alphatensor.js +19 -13
- package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.d.ts.map +1 -1
- package/src/core/geom/3d/octahedra/octahedral_direction_to_uv.js +3 -2
- package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +3 -2
- package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/MeshShape3D.js +7 -0
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnionShape3D.js +3 -2
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.d.ts.map +1 -1
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +153 -148
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +7 -0
- package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.js +13 -10
- package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.d.ts +1 -1
- package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +2 -2
- package/src/core/geom/3d/sphere/sphere_raycast.d.ts +33 -0
- package/src/core/geom/3d/sphere/sphere_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/sphere/sphere_raycast.js +47 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts +24 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.d.ts.map +1 -0
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +39 -0
- package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.d.ts.map +1 -1
- package/src/core/geom/3d/tetrahedra/triangle/trace_triangular_depth_map.js +4 -2
- package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +3 -3
- package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +1 -1
- package/src/core/geom/3d/topology/tm_vertex_compute_normal.d.ts.map +1 -1
- package/src/core/geom/3d/topology/tm_vertex_compute_normal.js +4 -2
- package/src/core/geom/3d/util/make_justified_point_grid.d.ts.map +1 -1
- package/src/core/geom/3d/util/make_justified_point_grid.js +18 -10
- package/src/core/geom/ConicRay.d.ts.map +1 -1
- package/src/core/geom/ConicRay.js +11 -13
- package/src/core/geom/packing/max-rect/removeRedundantBoxes.d.ts.map +1 -1
- package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +19 -4
- package/src/core/geom/vec3/v3_array_copy.d.ts +3 -3
- package/src/core/geom/vec3/v3_array_copy.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_array_copy.js +2 -2
- package/src/core/geom/vec3/v3_cross.d.ts +17 -0
- package/src/core/geom/vec3/v3_cross.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_cross.js +20 -0
- package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.d.ts.map +1 -0
- package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.js +1 -1
- package/src/core/geom/vec3/v3_subtract.d.ts +16 -0
- package/src/core/geom/vec3/v3_subtract.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_subtract.js +19 -0
- package/src/core/graph/coloring/colorizeGraph.js +2 -2
- package/src/core/graph/csr/CSRGraph.d.ts.map +1 -1
- package/src/core/graph/csr/CSRGraph.js +325 -319
- package/src/core/graph/layout/CircleLayout.d.ts.map +1 -1
- package/src/core/graph/layout/CircleLayout.js +8 -6
- package/src/core/graph/metis/native/refine/compute_kway_params.d.ts.map +1 -1
- package/src/core/graph/metis/native/refine/compute_kway_params.js +139 -138
- package/src/core/graph/mn_graph_coarsen.d.ts.map +1 -1
- package/src/core/graph/mn_graph_coarsen.js +4 -2
- package/src/core/graph/v2/NodeContainer.js +7 -7
- package/src/core/localization/LocalizationEngine.js +1 -1
- package/src/core/math/bell_membership_function.d.ts.map +1 -1
- package/src/core/math/bell_membership_function.js +3 -1
- package/src/core/math/complex/complex_add.d.ts +4 -4
- package/src/core/math/complex/complex_add.d.ts.map +1 -1
- package/src/core/math/complex/complex_add.js +3 -3
- package/src/core/math/complex/complex_div.d.ts +4 -4
- package/src/core/math/complex/complex_div.d.ts.map +1 -1
- package/src/core/math/complex/complex_div.js +3 -3
- package/src/core/math/complex/complex_mul.d.ts +4 -4
- package/src/core/math/complex/complex_mul.d.ts.map +1 -1
- package/src/core/math/complex/complex_mul.js +3 -3
- package/src/core/math/complex/complex_sub.d.ts +4 -4
- package/src/core/math/complex/complex_sub.d.ts.map +1 -1
- package/src/core/math/complex/complex_sub.js +3 -3
- package/src/core/math/idct_1d.d.ts +4 -4
- package/src/core/math/idct_1d.d.ts.map +1 -1
- package/src/core/math/idct_1d.js +3 -3
- package/src/core/math/noise/create_simplex_noise_2d.d.ts.map +1 -1
- package/src/core/math/noise/create_simplex_noise_2d.js +4 -2
- package/src/core/math/noise/sdnoise.d.ts.map +1 -1
- package/src/core/math/noise/sdnoise.js +12 -9
- package/src/core/math/physics/mie/compute_bhmie_optical_properties.d.ts.map +1 -1
- package/src/core/math/physics/mie/compute_bhmie_optical_properties.js +94 -50
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +3 -6
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
- package/src/core/math/physics/mie/lorenz_mie_coefs.js +180 -157
- package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts +3 -4
- package/src/core/math/physics/mie/mie_ab_to_optical_properties.d.ts.map +1 -1
- package/src/core/math/physics/mie/mie_ab_to_optical_properties.js +47 -21
- package/src/core/math/random/randomIntegerBetween.d.ts.map +1 -1
- package/src/core/math/random/randomIntegerBetween.js +4 -1
- package/src/core/math/solveCubic.d.ts.map +1 -1
- package/src/core/math/solveCubic.js +95 -82
- package/src/core/math/spline/computeCatmullRomSplineUniformDistance.d.ts.map +1 -1
- package/src/core/math/spline/computeCatmullRomSplineUniformDistance.js +13 -0
- package/src/core/math/statistics/softmax.js +1 -1
- package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts +1 -0
- package/src/core/model/node-graph/visual/NodeGraphVisualData.d.ts.map +1 -1
- package/src/core/model/node-graph/visual/NodeGraphVisualData.js +2 -1
- package/src/core/model/node-graph/visual/NodeVisualData.js +1 -1
- package/src/core/model/object/ImmutableObjectPool.d.ts +7 -0
- package/src/core/model/object/ImmutableObjectPool.d.ts.map +1 -1
- package/src/core/model/object/ImmutableObjectPool.js +20 -10
- package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.d.ts.map +1 -1
- package/src/core/model/reactive/evaluation/MultiPredicateEvaluator.js +39 -2
- package/src/core/model/reactive/model/terminal/ReactiveReference.d.ts.map +1 -1
- package/src/core/model/reactive/model/terminal/ReactiveReference.js +2 -0
- package/src/core/parser/simple/readHexToken.d.ts.map +1 -1
- package/src/core/parser/simple/readHexToken.js +6 -0
- package/src/core/primitives/numbers/number_pretty_print.d.ts.map +1 -1
- package/src/core/primitives/numbers/number_pretty_print.js +4 -1
- package/src/core/primitives/strings/string_jaro_winkler.js +1 -1
- package/src/core/process/CompositeProcess.js +1 -1
- package/src/core/process/action/AsynchronousDelayAction.d.ts.map +1 -1
- package/src/core/process/action/AsynchronousDelayAction.js +3 -0
- package/src/core/process/executor/ConcurrentExecutor.d.ts.map +1 -1
- package/src/core/process/executor/ConcurrentExecutor.js +3 -2
- package/src/core/process/task/util/randomCountTask.d.ts.map +1 -1
- package/src/core/process/task/util/randomCountTask.js +3 -1
- package/src/core/process/undo/ActionProcessor.d.ts.map +1 -1
- package/src/core/process/undo/ActionProcessor.js +5 -3
- package/src/core/process/worker/WorkerBuilder.js +3 -3
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +4 -2
- package/src/engine/control/first-person/DESIGN.md +1 -1
- package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts +55 -0
- package/src/engine/control/first-person/FirstPersonMotionPhase.d.ts.map +1 -0
- package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +23 -2
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.js +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +168 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +115 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +71 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +255 -55
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts +82 -43
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/LedgeGrab.js +405 -213
- package/src/engine/control/first-person/abilities/Mantle.d.ts +6 -0
- package/src/engine/control/first-person/abilities/Mantle.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/Mantle.js +104 -45
- package/src/engine/control/first-person/abilities/ScrambleUp.d.ts +61 -0
- package/src/engine/control/first-person/abilities/ScrambleUp.d.ts.map +1 -0
- package/src/engine/control/first-person/abilities/ScrambleUp.js +182 -0
- package/src/engine/control/first-person/math/jumpDynamics.d.ts +84 -0
- package/src/engine/control/first-person/math/jumpDynamics.d.ts.map +1 -0
- package/src/engine/control/first-person/math/jumpDynamics.js +108 -0
- package/src/engine/control/first-person/prototype_first_person_controller.js +45 -1
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +8 -0
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +1 -1
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +1 -1
- package/src/engine/graphics/shadows/testShadowMapRendering.js +1 -1
- package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -0
- package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -0
- package/src/engine/physics/PLAN.md +6 -5
- package/src/engine/physics/constraint/solve_constraints.d.ts +4 -1
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +147 -33
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +1750 -1747
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
- package/src/engine/physics/gjk/gjk_epa_penetration.d.ts +12 -8
- package/src/engine/physics/gjk/gjk_epa_penetration.d.ts.map +1 -1
- package/src/engine/physics/gjk/gjk_epa_penetration.js +447 -158
- package/src/engine/physics/narrowphase/convex_convex_manifold.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/convex_convex_manifold.js +22 -25
- package/src/engine/physics/narrowphase/convex_decomposition.d.ts +32 -13
- package/src/engine/physics/narrowphase/convex_decomposition.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/convex_decomposition.js +61 -65
- package/src/engine/physics/narrowphase/mesh_convex_hull.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/mesh_convex_hull.js +13 -8
- package/src/engine/physics/narrowphase/refine_ray_concave.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_concave.js +5 -3
- package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_hit.js +81 -78
- package/src/engine/sound/SoundEngine.d.ts.map +1 -1
- package/src/engine/sound/SoundEngine.js +28 -0
- package/src/engine/sound/dB2Volume.d.ts +1 -1
- package/src/engine/sound/dB2Volume.d.ts.map +1 -1
- package/src/engine/sound/dB2Volume.js +1 -1
- package/src/engine/sound/ecs/SoundController.d.ts +4 -0
- package/src/engine/sound/ecs/SoundController.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundController.js +4 -0
- package/src/engine/sound/ecs/SoundControllerSystem.d.ts +5 -0
- package/src/engine/sound/ecs/SoundControllerSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/SoundControllerSystem.js +5 -0
- package/src/engine/sound/ecs/audio/AudioEmitter.d.ts +69 -0
- package/src/engine/sound/ecs/audio/AudioEmitter.d.ts.map +1 -0
- package/src/engine/sound/ecs/audio/AudioEmitter.js +83 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts +97 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.d.ts.map +1 -0
- package/src/engine/sound/ecs/audio/AudioEmitterSystem.js +238 -0
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts +90 -0
- package/src/engine/sound/ecs/audio/LiveEmitterSet.d.ts.map +1 -0
- package/src/engine/sound/ecs/audio/LiveEmitterSet.js +324 -0
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts +59 -0
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.d.ts.map +1 -0
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -0
- package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts +16 -65
- package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts.map +1 -1
- package/src/engine/sound/ecs/emitter/SoundEmitter.js +19 -224
- package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts +26 -29
- package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.d.ts.map +1 -1
- package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +168 -135
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts +36 -59
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.d.ts.map +1 -1
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +154 -390
- package/src/engine/sound/ecs/emitter/SoundTrack.d.ts +20 -23
- package/src/engine/sound/ecs/emitter/SoundTrack.d.ts.map +1 -1
- package/src/engine/sound/ecs/emitter/SoundTrack.js +34 -152
- package/src/engine/sound/sopra/IMPLEMENTATION_PLAN.md +993 -0
- package/src/engine/sound/sopra/README.md +643 -7
- package/src/engine/sound/sopra/SopraEngine.d.ts +229 -0
- package/src/engine/sound/sopra/SopraEngine.d.ts.map +1 -0
- package/src/engine/sound/sopra/SopraEngine.js +423 -0
- package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts +26 -0
- package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.d.ts.map +1 -0
- package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -0
- package/src/engine/sound/sopra/asset/BufferProvider.d.ts +24 -0
- package/src/engine/sound/sopra/asset/BufferProvider.d.ts.map +1 -0
- package/src/engine/sound/sopra/asset/BufferProvider.js +29 -0
- package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts +31 -0
- package/src/engine/sound/sopra/asset/StubBufferProvider.d.ts.map +1 -0
- package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -0
- package/src/engine/sound/sopra/definition/BusDefinition.d.ts +83 -0
- package/src/engine/sound/sopra/definition/BusDefinition.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/BusDefinition.js +142 -0
- package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -0
- package/src/engine/sound/sopra/definition/DuckingRule.d.ts +71 -0
- package/src/engine/sound/sopra/definition/DuckingRule.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/DuckingRule.js +106 -0
- package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -0
- package/src/engine/sound/sopra/definition/EventDescription.d.ts +132 -0
- package/src/engine/sound/sopra/definition/EventDescription.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/EventDescription.js +259 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +71 -0
- package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts +51 -0
- package/src/engine/sound/sopra/definition/MixerSnapshot.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -0
- package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -0
- package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts +72 -0
- package/src/engine/sound/sopra/definition/ParameterDefinition.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -0
- package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -0
- package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts +14 -0
- package/src/engine/sound/sopra/definition/SopraPanningModel.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/SopraPanningModel.js +20 -0
- package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts +10 -0
- package/src/engine/sound/sopra/definition/VoiceStealMode.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts +93 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts +80 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +181 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +74 -0
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts +34 -0
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +100 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +101 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +230 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts +103 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts +40 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +91 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts +44 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +65 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +131 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts +17 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -0
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts +24 -0
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts +70 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -0
- package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts +74 -0
- package/src/engine/sound/sopra/definition/effect/EqEffect.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -0
- package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts +49 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +101 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts +18 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.d.ts.map +1 -0
- package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -0
- package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts +31 -0
- package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.d.ts.map +1 -0
- package/src/engine/sound/sopra/legacy/soundEmitterToEventDescription.js +106 -0
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts +79 -0
- package/src/engine/sound/sopra/runtime/BusGraph.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/BusGraph.js +227 -0
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts +144 -0
- package/src/engine/sound/sopra/runtime/EventInstance.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/EventInstance.js +579 -0
- package/src/engine/sound/sopra/runtime/ParameterStore.d.ts +42 -0
- package/src/engine/sound/sopra/runtime/ParameterStore.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -0
- package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts +42 -0
- package/src/engine/sound/sopra/runtime/SopraPlaybackContext.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -0
- package/src/engine/sound/sopra/runtime/Voice.d.ts +67 -0
- package/src/engine/sound/sopra/runtime/Voice.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/Voice.js +145 -0
- package/src/engine/sound/sopra/runtime/VoiceManager.d.ts +38 -0
- package/src/engine/sound/sopra/runtime/VoiceManager.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -0
- package/src/engine/sound/sopra/runtime/VoicePool.d.ts +12 -0
- package/src/engine/sound/sopra/runtime/VoicePool.d.ts.map +1 -0
- package/src/engine/sound/sopra/runtime/VoicePool.js +17 -0
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts +11 -0
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.d.ts.map +1 -0
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -0
- package/src/engine/sound/sopra/serialization/sopraJSON.d.ts +33 -0
- package/src/engine/sound/sopra/serialization/sopraJSON.d.ts.map +1 -0
- package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -0
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts +27 -0
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.d.ts.map +1 -0
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -0
- package/src/engine/sound/sopra/util/MockAudioContext.d.ts +74 -0
- package/src/engine/sound/sopra/util/MockAudioContext.d.ts.map +1 -0
- package/src/engine/sound/sopra/util/MockAudioContext.js +215 -0
- package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts +15 -0
- package/src/engine/sound/sopra/util/buildAttenuationCurve.d.ts.map +1 -0
- package/src/engine/sound/sopra/util/buildAttenuationCurve.js +40 -0
- package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts +34 -0
- package/src/engine/sound/sopra/util/fadeOutAndStop.d.ts.map +1 -0
- package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -0
- package/src/engine/sound/volume2dB.d.ts +1 -1
- package/src/engine/sound/volume2dB.d.ts.map +1 -1
- package/src/engine/sound/volume2dB.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/sampling/v3_orthonormal_matrix_from_normal.d.ts.map +0 -1
- package/src/engine/physics/narrowphase/ray_shapes.d.ts +0 -66
- package/src/engine/physics/narrowphase/ray_shapes.d.ts.map +0 -1
- package/src/engine/physics/narrowphase/ray_shapes.js +0 -187
- package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts +0 -23
- package/src/engine/sound/ecs/emitter/SoundEmitterChannel.d.ts.map +0 -1
- package/src/engine/sound/ecs/emitter/SoundEmitterChannel.js +0 -32
- package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts +0 -18
- package/src/engine/sound/ecs/emitter/SoundTrackNodes.d.ts.map +0 -1
- package/src/engine/sound/ecs/emitter/SoundTrackNodes.js +0 -18
- package/src/engine/sound/sopra/AbstractAudioClip.d.ts +0 -26
- package/src/engine/sound/sopra/AbstractAudioClip.d.ts.map +0 -1
- package/src/engine/sound/sopra/AbstractAudioClip.js +0 -29
- package/src/engine/sound/sopra/ContainerAudioClip.d.ts +0 -12
- package/src/engine/sound/sopra/ContainerAudioClip.d.ts.map +0 -1
- package/src/engine/sound/sopra/ContainerAudioClip.js +0 -13
- package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts +0 -12
- package/src/engine/sound/sopra/RandomContainerAudioClip.d.ts.map +0 -1
- package/src/engine/sound/sopra/RandomContainerAudioClip.js +0 -15
- package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts +0 -7
- package/src/engine/sound/sopra/SequenceContainerAudioClip.d.ts.map +0 -1
- package/src/engine/sound/sopra/SequenceContainerAudioClip.js +0 -8
- package/src/engine/sound/sopra/SilenceAudioClip.d.ts +0 -13
- package/src/engine/sound/sopra/SilenceAudioClip.d.ts.map +0 -1
- package/src/engine/sound/sopra/SilenceAudioClip.js +0 -15
- /package/src/{engine/graphics/sh3/path_tracer/sampling → core/geom/vec3}/v3_orthonormal_matrix_from_normal.d.ts +0 -0
|
@@ -23,6 +23,7 @@ import { PhysicsSurfacePoint } from "../../physics/queries/PhysicsSurfacePoint.j
|
|
|
23
23
|
import { FirstPersonPlayerController } from "./FirstPersonPlayerController.js";
|
|
24
24
|
import { DecisionPoint } from "./mastery/DecisionPoint.js";
|
|
25
25
|
import { computeJumpFromApex } from "./math/computeJumpFromApex.js";
|
|
26
|
+
import { jumpForceForHeight, launchVelocityForForce } from "./math/jumpDynamics.js";
|
|
26
27
|
import { computeLRCBreathRate } from "./math/computeLRCBreathRate.js";
|
|
27
28
|
import { computeMassRatios } from "./math/computeMassRatios.js";
|
|
28
29
|
import { Spring } from "./math/Spring.js";
|
|
@@ -143,6 +144,26 @@ class PerEntityRuntime {
|
|
|
143
144
|
/** Yaw rate (rad/s) computed in look consumption — for evaluators. */
|
|
144
145
|
this.yawRateRadPerSec = 0;
|
|
145
146
|
|
|
147
|
+
// -- Render-rate look + position interpolation ---------------------
|
|
148
|
+
// The camera DIRECTION (yaw/pitch) is consumed at RENDER rate (see the
|
|
149
|
+
// controller's _consumeLook), so it tracks the mouse smoothly instead of
|
|
150
|
+
// being aliased by the 60Hz sim sampling — consuming the accumulated
|
|
151
|
+
// mouse delta once per fixed step beats against an unaligned mouse
|
|
152
|
+
// report rate and makes a slow turn lurch (the reported snap). The body
|
|
153
|
+
// POSITION still advances only at the fixed step, so it's blended
|
|
154
|
+
// between the last two steps by the sub-step alpha to stay smooth on a
|
|
155
|
+
// high-refresh display.
|
|
156
|
+
/** Body yaw at the end of the previous fixed step — used to derive the
|
|
157
|
+
* per-step turn RATE that drives look-lean, decoupled from per-frame
|
|
158
|
+
* input jitter. */
|
|
159
|
+
this.prevFixedYaw = 0;
|
|
160
|
+
this.renderPrevPos = new Vector3();
|
|
161
|
+
this.renderCurPos = new Vector3();
|
|
162
|
+
/** When true, the next position snapshot collapses prev=cur (no blend)
|
|
163
|
+
* — set on a body teleport (e.g. the ledge-grab hang snap) so the
|
|
164
|
+
* camera doesn't glide across the jump. */
|
|
165
|
+
this.renderSnap = false;
|
|
166
|
+
|
|
146
167
|
/** Horizontal+vertical velocity. We integrate these inside the system
|
|
147
168
|
* when no external physics layer is attached. */
|
|
148
169
|
this.velocityX = 0;
|
|
@@ -160,6 +181,13 @@ class PerEntityRuntime {
|
|
|
160
181
|
this.anticipationRemaining = 0;
|
|
161
182
|
/** Cached derived gravity (m/s^2) from peakHeight + timeToApex. */
|
|
162
183
|
this.gravity = 9.81;
|
|
184
|
+
/**
|
|
185
|
+
* Cached jump PUSH-OFF FORCE (newtons) — the physical leg force that
|
|
186
|
+
* reaches `peakHeight` at the reference mass, the quantity jump power is
|
|
187
|
+
* expressed in. Derived at link via {@link jumpForceForHeight}; abilities
|
|
188
|
+
* (e.g. the scramble wall-kick) launch off this same force.
|
|
189
|
+
*/
|
|
190
|
+
this.jumpForce = 0;
|
|
163
191
|
/** Cached derived jump impulse (m/s upward), post-mass-scaling. */
|
|
164
192
|
this.jumpInitialVy = 5.0;
|
|
165
193
|
/**
|
|
@@ -299,6 +327,23 @@ class PerEntityRuntime {
|
|
|
299
327
|
|
|
300
328
|
/** Cached eye entity ID. -1 until link assigns it. */
|
|
301
329
|
this.eyeEntity = -1;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* One-shot hand-off flag: LedgeGrab sets it on a pull-up release so
|
|
333
|
+
* Mantle (next tick) knows this is a ledge pull-up — it then allows a
|
|
334
|
+
* too-thin top (auto-mantle still requires a standable one) and vaults
|
|
335
|
+
* OVER instead of onto. Mantle consumes it in onActivate.
|
|
336
|
+
*/
|
|
337
|
+
this.ledgePullUpRequest = false;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Seconds remaining in the post-release ledge re-grab refractory
|
|
341
|
+
* window. Set by {@link LedgeGrab} on deactivation, aged down by dt
|
|
342
|
+
* each fixed step, and read by LedgeGrab.canActivate — so a deliberate
|
|
343
|
+
* dismount can fall clear of the grab window without the auto-catch
|
|
344
|
+
* snapping the body straight back onto the same lip.
|
|
345
|
+
*/
|
|
346
|
+
this.ledgeRegrabCooldown = 0;
|
|
302
347
|
}
|
|
303
348
|
}
|
|
304
349
|
|
|
@@ -491,7 +536,21 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
491
536
|
const derived = { gravity: 0, initialVelocity: 0 };
|
|
492
537
|
computeJumpFromApex(controller.config.jump.peakHeight, controller.config.jump.timeToApex, derived);
|
|
493
538
|
runtime.gravity = derived.gravity;
|
|
494
|
-
|
|
539
|
+
// Express jump power as a physical push-off FORCE (newtons): the force the
|
|
540
|
+
// legs deliver to reach peakHeight at the REFERENCE mass. Stored so other
|
|
541
|
+
// moves (the scramble wall-kick) can launch off the SAME force.
|
|
542
|
+
const bodyCfg = controller.config.body;
|
|
543
|
+
runtime.jumpForce = jumpForceForHeight(
|
|
544
|
+
bodyCfg.referenceMass, runtime.gravity, bodyCfg.jumpPushoffDistance, controller.config.jump.peakHeight,
|
|
545
|
+
);
|
|
546
|
+
// Force → launch velocity for the reference body (== √(2·g·peakHeight)),
|
|
547
|
+
// then the mass-coupling dial (jumpV0Scale ∝ 1/√mass, modulated by
|
|
548
|
+
// massCouplingStrength) scales it for the actual body. Identical result
|
|
549
|
+
// to the prior `derived.initialVelocity · jumpV0Scale`, now routed
|
|
550
|
+
// through the force so jump power has a single physical source.
|
|
551
|
+
runtime.jumpInitialVy =
|
|
552
|
+
launchVelocityForForce(runtime.jumpForce, bodyCfg.referenceMass, bodyCfg.jumpPushoffDistance)
|
|
553
|
+
* runtime.massRatios.jumpV0Scale;
|
|
495
554
|
|
|
496
555
|
// Seed yaw from the starting body rotation. `toEulerAnglesYXZ`
|
|
497
556
|
// returns (pitch, yaw, roll) — we only care about y.
|
|
@@ -499,6 +558,11 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
499
558
|
runtime.bodyYaw = SCRATCH_V3_A.y;
|
|
500
559
|
runtime.eyePitch = 0;
|
|
501
560
|
|
|
561
|
+
// Seed render-rate-look + position-interpolation state to the spawn pose.
|
|
562
|
+
runtime.prevFixedYaw = runtime.bodyYaw;
|
|
563
|
+
runtime.renderPrevPos.copy(bodyTransform.position);
|
|
564
|
+
runtime.renderCurPos.copy(bodyTransform.position);
|
|
565
|
+
|
|
502
566
|
// Initialize springs to standing-eye-height baseline
|
|
503
567
|
runtime.eyeHeightSpring.settle(controller.config.body.height);
|
|
504
568
|
runtime.fovSpring.settle(controller.config.fov.base);
|
|
@@ -610,42 +674,24 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
610
674
|
// independently ages all samples).
|
|
611
675
|
controller.mastery.tick(dt);
|
|
612
676
|
|
|
613
|
-
// -- L1.a:
|
|
614
|
-
//
|
|
615
|
-
//
|
|
616
|
-
//
|
|
617
|
-
//
|
|
618
|
-
//
|
|
619
|
-
//
|
|
620
|
-
//
|
|
621
|
-
//
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
// Cache yaw rate for mastery evaluators (look-lean, foot-asymmetry-
|
|
633
|
-
// turn, etc.). Rad/s, signed (negative = turning right in our
|
|
634
|
-
// convention — matches yawDelta).
|
|
635
|
-
runtime.yawRateRadPerSec = yawDelta / Math.max(dt, 1e-4);
|
|
636
|
-
|
|
637
|
-
runtime.bodyYaw += yawDelta;
|
|
638
|
-
// keep yaw bounded (purely cosmetic — sin/cos handle wraparound fine)
|
|
639
|
-
if (runtime.bodyYaw > Math.PI) runtime.bodyYaw -= TWO_PI;
|
|
640
|
-
else if (runtime.bodyYaw < -Math.PI) runtime.bodyYaw += TWO_PI;
|
|
641
|
-
|
|
642
|
-
runtime.eyePitch = clamp(
|
|
643
|
-
runtime.eyePitch + pitchDelta,
|
|
644
|
-
cfg.look.pitchMinDeg * DEG_TO_RAD,
|
|
645
|
-
cfg.look.pitchMaxDeg * DEG_TO_RAD,
|
|
646
|
-
);
|
|
647
|
-
|
|
648
|
-
// Write body yaw back to transform (pure yaw, no pitch on body)
|
|
677
|
+
// -- L1.a: Derive the per-step turn rate ------------------------
|
|
678
|
+
// Look (yaw/pitch) is consumed at RENDER rate in {@link _consumeLook} so
|
|
679
|
+
// the camera tracks the mouse without 60Hz aliasing — consuming the
|
|
680
|
+
// accumulated mouse delta once per fixed step beats against an unaligned
|
|
681
|
+
// mouse report rate and makes a slow turn lurch (the reported snap).
|
|
682
|
+
// fixedUpdate reads the latest yaw and derives the per-fixed-step turn
|
|
683
|
+
// RATE for look-lean + the turn evaluators, from the yaw change since the
|
|
684
|
+
// previous step (shortest-arc across the ±π wrap) — smooth and decoupled
|
|
685
|
+
// from per-frame input jitter.
|
|
686
|
+
let yawStep = runtime.bodyYaw - runtime.prevFixedYaw;
|
|
687
|
+
if (yawStep > Math.PI) yawStep -= TWO_PI;
|
|
688
|
+
else if (yawStep < -Math.PI) yawStep += TWO_PI;
|
|
689
|
+
runtime.yawRateRadPerSec = yawStep / Math.max(dt, 1e-4);
|
|
690
|
+
runtime.prevFixedYaw = runtime.bodyYaw;
|
|
691
|
+
|
|
692
|
+
// Write body yaw back to the transform (pure yaw, no pitch on body) —
|
|
693
|
+
// the collision sweep + sensors use it. The camera uses runtime.bodyYaw
|
|
694
|
+
// directly, which _consumeLook keeps current at render rate.
|
|
649
695
|
bodyTransform.rotation.fromAxisAngle(Vector3.up, runtime.bodyYaw);
|
|
650
696
|
|
|
651
697
|
// -- Shared flags. Computed BEFORE the ability tick so abilities
|
|
@@ -661,6 +707,13 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
661
707
|
// L2 observers read sinYaw/cosYaw as locals — destructure once.
|
|
662
708
|
const { sinYaw, cosYaw } = runtime;
|
|
663
709
|
|
|
710
|
+
// Age the ledge re-grab refractory window (dt-driven). Decremented
|
|
711
|
+
// BEFORE the ability layer so LedgeGrab.canActivate sees the current
|
|
712
|
+
// value; it gates the auto-catch for a beat after any dismount.
|
|
713
|
+
if (runtime.ledgeRegrabCooldown > 0) {
|
|
714
|
+
runtime.ledgeRegrabCooldown = Math.max(0, runtime.ledgeRegrabCooldown - dt);
|
|
715
|
+
}
|
|
716
|
+
|
|
664
717
|
// -- Ability layer: at most one active ability owns motion. The
|
|
665
718
|
// set returns true when no ability owned the tick, in which
|
|
666
719
|
// case base L1.b-h runs below; false means an ability fully
|
|
@@ -670,6 +723,13 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
670
723
|
controller, runtime, bodyTransform, runtime.sensors, dt, this,
|
|
671
724
|
);
|
|
672
725
|
|
|
726
|
+
// The ledge-pull-up request is set and consumed WITHIN abilities.tick
|
|
727
|
+
// (LedgeGrab release → Mantle activation, same call). Clear it here as
|
|
728
|
+
// a safety net so a pull-up that didn't activate a mantle can't leak
|
|
729
|
+
// the flag into a later auto-mantle (which would let it vault a thin
|
|
730
|
+
// wall it should have refused).
|
|
731
|
+
runtime.ledgePullUpRequest = false;
|
|
732
|
+
|
|
673
733
|
// Now resolve crouch (updates prevCrouchHeld) — used by base and L2.
|
|
674
734
|
// Headroom-aware: force-keeps the player crouched under an overhang.
|
|
675
735
|
const isCrouchActive = this._resolveCrouchHeld(controller, runtime, bodyTransform);
|
|
@@ -977,13 +1037,21 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
977
1037
|
wantsCrouch = intent.crouch;
|
|
978
1038
|
}
|
|
979
1039
|
|
|
980
|
-
// Headroom override
|
|
981
|
-
//
|
|
982
|
-
// crouched
|
|
983
|
-
//
|
|
984
|
-
//
|
|
985
|
-
//
|
|
986
|
-
|
|
1040
|
+
// Headroom override — block UN-crouching under an overhang. A player who
|
|
1041
|
+
// is ALREADY low (crouched or prone) and wants to stand is force-kept
|
|
1042
|
+
// crouched while the Stand collider won't fit: letting it grow into the
|
|
1043
|
+
// overhang would have the next tick's depenetration shove the player out
|
|
1044
|
+
// the bottom, through the floor. `crouchBlocked` records this for HUD /
|
|
1045
|
+
// camera.
|
|
1046
|
+
//
|
|
1047
|
+
// Crucially this fires ONLY when already low. A STANDING player who walks
|
|
1048
|
+
// under a low ceiling is NEVER auto-pushed down into a crouch — their
|
|
1049
|
+
// full-height capsule simply can't fit, so the mover blocks their forward
|
|
1050
|
+
// motion instead. "If I can't clear it, I don't move forward." Dropping
|
|
1051
|
+
// posture is the player's choice (press crouch), not the ceiling's.
|
|
1052
|
+
const alreadyLow = runtime.lastPosture === FirstPersonPosture.Crouch
|
|
1053
|
+
|| runtime.lastPosture === FirstPersonPosture.Prone;
|
|
1054
|
+
if (!wantsCrouch && alreadyLow) {
|
|
987
1055
|
const growDelta = runtime.standTop - runtime.crouchTop;
|
|
988
1056
|
if (!this._hasHeadroomToGrow(runtime, bodyTransform, runtime.colliderShapeCrouch, growDelta)) {
|
|
989
1057
|
state.crouchBlocked = true;
|
|
@@ -1107,7 +1175,12 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1107
1175
|
);
|
|
1108
1176
|
|
|
1109
1177
|
sig.onJumpStart.send1({ peakHeight: cfg.jump.peakHeight });
|
|
1110
|
-
|
|
1178
|
+
// NOTE: onLeaveGround is fired by the motor (_onLeaveGround)
|
|
1179
|
+
// when the move actually breaks ground contact this same tick —
|
|
1180
|
+
// with reason "jump" since midJump is now true. Firing it here
|
|
1181
|
+
// too double-sent the signal on every grounded jump (and a
|
|
1182
|
+
// spurious second "jump" leave on a coyote jump, which already
|
|
1183
|
+
// left ground on the walk-off). Let the motor own it.
|
|
1111
1184
|
}
|
|
1112
1185
|
}
|
|
1113
1186
|
}
|
|
@@ -1474,12 +1547,15 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1474
1547
|
let posture = isCrouchActive
|
|
1475
1548
|
? FirstPersonPosture.Crouch
|
|
1476
1549
|
: FirstPersonPosture.Stand;
|
|
1477
|
-
// Headroom floor
|
|
1478
|
-
//
|
|
1479
|
-
//
|
|
1480
|
-
//
|
|
1481
|
-
//
|
|
1482
|
-
|
|
1550
|
+
// Headroom floor — block UN-proning under a very low overhang. Only an
|
|
1551
|
+
// ALREADY-prone body (e.g. one that slid into a crawl-height tunnel) is
|
|
1552
|
+
// force-kept prone while the Crouch collider can't fit above it. A player
|
|
1553
|
+
// merely crouching by intent is NOT auto-dropped to prone when they meet
|
|
1554
|
+
// a lower overhang — same rule as above: the mover blocks their forward
|
|
1555
|
+
// motion instead of the ceiling shoving them down. Uses the post-move
|
|
1556
|
+
// position, so it reflects where the body actually ended up this tick.
|
|
1557
|
+
if (posture === FirstPersonPosture.Crouch
|
|
1558
|
+
&& runtime.lastPosture === FirstPersonPosture.Prone) {
|
|
1483
1559
|
const proneGrow = runtime.crouchTop - runtime.proneTop;
|
|
1484
1560
|
if (!this._hasHeadroomToGrow(runtime, bodyTransform, runtime.colliderShapeProne, proneGrow)) {
|
|
1485
1561
|
posture = FirstPersonPosture.Prone;
|
|
@@ -1622,6 +1698,104 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1622
1698
|
pose.postureAmount = clamp((cfg.body.height - state.eyeHeight) / postureSpan, 0, 1);
|
|
1623
1699
|
|
|
1624
1700
|
pose.aimPitch = runtime.eyePitch;
|
|
1701
|
+
|
|
1702
|
+
this._assertTickInvariants(controller, runtime, bodyTransform);
|
|
1703
|
+
this._snapshotRenderPose(runtime, bodyTransform);
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
/**
|
|
1707
|
+
* Record this fixed step's authoritative body position as the latest
|
|
1708
|
+
* render-interpolation endpoint, shifting the old latest to "previous".
|
|
1709
|
+
* {@link _composeEye} blends prev→cur by the sub-step alpha so the camera
|
|
1710
|
+
* position is smooth at any refresh rate. (Yaw/pitch aren't snapshotted —
|
|
1711
|
+
* they're render-rate.) On a teleport (`renderSnap`), prev and cur collapse
|
|
1712
|
+
* to the new position so the camera jumps rather than gliding across it.
|
|
1713
|
+
* @private
|
|
1714
|
+
*/
|
|
1715
|
+
_snapshotRenderPose(runtime, bodyTransform) {
|
|
1716
|
+
const p = bodyTransform.position;
|
|
1717
|
+
if (runtime.renderSnap) {
|
|
1718
|
+
runtime.renderSnap = false;
|
|
1719
|
+
runtime.renderPrevPos.set(p.x, p.y, p.z);
|
|
1720
|
+
runtime.renderCurPos.set(p.x, p.y, p.z);
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1723
|
+
runtime.renderPrevPos.copy(runtime.renderCurPos);
|
|
1724
|
+
runtime.renderCurPos.set(p.x, p.y, p.z);
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
/**
|
|
1728
|
+
* Dev-only invariant guard (meep asserts compile out of prod, so this is
|
|
1729
|
+
* free there). Catches the class of corruption that surfaces as an
|
|
1730
|
+
* unexplained camera "snap": a NaN/Infinity leaking into the yaw/pitch the
|
|
1731
|
+
* eye composes from, or into the body's velocity / position. Runs once at
|
|
1732
|
+
* the END of every fixed step, so a bad value is caught the tick it appears
|
|
1733
|
+
* — naming the layer that produced it — instead of manifesting as a camera
|
|
1734
|
+
* jump frames (or seconds) later when something finally reads it.
|
|
1735
|
+
* @private
|
|
1736
|
+
*/
|
|
1737
|
+
_assertTickInvariants(controller, runtime, bodyTransform) {
|
|
1738
|
+
const p = bodyTransform.position;
|
|
1739
|
+
assert.ok(Number.isFinite(runtime.bodyYaw),
|
|
1740
|
+
"FP invariant: runtime.bodyYaw is non-finite (camera yaw corrupted)");
|
|
1741
|
+
assert.ok(Number.isFinite(runtime.eyePitch),
|
|
1742
|
+
"FP invariant: runtime.eyePitch is non-finite (camera pitch corrupted)");
|
|
1743
|
+
assert.ok(Number.isFinite(controller.state.leanRollRad),
|
|
1744
|
+
"FP invariant: state.leanRollRad is non-finite (camera roll corrupted)");
|
|
1745
|
+
assert.ok(
|
|
1746
|
+
Number.isFinite(runtime.velocityX)
|
|
1747
|
+
&& Number.isFinite(runtime.velocityY)
|
|
1748
|
+
&& Number.isFinite(runtime.velocityZ),
|
|
1749
|
+
"FP invariant: runtime.velocity is non-finite",
|
|
1750
|
+
);
|
|
1751
|
+
assert.ok(
|
|
1752
|
+
Number.isFinite(p.x) && Number.isFinite(p.y) && Number.isFinite(p.z),
|
|
1753
|
+
"FP invariant: body position is non-finite",
|
|
1754
|
+
);
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
/**
|
|
1758
|
+
* Consume the accumulated mouse-look delta into body yaw + eye pitch at
|
|
1759
|
+
* RENDER rate (once per render frame, from {@link _composeEye}). This is the
|
|
1760
|
+
* fix for the slow-turn camera snap: sampling `intent.look` at the 60Hz
|
|
1761
|
+
* fixed step aliases an unaligned mouse report rate into an uneven turn,
|
|
1762
|
+
* whereas consuming it every render frame tracks the mouse as smoothly as it
|
|
1763
|
+
* arrives. `intent.look` is zeroed after consuming so the same delta isn't
|
|
1764
|
+
* re-applied next frame.
|
|
1765
|
+
*
|
|
1766
|
+
* Conventions (raw mouse delta source — movementX/Y positive moving
|
|
1767
|
+
* right/down): look.x > 0 ("mouse right") → turn right (the yaw sign is
|
|
1768
|
+
* negated because the engine is left-handed with +Z forward, so a +Y
|
|
1769
|
+
* rotation reads as a LEFT turn through the camera); look.y > 0 → look down,
|
|
1770
|
+
* flipped by invertY.
|
|
1771
|
+
* @private
|
|
1772
|
+
*/
|
|
1773
|
+
_consumeLook(controller, runtime) {
|
|
1774
|
+
const intent = controller.intent;
|
|
1775
|
+
const cfg = controller.config;
|
|
1776
|
+
let yawDelta = -intent.look.x;
|
|
1777
|
+
const pitchSign = cfg.look.invertY ? -1 : 1;
|
|
1778
|
+
let pitchDelta = intent.look.y * pitchSign;
|
|
1779
|
+
intent.look.set(0, 0);
|
|
1780
|
+
|
|
1781
|
+
// Reject input SPIKES. A single render frame's look delta beyond a sane
|
|
1782
|
+
// bound is a corrupt browser/driver `movementX` (a high-res mouse under
|
|
1783
|
+
// OS pointer acceleration, or a pointer-lock burst), not a real turn —
|
|
1784
|
+
// applying it snaps the camera 20–100°. Drop the spiking axis; legit
|
|
1785
|
+
// turns (even fast flicks) stay well under the bound at render rate.
|
|
1786
|
+
const maxDelta = cfg.look.maxFrameDeltaRad;
|
|
1787
|
+
if (Math.abs(yawDelta) > maxDelta) yawDelta = 0;
|
|
1788
|
+
if (Math.abs(pitchDelta) > maxDelta) pitchDelta = 0;
|
|
1789
|
+
|
|
1790
|
+
runtime.bodyYaw += yawDelta;
|
|
1791
|
+
if (runtime.bodyYaw > Math.PI) runtime.bodyYaw -= TWO_PI;
|
|
1792
|
+
else if (runtime.bodyYaw < -Math.PI) runtime.bodyYaw += TWO_PI;
|
|
1793
|
+
|
|
1794
|
+
runtime.eyePitch = clamp(
|
|
1795
|
+
runtime.eyePitch + pitchDelta,
|
|
1796
|
+
cfg.look.pitchMinDeg * DEG_TO_RAD,
|
|
1797
|
+
cfg.look.pitchMaxDeg * DEG_TO_RAD,
|
|
1798
|
+
);
|
|
1625
1799
|
}
|
|
1626
1800
|
|
|
1627
1801
|
/**
|
|
@@ -1635,6 +1809,10 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1635
1809
|
const runtime = this.runtime.get(entity);
|
|
1636
1810
|
if (runtime === undefined) return;
|
|
1637
1811
|
|
|
1812
|
+
// Consume mouse-look at RENDER rate so the camera direction tracks the
|
|
1813
|
+
// mouse smoothly, decoupled from the aliased 60Hz sim sampling.
|
|
1814
|
+
this._consumeLook(controller, runtime);
|
|
1815
|
+
|
|
1638
1816
|
const dt = this._currentRenderDt;
|
|
1639
1817
|
const cfg = controller.config;
|
|
1640
1818
|
const state = controller.state;
|
|
@@ -1710,11 +1888,23 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1710
1888
|
: 0;
|
|
1711
1889
|
stack.push("posture.sprintShift", 0, 0, cfg.posture.sprintForwardShiftM * sprintShiftFraction);
|
|
1712
1890
|
|
|
1713
|
-
//
|
|
1891
|
+
// Body POSITION advances only at the fixed step → blend the last two
|
|
1892
|
+
// steps by the engine's sub-step alpha (the same fraction the
|
|
1893
|
+
// InterpolationSystem uses for physics bodies) so it's smooth on a high-
|
|
1894
|
+
// refresh display. Yaw + pitch are already render-rate (consumed in
|
|
1895
|
+
// _consumeLook), so they're used directly — no blend, no aliasing.
|
|
1896
|
+
const alpha = this.entityManager.getFixedStepAlpha();
|
|
1897
|
+
const iPosX = lerp(runtime.renderPrevPos.x, runtime.renderCurPos.x, alpha);
|
|
1898
|
+
const iPosY = lerp(runtime.renderPrevPos.y, runtime.renderCurPos.y, alpha);
|
|
1899
|
+
const iPosZ = lerp(runtime.renderPrevPos.z, runtime.renderCurPos.z, alpha);
|
|
1900
|
+
const qYaw0 = SCRATCH_Q_A.fromAxisAngle(Vector3.up, runtime.bodyYaw);
|
|
1901
|
+
|
|
1902
|
+
// Transform body-local accumulated offset into world space (about the
|
|
1903
|
+
// render-rate yaw, to match the interpolated base position).
|
|
1714
1904
|
const worldOffset = SCRATCH_V3_B.copy(stack.offset);
|
|
1715
|
-
worldOffset.applyQuaternion(
|
|
1905
|
+
worldOffset.applyQuaternion(qYaw0);
|
|
1716
1906
|
|
|
1717
|
-
eyeTransform.position.
|
|
1907
|
+
eyeTransform.position.set(iPosX, iPosY, iPosZ);
|
|
1718
1908
|
eyeTransform.position._add(worldOffset.x, worldOffset.y, worldOffset.z);
|
|
1719
1909
|
|
|
1720
1910
|
// -- Eye rotation: body yaw × eye pitch × roll -------------------
|
|
@@ -1763,13 +1953,23 @@ export class FirstPersonPlayerControllerSystem extends System {
|
|
|
1763
1953
|
// composition: yaw * pitch * roll
|
|
1764
1954
|
// pitch around world X — yaw applied after, so effective axis is camera-local right
|
|
1765
1955
|
// roll around world Z — yaw and pitch applied after, so effective axis is camera-local forward
|
|
1766
|
-
const qYaw = SCRATCH_Q_A
|
|
1956
|
+
const qYaw = qYaw0; // SCRATCH_Q_A, already the render-rate yaw
|
|
1767
1957
|
const qPitch = SCRATCH_Q_B.fromAxisAngle(Vector3.right, pitchTotal);
|
|
1768
1958
|
const qRoll = SCRATCH_Q_C.fromAxisAngle(Vector3.forward, rollTotal);
|
|
1769
1959
|
|
|
1770
1960
|
eyeTransform.rotation.multiplyQuaternions(qYaw, qPitch);
|
|
1771
1961
|
eyeTransform.rotation.multiply(qRoll);
|
|
1772
1962
|
|
|
1963
|
+
// Dev-only camera-output guard (compiled out of prod). The composed eye
|
|
1964
|
+
// direction is exactly what the player sees; if a spring (head-droop,
|
|
1965
|
+
// breath nod) or lean ever drove pitch/roll to NaN, the camera would
|
|
1966
|
+
// snap to garbage. Assert it here, at the source of the visible jump.
|
|
1967
|
+
const er = eyeTransform.rotation;
|
|
1968
|
+
assert.ok(
|
|
1969
|
+
Number.isFinite(er.x) && Number.isFinite(er.y) && Number.isFinite(er.z) && Number.isFinite(er.w),
|
|
1970
|
+
"FP invariant: composed eye rotation is non-finite (camera direction corrupted)",
|
|
1971
|
+
);
|
|
1972
|
+
|
|
1773
1973
|
// -- FOV ---------------------------------------------------------
|
|
1774
1974
|
let fovTarget = cfg.fov.base;
|
|
1775
1975
|
if (cfg.fov.sprintAdd !== 0) {
|
|
@@ -1,67 +1,106 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ledge-grab ability —
|
|
3
|
-
* from it
|
|
2
|
+
* Ledge-grab ability — catch a forward ledge while descending, then HANG
|
|
3
|
+
* from it and traverse it: shimmy along the edge, pull up / vault over it,
|
|
4
|
+
* or dismount.
|
|
4
5
|
*
|
|
5
|
-
* Activation:
|
|
6
|
-
* - `sensors.ledgeAhead.hit`
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - `state.airborneTime >= minAirborneTime` —
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
6
|
+
* Activation (AUTO-CATCH):
|
|
7
|
+
* - `sensors.ledgeAhead.hit` — a forward+up obstacle probe found a
|
|
8
|
+
* grabbable edge (the same probe mantle uses). This already implies the
|
|
9
|
+
* body is facing a wall with a top, so even neutral input catches it.
|
|
10
|
+
* - `runtime.velocityY <= 0` — descending or static. We don't auto-catch
|
|
11
|
+
* on the way UP (that would feel like the world grabbed you mid-jump).
|
|
12
|
+
* - `state.airborneTime >= minAirborneTime` — a small post-takeoff window
|
|
13
|
+
* where ledge-grab can't fire even if instantly at apex.
|
|
14
|
+
* - NOT moving away — the move intent, taken to world space and projected
|
|
15
|
+
* onto the wall's outward normal, must not exceed `moveAwayThreshold`.
|
|
16
|
+
* You won't catch a ledge you're deliberately leaving (this also blocks
|
|
17
|
+
* a same-tick re-grab right after an away-dismount).
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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).
|
|
19
|
+
* The hanging input model (evaluated every tick): the move intent is taken
|
|
20
|
+
* to WORLD space and decomposed against the wall frame captured at grab —
|
|
21
|
+
* the outward normal `n` and the horizontal edge tangent `t = (-nz, nx)`.
|
|
22
|
+
* This makes toward / away / lateral facing-INDEPENDENT, which is exactly
|
|
23
|
+
* what makes "turn the camera to look away ≠ dismount" fall out for free.
|
|
28
24
|
*
|
|
29
|
-
*
|
|
30
|
-
* -
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
25
|
+
* - `away = worldMove · n` (>0 = off the wall, <0 = into it)
|
|
26
|
+
* - `lateral = worldMove · t` (signed, along the edge)
|
|
27
|
+
* - `facing = forward · (-n)` (how squarely the camera faces the wall)
|
|
28
|
+
*
|
|
29
|
+
* Per-tick decision (mutually exclusive — opposite axes can't both be high):
|
|
30
|
+
* 1. PULL-UP / VAULT — moving toward the wall, OR jump pressed while
|
|
31
|
+
* facing within `pullUpFacingConeDeg` of it. Hands off to Mantle
|
|
32
|
+
* (`runtime.ledgePullUpRequest`): onto a standable top, or a vault
|
|
33
|
+
* over a too-thin one.
|
|
34
|
+
* 2. DISMOUNT (drop) — crouch, or an away-DOMINANT world-move past
|
|
35
|
+
* `moveAwayThreshold` (conservative: a strafe that merely bleeds into
|
|
36
|
+
* `away` shimmies instead — leaving the hang is more consequential).
|
|
37
|
+
* 3. SHIMMY — lateral intent dominant: step along the edge if it stays
|
|
38
|
+
* clear and continuous; otherwise clamp (hold) — a shimmy NEVER drops.
|
|
39
|
+
* 4. HOLD — snap to the hang pose, accrue fatigue.
|
|
40
|
+
* 5. SLIP — exertion saturates (forced release).
|
|
41
|
+
* A jump pressed while facing AWAY is consumed (no back-hop in v1) and
|
|
42
|
+
* you keep hanging.
|
|
40
43
|
*
|
|
41
44
|
* 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.
|
|
45
|
+
* preempt an active ledge-grab — that's the point of placing ledge higher.
|
|
47
46
|
*
|
|
48
47
|
* @author Alex Goldring
|
|
49
48
|
* @copyright Company Named Limited (c) 2026
|
|
50
49
|
*/
|
|
51
50
|
export class LedgeGrab extends Ability {
|
|
52
51
|
/** @private Wall-face anchor (x,z), the face's outward normal (x,z),
|
|
53
|
-
* and the top-edge height (y) — captured at onActivate
|
|
54
|
-
* is built from the WALL, not
|
|
55
|
-
* facing, so it stays just outside the wall
|
|
52
|
+
* and the top-edge height (y) — captured at onActivate and advanced
|
|
53
|
+
* while shimmying. The hang pose is built from the WALL, not the
|
|
54
|
+
* (possibly oblique) body facing, so it stays just outside the wall
|
|
55
|
+
* at any approach angle. */
|
|
56
56
|
private _anchorX;
|
|
57
57
|
_anchorZ: number;
|
|
58
58
|
_nx: number;
|
|
59
59
|
_nz: number;
|
|
60
60
|
_edgeY: number;
|
|
61
|
+
/** @private Scratch query primitives for the shimmy probes — refilled
|
|
62
|
+
* in place so a hanging player doesn't allocate each tick. */
|
|
63
|
+
private _ray;
|
|
64
|
+
_hit: PhysicsSurfacePoint;
|
|
61
65
|
canActivate(controller: any, runtime: any, sensors: any): boolean;
|
|
62
66
|
onActivate(controller: any, runtime: any): void;
|
|
63
67
|
canInterrupt(): boolean;
|
|
68
|
+
onDeactivate(controller: any, runtime: any): void;
|
|
64
69
|
tick(controller: any, runtime: any, bodyTransform: any, dt: any, _system: any): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* World-space move intent (clamped to the unit disk) dotted with a
|
|
72
|
+
* horizontal axis (ax, az). Uses the controller's own move→world
|
|
73
|
+
* convention (screen_fwd = (sinYaw, cosYaw)). Facing-independent by
|
|
74
|
+
* construction — it's the intent in WORLD space, not camera space.
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
private _worldMoveDot;
|
|
78
|
+
/**
|
|
79
|
+
* Is the grabbed lip still under us? Probes the CAPTURED anchor (a down-ray
|
|
80
|
+
* just past the face, into the wall along −n), independent of where the
|
|
81
|
+
* camera looks — so turning to look away never reads as "ledge lost". Falls
|
|
82
|
+
* back to the facing-relative sensor only when no physics backend is present
|
|
83
|
+
* (the flat-ground unit harness, which simulates loss via that sensor).
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
private _ledgeStillThere;
|
|
87
|
+
/**
|
|
88
|
+
* Attempt one shimmy step of `dir` (±1) along the edge tangent. Returns
|
|
89
|
+
* true if it stepped (clear AND continuous), false if it CLAMPED — a clamp
|
|
90
|
+
* holds in place, it never drops. On success it advances the anchor and
|
|
91
|
+
* re-captures the edge height so an undulating top is tracked.
|
|
92
|
+
*
|
|
93
|
+
* Two probes, both must pass:
|
|
94
|
+
* (A) lateral CLEARANCE — a ray along the tangent from the body centre
|
|
95
|
+
* must be free for the step (a perpendicular/concave wall blocks it).
|
|
96
|
+
* (B) edge CONTINUITY — a down-ray just past the shifted edge must find
|
|
97
|
+
* the lip still at ~edge height (else the edge ended).
|
|
98
|
+
* Needs the physics backend; without it (flat-ground unit harness) it
|
|
99
|
+
* can't verify geometry, so it clamps.
|
|
100
|
+
* @private
|
|
101
|
+
*/
|
|
102
|
+
private _tryShimmy;
|
|
65
103
|
}
|
|
66
104
|
import { Ability } from "./Ability.js";
|
|
105
|
+
import { PhysicsSurfacePoint } from "../../../physics/queries/PhysicsSurfacePoint.js";
|
|
67
106
|
//# sourceMappingURL=LedgeGrab.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LedgeGrab.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/LedgeGrab.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LedgeGrab.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/control/first-person/abilities/LedgeGrab.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH;IAMQ;;;;iCAI6B;IAC7B,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,YAAY;IACZ,eAAe;IAEf;mEAC+D;IAC/D,aAAsB;IACtB,0BAAqC;IAGzC,kEAiCC;IAED,gDAuDC;IAED,wBAIC;IAED,kDAOC;IAED,wFA6GC;IAED;;;;;;OAMG;IACH,sBASC;IAED;;;;;;;OAOG;IACH,yBAgBC;IAED;;;;;;;;;;;;;;OAcG;IACH,mBA8CC;CACJ;wBA9YuB,cAAc;oCAFF,iDAAiD"}
|