Building a 3D Flash Engine in 19 Lines of Code

Intro

In this example, you’re going to build a 3D engine based on perspective scaling in 19 lines of code. Before Flash 10 there was no native support for 3D and all you had were x and y coordinates to play around with. So you needed to add another dimension to get 3D – a z-axis. So the trick to creating a z-axis was to use perspective scaling. Which means that as an object moves away from you it gets small and as it moves towards you it get larger. But we need to quantify this idea (make some math out of it) so we can program it. And that comes from Thales Theorem.

Thales Theorem

Imagine that you are in your home looking out the window. As you approach the window objects outside look larger and as you get farther away from the window objects outside look smaller. Your distance from the window is called your focal length (fl), the window is your projection plane (or viewport), and your eye is the vanishing point.

Now don’t move – this fixes your focal length – and watch outside as objects move closer to and farther away from your window. As a bird flies closer to the window it looks larger and as it flies away it looks smaller. This is your z-axis – the distance between the outside object and your window pane. And the equation that governs the behavior that you see is given below;

sizeRatio = size/SIZE = fl/(fl + z)

where your sizeRatio equals “one” when your outside object is at the window and “zero” when your object (bird) flies far away (off to infinity). This equation works and is illustrated in the graphic below as a Blender monkey peering at a projection plane.

Application of Thales Theorem

Application of Thales Theorem

Z-Sorting

When dealing with multiple objects that overlap, perspective scaling alone is not enough. In the Flash Player you need to z-sort. This is even an issue with Gumbo (Flex 4). When creating a 3D carousel for example you need to z-sort the objects as they spin to put the closest one on top of the stack. The technical name is transposition and in AS2 it was easily accomplished using the swapDepths method. But in AS3 it is a little more complicated.

In AS3, the display list functions as an array and each display object has an index. The index start at zero and goes up to the number of objects on your stage where index zero is the bottom object. So since the display object is a child you can change its position using the setChildIndex method.

Since all your objects are in an array, you can sort that array by z and then set the indices of your array objects based on z. And that’s how it is presently done! Here’s a sort code snippet that illustrates the concept

private function sortmyZ():void
{

myObjects.sortOn(“myZvalue”, Array.DESCENDING|Array.NUMERIC)
for(var i:uint =0; i<numObjects; i++)

{

var myObject:MYObject3D = myObjects[i];
setChildIndex(myObject, i);

}

}

The code snippet sorts the objects in reverse numerical order from high to low based on the myZvalue of your objects. Thus, the objects further away from your projection plane get a lower index value placing them on the bottom of the stack.

This method will need to be called each time your 3D engine iterates the position of your objects. Typically this occurs on an onEnterFrame event.

With that said, you’re now ready to build your3D engine.

3D Flash Engine in 19 Lines of Code

Here is the Demo, Download, Youtube, and Discussion.

Demo

http://www.professionalpapervision.com/demos/web/flash19engine/

Download

http://flex3cookbook2.googlecode.com/files/engine3D19lines.zip

Youtube: How it was made


Discussion

Here are the steps for creating the program:

1. Start by importing the Sprite class; this is where you are going to draw a ball that you will animate in 3D.

import flash.display.Sprite;//imports sprite class

2. Next declare your variables zposition, Angle, and focal length.

var zposition:Number = 0;//z postion
var myAngle:Number =0;//Angle of myBall
var fl:Number = 250; //focal length

3. Next create your ball and add it to the stage.

var myBall:Sprite = new Sprite();//instantiates myBall sprite
myBall.graphics.beginFill(0xFF0000);//Assigns a ball color
myBall.graphics.drawCircle(0, 0, 40);//draws your ball at (0,0)
myBall.graphics.endFill();//ends the fill
addChild(myBall);//adds the ball to the stage

4. Next create your onEnterFrame listener which loops through your equations of motion. This is the heart of all 3D engines.

addEventListener(Event.ENTER_FRAME, onEnterFrame);//loops equations

5. Finally, create the function that will be looped. These are your equations of motion which govern the perspective as it is changed and converts 3D to 2D (or projects onto the viewport).

function onEnterFrame(event:Event):void{
var scale:Number = fl / (fl + zposition);//scale perspective
myAngle=myAngle+.1;//iterates angle
if(Math.abs(myAngle)>=20) myAngle=-myAngle;//change sign
myBall.x = 300*Math.sin(myAngle)*scale+300; //ball orbit x
myBall.y = 300*Math.cos(myAngle)*scale; //ball orbit y
myBall.scaleX = scale;//scales perspective in x
myBall.scaleY = scale;//scales perspective in y
zposition = myAngle*100;} //increments z

Though this is not Papervision it illustrates a number of elements that every 3D engine possesses;

  • a frame looper/renderer
  • perspective (z-coordinate)
  • projection onto a viewport
  • primitive or basic shape
  • addition of a color (or material)

And all of this in just 19 line of code. If only it would have stayed this simple. Papervision started off with only 20 classes, now it is in the hundreds and growing. But as they say, no pain no gain.

Click more below to see the paste-able code. Just cut and past the code below into flash and watch the magic of perspective occur.

3D Engine Code

import flash.display.Sprite;//imports sprite class
var zposition:Number = 0;//z postion
var myAngle:Number =0;//Angle of myBall
var fl:Number = 250; //focal length
var myBall:Sprite = new Sprite();//instantiates myBall sprite
myBall.graphics.beginFill(0xFF0000);//Assign a ball color
myBall.graphics.drawCircle(0, 0, 40);//draws your ball at 0,0
myBall.graphics.endFill();//ends the fill
addChild(myBall);//adds the ball to the stage
addEventListener(Event.ENTER_FRAME, onEnterFrame);//loops equations
function onEnterFrame(event:Event):void{
var scale:Number = fl / (fl + zposition);//scale perspective
myAngle=myAngle+.1;//iterates angle
if(Math.abs(myAngle)>=20) myAngle=-myAngle;//change sign
myBall.x = 300*Math.sin(myAngle)*scale+400; //ball orbit x
myBall.y = 300*Math.cos(myAngle)*scale+200; //ball orbit y
myBall.scaleX = scale;//scales perspective in x
myBall.scaleY = scale;//scales perspective in y
zposition = myAngle*100;} //increments z

About these ads

7 Responses to Building a 3D Flash Engine in 19 Lines of Code

  1. man this is great! thanks!

  2. [...] > Building a 3D Flash Engine in 19 Lines of Code | Professional Papervision3D Book [...]

  3. lance pollard says:

    Hey!

    Any ideas on how to use the Matrix3D/Vector3D classes to rotate/scale/tween display objects around any axis/registration point?? There is nothing out there on this stuff, thank you for all your tutorials.

    Best,
    Lance

  4. lance pollard says:

    cs4

    • Mike Lively says:

      A great place to go right now is Adobe Docs (and just start experimenting – that’s what most people do – the good ones).

      I’ve put up some posts which use Matrix3D and Vector3D and will continue…so keep checking.

      Also, checkout – Keith Peter’s book on Advanced Animation, Flash&Math, Senocular, and my Links page which is tracking CS4 3D work.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: