One of great advantages of the native 3D methods available in Flash Player 10 is the ability to literally 'build' 3D objects by placing their elements in the 3D space. Once an object is build, for example, a cube, we can use rotationY, rotationX, and rotationZ to rotate the object. The depth sorting, however, still has to be done "by hand", and in the presence of perspective projection can become tricky. Click on the screen shot above to open in a new window an applet that illustrates the basic issues involved.
- Download all files corresponding to the applets in this tutorial: zsort.zip
The files corresponding to the applet on this page are sort_test.fla and CubeSortTest.as.
The cubes that you see in this applet are five instances of the custom CubeSortTest class. Within the class, the cube is build in such a way that the registration point (0,0,0) falls in the center of the cube. Each side is a separate Sprite with its registration point at the center of the side.
The cube build in the class is rotated using rotationX, rotationY, rotationZ properties. How to sort the sides of the cube so they appear in the correct order? The standard method is to sort them by the z-coordinate of the center of each side. But which z-coordinate? The z-coordinate relative to the cube or the z-coordinate relative to the MainTimline ("root"). The later is accesible from within the class via:
relative_z = side.transform.getRelativeMatrix3D(root).position.z;
One of the radio buttons in the applet allows you to choose this sorting method. You will observe that it works well only if the center of the cube is close to the pespective projection center of "root " which is in the center of the Stage. For other cubes the method doesn't work very well and often displays sides incorrectly.
One should note that unless we change the z-coordinate of our cube - an instance of the CubeSortTest class, the z-coordinate of the center of each side relative to "root" and the z-coordinate relative to the cube are the same. So the radio buttons "z-coordinate relative to Stage" and "z-coordinate relative to cube" give exactly the same results.
The default option in the applet, the option that does work reliably for all cubes, is sorting with respect to the "Distance from the observer". For each side, we calculate the distance from the center of the side to the observer. The observer's 3D coordinates are as follows. Observer's x,y-coordinates are the same as the x,y-coordinates of root.transform.perspectiveProjection.projectionCenter, i.e., the same as coordinates of the projection center. The z-coordinate of the observer is equal to -root.transform.perspectiveProjection.focalLength. (In computer graphics it is the position of the observer that is actually called "projection center".) By sorting sides by their distance from the observer we account for their x,y-coordinates and the perspective projection settings. Below is a picture that illustrates this sorting method.
Within the class, we access the position of the observer as follows:
observerPos.x = root.transform.perspectiveProjection.projectionCenter.x;
observerPos.y = root.transform.perspectiveProjection.projectionCenter.y;
observerPos.z = - root.transform.perspectiveProjection.focalLength;
We use "getRelativeMatrix3D(root)" to calculate the coordinates of the center of each side relative to the MainTimline as well. Then we calculate the distance using the distance formula given on the picture above.
Z-sorting is greatly simplified if every instance of the CubeSortTest class has its own custom perspective projection. The visual results are often more pleasing in that case also, even though they might not be mathematically quite correct.
We show an example in which each cube has its own PerspectiveProjection object on the next page.