Hacker News new | past | comments | ask | show | jobs | submit login
Nphysics – 2 and 3-dimensional rigid body physics engine in pure Rust (github.com)
78 points by dbaupp on Sept 2, 2013 | hide | past | web | favorite | 21 comments

> In a not-that-near future, C++ will die of ugliness

I am so excited for that day. There are some really amazing upcoming languages positioning themselves to replace C++ for new applications. Rust seems to be in the best spot right now; Nimrod is also pretty compelling.

That day might never come. Good things of rust will eventually make their way into newer C++ standards. The industry largely depends on C/C++, and switch to other languages is getting out of the comfort zone.

You might get some of the good stuff, but you won't get its killer feature, robustness, without sacrificing backwards compatibility. And that's not going to happen.

Eventually we have to move on to more robust programming languages where null pointers and pointers to freed memory are not allowed.

Out of curiosity, in what ways is Rust that much less uglier than C++? I've only looked through the docs and the code provided and it seems to be riddled with the same type of "ugliness" inherent to C++ - namely the ugliness symbolized by the need for all of the special characters like * and &. It seems like Rust has some nice syntax for pattern matching, but what else?

Syntax is undoubtedly important, but primarily as a means of elegantly expressing the unique semantics of a language. The visible ugliness is the language being explicit about low-level details.

So what else? Rust isn’t a huge innovation in terms of language features, but it does take advantage of relatively recent advances in language design (e.g. typeclasses) and has an excellent combination of defaults. The important ones are memory safety, an ownership model (think unique_ptr/shared_ptr), immutability, and isolated lightweight threads.

Well, it also handles lifetimes, which is certainly a huge improvement in terms of safety, though it comes at, shall we say, syntactic cost:

  pub fn to_rigid_body_or_fail<'r>(&'r self) -> &'r RigidBody<N, LV, AV, M, II> {

You're only thinking about syntax. Look deeper.

I'm hoping for a not-that-far future ... Jokes apart, does Rust perform as well as C++?

Anecdotally yes, within a few percent, depending on what you measure. Safe code tends not to perform as well as unsafe code, but this is also true in C++—most applications just tend to err (and I mean err) on the side of performance.

The difference is that in Rust you can write unsafe implementation of safe interface. In C++ you cannot specify safe interface. (You can and should document memory management assumptions in C++, but C++ compiler does not enforce such documentations.)

In case someone is struggling because they didn't read the docs or they are not into game-dev

- you need Rust compiler from the master branch (0.8-pre)

- dependencies needed: libglu1-mesa-dev freeglut3-dev mesa-common-dev libGL-dev libopenal-dev libxrandr-dev libxi-dev libglew1.5-dev libjpeg62-dev libfreetype6-dev libsndfile1-dev; SFML 2.1, CSFML 2.1; build glfw3 with cmake -DBUILD_SHARED_LIBS:BOOL=ON

How does the code handle the jump from SE(2) to SE(3) in a clean fashion? Pretty much any integrator you cook up will keep your configuration in SE(2), but a discrete integrator of the Newton-Euler equations takes a bit more care.

So, I don't know Rust very well and their code is not really documented at all, so this is just a guess. But...

It seem that the default world container assigns an integrator called "BodySmpEulerIntegrator", for which I can't seem to find the source. In any case, with a name like that I would have two predictions:

a) 'Smp' stands for 'simple' in which case this would be a stock/naive/vanilla Euler integrator. If that's indeed true, then I suspect the answer is that it will NOT handle the transition to SE(n>2), as they tend to blow up when the Hamiltonian becomes at all stiff. That is usually the case for your standard 6N+2 dof system in 3D.

b) 'Smp' stands for 'symplectic', which would make the default integrator some form of symplectic euler integrator. To my knowledge any SI should handle a 3D non-timevariant, non-chaotic Hamiltonian. This seems much more likely, given the amount of effort they've put in. Indeed, if you look at the examples that have a 2- and 3-D version, they don't seem to reassign the integrator.

That's a lot of guess-work on my part, though.

This would appear to be the source of BodySmpEulerIntegrator, or at least a starting-point (I don't know Rust): https://github.com/sebcrozet/nphysics/blob/916199c0a67219482....

It calls[1] into a module called `euler`[2], and that looks like a very basic euler integrator.

[1]: https://github.com/sebcrozet/nphysics/blob/916199c0a67219482...

[2]: https://github.com/sebcrozet/nphysics/blob/916199c0a67219482...

Well again the code is nearly completely opaque to me (goes to show you that there is such a thing as too much abstraction) but again based off of the name "semi_implicit_integrate" it would be crazy for this to be anything but a Semi-Implicit Euler integrator. That falls into the class of symplectic integrators, so it should handle SE(3) fine.

There is also a explicit method in there, which probably won't handle it very well.

On the other hand, I hesitate to argue with the author about their own code... or are you just the OP?

I'm just an interested onlooker, yes.

UGRAD mechanics class of the future should be to program a physics simulation engine in the language of your choice.

That's what one of my undergrad mechanics classes was. Actually that was just a project in the course, along with all of the usual theory, lectures, assignments etc.

I don't think that's terribly unusual.

Cool! Which school was that? Did they just assume you knew coding to begin with or did they teach the programming aspect also?

Did you keep any lecture notes/code from that project? I'm working on something along those lines[1], but not sure how to do the collisions and contact forces.

The source code of box2D is very useful and I have some other physics engine resources but something with a more physics-lesson flavour could be very handy as inspiration.

[1] https://github.com/ivanistheone/phys.js

Hey, sorry I didn't see this for a week. Another victim of the short halflife of HN threads ;-)

Anyhow, I suspect that code still exists somewhere, but offhand I can't see where that is; likely a backup somewhere. It was some time ago. As for lecture notes, I'm not sure they'd help very much. I should have been more accurate: my mechanics course was just a mechanics course where we had to pick a project. I chose to make a physics simulator, so all the research therein was not part of the course.

There are a number of ways to do collision detection. If memory serves I used a bisection method with bounding volume intersection trees. I believe this is a known technique you can look up. If not, it basically amounts to dividing up your objects into a series of adjacent bounding volumes, for example divide the bounding volume into octants. Then at each simulated time step, you run through tree structure which shows all of the locations where two octants belonging to different objects intersect. Any one of these intersections essentially means that a collision has already happened, and you've simulated your way into an impossible situation (assuming non-deformable bodies). So what you have to do is find out the time step when the collision actually occurred at that locale. One way to do this is to backtrack and use a bisection method[1] to zero in on your collision time, and then begin simulating again from there. At each collision point you need to determine the time of collision (face-face, face-vertex, etc.) and calculate the contact forces iteratively until everything is resolved.

Calculating the contact forces is actually the tricky bit, and there's been a good deal of research on that topic. The trouble is that the contact forces are interdependent, so you can't just solve them in parallel, or exactly. It pretty much boils down to a Quadratic Optimization problem, which needs a non-convex optimizer to solve (I believe cvxopt has one, but if you're working in JS...). The details of that method get hairy pretty quickly, and are far out of scope for a HN reply, unfortunately.

You probably knew most of that already, but in any case, there it is. Let me know if you have any more specific questions.

EDIT: The school was the University of British Columbia, and the course was like the second classical mechanics course or something. It didn't teach any programming or computer science aspects. They knew that most of the class was capable of the required feats because of the prereqs for the course and the programs people were in, so they pretty much just threw us into the deep end.

[1] http://en.wikipedia.org/wiki/Bisection_method

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact