Email Updates RSS Subscribe
Line

This blog is created and maintained by the technical team at Hook in an effort to preserve and share the insights and experience gained during the research and testing phases of our development process. Often, much of this information is lost or hidden once a project is completed. These articles aim to revisit, expand and/or review the concepts that seem worth exploring further. The site also serves as a platform for releasing tools developed internally to help streamline ad development.

Launch
Line

Hook is a digital production company that develops interactive content for industry leading agencies and their brands. For more information visit www.byhook.com.

Line

Fuzzy Physics – Pt 1: Constraint Dynamics

Line
Posted on December 6th, 2009 by Brad
Line

If you’ve ever worked on any client projects requiring ‘realistic’ or ‘real-world’ physics, you’ve probably found that their idea of realistic differs wildly from the physics resultant from the Big Bang.  Likewise with games, its often enough and even better to convey the feel of physics rather than running a precise simulation.  After all, you are dealing with a combination of the audience’s senses, impressions, and perceptions of the real world, and perpetuating that lie is more important than the truth as measured by Newton.

While there are several great Actionscript physics engines out there, which we have used to great success, we also needed a toolset for handling those more… quirky requests.  Out of this necessity, and surely an expression of my own masochism, I have undertaken an attempt at creating a set of tools for creating physics based movement (rather than a full blown physics engine) that is better suited at handling these ambiguities, and will be presenting the difficulties and discoveries encountered as that toolset develops.  Here goes:

Implicit Velocity Integration

Having written plenty of on-the fly physics code, my go-to approach was simply plugging in numbers into the classical mechanics formulas:

v = {Delta p} / {Delta t}, a = {Delta v} / {Delta t} and F = m a

Which were integrated into the system each update along these lines (known as Euler integration):

calculate acceleration according to accumulated forces:

a_n = F/ m

integrate that acceleration into the velocity:

v_{n+1} =  v_n + a_n Delta t

integrate velocity into the position:

x_{n+1} =  x_n + v_n  Delta t

It is a very simple and intuitive approach that can get you pretty far for most simple cases (where accuracy isn’t crucial).  A little further research into the topic brought me to the Numerical Integration chapter of Keith Peters’ book AdvancED ActionScript 3.0 Animation, which gave a great overview of the various  accuracy issues involved with  simulated motion, and the first mention of integration I’ve seen in an Actionscript specific context.  The most important take away from that in regards to fuzzy physics was the deliciously black-magic-esque Verlet Integration.  The most cited and plainly stated (at least to a non-rocket scientist) description of which is in the paper ‘Advanced Character Physics’ by Thomas Jakobsen, which is available all over the interweb (link at bottom).

x_{n+1}  =  x_n + (x_n - x_{n-1}) + a_n t^2

or

x_{n+1}  =  {2.0 x_n} - 1.0 x_{n-1} + a_n t^2 (according to Jakobsen)

How Verlet differs from other integration schemes is that rather than storing and modifying position and velocity in sequence, the velocity is determined each step by measuring the point’s current position from its previous position.  While seemingly no-big-deal, what this offers us is direct control over the point’s position while the physics system catches up, rather than making offerings of forces and impulses to the gods within the machine and hoping the results work out pleasingly*.  The points I am referring to can be anything represented by a position and mass: particles, vertices, boids, etc.  and will be the focus of early development due to that simplicity.

*Note: This is in no way to say that Verlet is the end-all be-all of physics integration schemes, it wont necessarily pass the stress test of 100s of stacking boxes the way rigid-body physics would.

Using implicit velocity also allows us to focus on the relationship between points and manipulate the negative space around them (mmmmmsoft-bodies).  Which brings us to the point of this first post:

Constraints

A constraint represents a relationship between two point-masses and is used to ‘correct’ those points’ positions as to satisfy the constraint’s requirements (called relaxation from here-on out).  These requirements could be that the points maintain a set distance, a minimum/maximum distance, or just about any silly condition you can dream up.

Example 1 illustrates a simple Equality (rigid) constraint in 1 dimension, which relaxes to maintain a set distance between the two points, while distributing the correction between the points based on the weight shift.

delim{|}{x_2 - x_1}{|} = l, where delim{|}x{|} represents vector magnitude.

So on each update we are effectively moving each point-mass by a fraction of the displacement between the two as it differs from the constraint’s rest length.  If you are familiar with spring physics, this should feel very similar, given that spring force is calculated by displacement:

F = -k{Delta}x, where k is the elasticity of the spring

However, through this rigid constraint approach, our points are bound by springs that are precisely so elastic and dampened enough to maintain the specific relationship we have defined! (Which isn’t exactly the most practical or efficient thing to achieve with spring physics, we’ll cover spring-based motion in another post)

Let’s expand this concept to 2D, add a little mouse driven movement and see what happens:

Here I am using the same rigid constraint mechanism as described above, only when a point is clicked on, the weight shifts so that there is zero correction on the dragged point, while there is 100% correction on the connected point for what is beginning to resemble a kinematic chain. Here is the dynamics update in psuedo-code

// start off by applying our driving force, in this case mouse position
drivingPoint.position = mousePosition;
 
// relax our constraint
// find the displacement between the points
// Vector2D is my own version of a 2D object representation, but the concept here is any
// n-dimensional object (x, y, Point, DisplayObject, Vector3D, etc. )
var delta:Vector2D = pointB - pointA;
 
// then the ratio between that delta and the rest length
var ratio:Number = (delta.length - constraint.length) / delta.length;
 
// correct the position of our points
pointA += delta * ratio * constraint.strengthA;
pointB -= delta * ratio * constraint.strengthB;

With that basic constraint dynamic in place, we can now incorporate the implicit velocity system mentioned above to add a feeling of momentum and inertia.  More psuedo-code:

First, some basic set-up:

// these two variables will be switched depending
// on which side of the constraint we click
var dragPoint:VerletPointMass;
var endPoint:VerletPointMass;
 
// a gravity constant
var gravity:Number = 8.0;
 
// our timestep frequency (it is critical when dealing with physics to maintain a consistent update frequency)
// in the examples I have a corrected timer that runs the movement update at a fixed interval of 0.33 seconds
var timeDelta:Number = 0.33;

Then, add to our update loop:

// because mouse movement is our driving force, we move that first, then correct the rest of our system
// we're just using a basic linear interpolation here to get some smoothness
dragPoint.old = dragPoint.position;
dragPoint.position += (mouse - dragPoint.position) * 0.5;
 
// some temporary variables for our position modification
// because we need to properly store our old position for the next update
var newX:Number, newY:Number;
 
// integrate the movement according to Jakobsen's technique (chosen for clarity and simple drag)
newX = 1.9 * endPoint.position.x - 0.9 * endPoint.old.x + (0 * timeDelta * timeDelta);
newY = 1.9 * endPoint.position.y - 0.9 * endPoint.old.y + (gravity * timeDelta * timeDelta);
 
endPoint.old = endPoint.position;
endPoint.position.x = newX;
endPoint.position.y = newY;
 
// from there, run the constraint relaxation as described above
// and the endpoint will maintain a fixed distance from the point being dragged
// while simultaneously being affected by gravity and a 'pull' force from the mouse
// as translated through the constraint

And here is what you get:

Get Adobe Flash player

Next up, I’ll be doing some experiments with some different constraint set-ups as well as more advanced motion.

see also:

Thomas Jakobson’s Advanced Character Physics at Gamasutra

Gaffer on Games: An overview of Euler and RK4 Integration Schemes

Line
5 Responses to “Fuzzy Physics – Pt 1: Constraint Dynamics”
  1. Corbin says:

    Beautiful theme. I am just starting out learning about Blogengine so seeing themes and info like this is very helpful.

  2. ricky says:

    well written and nice examples. looking forward to part two. also, thanks for the nod and point to the AdvancED book, picked up, and it too is a great resource.

  3. Pumpy Mcstashe says:

    Will you be extending the series to include quantum physics? I am having trouble reconciling my in-game grenade launcher’s kickback when deployed within clouds of Bose-Einstein condensate (generally helium-4, duh!) in deep space. I mean, does the probability waveform just collapse or what? Right?

  4. wilson phillips says:

    One time I was this party, hanging out, doing what sweet dudes do (drinking tons of beer and eating all the Funyuns, sorry Steve) and noticed that something seemed a little odd…

  5. Jeremy says:

    great stuff


Leave a Reply

*

Line
Line
Pony