空模様
3DのテクスチャーとしてBitmapをなんとかきれいに貼り付けられるようになった頃、
* さてこの方法ではどれくらいのスピードが出るのだろうか?
* と疑問に思ってテストとして作ったもの(wonderflでも動くように、
* 細々と書き換えたけど)。
*
* 30fps640*480のflvを読み込み、再生しっぱなしにして、
* それを4つの面のBitmapDataに対してdrawしている。
* 結果、とりあえず目的に対しては十分に高速であることがわかった。
*
*
/**
* Copyright umhr ( http://wonderfl.net/user/umhr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vqUu
*/
/*
* 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.jp/wonderfl/";
Security.loadPolicyFile("http://mztm.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+"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;
}
}
}
}