The Flint particle animation library for Flash and Flex is a powerful way of animating large groups of objects that can be attracted and repelled by each other in 3D. Flint's 3D environment has a high-level API to set up animations with just a few commands. This article describes the basic parts of a Flint application by extending Flint's flocking sample to show flies being attracted to restaurants with poor health inspection scores.

A Flint application must first define a Renderer object to serve as the stage of the animation. Flint's Flex renderers extend UIComponent and can use bitmaps, lines, or DisplayObjects to represent particles. To use a SWF of a fly as the particle, the application creates a DisplayObjectRenderer. Each Renderer has a Camera object as a property, and waits to have Emitter objects added to it. Emitters are responsible for defining the objects to be animated and their behaviors, and they are where most Flint programming takes place.


Clicking the image will launch the application

The Renderer is defined in MXML:

<f:DisplayObjectRenderer id="renderer" width="1195" height="675" />


The Camera and Emitter are defined in ActionScript once initialization data for the Emitter's group of objects has been loaded at run time by Flex's HTTPService.

// Aim camera
renderer.camera.position = new Point3D(0, 0, -400);
renderer.camera.target = new Point3D(0, 0, 0);
renderer.camera.projectionDistance = 400;

// Create flocks of objects
var theFlocks:XMLList = settingsService.lastResult.flocks.flock;
var theGravityPoints:XMLList = settingsService.lastResult.gravityPoints.gravityPoint;
for (var n:Number=0; n<theFlocks.length(); n++)
{
emitter = new Flock(theFlocks[n], theGravityPoints);
renderer.addEmitter( emitter );
emitter.start();
}


The Flock class extends the Emitter3D interface so it can be attached as an Emitter to the Renderer object. The class's constructor receives initialization data, such as the number of objects to create.

Object animations are created in two stages: initialization and action. Initializers define the starting state of an object, and actions define how they change over time. Both are added to the Emitter. For example, you would typically initialize an emitter's objects with a starting position and velocity, and then add a Move action to move them.

The following initializer command positions the flies above the map:

addInitializer( new Position( new BoxZone( mapWidth*2, mapHeight*2, mapDepth, new Point3D( 0, 0, 0 ), new Vector3D( 0, 1, 0 ), new Vector3D( 0, 0, 1 ) ) ) );


Each fly in the Flock class shares the same rules of attraction. Flies are strongly attracted to restaurants, and also weakly attracted to other flies.

To attract flies to restaurants, the Flock class creates gravity wells within the 3D landscape. Gravity wells are specific to each Emitter, and are defined with the GravityWell action:

var gravity:Number = gravityData[n].points * 2;
var reach:Number = gravityData[n].points * 1;
addAction( new GravityWell(gravity, gravityPoint, reach) );


The restaurant health inspection data was gathered from the NYC Health web site and stored in an XML file, which also contains the coordinates of each restaurant on a Google map image. The worse the inspection score, the more powerful a restaurant's gravity.

The weak attraction between flies is also defined on the Emitter level. To create flocking behavior in Flint, you usually add the ApproachNeighbors, MinimumDistance, and MatchVelocity actions to an Emitter. The actions are initialized with their target values and the acceleration each will impose on its object to reach the target. For example, the MinimumDistance action seeks to keep a minimum distance of 20 co-ordinates between flies, and will move the flies quickly to maintain this distance:

addAction( new ApproachNeighbours( 100, 100 ) );
addAction( new MinimumDistance( 20, 600 ) );


Once an Emitter has been initialized with its images, objects, and actions, its start() method is called to start the animation:

emitter.start();


Flint is an easy library to pick up and experiment with. The author, Richard Lord, has posted a conference presentation on his web site that's a good introduction to its architecture. For more info, check out his snowfall tutorial, and the library of built-in Flint effects on slekx.com. The Flint library's code examples are the best place to start experimenting, but if you want to download my source it's here. Now, if I can think of a way to use it on a production application...