forked from: forked from: Basic3D on 2008-12-22
とりあえず複数のオブジェクト
// forked from umhr's forked from: Basic3D on 2008-12-22
// forked from umhr's forked from: Basic3D on 2008-12-22
//とりあえず複数のオブジェクト
package
{
/**
*
* @author umhr
*/
import flash.display.*
import flash.events.*
import flash.text.*
import flash.utils.*
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="30")]
public class Basic3D extends Sprite {
private var originPoz:Array = new Array([[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]],[[0,0,0],[-75,-75,0],[-75,75,0],[75,75,0],[75,-75,0]]);
private var stage_sp:Sprite = new Sprite();
private var fpsstage_sp:Sprite = new Sprite();
private var polygonSp_array:Array = new Array();
private var _count:int;
private var loadFiles_array:Array;
private var onComplete:Function = function():void{};
private var data_xml:XML;
private var loadNum:int;
private var loadCompNum:int;
public function Basic3D() {
stage_sp.x = stage_sp.y = 465/2;
for (var i:uint = 0; i<originPoz.length; i++) {
polygonSp_array[i] = new Sprite();
stage_sp.addChild(polygonSp_array[i]);
}
this.addChild(fpsstage_sp);
this.addChild(stage_sp);
setFpsCounter(fpsstage_sp,30);
this.addEventListener(Event.ENTER_FRAME,main);
}
private function main(e:Event):void{
var _poz:Array = arrayClone(originPoz);
_count ++;
localAffine(_poz,[[0,0,75,0,0,0],[0,0,0,0,0,0],[0,0,-75,0,0,0],[150,0,0,0,Math.PI/2,0],[-150,0,0,0,-Math.PI/2,0],[0,150,0,Math.PI/2,0,0],[0,-150,0,-Math.PI/2,0,0]])
globalAffine(_poz,[0,0,0,_count/30,_count/60,_count/90]);
var zSort_array:Array =zSort(_poz);
perspective(_poz);
drawFill(_poz,zSort_array);
}
//
//ローカル座標でのアフィン変換Affin transform
public function localAffine(__poz:Array,__view:Array):void {
var _length:uint = new uint(__poz.length);
for (var i:int = 0; i<_length; i++) {
var d_x:Number = __view[i][0];
var d_y:Number = __view[i][1];
var d_z:Number = __view[i][2];
var n_cx:Number = Math.cos(__view[i][3]);
var n_sx:Number = Math.sin(__view[i][3]);
var n_cy:Number = Math.cos(__view[i][4]);
var n_sy:Number = Math.sin(__view[i][4]);
var n_cz:Number = Math.cos(__view[i][5]);
var n_sz:Number = Math.sin(__view[i][5]);
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(__poz[i].length);
for (var j:uint = 0; j<i_length; j++) {
var af_x:Number = __poz[i][uint(j)][uint(0)];
var af_y:Number = __poz[i][uint(j)][uint(1)];
var af_z:Number = __poz[i][uint(j)][uint(2)];
__poz[i][uint(j)][uint(0)] = af_x*af_xx+af_y*af_xy+af_z*af_xz+d_x;
__poz[i][uint(j)][uint(1)] = af_x*af_yx+af_y*af_yy+af_z*af_yz+d_y;
__poz[i][uint(j)][uint(2)] = af_x*af_zx+af_y*af_zy+af_z*af_zz+d_z;
}
}
}
//グローバル座標でのアフィン変換Affin transform
public function globalAffine(__poz:Array,__view:Array):void {
var d_x:Number = __view[int(0)];
var d_y:Number = __view[int(1)];
var d_z:Number = __view[int(2)];
var _cx:Number = Math.cos(__view[int(3)]);
var _sx:Number = Math.sin(__view[int(3)]);
var _cy:Number = Math.cos(__view[int(4)]);
var _sy:Number = Math.sin(__view[int(4)]);
var _cz:Number = Math.cos(__view[int(5)]);
var _sz:Number = Math.sin(__view[int(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:int = new int(__poz.length);
for (var i:int = 0; i<_length; i++) {
var i_length:int = new int(__poz[i].length);
for (var j:int = 0; j<i_length; j++) {
var af_x:Number = __poz[i][int(j)][int(0)];
var af_y:Number = __poz[i][int(j)][int(1)];
var af_z:Number = __poz[i][int(j)][int(2)];
__poz[i][int(j)][int(0)] = af_x*af_xx+af_y*af_xy+af_z*af_xz+d_x;
__poz[i][int(j)][int(1)] = af_x*af_yx+af_y*af_yy+af_z*af_yz+d_y;
__poz[i][int(j)][int(2)] = af_x*af_zx+af_y*af_zy+af_z*af_zz+d_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 = 500/(500+arg_array[i][j][int(2)]);
arg_array[i][j] = [arg_array[i][j][int(0)] * _per,arg_array[i][j][int(1)] * _per,_per];
}
}
}
//面を描く
private function zSort(__poz:Array):Array{
var z_array:Array = new Array();
var _length:int = __poz.length;
for (var i:int = 0; i<_length; i++) {
z_array[i] = distance(__poz[i][int(0)],[0,0,-500]);
}
return z_array.sort(Array.NUMERIC|Array.RETURNINDEXEDARRAY|Array.DESCENDING);
}
private function drawFill(__poz:Array,_z_array:Array):void{
var _length:int = __poz.length;
for (var i:int = 0; i<_length; i++) {
var _i:int = _z_array[i];
polygonSp_array[i].graphics.clear();
var g:Graphics = polygonSp_array[i].graphics;
g.lineStyle(1, 0x000000, 1.0); // 線のスタイル指定
g.beginFill(0xFF0000, 0.8); // 面のスタイル設定
var _len:int = __poz[_i].length;
g.moveTo (__poz[_i][_len-1][int(0)], __poz[_i][_len-1][int(1)]);
for (var j:int = 1; j<_len; j++) {
g.lineTo(__poz[_i][j][int(0)], __poz[_i][j][int(1)]);
}
g.endFill();
}
}
//二点間の距離を返す関数。
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);
}
//arrayの複製。再起処理を行っている。
private 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;
}
//FPSを表示
private function setFpsCounter(_stage:Object,stageFPS:Number = -1):Sprite{
if(stageFPS == -1){
stageFPS = _stage.frameRate;
}
var _sp:Sprite = new Sprite();
_stage.addChild(_sp);
var _tf:TextField = new TextField();
var count:int = 1;
var oldTimer:uint = getTimer();
_sp.addChild(_tf);
_sp.addEventListener(Event.ENTER_FRAME,fpsCounter);
function fpsCounter(e:Event):void{
if (count < stageFPS) {
count ++;
} else {
_tf.text = "fps"+stageFPS*1000/(getTimer()-oldTimer);
oldTimer = getTimer();
count = 1;
}
}
return _sp;
}
}
}