Simple example "game" illustrating how an integration of nphysics into Amethyst could look like. This example uses the master version of Amethyst and has all the nphysics related logic abstracted away in a separate crate (game_physics).
Rust version:
rustc 1.36.0-nightly (3991285f5 2019-04-25)
Clone the repository:
$ git clone https://github.com/bamling/amethyst-nphysics-example.gitChange into the checkout directory:
$ cd amethyst-nphysics-exampleExecute Cargo:
$ cargo run- Allow multiple
PhysicsColliders perEntity - Allow
PhysicsColliders withoutPhysicsBody - Automatically apply margin to full
Shapesize - Add more
Shapes - Add other debug shapes
- Expose channels for
CollisionEvents andProximityEvents - Remove custom
Isometry,MatrixandPointtypes - Refactor body/collider
Sytems - Ray interferences to prevent tunneling issues*
- Custom
GameDatawith separate dispatcher for movement/physics basedSystems (executed duringfixed_update(..)) - Clean up
game_physicscrate exports - Add tests
- Introduce generic type parameters over
f32 - Examples on how to use the crate
- Polishing, polishing, polishing...
- Build automation/CI
- Publish to crates.io (migrate repository for that?)
*Thanks to sebcrozet for the idea:
Well, you can cast a ray on the world using: https://www.nphysics.org/rustdoc/nphysics3d/world/struct.ColliderWorld.html#method.interferences_with_ray. The ray direction would be the player desired velocity, and the ray starting point would be right in front of the player in that direction. If interferences are found, then find the one with the smallest toi field: https://www.ncollide.org/rustdoc/ncollide3d/query/ray_internal/struct.RayIntersection.html#structfield.toi which is < 1.0. Then you take this toi (if it exists) and multiply it with the players' desired velocity. This will give you a new vector that is the velocity you actually want to apply to your player.
let point_in_front_of_the_player = desired_velocity.normalize() * (player_box_radius + 0.1) + player_center_position;
let ray = Ray::new(point_in_front_of_the_player, desired_velocity);
let toi = world.interferences_with_ray(ray, CollisionGroups::default()).fold(1.0, |a, inter| a.min(inter.1.toi));
let velocity_to_apply = desired_velocity * toi;