By Rodney Smith
Rodney Smith
7 December 2009


Prerequisite knowledge
You should have a basic understanding of the Adobe Flash authoring interface, working with symbols, and mouse interaction. An awareness of 3D is useful too; you should be familiar with the topics discussed in Mariko Ogawa's article, Exploring the new 3D features in Flash. Links to more information about 3D in Flash are included at the end of this tutorial.
User level
Required products
Flash Player 10
Adobe Animate CC
The three-dimensional capabilities of Adobe Flash CS4 Professional allow changes in the zoom and view perspective, and its handling of 3D math makes it easier to navigate in and around a 3D scene. Game developers and animators can now incorporate 3D view and movement more easily than before.
This tutorial explores two different ways to change what is shown on the Stage
  • Changing the viewpoint through pan and zoom
  • Moving the objects themselves within the 3D space
Moving the viewpoint is simple and acts like a camera zoom lens. Moving objects on the Stage using the object's x, y, and, z attributes is not much more difficult and offers full movement on each axis—it's like holding an object in your hands with the ability to move it in and out, up and down, and also allows rotations of the scene itself.
The code in this tutorial demonstrates both methods, including how to perform multiple transformations using the Matrix3D class. The sample files contain navigational UI controls for changing the view using both approaches, as shown in Figure 1.

Constructing a 3D scene

Flash display objects such as Sprites are flat, even when put in a 3D world. As you can with photographs, you can position them any way you want. But to create a three-dimensional structure with depth, you'll need multiple display objects.
In the scene I create in this article, each wall or floor is created in its own Sprite, then rotated into the correct position. As shown in Figure 2, the wall (pink rectangle), which is originally flat, is "lifted" into position by increasing the rotationYproperty to 90 degrees. Note that its upper left registration point (0,0) marked in Figure 2 remains the same relative to the other rectangle, the brown floor. It is easiest to position using the registration point and then rotate into the correct 3D orientation. I find that it is also easiest to construct the scene looking down from the top of the model so that x and y are xand y, and z is for height, as I did in this tutorial. Figure 2 is tilted with a 3D perspective so that the wall height can be seen.
Figure 2. Vertical wall's rotationY property changed from 0 to 90 degrees
Figure 2. Vertical wall's rotationY property changed from 0 to 90 degrees
For vertical surfaces like walls, the rotation is like picking up one side of a flat board to make it a vertical wall. Once the wall is positioned, Flash Player handles all of the calculations and redraws for you when you move the viewpoint.

Constructing the 3D object

The sample Flash project contained in the sample file constructs a 3D object in the sample file, creating a new Sprite for each wall, floor, and ceiling. The ModelSprite class contains constants for the size and positions of the walls and ceiling, making them changeable in one spot. The ceiling is a 2D object just like the floor, except its z position is decreased to be closer to the user so that it is "above" the floor. Walls are drawn as flat rectangles, then rotated along the x or y axis to stand them up into position (see Figure 2).

UI controls

The file 3DViewControl.fla contains a Stage with radio buttons for the two types of navigation, a button to reset the position, and labels for the Slider that gets constructed in ActionScript. Most construction happens in the file when the user clicks either of the two option buttons, which invoke the viewpointHandler() or moveObjectsHandler() functions to set up the two different approaches to changing the view of a 3D scene. With the scene now set up, I describe how each works in the next section.

Navigating in 3D

Your view of a 3D scene is controlled by two variables: projectionCenter, which defines the x and y coordinates of the viewer; and fieldOfView, which defines how wide a view of the scene the viewer sees. Decreasing the fieldOfView value is like zooming in with a camera lens. Both variables are part of the root.transform.perspectiveProjection class.

Moving the camera (viewpoint or projection center)

Changing the view can be done by changing the projectionCenter variables, which is like moving the camera up/down and left/right. In the sample code, the viewpoint is moved in the function doDragProjectionCenter with this line of code:
root.transform.perspectiveProjection.projectionCenter = new
which sets the projection point to the current mouse position.
You can zoom by pressing Shift and moving the mouse up and down, or you can use the Slider on the left side of the Stage. Zooming in is done by setting a smaller fieldOfView value, making the objects appear larger.

Z ordering problem

The sample code has a problem with z-ordering when moving around the scene because re-sorting based on the new zorder is not being done. When viewed from the left, the pink wall should be shown in front of the other walls (which it is), but when moving the viewpoint to the right, the tan wall should be in front (which it isn't). The z order hasn't changed, which means the pink wall is being drawn on top of the tan wall. This problem is solvable by sorting the display list using the z-ordering base on the new viewpoint. The getRelativeMatrix3D method of the Transform class is used to perform this reordering. An explanation and solution to the z order re-sort, titled Using Matrix3D objects for reordering display, is part of the Programming ActionScript 3 for Flash documentation (also linked to at the end of this tutorial, among others).
I added a Timer to continue moving the projection point when the mouse is dragged outside the Stage so you could see a wider range of viewpoint values.

Moving objects on the Stage

The second approach to changing the view is by moving all the objects in the scene and keeping the viewpoint and field of view the same. At first I thought this would involve more calculations but it is as simple as "change the positions of all the objects on the Stage." Flash handles the 3D view calculations—the code moves objects in the x, y, and z planes by setting the x, y, and z values.
Start by clicking the Move Objects option button. Two buttons appear: Pan and Orbit. Select Pan, and you can drag the object left and right, up, and down. A more efficient way of setting more than one variable is by using the Matrix3D class because it performs one calculation with the new values instead of performing the calculations after each value is set. In the code, the moveObjects() function uses Matrix3D.appendTranslation() to set the x and y positions at the same time:
tray.transform.matrix3D.appendTranslation(offsetX, offsetY, 0);
Zoom moves the object closer to the viewer by decreasing the z position. In the code, this is tray.z += offsetY, where a negative offsetY causes the view to zoom in.
I took it further by implementing "Orbit," which is possible only by changing values of the objects themselves. Orbit is an interesting 3D movement, in which the object is rotated in both the y and x axes, enabling you to spin it around and see the sides and back of the object. Simple orbit movement is accomplished by changing the rotationX and rotationY properties, or by using the Matrix3D class to perform the rotations, as in this code:
//Perform both rotations together
tray.transform.matrix3D.prependRotation(-offsetX / 2, Vector3D.Y_AXIS);
tray.transform.matrix3D.prependRotation( offsetY / 2, Vector3D.X_AXIS);
However, because 3D rotations are not commutative—meaning that the order of operation is important and the code performs both y and x rotations multiple times—the image will tilt. To see this, click Orbit, uncheck the No Tilt box, and move the mouse in a circle. Just as if I had done the same operations with a Rubik's Cube in front of me, I get a tilted image (see Figure 3).
Figure 3. Residual z rotation after multiple x and y rotations
While this is natural, it isn't what I want in an orbit feature, so I added the No Tilt check box, which uses the following code in the function orbitObjects() to avoid the tilt, or z rotation. The code undoes the previous x rotation, then applies the new y rotation and then the new x rotation. This keeps the z rotation zero during all rotations:
//"Undo" the X rotation from previous rotation
tray.transform.matrix3D.prependRotation(-currentXrotation, Vector3D.X_AXIS);

//Apply the new Y rotation
tray.transform.matrix3D.prependRotation(-offsetX / 2, Vector3D.Y_AXIS);

//Add the new X rotation to previous X rotation and "re"apply it currentXrotation += offsetY/2;
tray.transform.matrix3D.prependRotation(currentXrotation, Vector3D.X_AXIS);
Try moving the mouse in a circle with the No Tilt option selected, and then with the No Tilt option unselected. With it off, a tilt to the object on the z axis appears, even when trying to rotate the object back to its original position. The division by two helps slow the rotation.
The function resetPosition restores the object's x, y, and z original values and sets all rotations to zero.

Where to go from here

Moving objects on the Stage as a way to change a view of a 3D scene is not much more complex than moving the viewpoint. The ability to view a 3D scene and change your view of it opens the door to exploring visual data in useful ways.
For another tutorial about 3D in Flash and ActionScript 3, read my companion article, 3D moving stars in Flash using ActionScript 3.
Below is some additional information from various documentation sources about 3D and Flash:
  • Using Matrix3D objects for reordering display (Programming ActionScript 3 for Flash)
  • Creating and editing artwork: 3D graphics (Using Flash CS4 Professional)
  • Working in three dimensions (Programming ActionScript 3 for Flash)
  • Matrix3D (Flash CS4 Professional ActionScript 3 Language Reference)
  • PerspectiveProjection (Flash CS4 Professional ActionScript 3 Language Reference)