NPhysics: 2D and 3D Real-Time Physics Engine for Rust
nphysics.org
nphysics.org
Carmageddon 2 (as the last example I can think of) instead found out when the next intersection would happen, precisely, moved time forward exactly that far and then resolved the collision using impulses and would then repeat until it reached a frame's worth of time. In pathological cases, this resulted in a frame taking nearly a second, but that was rare and the physics were much less spongey and more realistic.
Not sure if that is what you had in mind. Also, intersections / collisions aren't the only dynamic in such a simulation.
Intersection and post-correction still seems to be present (and the sponge/spring behaviour) in demos even when you increase CCD steps and enable sub-stepping. Look at how much the bottom cubes/spheres intersect when the stack lands. (It's hard to tell what the demo called CCD is demonstrating.)
> intersections / collisions aren't the only dynamic in such a simulation.
Fair. (Contact points and friction also seemed more stable/realistic in Carmageddon 2 than in most physics libraries.)
For stability and performance reasons physics engines usually have parameters that soften or add compliance to contacts/constraints. A bit of compliance is almost always better than infinitely stiff collisions/constraints. There are cases where infinitely stiff systems either have no solution, are very expensive to solve, or would produce very extreme impulses (causing things to explode). Including some compliance fixes these issues. It is also often required to produces more realistic looking results since objects in real life aren't infinitely stiff, they either flex or break.
For performance reasons most physics engines also do not completely solve their constraints. They either use a fixed number of iterations (most common, including the demos here) or solve up to some specified error threshold. This tends to add some additional compliance to complex scenes (stacks/piles of objects for example).
With the right parameters a good rigid body physics engine should be able to prevent noticeable interpenetration in most situations, though the performance cost may not be worth it. In these demos if you max out Position iterations, velocity iterations, and frequency you should see significantly less interpenetration.
As for continuous collision detection/sub-stepping, this is a very common feature to prevent fast moving objects from clipping into or tunneling through other objects. However resting/continuous contact cannot be handled by stepping to the next intersection time and so have to be handled differently. Also multiple simultaneous or near simultaneous collisions can grind things to a halt in degenerate cases (such as multiple stacked objects that are almost, but not quite in resting contact). This is why physics engines that support continuous collision usually let you set a maximum number of sub-steps.
I wonder if someone uses a hybrid approach of CCD with a constrained time budget, meaning you will use CCD until the budget is exhausted, after which simulation will jump to the next frame time.
Continuous collision detection is great if you only need spheres, capsules, or some combination for moving objects and all of your static objects are triangles. EPA algorithms are far less accurate than exact algorithms, plus the continuous algorithms are faster and give you the contact normal for free (I.e, the problem of determining which direction the objects need to be pushed is trivial, as the objects aren’t overlapping to begin with).
If you only have one moving object that interacts with static objects only, it is possible to prevent overlap as you described.
However, if you have a complex system, you can’t just stop an object before it overlaps. The best thing to do is to move the objects the remaining part of the time step, converting the contact information from the TOI collision to one where the contact points have traveled and the geometries are overlapping.
So really, I would say the primary benefit of continuous collision detection routines are supplemental to a good collision/contact generation routine, and they don’t really affect the physics simulation in very many meaningful ways, unless your engine uses it in extremely specific situations
Body deformation is mentioned as a feature. Is this equivalent to what other renderer call soft body physics opposed to rigid body physics? And can I treat such an object as a rigid object again if I wanted to and can I have compound objects with soft and rigid parts? Had some problems with that in some renderers.
Here is an example of what I would basically understand under that term:
https://www.babylonjs-playground.com/#480ZBN#2
This is babylon.js with ammo.js (I think it is ammo.js for the physics part).
Check out the demos in your browser: https://nphysics.org/all_examples3/
Also check out the fluid simulation engine that is a sister project of nphysics: https://salva.rs
I had to hack up the Box2D port to pool short lived objects that would normally exist on the stack.
Which was kind of frustrating, as it was all compiled back down to C++ again anyway.
As far as I can tell, this is single threaded CPU only, right? I wonder if it wouldn't be more appealing to do it parallel on the GPU instead when starting a new physics engine today, especially given how hard it is to change that later on.
The problems are that: 1) There may not be enough islands to make full use of the available threads. 2) For many frames there might be a single island which is particularly expensive to solve, so the benefit from parallelisation is reduced.
The broad-phase itself might benefit significantly from parallelisation though.
Of course, pathological cases can generate a ton of batches. Usually such implementations will use a final 'catchall' batch of some kind after N normal batches. That final batch can be handled sequentially or with a fully parallel jacobi-ish solver (which typically has worse convergence than PGS/SI, but it's usually not a problem in context).
It's extremely easy to get started with the basics, and then there's a long ramp of increasingly difficult features you can implement. So if you're doing it for fun/learning, it's a great project.
One of my first programming projects when I started learning Java in high school was a 2D physics system. Just took the equations from my physics class and implemented them in code and bam, you have particle physics. And then I figured out how to make those particles into circles with collision and added infinite lines for them to bounce off of, without really knowing what I was doing.
Then in an early CS class in college my team for a project did a similar engine but with arbitrary equilateral polygons for colliders. We had someone who already knew the math for doing those intersection checks, so it wasn't too hard.
But yeah: things obviously get hard at a certain point, but it's not one of those projects where you don't see any satisfying results until you've mastered it.
There's no doubt that GPUs have the flops/bandwidth advantage, and even all the overheads of adapting a physics engine to a GPU won't completely eliminate those advantages. If a company needed an absolute-maximum-performance backend simulation on computers they built to spec, it could definitely make sense.
But when you move into the realm of game client simulation, it's harder to justify the use of GPUs. Very, very few gamers have multiple GPUs, and the one GPU they do have is often already quite busy.
Ignoring all the nightmarish issues around driver bugs and vendor compatibility, it comes down a question of comparative advantage. GPUs are extremely good at graphics. They can also do a pretty darn good job at physics. Or sound path tracing. Or machine learning inference. Or any number of other high throughput workloads. There's a limited budget, and there's no reason to leave a beefy CPU idle. What task allocation gives you the most bang for the buck? Would your average gamer be okay with worse graphics, just because the GPU is needed to perform physics simulation in order to play the game? The answer will sometimes be yes, but it's something to be careful about.
Plus, especially with the latest surge in CPU performance and competition courtesy of AMD, CPUs can do a pretty darn good job of running physics simulations per dollar.
As a rust newbie, I guess I should run in "cargo build" in the example folders. But both output the error
error[E0463]: can't find crate for `std`
What I missed here?
I'm sooo tempted to dive into Rust head-in. Have only dabbled a bit with it so far. The main thing holding me back at this point is that Rust seems to lack a decent ecosystem for data science and AI/DL/ML (in particular, a set of crates that has proven useful and stable in real-world AI/DL/ML applications).
That being said, you should definitely give Rust a try. I find it to be an absolute joy to use
PS. The link shared by dabreegster has a fairly detailed list of missing facilities: https://news.ycombinator.com/item?id=23615175
Your reaction to arewelearningyet is similar to how I feel about:
However, at least for GUI I know that Raph Levien is really pushing a focus on GUI at the moment. https://raphlinus.github.io/rust/druid/2019/10/31/rust-2020....
I wish I could contribute more. You really summed up how I feel about Rust: "It seems every day I see a new shiny thing made with Rust that was developed remarkably quickly, runs quite smoothly, and appears to be magically bug-free."
Even the maligned actix web framework in Rust is still leading performance benchmarks: https://www.techempower.com/benchmarks/#section=data-r19&hw=...
As far I know there aren’t any good computer vision libraries for Rust?
The only other "fast, practical, memory-safe, widely used language" that looks like a real alternative to Rust is Swift. But unlike Swift, rust was designed from the ground up for for data parallelism and other forms of concurrency with "zero-cost abstractions" the allow "fearless concurrency" (e.g., take a look at https://github.com/nikomatsakis/rayon/ to get an idea of what's possible), and for predictable performance (e.g., compiled code doesn't suddenly slow-down to collect garbage or synchronize reference counts among CPUs). Concurrency appears to have been an afterthought in Swift's case, explicitly: https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9... . See also https://doc.rust-lang.org/book/ch16-00-concurrency.html and https://blog.spencerkohan.com/impressions-of-rust-as-a-swift...
Data parallelism and other forms of concurrency should become more and more important over time as models grow larger and larger, well beyond GPT-3's 175 billion parameters. This would favor rust.