Procedural manipulation of Flash CS4 IK

ikbones

I finally started playing around with the new features of Flash CS4.
One thing I have been really curious to try out was the application of an inverse kinematic armature to a raw shape. The discovery that you can’t generate and apply joints and bones procedurally (you have to construct your armature using the Flash tool) was sort of a semi-anticipated disappointment, but hey, I guess you can’t have everything.

The good news is that you still can manipulate a hand-built, existing armature and its components using code, as the following quick example demonstrates.

Drag around the circular handle to deform the shape:

Please feel free to try out the following code yourself. All you need is a simple setup consisting of a shape with a few bones attached to it. The code will recursively walk through the hierarchy of bones/joints, find the last one, and attach the drag-handle and an IKMover object to it.

// Flash CS4 IKTest (C) edvardtoth.com
 
package  
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import fl.ik.*;
 
	// Important: make sure your "type" armature-property is set to "runtime" instead of "authortime"
 
	public class IKTest extends Sprite
	{
		private var armature:IKArmature; 
 
		private var currentJoint:IKJoint;
		private var currentJointPosition:Point;
 
		private var newPosition:Point;
 
		private var handle:Sprite;
		private var mover:IKMover;
 
		public function IKTest() 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.quality = StageQuality.HIGH;
			stage.align = StageAlign.TOP_LEFT;
			stage.showDefaultContextMenu = false;
 
			setupHandle();
 
			addEventListener (Event.FRAME_CONSTRUCTED, startUp);
		}
 
		private function startUp (event:Event):void
		{
			removeEventListener (Event.FRAME_CONSTRUCTED, startUp);
 
			this.scrollRect = this.getRect(this);
 
			// finds the first IK armature in the hierarchy, and its root joint as the starting point
			armature = IKManager.getArmatureAt(0);
			currentJoint = armature.rootJoint;
 
			findEndJoint();
		}
 
		// recursively iterates through the bones and joints to find the last one
		private function findEndJoint():void
		{
			if (currentJoint.numChildren != 0)
			{			
				currentJoint = currentJoint.getChildAt(0);
				findEndJoint();
			}
			else
			{
				// if the last joint is found, an IKMover and the drag-handle are attached to it
				currentJointPosition = currentJoint.position;
 
				mover = new IKMover (currentJoint, currentJointPosition);
 
				addChild (handle);
				handle.x = currentJointPosition.x;
				handle.y = currentJointPosition.y;
 
				addEventListener (Event.ENTER_FRAME, updateFrame);
			}
		}
 
		// matches the position of the last joint to the position of the handle
		private function updateFrame (event:Event):void
		{
			newPosition = new Point (handle.x, handle.y);
 
			mover.moveTo (newPosition);
		}
 
 
		// creates the circular handle sprite
		private function setupHandle():void
		{
			handle = new Sprite();
 
			handle.graphics.lineStyle (4, 0x000000, 1.0, false, LineScaleMode.NORMAL);
			handle.graphics.beginFill (0x000000, 0.0);
			handle.graphics.drawCircle (0, 0, 20);
			handle.graphics.endFill();			
 
			handle.addEventListener (MouseEvent.MOUSE_DOWN, onDown);
			handle.addEventListener (MouseEvent.MOUSE_UP, onUp);
		}
 
 
		private function onDown (event:MouseEvent):void
		{
			event.currentTarget.startDrag();
		}
		private function onUp (event:MouseEvent):void
		{
			event.currentTarget.stopDrag();
		}
 
 
	}
 
}

There are no comments yet. Be the first and leave a response!

Leave a Reply

Headway Themes — The Drag & Drop WordPress Theme