Nphysics – 2 and 3-dimensional rigid body physics engine in pure Rust
github.com
github.com
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.
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.
pub fn to_rigid_body_or_fail<'r>(&'r self) -> &'r RigidBody<N, LV, AV, M, II> {Eventually we have to move on to more robust programming languages where null pointers and pointers to freed memory are not allowed.
- 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
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.
[1]: https://github.com/sebcrozet/nphysics/blob/916199c0a67219482...
[2]: https://github.com/sebcrozet/nphysics/blob/916199c0a67219482...
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 don't think that's terribly unusual.
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.
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.