Labs.byHook 

Scripts, Tools & Methods Developed at Hook 
In my last post I went over basic velocityless integration and constraint systems to create some simple and easy inverse kinematic dynamics. Before moving on to more complicated fair like rigid bodies and particle systems from that groundwork, I wanted to try and apply those basic principles to something a little more tangible. After all, this is about breathing pixelated life and death into the computer screen.
Several of my early experiments with Verlet and the resultant IK chains started taking on a remarkably organic feel as forms not unlike tentacles and wings started emerging. So, I figured a nice little test of this system would be to make a self propelled codeorganism with all its movement and character imparted by dynamics rather than timeline animation or tweening engines. Aside from being affected and propelled by forces, I want to try and push this system to apply basic animation principles to impart some additional character in its movement. A tall order perhaps.
To keep things simple, I’m going to model the motion after an aquatic invertebrate. Broken into steps, each move should consist of:
While fairly simple on their own, incorporating them into a dynamic motion system that is as simple and reusable as it is expressive can be quite a mindbender. So lets dig in from the middle with a heroic dose of spring physics.
Driving the Motion: Spring Physics
Giving a short consideration to the issue of moving from point A to point B, the following options were the most obvious:
The spring option became the obvious choice mostly because of the requirement of anticipating our moves, which with the other systems requires more complicated and arbitrary calculations to cram that in. Also, spring force is highly dynamic, and while the arrive behavior would grant us a certain amount of that, I find it imperative to make the antic as easy to implement as possible because:
Spring forces are a really simple and great way to implement dynamic motion. Whereas friction and other forces require additional calculations of surface normals and relative velocities, for basic linear springs, all you need is a displacement, as stated by Hooke’s Law:
where:
is our elasticity constant
is our displacement (in the form of a vector or scalar, depending on your number of dimensions)
What this means is that the force applied by our virtual spring is directly proportional to to displacement of our object from its ‘home’ position, where the spring is at 0 stretch. But the really fantastic part of this is that the spring will take care of all the acceleration and deceleration for you as the object moves.
Note that Hooke’s Law applies only to linear elastic forces, when your springs start extending beyond their natural limits, other forces take over, but for most cases this is not an issue.
The above example is a simple demonstration of Hooke’s law applied to the motion of a pointmass, which will essentially serve as the motor moving forward. This spring force is integrated via Jakobsenstyle Verlet, however, you could use just about any other integration scheme for a similar effect. The trailing ‘orientation’ point is moved via a singledirection rigid constraint to help give our object a better sense of direction. Here the spring force (gray) and velocity (red) vectors are drawn out to help visualize exactly how the motion is being generated. Here is the psuedocode:
// first, find the 2D displacement from our position to our at rest position var displacement:Vector2D = lead.position  target; // multiply that by the negative of the elasticity constant (adjust this number to your liking) var force:Vector2D = displacement * 0.9; // integrate that force into our movement via Verlet // the numbers preceding our current and previous positions are the Jakobsen 'drag' values noodled to taste // without that 'drag' the spring would oscillate endlessly, if you're into that // note that i am also using a determinate timer so that my updates run at a consistent interval // with a time delta per update of about 0.25 var x:Number = (1.7 * lead.position.x)  (0.7 * lead.previous.x) + force.x * timeDelta * timeDelta; var y:Number = (1.7 * lead.position.y)  (0.7 * lead.previous.y) + force.y * timeDelta * timeDelta; // reset our previous position to what was our current going into this time step lead.previous.x = lead.position.x; lead.previous.y = lead.position.y; // update the position according to our motion integration lead.position.x = x; lead.position.y = y; // then you would apply constraints, etc.
All you have to do then is change the objects position or its rest position and it will start moving. With that basic foundation for motion in place, lets add in the anticipation to help give it a feel of selfmotivation. With Verlet and springs, this becomes a simple matter of just moving our object by a fraction of the displacement between our current position and the target position, but away from the target position, the integration takes over from there.
The example above should illustrate the subtle effect of telegraphing the move with an antic. Just by moving the object away from the new target a small velocity is imparted, which is slowed until the spring reverses the direction towards the target. There are slight variations that could be used depending on the desired result, but the position shift does the job well and is as simple as it gets. Here is the psuedocode on the mouse down:
// as we did for the spring force calculation, get the displacement vector var displacement:Vector2D = lead.position  target; displacement *= 0.2; lead.position += displacement
With a freakishly small amount of code (outside of UI and a 2Dcoordinate storage class) I’ve established a basic motor for the codeling so it can swim about on stage, in a hopefully appealing manner. But we can still add a little more life to it using these basic tools.
Adding Form: Squash and Stretch
While the antic works well and good to add some illusion of life to our codeling, to really sell it we need to find a way to show how its motion is affecting it other than position alone. A quick and easy way to do this would be to use a sprite animation of it scrunching up and extending out, but that wouldn’t be nearly as fun as doing that within our dynamics system.
Here is where our orientation point will really come into play. What we’ll do here is add a little inertia to that point and soften up the rigid constraint pushing it away from the lead point, effectively making it a pliable spine.
The effect should be quite subtle until you slow it down, but either way you should at least get the feeling that the object is stretching and compressing along with its movement, with a slight overlap in the action. Here is where the math starts getting a little more complicated. While I am still using the same integration technique as the lead point, I am dampening movement of the orientation towards the lead point separately from the movement tangential to that. This is merely an aesthetic choice to reduce the rotation of the orientation point around the lead point.r.
The modified dynamics update now includes (note that while this smells slightly different from the above integration of the lead point, it tastes exactly the same)
// get the velocity going into this timestep (this is equivalent to the "2.0 * position  1.0 * old" portion of the Jakobsen formula) var velocity:Vector2D = orientation.position  orientation.old; // we want to break this velocity up into components relative to the displacement to the lead point var displacement:Vector2D = lead.position  tail.current; // to get the component parallel to the displacement we project the velocity onto that displacement // first use the dot product of the two vectors to find a ratio by which we are going to scale our projected onto vector var dp:Number = velocity.x * displacement.x + velocity.y * displacement.y; var ratio:Number = dp / (displacement.length * displacement.length); // then use the following formula var parallel:Vector2D = new Vector2D (); parallel.x = displacement.x * ratio; parallel.y = displacement.y * ratio; // the perpendicular component is then just the parallel component subtracted from the original var perpendicular:Vector2D = velocity  parallel; // dampen independently parallel *= 0.7; perpendicular *= 0.5; // then back to our standard integration, combining the two components back together tail.old = tail.current; tail.current += parallel + perpendicular;
That code will allow us to impart some inertia on the orientation point, letting it drag and overshoot based on the lead points movement. But before setting that in motion, the constraint logic needs some modifications, otherwise it will null all that delicious overlapping action out. You may have noticed that the movement of the orientation point is now somewhat springlike, but that isn’t accomplished through a spring force as with the lead point but by the new ‘soft’ constraint setup, which gradually corrects the constraint each update. A big issue I encountered with a soft unilateral constraint combined with inertia is the inevitable point at which your moving point crosses through its reference point. While you could use some sort of gradient correction strength, for simplicity I set the constraint up with with capabilities for:
So while the constraint will gradually correct towards its preferred length under normal conditions, it drastically increases the correction for cases of extreme compression and extension to try and ensure that the point doesn’t pass through its reference, a sort of hybrid prismatic joint if you will. Here is the pseudocode for the new constraint relaxation:
// using our displacement vector from above var displacement:Vector2D = lead.position  orientation.position; // the ratio of that displacement vector we will be correcting by var ratio:Number = 0.0; // we can also vary the strength of correction based on which case var strength:Number = 0.0; // we have 3 cases, over compression, over extension, and normal correction, otherwise nothing needs to be done< // the ratio variable will be defined depending on which case we are in if (displacement.length < minLength) { ratio = (displacement.length  minLength) / displacement.length; strength = 0.8; } else if (displacement.length > maxLength) { ratio = (displacement.length  maxLength) / displacement.length; strength = 0.8; } else if (displacement.length != relaxedLength) { ratio = (displacement.length  relaxedLength) / displacement.length; strength = 0.1; } // then, just correct the position displacement *= ratio * strength; orientation.position += displacement;
With a solid line of action in place for direction, squash and stretch, I want to add a couple more points/constraints to illustrate the internal action as well as to establish a solid volume to the object.
Simply by adding 2 points and 5 additional constraints (2 from each side to the lead and orientation points, and 1 between the points), I have added a squash effect as the object compresses both while anticipating the move as well as during the recoil, all without adding complexity to the dynamics update with angle calculations and other scary math. But what I’m really interested in with these points is the ability to link additional structures to them, like tendrils and tentacles.
The constraints used are extremely simple soft unilateral constraints and a basic prismatic constraint between the two side points, so there are occasions in which the constraints collapse and buckle during extreme movement. But because the motion is intended to be a bit more subdued, I’m not going to worry about bugs that will eventually be voided out.
Hopefully I’ve demonstrated how with a few constraints and springs you can add some more life to dynamic movement, and its not too hard to imagine some cute little beady eyes and nasty, big, pointy teeth on my sparse vector graphics.
This is sick. Thanks!