package { /* a z-sorting example using drawTriangles() more info here : http://actionsnippet.com/?p=2080 */ import flash.display.*; import flash.geom.*; import flash.events.*; [SWF(width = 500, height=500, backgroundColor = 0x000000)] public class Zsorting extends MovieClip { private var verts:Vector.<Number>; private var pVerts:Vector.<Number>; private var uvts:Vector.<Number>; private var indices:Vector.<int>; private var sortedIndices:Vector.<int>; private var faces:Array; private var m:Matrix3D; private var poly:Vector.<Number>; private var transPoly:Vector.<Number>; private var tex:BitmapData; private var persp:PerspectiveProjection; private var proj:Matrix3D; public function Zsorting(){ // init x = stage.stageWidth / 2; y = stage.stageHeight / 2; // standard Vectors for using drawTriangles verts = new Vector.<Number>(); pVerts; uvts; indices; // needed for z-sorting sortedIndices; faces = []; // we'll use this for tranforming points // and as the transormation matrix for our render m = new Matrix3D(); // plot a poly poly; poly = Vector.<Number>([ 0, 0, 0, 10, 0, 0, 0,10, 0]); verts = verts.concat(poly); faces.push(new Vector3D()); // add two polygons by transorming the poly Vector // and concatenating it to the verts Vector // Vector3D instances are added to the faces // Array for z-sorting // temp vect for any transformed polygons transPoly = new Vector.<Number>(); m.appendRotation(10, Vector3D.Z_AXIS); m.appendTranslation(0,-2,5); m.transformVectors(poly, transPoly); verts = verts.concat(transPoly); faces.push(new Vector3D()); m.appendRotation(10, Vector3D.Z_AXIS); m.appendTranslation(0,-2,5); m.transformVectors(poly, transPoly); verts = verts.concat(transPoly); faces.push(new Vector3D()); // hard coded indices indices = Vector.<int>([0, 1, 2, 3, 4, 5, 6, 7, 8]); sortedIndices = new Vector.<int>(indices.length, true); // create texture tex = new BitmapData(100,100,false, 0x000000); tex.fillRect(new Rectangle(0,0,50,50), 0xFF0000); tex.fillRect(new Rectangle(50,0,50,50), 0x0000FF); tex.fillRect(new Rectangle(0,50,50,50), 0x00FF00); // hard coded uvts uvts = Vector.<Number>([0,0,0, .5,0,0, 0,.5,0, .53, 0, 0, 1, 0, 0, .53, .5, 0, 0,.6,.5, 0,.6,0, 0,1, 0]); // fix all vector lengths verts.fixed = true, uvts.fixed = true, indices.fixed = true pVerts = new Vector.<Number>(verts.length/3 * 2, true); // we need these if we want perspective persp = new PerspectiveProjection(); // projection matrix proj = persp.toMatrix3D(); addEventListener(Event.ENTER_FRAME, onLoop); } // private methods private function onLoop(evt:Event):void { m.identity(); m.appendRotation(mouseY * 2, Vector3D.X_AXIS); m.appendRotation(mouseX * 2, Vector3D.Y_AXIS); // push everything back so its not to close m.appendTranslation(0,0,40); // append the projection matrix at the end m.append(proj); Utils3D.projectVectors(m, verts, pVerts, uvts); var face:Vector3D; var inc:int = 0; for (var i:int = 0; i<indices.length; i+=3){ face = faces[inc]; face.x = indices[i]; // it may look odd, but casting to an int // when doing operations inside array sytnax // adds a big speed boost face.y = indices[int(i + 1)]; face.z = indices[int(i + 2)]; var i3:int = i * 3; // get the average z position (t value) and store it in the Vector3D w property // depending on your model, you may not need to do an average of all 3 values face.w = (uvts[int(i3 + 2)] + uvts[int(i3 + 5)] + uvts[int(i3 + 8)]) * 0.333333; inc++; } // sort on w, so far this beats all other sorting methods for speed, // faster than Vector.sort(), faster than any custom sort method I could find faces.sortOn("w", Array.NUMERIC); // re-order indices so that faces are drawn in the correct order (back to front); inc = 0; for each (face in faces){ sortedIndices[inc++] = face.x; sortedIndices[inc++] = face.y; sortedIndices[inc++] = face.z; } graphics.clear(); graphics.beginBitmapFill(tex, null, false, false); graphics.drawTriangles(pVerts, sortedIndices, uvts, TriangleCulling.NONE); } } } Z-Sorting and drawTriangles()