-
-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nphysics-ecs: simplify integration of nphysics with an ECS. #149
Comments
FWIW, as someone currently using nphysics with an ECS, I find the existing interface ideal since I don't have a 1-to-1 relationship between entities and bodies. Would be interested to see what impact this has on nphysics performance, though! |
Sorry for going MIA, had a lot of day job things to take care. I think the proposal looks good! |
@Ralith while that's true, I think syncing data between the Worlds also quickly becomes tedious. |
I don't sync data between them and I'm not sure why I would. Entities that are associated with a body store that body's handle, and any system that wants to know details about the body looks them up in the usual way. |
Hello, I should be able to begin experimenting "soon", thanks for considering and organising this. Would ncollide require a similar solution, as far as I'm aware, it also contains a Thanks |
ncollide does have a World, but it also allows for the steps to be called separately instead of all together through a World. As far as I can tell, nphysics expects its users to go through the World to get physics things done. |
If nothing else, a proof of concept can be assembled for NCollide alone (no NPhysics behavior), just by assembling the building blocks of NCollide in specs in the same order as in the NCollide world. |
Is there any idea on the performance impact this would have on nphysics (when using it with Specs, or Pyro, for example)? I don’t see it mentioned anywhere, and I understans that’s something that has to be benchmarked, but I think it makes sense to put performance as one of the top priorities for this integration, so that it can be taken into account – and measured – every step of the way. |
What might be helpful for this would be to break out parts of the physics simulation functionality into their own procedures that can be called on disparate parts of the world, wherever they happen to be. ECS architectures generally are opinionated in preferring that data is laid out in the open in a particular place for systems to process them as they need to as opposed to being encapsulated with the methods that predominantly operate on them, which appears to be the architecture of the physics world in nphysics. |
Some users in Discord think that decoupling the simulation data from the application of mechanics (which is truly the root of this issue here) is not a good idea (namely @Ralith and @Andlon) so I figured I'd write on the issue tracker here what problems this solves beyond ✨ magical parallelism ✨ or any other performance gains/losses that simply can't be quantified without thoroughly developed implementation work. A great case brought up by @ldesgoui on discord are the requirements necessary for history, which requires far more granular access to the data in the simulation than is currently possible. While one of the levels of granularity required may be fixed with the current design (field access), another is necessarily held back (ownership). Many problems are solved in the structure of handling that data when the primary owner of it is not the World where stepping occurs, but the program who calls the stepping function. Lending data to the simulation functions is far less problematic in designing the ownership through the program in whole (especially when that program actually has The first, and greatest, issue that came to mind for me was considering the Uniform Access Principle in the API design of nphysics in an ECS context. Not only does the solution advocated for by Ralith necessitate unnecessary copying in Entity Transform data, but it undermines the API of the ECS it's hoisted onto. More orthogonal implementations (implementing Dynamics information Components and synchronizing them alongside Transform data back and forth between ECS storage and the nphysics World) incur even greater costs. And considering the progress being made in ECS tooling for inspection of Entities and their associated Storages, among many other benefits brought by conserving UAP in this layer, the design of nphysics left as it is now would appear completely bizarre to the average ECS/Amethyst user. What's more, is that I believe that the current World design could be preserved as a data storage implementation, such that the API for those seeking to continue to use nphysics the same way, would be able to. |
I must admit I'm somewhat surprised by being tossed into this discussion after what I believed was idle chatting on Discord. I must say that I'm not particularly invested in this particular issue, and wasn't originally planning to say anything about it on here. That said, now that I've been singled out, I suppose I will need to clarify a few things.
That is certainly not my position - or at least, not without significant qualifications. I'm also not opposed to this I'm confused about the real topic of the discussion going on here. On the one hand, I get the impression that @sebcrozet mainly proposes simply to create a layer on top of On the other hand, I have the impression that parts of the discussion is also about modifying Another worry that I have, is the idea of trying to structure the physics engine itself in terms of "systems". My claim is that a general purpose physics simulator simply does not fit inside of a traditional ECS architecture. Let's take an example, such as ``force generation" (i.e. given a set of bodies, return the forces acting on these bodies). One might be tempted to make these force generators systems. However, consider e.g. a Runge-Kutta 4 time integrator. Here one would need to evaluate forces multiple times within a single time step, and so one cannot simply organize "force computation" and "time integration" as steps in a sequence of systems. Instead, the "time integration" would need to call the "force computation" at selected points in time. Another example is the fully implicit time integration of finite element soft bodies. In this case, one would need to evaluate forces at every step of a loop of a non-linear system solver. What both of these two examples have in common, is that they exhibit something that tends to come up a lot when designing physics simulators, namely that ``systems" call other systems. Obviously, this breaks with the traditional ECS architecture in which systems are called in a linear sequence. I'll finish this part by saying that there may very well be many modifications to
Can you clarify? What is missing? Is he not able to simply copy out the data he needs after every time steps, thus recording a history of past events? (arguably any recording of historical values is beyond the responsibilities of a physics engine, and would always require copying data). |
Can you support this claim? What specific otherwise-difficult problems are solved?
I'm not trying to advocate any particular design here, but this is false. There is no need to copy significant quantities of data to/from an nphysics World in the current API. If you want to know the current transform of a rigid body, you look it up when in the World when needed.
I don't think nphysics' current API is bizarre. It looks like the uniform access principle is about providing an opaque interface that doesn't expose whether a value was cached or computed, which I don't think the current API is in violation of, either--though I'd think exposing internal state for storage in ECS columns might constitute a violation. Can you provide some specific examples of the many benefits you allude to? |
My honest apologies! These things can be time consuming. I will respond to your message below for posterity but don't find it necessary to respond to this message if you don't find the time or interest to do so.
To be clear I only personally hope for the latter. I don't think there are plans on forcing users to use an ECS with nphysics :P
I'm not sure how "traditional" specs is but this is definitely not the case for how its default dispatcher operates. Also, hopefully, the upcoming Inversion of control within systems using trait-based type parameters (my proposed solution for something inline with the integrator's normal operation), imo is not so much a "violation" of ECS but your mileage may vary on that. Other languages don't necessarily have the features to make that possible without a nightmarish or confusing API, while for Rust it is obvious to the user, and the state of the program, along with how that state is stored and accessed, is still reaping the UAP and performance benefits of ECS (although I honestly don't think it's possible to parallelize the physics system in ECS itself, Seb mentioned above the issues in that each calculation relies on the results of the previous, in the methods he considered splitting off)
Yes, History is always going to requiring copying. This does not mean that reducing the number of copies performed isn't beneficial.
A great example is the case of a generic-based trait implementation of force generators over the type parameters of the physics system. It is impossible to execute such a design because of the ownership of the data.
There is no point in using an ECS if you're just going to ignore the Entity+Component part and leave it just for handle lookups. Most average implementations at the very least utilize a Transform component to aid in rendering. The reason why it is implemented as so is to make iterating over the storages cache efficient. Actually making effort to expose at the very least Transform information for users who probably are already using a Transform, who probably already have systems that interact with that information, will cause unnecessary copies. Which brings me to the case of UAP, which you completely misunderstand. UAP is about the uniformity of accessing information in an API. What this means, is that data, regardless of kind, may be accessed through the same notation as all other data within that api. When using nphysics in an ECS as you suggest, there is literally no uniformity, which is why I suggested it would appear bizarre to many users to do what you suggest. I assume I need to address why having a uniform API would be beneficial in the first place. You'll find that discussion about UAP on places such as wikiwikiweb focus on the uniformity of notation within programming languages. However, we are not considering changing Rust, we are discussing the API of stateful libraries (nphysics and things that otherwise fit into specs in a way that is standard for the architecture). So we must consider the notation here as the API through which information is accessed and mutated. For many specs libraries, what you must do is create a Storage for that information, add the type for that information to the Data of whatever System you want to access or mutate it, and then operate on the received Storage, which should be plain data in almost all cases, that contains all relevant state for that Storage. In the nphysics implementation within specs that you suggest, you must do all of this, obviously, storing the whole nphysics world within a Resource, instead of placing the individual properties as Storages, and instead creating a Storage with handles to the nphysics World Resource, where the state of the program is essentially hidden, causing users to have to iterate over the Storage of Handles, using nphysic's specific api's for dereferencing handles in a World, dereferencing piecemeal over each handle in the Storage with your World Resource in hand, any time you wish to operate on the data within nphysics through your Systems. And this is just to access and mutate the data within a system, involving any sort of Storage.
Neither do I. But doing the above would appear bizarre to any average user coming to use ECS with nphysics. Just the act of accessing and mutating data is completely irregular from any normally Storage-based api.
Apologies for any typos or poor articulations, this message ended up quite long. |
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 and 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 amethyst/amethyst#942 (comment)
Cc @Rhuagh and @ldesgoui who might be interested in contributing.
Systems: the stepping function
The most critical method of nphysics is the World::step 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:
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:
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:
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 which is quite popular and well maintained.The different milestones for this ECS integration should be set by increasing order of complexity:
The text was updated successfully, but these errors were encountered: