package { import flash.display.Sprite; import flash.events.Event; import flash.display.StageScaleMode; import flash.display.StageAlign import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.TriangleCulling; import flash.geom.PerspectiveProjection; import flash.geom.Utils3D; import flash.geom.Vector3D; import flash.geom.Matrix3D; [SWF(backgroundColor="0x000000", width="800", height="600", frameRate="24")] public class Wave extends Sprite { [Embed(source="assets/koi.jpg")] public var Koi:Class; public var imgWidth:Number=800; public var imgHeight:Number=543; public var rows:Number = 5; public var cols:Number = 20; private var triWidth:Number; private var triHeight:Number; private var vertices:Vector.; private var indices:Vector.; private var uvtData:Vector.; private var perspective: PerspectiveProjection; private var projectionMatrix : Matrix3D; private var projectedVerts:Vector.; private var focalLength:Number = 50; private var texture:BitmapData; private var container:Sprite; private var xoffset:Number; private var yoffset:Number; private var wavelength:Number=200;//not implemented yet private var amplitude:Number = 20; private var numVertices:Number = (rows+1)*(cols+1); private var waveOffset:Number = 0; private var speed:Number = 0.05; public function Wave() { init(); } private function init():void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; container = new Sprite(); texture = new Koi().bitmapData; xoffset = imgWidth*.5; yoffset = imgHeight*.5; container.x = stage.stageWidth/2 ; container.y = stage.stageHeight/2 ; addChild(container); vertices = new Vector.(); indices = new Vector.(); uvtData = new Vector.(); //set up perspective perspective = new PerspectiveProjection(); perspective.fieldOfView = 50; //3D transformation matrix - used to rotate object projectionMatrix = perspective.toMatrix3D(); projectedVerts = new Vector.(); triWidth=imgWidth/cols; triHeight=imgHeight/rows; //initialize vertices as flat mesh (z=0) for(var row:int = 0; row <= rows; row++){//note : one more row of vertices than rows of triangles for(var col:int = 0; col <= cols; col++){//note : one more col of vertices than col of triangles vertices.push(triWidth*col - xoffset,triHeight*row - yoffset, 0); //add uvt uvtData.push(col/cols, row/rows, 1); } } //now define triangles for(row= 0; row < rows; row++){ for(col= 0; col < cols; col++){ var i:int = row*(cols+1) + col;// top row var i2:int = (row+1)*(cols+1) + col;//next row /* triangle arrangement i--------(i+1) | / | | / | | / | |/ | i2 ------(i2 +1) */ indices.push(i, i + 1, i2); indices.push(i2, i + 1, i2 + 1); } } addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(event:Event):void { //change z values according to sine wave function for(var v:int = 2; v < vertices.length; v+=3){ var x:Number = vertices[v-2] - (waveOffset+=speed); z = amplitude*Math.sin(x*Math.PI/180); vertices[v] = z; } container.x = stage.stageWidth/2 ; container.y = stage.stageHeight/2 ; projectionMatrix = perspective.toMatrix3D(); projectionMatrix.prependTranslation(0.0,0.0,30); Utils3D.projectVectors(projectionMatrix, vertices, projectedVerts, uvtData); container.graphics.clear(); container.graphics.beginBitmapFill(texture,null, false, false); //container.graphics.beginFill(0xFF00FF); //container.graphics.lineStyle(1,0xFF0000,1); container.graphics.drawTriangles(projectedVerts, indices, uvtData, TriangleCulling.NEGATIVE); container.graphics.endFill(); } } }