Scripts, Tools & Methods Developed at Hook
While position-based dynamics can quickly create cool IK and rope effects due to its particle/constraint structure, it is often mentioned solely in the context of cloth and soft-body simulation while rigid body dynamics are only hinted at, and for good reason. Most behaviors of position-based systems are emergent and make much of the work feel more like alchemy than robotics, melting together a combination of vertices and constraints in hopes that you’ll get something solid and well-behaved. But those complex behaviors that materialize from such simple means are what makes the position-based approach so great.
As opposed to particle-based dynamics, rigid body dynamics are differentiated by an additional degree of freedom or 3, along with big scary words like inertia tensor, center of mass, angular momentum, moment of inertia, torque, quaternions, etc. While these concepts are valuable to be aware of, it sure does complicate simulated and interactive movement, so I’m after something I can handle early in the morning without first mainlining a case of Red Bull.
Spending hours sifting through the search engine desert with a hair pick doesn’t turn up much in terms of specific implementation of rigid-bodies with position-based dynamics, but, there are a few decent starting points that can be found, with varying complexity:
Each has a certain driving force behind its use, and along with that, certain strengths and weaknesses. One of the main things I’m looking for is the ability to arbitrarily add particle ‘effectors’ to the body, moving it by imparting both translational and rotational (torque) forces. As such, these particles can represent attachments, contacts, or mass distributions. This is where things start getting esoteric and nebulous, as the point-masses that make up a body can end up moving in completely independent ways as dictated by other connected bodies or forces. Also, something closer to well-behaved soft-bodies would be sweet too.
I plan on running some experimentation with each to get a feel for the nuances and sticking points, or possibly develop a different approach entirely. This post will focus on Jakobsen’s loose box construction (as opposed to the basis-vector coordinate/particle system, or the triangle/tetrahedron approach), specifically on applying arbitrary forces to it.
The Spring-Mass Model
The real strength of the spring-mass rigid body model as described by Jakobsen is the absolute simplicity with which you can create a simple object that can fall, bounce and settle into place fairly realistically. Besides friction and standing-contacts, this can be implemented completely with the standard Verlet integration and constraint relaxation as discussed previously. The particle dynamics are then magically transformed into rigid body dynamics.
While moving a vertex and thus the body is as simple as moving a particle, applying a torque to somewhere other than a vertex is a little tricky. To this end, I started with a more simplified case based on Jakobsen’s stick collision correction. The objective here was to create an ‘edge’ rigid body, which is pretty much the most basic rigid body type you can get, defined by two-end points (a single point can’t have rotational movement applied so its not a rigid body, deal with it).
The above example illustrates the point-force that will be used to push the edge. For simplicity’s sake I am using mouse movement, but that could very well be replaced with any sort of force you can boil down to the movement of a particle. Displayed are the crucial pieces of information we need initially: the point on the edge where the collision happened and the movement of the point-force as created by the collision. What we want to do is move the collision point on the edge towards the particle that flies off, and translate that movement to the edge’s end-points relative to where along the edge we collided. This is done by using the equations for stick correction as described in ‘Advanced Character Physics’.
The first step is to define point p along the edge. This is done using the equation:
& are the end-points of our edge, and & are constants (totalling 1) describing where along the edge the points rests. For example, if is the way between and , while . Though a little abstract, what this affords us is less vector or matrix operations doing coordinate conversions, and the location of will adjust as the edge scales. Likewise, because of those constants, we can use it to define points , and after correction:
where indicates the state after correction
To jump off a bit from Jakobsen, I applied the basic distance constraint math to & (our point-force position) to find as is illustrated here:
As you can see is about midway between and the applied force particle.
This is where Jakobsen gets a little crazy with the linear algebra, and ends up with the following formulas for x1′ and x2′
After digging through his derivation for for a little too long, it turns out to be 1 over the summed squares of the line coefficients:
while is just the displacement vector between & . As you can see, the end-points are moved relative to how close to they are, this is what gives us that tasty torque rather than just moving the edge along the direction of the point-force’s movement.
You may notice in the above illustration that while keeps its relative distances intact, the edge stretches (especially in more extreme angles and velocities). This gets corrected in time by the distance constraint binding the edge-points, so adding additional logic to correct that wasn’t really of concern.
Here I’ve just taken the above code and worked it within my update, with 1 iteration for constraints and it feels pretty tangible. To play around with the implicit moment-of-inertia created by this technique I’ve modified the original formulas for and to factor in the mass of the system:
where is a weight variable (inverse mass of the point-mass)
To see how this works within the context of a rigid body, I created Jakobsen’s simple box body with an additional cross constraint (cross constraints not shown). The edge model above was then applied to the 4 sides of the box. Through simple distance constraint relaxation, the box maintains its shape, while plausibly being affected by the mouse.
Though I kept these examples minimal with some basic mouse-striking to simulate forces, this edge model technique would likely work very well with other methods of applying movement, like attached ropes or springs. How about a good old fashioned pros and cons list?
Either way, the speed and simplicity with which you can create some simple semi-rigid forms is astounding, and the spring-mass technique for rigid bodies can be a great option for more simple projects where a full-blown rigid body simulator would be overkill. But as the bodies start becoming more complex, more constraints are required to keep things in place, becoming more like duct-tape than a tool to model behavior.
While the edge model and collision response can definitely be useful in creating ropes and chains (eliminating the inherit gap in rigid joint chains), we are still lacking a truly useful way to define a local coordinate space to apply points to create rigid body effects. To this, a flattened version of Jakoben’s tetrahedral approach may be just the answer, as we can define vertices and point-forces with barycentric coordinates to simplify coordinate conversion. But thats a topic for another post…