package { import flash.display.Sprite; import flash.events.Event; import flash.display.BitmapData; import flash.geom.PerspectiveProjection; import flash.geom.Utils3D; import flash.geom.Vector3D; import flash.geom.Matrix3D; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.display.TriangleCulling; import com.bit101.components.*; [SWF(backgroundColor="0x000000", width="640", height="480", frameRate="30")] public class DrawCube2 extends Sprite { [Embed(source="assets/cube_map.jpg")] public var TextureBitmap: Class; private var texture : BitmapData; private var vertices : Vector.; private var projectedVerts : Vector.; private var indices : Vector.; private var uvts : Vector.; private var size : Number; private var perspective: PerspectiveProjection; private var projectionMatrix : Matrix3D; private var cube : Sprite; //private var rotAngle : Number = -115.0; private var rx:Number = 60; private var ry:Number = 40; private var rz:Number = 30; //controls private var rxSlider:HSlider; private var rySlider:HSlider; private var rzSlider:HSlider; private var corners:Vector.; public function DrawCube2() { size = 200; init(); } private function init():void { addControls(); // setup and initialize stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.quality = StageQuality.BEST; //texture is a bitmapData texture = new TextureBitmap().bitmapData; perspective = new PerspectiveProjection(); perspective.fieldOfView = 50; //3D transformation matrix - used to rotate object projectionMatrix = perspective.toMatrix3D(); var s:Number = size/2; //corners of cube - 8 /* vertices: ABCD = front , EFGH = back E --- F | / | | / | E --- A --- B --- F --- E | / | / | / | / | | / | / | / | / | H --- D --- C --- G --- H | / | | / | H --- G */ corners = Vector.([ new Vector3D(-s,-s,-s),// A [0] left top front new Vector3D(s,-s,-s), // B [1] right top front new Vector3D(s, s,-s), // C [2] right bottom front new Vector3D(-s, s,-s),// D [3] left bottom front new Vector3D(-s,-s, s),// E [4] left top back new Vector3D(s,-s, s),// F [5] right top back new Vector3D(s, s, s),// G [6] right bottom back new Vector3D(-s, s, s)// H [7] left bottom back ]); var faces:Array = [ {//TOP: AEFB vertices: [corners[0], corners[4], corners[5], corners[1]], uvts: [new Vector3D(0.25,0,1), new Vector3D(0.5,0,1), new Vector3D(0.5,1/3,1), new Vector3D(0.25,1/3,1)] }, {//LEFT: EADH vertices: [corners[4], corners[0], corners[3], corners[7]], uvts:[new Vector3D(0,1/3,1), new Vector3D(0.25,1/3,1), new Vector3D(0.25,2/3,1), new Vector3D(0,2/3,1)] }, {//FRONT: ABCD vertices: [corners[0], corners[1], corners[2], corners[3]], uvts:[new Vector3D(0.25,1/3,1), new Vector3D(0.5,1/3,1), new Vector3D(0.5,2/3,1), new Vector3D(0.25,2/3,1)] }, {//RIGHT: BFGC vertices: [corners[1], corners[5], corners[6], corners[2]], uvts:[new Vector3D(0.5,1/3,1), new Vector3D(0.75,1/3,1), new Vector3D(0.75,2/3,1), new Vector3D(0.5,2/3,1)] }, {//BACK: FEHG (reversed to keep winding positive) vertices: [corners[5], corners[4], corners[7], corners[6]], uvts:[new Vector3D(0.75,1/3,1), new Vector3D(1,1/3,1), new Vector3D(1,2/3,1), new Vector3D(0.75,2/3,1)] }, {//BOTTOM: DCGH vertices: [corners[3], corners[2], corners[6], corners[7]], uvts:[new Vector3D(0.25,2/3,1), new Vector3D(0.5,2/3,1), new Vector3D(0.5,1,1), new Vector3D(0.25,1,1)] }]; vertices = new Vector.(); indices = new Vector.(); uvts = new Vector.(); for(var i:int = 0; i < faces.length; i++){ var face:Object = faces[i]; //add face vertices for(var v:int = 0; v < face.vertices.length; v++){ vertices.push(face.vertices[v].x,face.vertices[v].y,face.vertices[v].z); } //add face indices var indx:Number = i*4;//index of top left point in rect indices.push(indx,indx + 1,indx + 3, indx + 1,indx + 2, indx + 3); //add uvt for(var u:int = 0; u < face.uvts.length; u++){ uvts.push(face.uvts[u].x,face.uvts[u].y,face.uvts[u].z);//actually u,v,t ;) } } projectedVerts = new Vector.(); //really just a container cube = new Sprite(); cube.x = stage.stageWidth/2; cube.y = stage.stageHeight/2; //cube.z = 200; addChild(cube); //each frame... addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(event:Event):void { cube.x = stage.stageWidth/2; cube.y = stage.stageHeight/2; //rotate projectionMatrix = perspective.toMatrix3D(); // controls the viewpoint: projectionMatrix.prependTranslation(0.0,0.0,30); projectionMatrix.prependRotation(rx,new Vector3D(1,0,0)/*Vector3D.X_AXIS*/); projectionMatrix.prependRotation(ry,new Vector3D(0,1,0)/*Vector3D.Y_AXIS*/); projectionMatrix.prependRotation(rz,new Vector3D(0,0,1)/*Vector3D.Z_AXIS*/); //get project vectors (3D projected as x,y positions in perspective) Utils3D.projectVectors(projectionMatrix, vertices, projectedVerts, uvts); //triangle indices cube.graphics.clear(); cube.graphics.beginBitmapFill(texture,null, false, false); /*cube.graphics.beginFill(0xFF00FF); cube.graphics.lineStyle(1,0xFF0000,1);*/ cube.graphics.drawTriangles(projectedVerts, indices, uvts, TriangleCulling.NEGATIVE); cube.graphics.endFill(); } private function addControls():void { //add controls for x,y,z rotation rxSlider = new HSlider(this, 500, 20, function(event:Event):void { rx = event.target.value; }); rxSlider.setSliderParams(0, 360, rx); addChild(rxSlider); //y rotation slider rySlider = new HSlider(this, 500, 40, function(event:Event):void { ry = event.target.value; }); rySlider.setSliderParams(0, 360, ry); addChild(rySlider); //z rotation slider rzSlider = new HSlider(this, 500, 60, function(event:Event):void { rz = event.target.value; }); rzSlider.setSliderParams(0,360, rz); addChild(rzSlider); } } }