package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.TriangleCulling; import flash.geom.PerspectiveProjection; import flash.geom.Vector3D; import flash.geom.Matrix3D; import flash.events.Event; public class cube extends Sprite { // store which vertices make up which plane public var plane:Vector.> ; // store the initial vertices of the model public var v:Vector.; // store the updated vertices after changing the matrix e.g. rotation public var currentV:Vector.; // define the field of view, find the focalLength, etc public var proj:PerspectiveProjection; // matrix3D for rotations etc. public var m:Matrix3D; // defines how the triangles will be drawn public var indices:Vector.; // just a variable for the length of each side of the cube public var k:int; // Number of sides and number of planes the model has public var planeSides:int; public var numPlanes:int; // draw everything in this sprite public var container:Sprite; // bitmapData for texture public var bd:BitmapData; // the texture [Embed(source = '../lib/winword.jpg')] public var pic:Class; public function cube():void { // make the texture into a bitmapData bd = (new pic() as Bitmap).bitmapData; m = new Matrix3D(); // define the field of view proj = new PerspectiveProjection(); proj.fieldOfView = 50; // define how the triangles on each face will be drawn indices = new Vector.(); indices.push(0, 1, 3, 1, 2, 3); // length of each side = k*2 k = 100; // define the initial vertices of the model // a cube has 8 vertices v = new Vector.(); v.push(new Vector3D( -k, -k, -k)); v.push(new Vector3D( k, -k, -k)); v.push(new Vector3D( k, k, -k)); v.push(new Vector3D( -k, k, -k)); v.push(new Vector3D( -k, -k, k)); v.push(new Vector3D( k, -k, k)); v.push(new Vector3D( k, k, k)); v.push(new Vector3D( -k, k, k)); // define num of sides and num of planes planeSides = 4; numPlanes = 6; // define which vertices make up each face/plane of the model // a cube has 6 faces/planes, and each is made up of 4 vertices // the order of the vertices is very important for rendering and culling plane = new Vector.>(); plane.push(Vector.([0, 1, 2, 3])); // facing you plane.push(Vector.([4, 0, 3, 7])); plane.push(Vector.([5, 4, 7, 6])); // facing the back (note: the order of vertices is anticlockwise here) plane.push(Vector.([1, 5, 6, 2])); plane.push(Vector.([4, 5, 1, 0])); // top plane.push(Vector.([3, 2, 6, 7])); // bottom // everything will be drawn here container = new Sprite(); addChild(container); // render the cube and make it rotate addEventListener(Event.ENTER_FRAME, render); } public function render(e:Event):void { // store the coordinates after calculation and will be drawn on 2D surface i.e. the screen var renderV:Vector. = new Vector.(); // define the texture mapping values var uvtData:Vector. = new Vector.(); uvtData.push(0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0); // rotate the cube by changing the values in the matrix 3D m.appendRotation(3, Vector3D.YAXIS); m.appendRotation(3, Vector3D.XAXIS); // store the coordinates of vertices after applying the above matrix currentV = new Vector.(); for each(var vv:Vector3D in v) { // apply the matrix to the vertices in 'v' vv = m.transformVector(vv); // perspective factor = focalLen / (focalLen + z of vertex) // each x y z need to multiply the above factor to transformed it to the 2D coordinates vv.w = (proj.focalLength + vv.z) / proj.focalLength; vv.project(); // renderV store 2D coordinates used to draw the cube on the screen renderV.push(vv.x, vv.y); // the original vertices stored in 'v' will not be changed. So store it in 'currentV' currentV.push(vv); } // draw things out container.graphics.clear(); container.x = stage.stageWidth / 2; container.y = stage.stageHeight / 2; // loop through all the faces/planes and draw them out one by one for each(var p:Vector. in plane) { var planeV:Vector. = new Vector.(); for (var i:int = 0; i < planeSides; i++ ) { planeV.push(renderV[p[i]* 2], renderV[p[i] * 2 + 1]); uvtData[i * 3 + 2] = 1 / currentV[p[i]].w; } container.graphics.beginBitmapFill(bd); container.graphics.drawTriangles(planeV, indices, uvtData, TriangleCulling.NEGATIVE); } } } }