/* * 3DのテクスチャーとしてBitmapをなんとかきれいに貼り付けられるようになった頃、 * さてこの方法ではどれくらいのスピードが出るのだろうか? * と疑問に思ってテストとして作ったもの(wonderflでも動くように、 * 細々と書き換えたけど)。 * * 30fps640*480のflvを読み込み、再生しっぱなしにして、 * それを4つの面のBitmapDataに対してdrawしている。 * 結果、とりあえず目的に対しては十分に高速であることがわかった。 * * */ package { import flash.display.Sprite; import net.hires.debug.Stats; import flash.events.Event; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.net.NetConnection; import flash.net.NetStream; import flash.media.Video; import flash.display.BitmapData; import flash.system.Security; [SWF(backgroundColor="0x000000")] /** * ... * @author umhr */ public class Main extends Sprite { private var Math3d:Math3dClass = new Math3dClass(); private var Poz:PozClass = new PozClass(); private var sp_array:Array = new Array(); private var Render:RenderClass = new RenderClass(); private var stgeW:int = stage.stageWidth / 2; private var stgeH:int = stage.stageHeight / 2; private var baseURL:String = ""; function Main() { if(isMztmjp()){ }else{ baseURL = "http://mztm.heteml.jp/umhr/mztmjpwp/"; Security.loadPolicyFile("http://mztm.heteml.jp/crossdomain.xml"); } Math3d.focalLength = 1000; var Texture:TextureClass = new TextureClass(); addChild(new Stats()); stage.scaleMode = "noScale"; setModel(); var connection:NetConnection = new NetConnection(); connection.connect(null); var netStream:NetStream = new NetStream(connection); netStream.addEventListener (NetStatusEvent.NET_STATUS ,NET_STATUS); function NET_STATUS (event : NetStatusEvent):void { switch(event.info.code){ case "NetStream.Play.Stop": netStream.seek(0); break; } } netStream.client = new Object(); netStream.play(baseURL+"umhr_pcloud14.flv"); var video_obj : Video = new Video(640,480); video_obj.attachNetStream(netStream); stage.addEventListener(Event.ENTER_FRAME,ENTER_FRAME); function ENTER_FRAME(e:Event):void { Poz.global_array[3] += (stage.mouseY-stgeH)/20000; Poz.global_array[4] += (stage.mouseX-stgeW)/20000; var poz_array:Array = new Array(); poz_array = Math3d.arrayClone(Poz.model_array); Math3d.localAffine(poz_array,Poz.local_array); Math3d.globalAffine(poz_array,Poz.global_array); Math3d.perspective(poz_array); Poz.zSort(poz_array,sp_array,stage); render(poz_array); } function render(poz_array:Array):void{ var _length:int = poz_array.length; var bmp_data : BitmapData = new BitmapData(640 , 480 , false , 0x111111); bmp_data.draw(video_obj); for (var i:int = 0; i<_length; i++) { var _sp:Sprite = sp_array[i]; _sp.graphics.clear(); Render.drawQuadrangleImage22(_sp,poz_array[i],bmp_data); } } stage.addEventListener(MouseEvent.CLICK,onClick); } private function isMztmjp():Boolean{ var _str:String = stage.loaderInfo.url; return (_str.substr(0,5) == "file:" || _str.indexOf("mztm.jp") > -1); } private function onClick(e:MouseEvent):void { Render.isDrawQuadrangleImage22Line = !Render.isDrawQuadrangleImage22Line; } private function setModel():void{ Poz.local_array[0] = [0,0,240,Math.PI,0,0]; Poz.local_array[1] = [0,0,-240,0,0,0]; Poz.local_array[2] = [0,240,0,-Math.PI/2,0,0]; Poz.local_array[3] = [0,-240,0,Math.PI/2,0,0]; var _length:int = Poz.local_array.length; for (var i:int = 0; i<_length; i++) { Poz.model_array[i] = [[0,0,0],[-320,-240,0],[0,-240,0],[320,-240,0],[-320,0,0],[0,0,0],[320,0,0],[-320,240,0],[0,240,0],[320,240,0]]; Poz.localTo_array[i] = Math3d.arrayClone(Poz.local_array[i]); sp_array[i] = new Sprite(); sp_array[i].x = stgeW; sp_array[i].y = stgeH; stage.addChild(sp_array[i]); } } } } //////////////// class RenderClass{ import flash.display.Sprite; import flash.geom.Matrix; import flash.display.BitmapData; import flash.media.Video; //クラスプロパティ //クラスメソッド //コンストラクタ public var isDrawQuadrangleImage22Line:Boolean; public function RenderClass(){ //trace("RenderClass imported"); } //インスタンスプロパティ //public var defaultColor:int = 0xff0000; public function drowLine(_sp:Sprite,poz_array:Array,_thickness:Number = 0,_color:int = 0xFF0000,_alpha:Number = 1):void{ //if(_color == -1){_color = defaultColor}; _sp.graphics.lineStyle(_thickness,_color,_alpha) _sp.graphics.beginFill (1,0xFF3333); var _l:int = poz_array.length; _sp.graphics.moveTo(poz_array[_l-1][0],poz_array[_l-1][1]); for (var j:int = 0; j<_l; j++) { _sp.graphics.lineTo(poz_array[j][0],poz_array[j][1]); } _sp.graphics.lineStyle() } public function drawQuadrangleImage(_sp:Sprite,poz_array:Array,bmp_data:BitmapData):void{ var bmp_dataW:Number = bmp_data.width; var bmp_dataH:Number = bmp_data.height; var _matrix:Matrix = setMatrix(poz_array[0],poz_array[1],poz_array[2],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[0][0],poz_array[0][1]); _sp.graphics.lineTo(poz_array[1][0],poz_array[1][1]); _sp.graphics.lineTo(poz_array[2][0],poz_array[2][1]); _sp.graphics.endFill(); var _ltX:Number = poz_array[2][0] - poz_array[3][0] + poz_array[1][0]; var _ltY:Number = poz_array[2][1] - poz_array[3][1] + poz_array[1][1]; _matrix = setMatrix([_ltX,_ltY],poz_array[1],poz_array[2],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[1][0],poz_array[1][1]); _sp.graphics.lineTo(poz_array[2][0],poz_array[2][1]); _sp.graphics.lineTo(poz_array[3][0],poz_array[3][1]); _sp.graphics.endFill(); } public function drawQuadrangleImage22(_sp:Sprite,poz_array:Array,bmp_data:BitmapData):void{ var bmp_dataW:Number = bmp_data.width/2; var bmp_dataH:Number = bmp_data.height/2; var _matrix:Matrix = setMatrix(poz_array[1],poz_array[2],poz_array[4],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); if(isDrawQuadrangleImage22Line){ _sp.graphics.lineStyle(1) } _sp.graphics.moveTo(poz_array[1][0],poz_array[1][1]); _sp.graphics.lineTo(poz_array[2][0],poz_array[2][1]); _sp.graphics.lineTo(poz_array[4][0],poz_array[4][1]); _sp.graphics.endFill(); var _ltX:Number = poz_array[4][0] - poz_array[5][0] + poz_array[2][0]; var _ltY:Number = poz_array[4][1] - poz_array[5][1] + poz_array[2][1]; _matrix = setMatrix([_ltX,_ltY],poz_array[2],poz_array[4],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[2][0],poz_array[2][1]); _sp.graphics.lineTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.lineTo(poz_array[4][0],poz_array[4][1]); _sp.graphics.endFill(); _matrix = setMatrix1(poz_array[2],poz_array[3],poz_array[5],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[2][0],poz_array[2][1]); _sp.graphics.lineTo(poz_array[3][0],poz_array[3][1]); _sp.graphics.lineTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.endFill(); _ltX = poz_array[5][0] - poz_array[6][0] + poz_array[3][0]; _ltY = poz_array[5][1] - poz_array[6][1] + poz_array[3][1]; _matrix = setMatrix1([_ltX,_ltY],poz_array[3],poz_array[5],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[3][0],poz_array[3][1]); _sp.graphics.lineTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.lineTo(poz_array[6][0],poz_array[6][1]); _sp.graphics.endFill(); _matrix = setMatrix2(poz_array[4],poz_array[5],poz_array[7],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[4][0],poz_array[4][1]); _sp.graphics.lineTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.lineTo(poz_array[7][0],poz_array[7][1]); _sp.graphics.endFill(); _ltX = poz_array[7][0] - poz_array[8][0] + poz_array[5][0]; _ltY = poz_array[7][1] - poz_array[8][1] + poz_array[5][1]; _matrix = setMatrix2([_ltX,_ltY],poz_array[5],poz_array[7],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.lineTo(poz_array[7][0],poz_array[7][1]); _sp.graphics.lineTo(poz_array[8][0],poz_array[8][1]); _sp.graphics.endFill(); _matrix = setMatrix3(poz_array[5],poz_array[6],poz_array[8],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[5][0],poz_array[5][1]); _sp.graphics.lineTo(poz_array[6][0],poz_array[6][1]); _sp.graphics.lineTo(poz_array[8][0],poz_array[8][1]); _sp.graphics.endFill(); _ltX = poz_array[8][0] - poz_array[9][0] + poz_array[6][0]; _ltY = poz_array[8][1] - poz_array[9][1] + poz_array[6][1]; _matrix = setMatrix3([_ltX,_ltY],poz_array[6],poz_array[8],bmp_dataW,bmp_dataH); _sp.graphics.beginBitmapFill(bmp_data, _matrix, false, false); _sp.graphics.moveTo(poz_array[6][0],poz_array[6][1]); _sp.graphics.lineTo(poz_array[8][0],poz_array[8][1]); _sp.graphics.lineTo(poz_array[9][0],poz_array[9][1]); _sp.graphics.endFill(); } private function setMatrix(poz0_array:Array,poz1_array:Array,poz2_array:Array,_w:Number,_h:Number):Matrix{ var _matrix:Matrix = new Matrix(); _matrix.a = (poz1_array[0]-poz0_array[0])/_w; _matrix.b = (poz1_array[1]-poz0_array[1])/_w; _matrix.c = (poz2_array[0]-poz0_array[0])/_h; _matrix.d = (poz2_array[1]-poz0_array[1])/_h; _matrix.tx = poz0_array[0]; _matrix.ty = poz0_array[1]; return _matrix; } private function setMatrix1(poz0_array:Array,poz1_array:Array,poz2_array:Array,_w:Number,_h:Number):Matrix{ var _matrix:Matrix = new Matrix(); _matrix.a = (poz1_array[0]-poz0_array[0])/_w; _matrix.b = (poz1_array[1]-poz0_array[1])/_w; _matrix.c = (poz2_array[0]-poz0_array[0])/_h; _matrix.d = (poz2_array[1]-poz0_array[1])/_h; _matrix.tx = poz0_array[0]-(poz1_array[0]-poz0_array[0]); _matrix.ty = poz0_array[1]-(poz1_array[1]-poz0_array[1]); return _matrix; } private function setMatrix2(poz0_array:Array,poz1_array:Array,poz2_array:Array,_w:Number,_h:Number):Matrix{ var _matrix:Matrix = new Matrix(); _matrix.a = (poz1_array[0]-poz0_array[0])/_w; _matrix.b = (poz1_array[1]-poz0_array[1])/_w; _matrix.c = (poz2_array[0]-poz0_array[0])/_h; _matrix.d = (poz2_array[1]-poz0_array[1])/_h; _matrix.tx = poz0_array[0]-(poz2_array[0]-poz0_array[0]); _matrix.ty = poz0_array[1]-(poz2_array[1]-poz0_array[1]); return _matrix; } private function setMatrix3(poz0_array:Array,poz1_array:Array,poz2_array:Array,_w:Number,_h:Number):Matrix{ var _matrix:Matrix = new Matrix(); _matrix.a = (poz1_array[0]-poz0_array[0])/_w; _matrix.b = (poz1_array[1]-poz0_array[1])/_w; _matrix.c = (poz2_array[0]-poz0_array[0])/_h; _matrix.d = (poz2_array[1]-poz0_array[1])/_h; _matrix.tx = poz0_array[0]-(poz2_array[0]-poz0_array[0])-(poz1_array[0]-poz0_array[0]); _matrix.ty = poz0_array[1]-(poz2_array[1]-poz0_array[1])-(poz1_array[1]-poz0_array[1]); return _matrix; } //インスタンスメソッド } //////////////// class PozClass{ //クラスプロパティ //クラスメソッド //コンストラクタ public function PozClass(){ //trace("Math3d imported"); } //インスタンスプロパティ //globalの座標[x,y,z,xr,yr,zr]; public var global_array:Array = new Array(0,0,0,0,0,0); public var globalTo_array:Array = new Array(0,0,0,0,0,0); public var local_array:Array = new Array(); public var localTo_array:Array = new Array(); public var model_array:Array = new Array(); //インスタンスメソッド public function zSort(poz_array:Array,sp_array:Array,target:Object):void{ var _length:int = poz_array.length; var z_array:Array = new Array(); for (var i:int = 0; i<_length; i++) { z_array[i] = poz_array[i][0][2]; } z_array = z_array.sort(Array.NUMERIC|Array.RETURNINDEXEDARRAY|Array.DESCENDING); for (var j:int = 0; j<_length; j++) { var _z:int = z_array[j]; target.setChildIndex(sp_array[_z],0); } } } //////////////// class TextureClass{ //import flash.display.Sprite; import flash.geom.Matrix; import flash.display.BitmapData; //クラスプロパティ //クラスメソッド //コンストラクタ public function TextureClass(){ //trace("RenderClass imported"); } //インスタンスプロパティ public var bmp11_array:Array = new Array(); public var bmp22_array:Array = new Array(); //画像をbitmapData化して、arrayに入れる。 public function setBmp11(img_array:Array):void{ var _length:int = img_array.length; for (var i:int = 0; i<_length; i++) { var imgW:int = img_array[i].width; var imgH:int = img_array[i].height; var bmp_data:BitmapData = new BitmapData(imgW,imgH, true, 0x00FFFFFF); bmp_data.draw(img_array[i]); bmp11_array[i] = bmp_data; } } //画像をbitmapData化して、arrayに入れる。2*2の4分割用。 public function setBmp22(img_array:Array):void{ var _length:int = img_array.length; for (var i:int = 0; i<_length; i++) { var imgW:int = img_array[i].width; var imgH:int = img_array[i].height; var Q_array:Array = new Array(); var mQ:Matrix = new Matrix(1,0,0,1,0,0); var bmpQ0_data:BitmapData = new BitmapData(imgW/2,imgH/2, true, 0x00FFFFFF); bmpQ0_data.draw(img_array[i],mQ); Q_array[0] = bmpQ0_data; var bmpQ1_data:BitmapData = new BitmapData(imgW/2,imgH/2, true, 0x00FFFFFF); mQ.tx= -imgW/2; bmpQ1_data.draw(img_array[i],mQ); Q_array[1] = bmpQ1_data; var bmpQ2_data:BitmapData = new BitmapData(imgW/2,imgH/2, true, 0x00FFFFFF); mQ.tx= 0; mQ.ty= -imgH/2; bmpQ2_data.draw(img_array[i],mQ); Q_array[2] = bmpQ2_data; var bmpQ3_data:BitmapData = new BitmapData(imgW/2,imgH/2, true, 0x00FFFFFF); mQ.tx= -imgW/2; bmpQ3_data.draw(img_array[i],mQ); Q_array[3] = bmpQ3_data; bmp22_array[i] = Q_array; } } //インスタンスメソッド } //////////////// class Math3dClass{ //クラスプロパティ //クラスメソッド //コンストラクタ public function Math3dClass(){ //trace("Math3d imported"); } //インスタンスプロパティ //var angle = 60; // 視野角? public var focalLength:Number = 1000;//焦点距離 //インスタンスメソッド //arrayの複製。再起処理を行っている。 public function arrayClone(ar:Array):Array { var _array:Array = new Array(); var _len:int = ar.length; for (var i:int = 0; i<_len; i++) { _array[i]=(ar[i] is Array)?arrayClone(ar[i]):ar[i]; } return _array; } //二点間の距離を返す関数。 public function distance(a_array:Array,b_array:Array):Number{ var _x:Number = a_array[0] - b_array[0]; var _y:Number = a_array[1] - b_array[1]; var _z:Number = a_array[2] - b_array[2]; return Math.sqrt(_x*_x+_y*_y+_z*_z); } //パースペクティブ public function perspective(arg_array:Array):void{ var _length:int = arg_array.length; for (var i:int = 0; i<_length; i++) { var j_length:int = arg_array[i].length; for (var j:int = 0; j<j_length; j++) { var _per:Number = focalLength/(focalLength+arg_array[i][j][2]); arg_array[i][j] = [arg_array[i][j][0] * _per,arg_array[i][j][1] * _per,_per]; } } } // //ローカル座標でのアフィン変換Affin transform public function localAffine(data_array:Array,poz_array:Array):void { var _length:uint = new uint(data_array.length); for (var i:int = 0; i<_length; i++) { var n_cx:Number = Math.cos(poz_array[i][3]); var n_sx:Number = Math.sin(poz_array[i][3]); var n_cy:Number = Math.cos(poz_array[i][4]); var n_sy:Number = Math.sin(poz_array[i][4]); var n_cz:Number = Math.cos(poz_array[i][5]); var n_sz:Number = Math.sin(poz_array[i][5]); var d_x:Number = poz_array[i][0]; var d_y:Number = poz_array[i][1]; var d_z:Number = poz_array[i][2]; var af_xx:Number = n_cz*n_cy+n_sx*n_sy*n_sz; var af_xy:Number = n_sx*n_sy*n_cz-n_sz*n_cy; var af_xz:Number = n_sy*n_cx; var af_yx:Number = n_cx*n_sz; var af_yy:Number = n_cx*n_cz; var af_yz:Number = -n_sx; var af_zx:Number = n_cy*n_sx*n_sz-n_sy*n_cz; var af_zy:Number = n_sy*n_sz+n_cy*n_sx*n_cz; var af_zz:Number = n_cx*n_cy; var i_length:uint = new uint(data_array[i].length); for (var j:uint = 0; j<i_length; j++) { var af_x:Number = data_array[i][uint(j)][uint(0)]; var af_y:Number = data_array[i][uint(j)][uint(1)]; var af_z:Number = data_array[i][uint(j)][uint(2)]; data_array[i][uint(j)][uint(0)] = af_x*af_xx+af_y*af_xy+af_z*af_xz+d_x; data_array[i][uint(j)][uint(1)] = af_x*af_yx+af_y*af_yy+af_z*af_yz+d_y; data_array[i][uint(j)][uint(2)] = af_x*af_zx+af_y*af_zy+af_z*af_zz+d_z; } } } // //グローバル座標でのアフィン変換Affin transform public function globalAffine(data_array:Array,poz_array:Array):void { var d_x:Number = poz_array[uint(0)]; var d_y:Number = poz_array[uint(1)]; var d_z:Number = poz_array[uint(2)]; var _cx:Number = Math.cos(poz_array[uint(3)]); var _sx:Number = Math.sin(poz_array[uint(3)]); var _cy:Number = Math.cos(poz_array[uint(4)]); var _sy:Number = Math.sin(poz_array[uint(4)]); var _cz:Number = Math.cos(poz_array[uint(5)]); var _sz:Number = Math.sin(poz_array[uint(5)]); var af_xx:Number = _cz*_cy+_sx*_sy*_sz; var af_xy:Number = _sx*_sy*_cz-_sz*_cy; var af_xz:Number = _sy*_cx; var af_yx:Number = _cx*_sz; var af_yy:Number = _cx*_cz; var af_yz:Number = -_sx; var af_zx:Number = _cy*_sx*_sz-_sy*_cz; var af_zy:Number = _sy*_sz+_cy*_sx*_cz; var af_zz:Number = _cx*_cy; var _length:uint = new uint(data_array.length); for (var i:uint = 0; i<_length; i++) { var i_length:uint = new uint(data_array[i].length); for (var j:uint = 0; j<i_length; j++) { var af_x:Number = data_array[i][uint(j)][uint(0)]; var af_y:Number = data_array[i][uint(j)][uint(1)]; var af_z:Number = data_array[i][uint(j)][uint(2)]; data_array[i][uint(j)][uint(0)] = af_x*af_xx+af_y*af_xy+af_z*af_xz+d_x; data_array[i][uint(j)][uint(1)] = af_x*af_yx+af_y*af_yy+af_z*af_yz+d_y; data_array[i][uint(j)][uint(2)] = af_x*af_zx+af_y*af_zy+af_z*af_zz+d_z; } } } } 空模様