Skip to content

Commit ca51627

Browse files
authored
Implement move-and-slide (#894)
# Objective - Resolves #438 - Supersedes #606 - Almost all kinematic character controllers use an algorithm called "move and slide", aka "collide and slide", "step slide", and similar, at their core - This algorithm basically says - Please move in this direction - if you collide with anything, slide along it - make sure you're not intersecting with anything, and report everything you collide with - see https://www.youtube.com/watch?v=YR6Q7dUz2uk for a video explanation ## Solution - Provide a `MoveAndSlide` `SystemParam` with an eponymous `move_and_slide` function - Implemented as a pure function, i.e. it does not mutate the ECS by itself - Returns a new position and velocity after movement and sliding along surfaces is complete - Every collision encountered during the slide is fed to a callback for optional processing. The callback is allowed to early-abort the slide. - Note: Currently, `move_and_slide` should be used to modify `Transform`, not `LinearVelocity`. The returned velocity should be stored elsewhere and passed to the next move and slide call to preserve momentum. ECS integration with `LinearVelocity` will be added later. - High level overview: (edited by @Jondolf to match new multi-plane solver) 1. Initial Gauss-Seidel depenetration pass 2. For each iteration, until movement is done or max iterations reached: - Sweep the shape along the velocity vector - If we hit something, move up to the hit point - Collect contact planes - Depenetrate based on intersections - Project velocity to be parallel to all contact planes - Inspirations - [kcc_prototypes](https://github.com/Ploruto/kcc_prototyping): general API shape, various code snippets - Box2D's [Character Mover](https://box2d.org/documentation/md_character.html): vector clipping and misc. ideas - Quake 3's [PM_SlideMove](https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/code/game/bg_slidemove.c#L45): 3D plane solver - [Solar Ash](https://store.steampowered.com/app/1867530/Solar_Ash/)'s implementation, as per [Tech Breakdown: Collision Sliding](https://blog.littlepolygon.com/posts/sliding/): depenetration - [Tweets](https://x.com/PhilippeStA/status/1233008602551590913) by Philippe St-Amand: new multi-plane solver that projects onto a convex cone, inspired by some of Philippe's ideas - Prior work in Avian KCC tech and comparison - [kcc_prototypes](https://github.com/Ploruto/kcc_prototyping): - very similar API - switched to Q3 plane solver, but then a hard-drive failure erased the progress. - no depenetration - [avian_collide_and_slide](https://github.com/tracefree/avian_collide_and_slide): - uses Q1 plane solving - no depenetration - [bevy_fps_controller](https://github.com/qhdwight/bevy_fps_controller): - Q1/Source inspired - no exposed collide-and-slide - no plane solving - no depenetration - Special thanks to @UndefinedBHVR, who spearheaded a first iteration of collide-and-slide that I was able to iterate on and who's breadcrumbs I followed a lot ❤️ - TODO: - [x] Fix some jitter on plane intersections - [x] Write docs - [x] Add examples to docs - [x] Replace the asset links juuuust before merging - See avianphysics/avian_asset_files#1 ## Out of Scope for this PR - Example KCC implementation - This is a deep rabbit hole and I'll leave that as a followup to not bloat this PR. - See #450 for a list of minimal character controllers that should be showcased eventually - For now, an integration into https://github.com/janhohenheim/character_controller_experiments will serve as proof that a KCC is doable with this API. - Changing the existing KCC examples - I think these should just be entirely rewritten later on - predicting intersections with moving bodies - calculating forces to be exerted onto touching dynamic bodies and vice versa - minimal examples, for now we just have the in-depth testbeds - a more diverse 2D testbed: requires parsing SVGs like Box2D ## Testing - [x] 3D testbed - `bevy run --example collide_and_slide -p avian3d` - [x] 2D testbed - `bevy run --example collide_and_slide -p avian2d` - [x] integration in https://github.com/janhohenheim/character_controller_experiments --- ## Showcase https://github.com/user-attachments/assets/426b0e4e-73ad-490c-acc2-1489eb848066
1 parent 56e4b84 commit ca51627

File tree

9 files changed

+1973
-13
lines changed

9 files changed

+1973
-13
lines changed

Cargo.lock

Lines changed: 167 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/avian2d/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,17 @@ name = "many_shapes"
170170
required-features = ["2d", "default-collider"]
171171

172172
[[example]]
173-
name = "one_way_platform_2d"
173+
name = "move_and_slide_2d"
174174
required-features = ["2d", "default-collider"]
175175

176176
[[example]]
177177
name = "move_marbles"
178178
required-features = ["2d", "default-collider"]
179179

180+
[[example]]
181+
name = "one_way_platform_2d"
182+
required-features = ["2d", "default-collider"]
183+
180184
[[example]]
181185
name = "prismatic_joint_2d"
182186
required-features = ["2d", "default-collider"]

0 commit comments

Comments
 (0)