package { import __AS3__.vec.Vector; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.display.TriangleCulling; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.geom.PerspectiveProjection; import flash.geom.Point; import flash.geom.Vector3D; import flash.geom.Matrix3D; import flash.text.TextField; import flash.text.TextFieldAutoSize; use namespace astro; /* author snolot at turbulent dot ca && b at turbulent dot ca */ [SWF(width=650, height=350, backgroundColor=0x000000, frameRate=0)] public class SimpleModelRender extends Sprite { private var output :Sprite = new Sprite(); private var projection :PerspectiveProjection = new PerspectiveProjection(); private var scene :Sprite = new Sprite(); private var primitive :Kidney = new Kidney(30); private var texture :BitmapData; private var debugtxt :TextField; private var lastmx :Number; private var lastmy :Number; private var mousedown :Boolean = false; private var auto :Boolean = false; [Embed(source = "images/grid2.jpg")] private var image:Class; public function SimpleModelRender() { setupOutput(); setup3D(); setupStage(); log('SimpleModelRender::Started',true); log('Use arrows UP and DOWN to change fieldOfView') } private function setup3D():void { projection.fieldOfView = 60; scene.transform.matrix3D = new Matrix3D(); texture = Bitmap(new image()).bitmapData; scene.addEventListener(Event.ENTER_FRAME, run); } private function setupOutput():void { output.x = stage.stageWidth / 2; output.y = stage.stageHeight / 2; addChild(output); } private function setupStage():void { stage.addEventListener(MouseEvent.MOUSE_DOWN, function(){mousedown=true}); stage.addEventListener(MouseEvent.MOUSE_UP, function(){mousedown=false}); stage.addEventListener(KeyboardEvent.KEY_UP,kHandler); stage.showDefaultContextMenu = false; stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; debugtxt = new TextField(); debugtxt.background = true; debugtxt.backgroundColor = 0x000000; debugtxt.textColor = 0xFFFFFF; debugtxt.autoSize = TextFieldAutoSize.LEFT; debugtxt.x = 0//stage.stageWidth - debugtxt.width; debugtxt.y = stage.stageHeight - debugtxt.height; addChild(debugtxt); } private function kHandler(e:KeyboardEvent):void { switch(e.keyCode) { case 38: projection.fieldOfView ++ break; case 40: projection.fieldOfView -- break; } log('Use arrows UP and DOWN to change fieldOfView', true); log('projection.fieldOfView : '+projection.fieldOfView ) } private function run(e:Event=null):void { var world:Matrix3D = scene.transform.matrix3D.clone(); world.append(projection.toMatrix3D()); var vertices :Vector. = new Vector.(); var indices :Vector. = new Vector.(); var i :int; var l :int; var temp :Vector. = new Vector.(); var plen :int = primitive.vertices.length; var ilen :int = primitive.indices.length; for (i = 0, l = plen; i < l; i++) { var vertex:Vector3D = primitive.vertices[i]; var vector:Vector3D = world.transformVector(vertex); vector.w = projection.focalLength / (projection.focalLength + vector.z); vector.project(); vertices.push(vector.x, vector.y); temp.push({z:vector.z, i:i}); } var triangles:Array = []; for (i = 0, l = ilen; i < l; i += 3) { var v1:Object = temp[primitive.indices[i ]]; var v2:Object = temp[primitive.indices[i + 1]]; var v3:Object = temp[primitive.indices[i + 2]]; triangles.push({ v1:v1, v2:v2, v3:v3, z:(v1.z + v2.z + v3.z) / 3 }); } triangles.sortOn("z", Array.NUMERIC); for each (var triangle:Object in triangles) indices.push(triangle.v1.i, triangle.v2.i, triangle.v3.i); output.graphics.clear(); output.graphics.beginBitmapFill(texture); output.graphics.drawTriangles(vertices, indices, primitive.uvs, TriangleCulling.NEGATIVE); if(auto) { scene.transform.matrix3D.prependRotation(2, Vector3D.XAXIS); scene.transform.matrix3D.prependRotation(3, Vector3D.YAXIS); } else { if(mousedown) { scene.rotationY -= (stage.mouseX - lastmx); scene.rotationX -= (stage.mouseY - lastmy); } lastmx = stage.mouseX; lastmy = stage.mouseY; } // scene.rotationX += 2; // scene.rotationY += 4; // scene.rotationZ += 3; } private function log(message:String, clearall:Boolean = false):void { if(clearall) debugtxt.text = message +'\n'; else debugtxt.text += message + '\n'; debugtxt.x = 0//stage.stageWidth - debugtxt.width; debugtxt.y = stage.stageHeight - debugtxt.height; } } }