Flash Native 3D Z-Depth Sorting

I recently needed to do some auto z-depth sorting in AS3, and thought I'd share what I came up with.
After doing this of course, I've found there are a number of examples of this already out there such as:
Ralph Hauwert's solution on leebrimlow.com
And http://www.flashandmath.com/flashcs4/zsort/

But that's okay, doing something yourself is a great way to learn ;).

One thing that is common amongst all the solutions is:

DisplayObject.transform.relativeMatrix3D.transformVector

and transforming a point from local coordinate space to absolute perspective coordinate space and sorting the children based on that.

import flash.geom.Vector3D;
import flash.events.Event;
 
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
 
function enterFrameHandler(event:Event):void {
	wallCluster1.transform.matrix3D.prependRotation(1, Vector3D.Z_AXIS, new Vector3D(700, 600, 0));
	wallCluster2.transform.matrix3D.prependRotation(1, Vector3D.Z_AXIS, new Vector3D(700, 600, 0));
	sort(wallCluster1);
}
 
function sort(target:DisplayObjectContainer):void {
	_sort(target, this);
}
 
function _sort(target:DisplayObjectContainer, root:DisplayObjectContainer):void {
	var n:uint = target.numChildren;
	var relativeZValues:Dictionary = new Dictionary(true);
	for (var i:int = 0; i < n; i++) {
		var iChild:DisplayObject = target.getChildAt(i);
		var relativeMatrix3D:Matrix3D = iChild.transform.getRelativeMatrix3D(root);
		if (relativeMatrix3D == null) continue;
		var bounds:Rectangle = iChild.getBounds(iChild);
		var relativeZ:Number = relativeMatrix3D.transformVector(new Vector3D(bounds.width / 2, bounds.height / 2, 0)).z;
		relativeZValues[iChild] = relativeZ;
		var newDepth:uint = i;
		for (var j:int = i - 1; j >= 0; j--) {
			var jChild:DisplayObject = target.getChildAt(j);
			if (relativeZ > relativeZValues[jChild]) {
				newDepth = j;
			} else {
				break;
			}
		}
		if (newDepth != i) {
			target.addChildAt(iChild, newDepth);
		}
		if (iChild is DisplayObjectContainer) {
			_sort(iChild as DisplayObjectContainer, root);
		}
	}
 
}

This site requires the Flash player to display correctly. Go to http://www.adobe.com/go/getflash/ to download this plugin.

AttachmentSize
ZDepthSortExample.fla453.58 KB