

Nphysics – 2 and 3-dimensional rigid body physics engine in pure Rust - dbaupp
https://github.com/sebcrozet/nphysics

======
evincarofautumn
> 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.

~~~
mden
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?

~~~
evincarofautumn
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.

~~~
mercurial
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> {

------
bilalhusain
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

------
santaclaus
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.

~~~
kyzyl
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.

~~~
unwind
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...](https://github.com/sebcrozet/nphysics/blob/916199c0a672194826b2696c97c5a5597b070c54/src/integration/body_integrator.rs#L86).

~~~
dbaupp
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...](https://github.com/sebcrozet/nphysics/blob/916199c0a672194826b2696c97c5a5597b070c54/src/integration/body_integrator.rs#L134)

[2]:
[https://github.com/sebcrozet/nphysics/blob/916199c0a67219482...](https://github.com/sebcrozet/nphysics/blob/916199c0a672194826b2696c97c5a5597b070c54/src/integration/euler.rs#L38)

~~~
kyzyl
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?

~~~
dbaupp
I'm just an interested onlooker, yes.

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

~~~
kyzyl
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.

~~~
ivan_ah
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](https://github.com/ivanistheone/phys.js)

~~~
kyzyl
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](http://en.wikipedia.org/wiki/Bisection_method)

