Current State of the Elixir Rigid Physics Library

  • Create stub physics engine server in Elixir as a GenServer(done)
  • Create visualizer for engine state using Three.js and Phoenix Channels (done)
  • Add first body type to physics engine: boxes! (done)
  • Add framework for doing dynamics sans collisions in engine (done)
  • Add collision detection framework for finding contact manifolds (in progress, see below)
  • Add collision restitution code
  • Add friction
  • Add joints and motors
  • Add more types of bodies beyond boxes (we’re going full convex hull, God help me)
  • Figure out how to spread the simulation across multiple processes
  • Figure out how to spread the simulation across multiple nodes

Since last update

I fixed a bunch of little annoying things that made working with (and debugging) the engine unpleasant.

  • The ERP visualizer now has the shorthand name “ERPviz”.
  • I fixed the behavior of up and down arrows in the data entry to match that of a command prompt, so muscle-memory wouldn’t punish users.
  • I’ve added instrumentation for getting frame timings (more on this later).
  • Went ahead and setup the ERPviz server to use a shared world for all connections.
  • Added a setup_scene helper to create some pre-populated scenes (very helpful for testing!).
  • Added visualization of contact points and normals.
  • Added start, stop, and clear helpers for the sim.
  • Added bulk body insertion.
  • Added capsule-capsule intersection.
  • Made narrowphase an official step of collisions.

Intersection primitives and ERP

Taking a page from the Valve Rubikon writeup, there are only a few intersection types I’m doing:

  • Sphere-sphere
  • Capsule-sphere
  • Capsule-capsule
  • Sphere-hull
  • Capsule-hull
  • Hull-hull

I’ve finished all the non hull-related pairings, though the capsule stuff was a near-failure. Capsule-capsule intersection, at its core, is about finding the distance between two line segments. That in turn is a constrained minimization problem, and without the code and explanations of David Eberly I probably would’ve spent all of July figuyring it out.

Since I only have four week left at Recurse center (including this week), I’m going to go ahead and timebox this to about a week. I need to implement GJK and SAT for the hull bits, and if I hit wall-time I’ll just need to live in a world of spheres and capsules and move on to dynamics.

The basic idea behind the hull stuff is that you’re taking a perfectly good set of two potentitally colliding polyhedra and performing a Minkowski Difference on them, and seeing if the resulting poylhedra in Minkowski space contains the origin or not..or at least, that is how I’d summarize some much better presentations of the topic.

Next steps

Once the hull stuff is done, I want to try and implement aggregate bodies. The idea is that a body should be able to be made of multiple shapes, so we can build things like tables or what have you out of simpler shapes. I’m not sure if this is a “nice-to-have” or a disaster in the making.

The math behind it is sound–you just use the parallel-axis theorom, I think, to add up the different shapes moments of inertia and then you can figure out a reasonable inertia tensor for the aggregate. Then, during collision detection, you just loop over the shapes instead of just the bodies.

My expected changes for such a thing would be:

  • Teach the bodies about having multiple shapes.
  • Teach bodies how to generate AABBs for multiple shapes and cache them.
  • Teach shapes (or, more likely, bodies) about having poses (in addition to the pose info we normally store for bodies).
  • Update the AABB code to handle posed shapes.
  • Update the collision wode to handle multiple and posed shapes.
  • Teach the bodies how to calculate their centroids.

That feels like about a few days of work, but could go faster or slower–let’s see how hulls go first.

Addendum: Paintballing

I went paintballing this weekend. That’s probably a whole ’nother post into itself, but all-in-all it was a wonderful experience and I failed to injure myself (I think, I hope!).