dimforge / dimforge/nphysics

nphysics-ecs: simplify integration of nphysics with an ECS.

Open
#149 13 comments 13 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
1.6k
Forks
120
PR merge metrics
No merged PRs in 30d

Description

This issues provides a coarse description of a potential solution for simplifying the integration of nphysics into an ECS. Current solutions can be found on various small games: [stacked-worlds](https://github.com/andreivasiliu/stacked-worlds) and [airjump-multi](https://github.com/thiolliere/airjump-multi). They are mostly based on synchronizing components added to the ECS world with data stored by the physics world.

The solution discussed here is the creation of a new crate named `nphysics-ecs` that would define whatever is necessary to easily integrate nphysics into various popular ECS.

See also https://github.com/amethyst/amethyst/issues/942#issuecomment-426418900
Cc @Rhuagh and @ldesgoui who might be interested in contributing.

## Systems: the stepping function

The most critical method of nphysics is the [World::step](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L222-L326) method. This single method will not be good enough for an ECS since it assumes full control over the physics world. Instead, each major parts of the engine should be represented as separate systems. This implies at least:

* One system for the collision detection [broad phase](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L264-L266)
* One system for the collision detection [narrow phase](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L267-L269)
* One system for the [island computation and solver](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L278-L311)

For the moment, those systems cannot be updated in parallel as they all depend on data generated by the system preceding it on this list.
There are a few steps I omitted here that should be executed by one of the systems described so far, or by a new one:

* Kinematic bodies position [integration](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L314-L323)
* Body kinematics [update](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L227-L228)
* Force generator [application](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L230-L232)
* Body dynamics [update](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L234-L236)
* [Synchronization](https://github.com/rustsim/nphysics/blob/master/src/world/world.rs#L239-L261) between colliders transforms and body transforms.

## Components: bodies, colliders, force generators, joint constraints

There can be several approach depending on how much granularity we want. At the coarsest level we could have:

* A RigidBody component containing a [RigidBody structure](https://github.com/rustsim/nphysics/blob/master/src/object/rigid_body.rs) from nphysics.
* A Collider component containing the description of a collider, i.e., its shape, transform, etc. See the [CollisionObject](https://www.ncollide.org/rustdoc/ncollide3d/world/struct.CollisionObject.html) struct from ncollide, and the specific data [ColiderData](https://www.nphysics.org/rustdoc/nphysics3d/object/struct.ColliderData.html) nphysics uses.
* A ForceGenerator component that would contain a struct implementing the [ForceGenerator](https://www.nphysics.org/rustdoc/nphysics3d/force_generator/trait.ForceGenerator.html) trait?
* One or several components for gravity and [integration parameters](https://www.nphysics.org/rustdoc/nphysics3d/solver/struct.IntegrationParameters.html).

Currently, all the bodies are contained by a `BodySet` which is part of the world. We might want to abstract various parts of the API of nphysics itself to be able to retrieve bodies from an arbitrary data provider.

I think it is best to ignore multibodies for a first prototype of `nphysics-ecs`. Multibodies will probably be more difficult to handle and their design (including some magic happening when a multibody link is removed) will be strongly affected by the upcoming work on deformable bodies.

One of the open questions is whether all this will have an impact on ncollide. Should the ncollide world also be split up into components and systems? Or can we achieve our goal on nphysics without requiring creating a `ncollide-ecs` crate too?

## How to proceed steps by steps

The development of the `nphysics-ecs` crate could start focusing on supporting [specs](https://crates.io/crates/specs) which is quite popular and well maintained.
The different milestones for this ECS integration should be set by increasing order of complexity:

1. Be able to have something able to simulate one rigid body that falls under gravity. This excludes collision detection, constraint solver, etc.
2. Add support for forces generators.
3. Add support for proxies (which are colliders without contact generation) and proximity detection.
4. Add colliders, without constraints solver.
5. Add support for the constraints solver, but without handling island computation nor body activation/sleeping.
6. Add support for kinematic bodies.
7. Add support for activation/sleeping.
8. Add support for island computation.
9. Add support for joint constraints

Contributor guide

No contributing guide indexed for this repository

Research direction

Read src/world/world.rs, especially World::step and the linked broad-phase, narrow-phase, solver, integration, update, and synchronization sections. Review the proposed milestones and specs as the initial ECS target; the issue is not done until the project agrees on a prototype scope and the required systems and components.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.