In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

四角い薔薇

三年位前(Flash9のPublic Alpha版!!)にクリッピングできたわーいで作ったものを、
元にWondeflで動くようにしながら細々ブラシュアップ。

マウスの位置で回転や、光源をコントロール。
キーボードの↑↓キーで視点、マウスのdeltaでviewpointを変えたりできるはず。

4角形ポリンゴンで、立方体の面を作っていて、
zの座標に応じて、クリッピングしている。

レンダリング側は、4角以上のポリゴンにも対応しているので、
クリッピングした結果の5角形とかも描ける。

これで、自動的に三角ポリゴンに分割とかできるようになったら、
テクスチャーつきでクリッピングできるのかな。今後の課題だ。

あと、やっぱsortがボトルネックになっていたので、作り直した。



*クリッピング
http://game.watch.impress.co.jp/docs/20040406/psp06.htm
http://game.watch.impress.co.jp/docs/20040406/psp.htm
Get Adobe Flash player
by umhr 03 Jul 2009
/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/giVH
 */

/*
三年位前(Flash9のPublic Alpha版!!)にクリッピングできたわーいで作ったものを、
元にWondeflで動くようにしながら細々ブラシュアップ。

マウスの位置で回転や、光源をコントロール。
キーボードの↑↓キーで視点、マウスのdeltaでviewpointを変えたりできるはず。

4角形ポリンゴンで、立方体の面を作っていて、
zの座標に応じて、クリッピングしている。

レンダリング側は、4角以上のポリゴンにも対応しているので、
クリッピングした結果の5角形とかも描ける。

これで、自動的に三角ポリゴンに分割とかできるようになったら、
テクスチャーつきでクリッピングできるのかな。今後の課題だ。

あと、やっぱsortがボトルネックになっていたので、作り直した。



*クリッピング
http://game.watch.impress.co.jp/docs/20040406/psp06.htm
http://game.watch.impress.co.jp/docs/20040406/psp.htm

*/
package 
{
	/**
	 * ...
	 * @author umhr
	 */
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	
	public class Main extends Sprite
	
	
	{
		function Main(){
			var i:int;
			
			var origin_array:Array = new Array();
			var num:int = 4
			for (i = 0 ; i < 7; i++) {
				num = num*1.8;
				origin_array.push([0, ["plane", 0], [[ -num, -num, -num], [num, -num, -num], [num, num, -num], [ -num, num, -num]]], [0, ["plane", 0], [[num, num, num], [num, -num, num], [ -num, -num, num], [ -num, num, num]]], [0, ["plane", 0], [[ -num, num, num], [ -num, -num, num], [ -num, -num, -num], [ -num, num, -num]]], [0, ["plane", 0], [[num, -num, -num], [num, -num, num], [num, num, num], [num, num, -num]]], [0, ["plane", 0], [[num, num, num], [ -num, num, num], [ -num, num, -num], [num, num, -num]]], [0, ["plane", 0], [[ -num, -num, -num], [ -num, -num, num], [num, -num, num], [num, -num, -num]]]);
			}
			
			
			
			var stageWidth:int = stage.stageWidth;
			var stageHeight:int = stage.stageHeight;
			
			var vpcutpoint_num:Number = new Number(290);
			var lightpoz_array:Array = new Array(0, 0, 300);
			var mcnum_num:int = origin_array.length;
			var n_dx:Number = new Number(0);
			var n_dy:Number = new Number(0);
			var n_dz:Number = new Number(0);
			var n_rx:Number = new Number(0);
			var n_ry:Number = new Number(0);
			var n_rz:Number = new Number(0);
			var sprits:Array = new Array();
			
			
			for (i = 0 ; i < origin_array.length;i++) {
				var sp:Sprite = new Sprite();
				this.addChild(sp);
				sp.x = stageWidth/2;
				sp.y = stageHeight/2;
				sprits.push(sp);
			}
			var sorter_array:Array = new Array();
			var sq_array:Array = new Array();
			function fc_create(fc_dx:Number, fc_dy:Number, fc_dz:Number, fc_rx:Number, fc_ry:Number, fc_rz:Number):void {
				var i:int;
				var j:int;
				
				//map
				var data_array:Array = Math3D.arraycopy(origin_array);
				
				//affine
				for (i = 0; i < data_array.length; i++) {
					
					var _array:Array = new Array();
					if(int(i/6)%2 == 0){
						_array[0] = Math.cos(fc_rx);
						_array[1] = Math.sin(fc_rx);
						_array[2] = Math.cos(fc_ry);
						_array[3] = Math.sin(fc_ry);
						_array[4] = Math.cos(fc_rz);
						_array[5] = Math.sin(fc_rz);
						_array[6] = fc_dz;
					}else{
						_array[0] = Math.cos(fc_ry);
						_array[1] = Math.sin(fc_ry);
						_array[2] = Math.cos(fc_rx);
						_array[3] = Math.sin(fc_rx);
						_array[4] = Math.cos(fc_rz);
						_array[5] = Math.sin(fc_rz);
						_array[6] = fc_dz;
					}
					
					for (j = 0; j<data_array[i][2].length; j++) {
						data_array[i][2][j] = Math3D.affine(data_array[i][2][j][0], data_array[i][2][j][1], data_array[i][2][j][2], _array);
					}
				}
				
				//clipping
				var dispcount_num:int = new int(0);
				var vp_difference_num:Number = new Number(vpcutpoint_num-Math3D.vp);
				for (i = 0; i<data_array.length; i++) {
					var ar_array:Array= new Array();
					for (j = 0; j<data_array[i][2].length; j++) {
						if (data_array[i][2][j][2]<vp_difference_num) {
							for (var k:int = 0; k<2; k++) {
								var m:int = (data_array[i][2].length-1+j+2*k)%data_array[i][2].length;
								var n:int = j%data_array[i][2].length;
								if (data_array[i][2][m][2]>vp_difference_num) {
									var n_wariai:Number = (vp_difference_num-data_array[i][2][n][2])/(data_array[i][2][m][2]-data_array[i][2][n][2]);
									var n_repointx:Number = (data_array[i][2][m][0]-data_array[i][2][n][0])*n_wariai+data_array[i][2][n][0];
									var n_repointy:Number = (data_array[i][2][m][1]-data_array[i][2][n][1])*n_wariai+data_array[i][2][n][1];
									ar_array.push([n_repointx, n_repointy, vp_difference_num]);
								}
							}
						} else {
							ar_array.push(data_array[i][2][j]);
						}
					}
					if(ar_array.length < 1){
						data_array[i][1][0] = "culled";
					}else{
						data_array[i][2] = ar_array.concat();
					}
				}
				
				//normal
				for (i = 0; i<data_array.length; i++) {
					if(data_array[i][1][0] == "culled"){
						continue;
					}
					
					var n_cx:Number = (data_array[i][2][1][1]-data_array[i][2][0][1])*(data_array[i][2][2][2]-data_array[i][2][1][2])-(data_array[i][2][1][2]-data_array[i][2][0][2])*(data_array[i][2][2][1]-data_array[i][2][1][1]);
					var n_cy:Number = (data_array[i][2][1][2]-data_array[i][2][0][2])*(data_array[i][2][2][0]-data_array[i][2][1][0])-(data_array[i][2][1][0]-data_array[i][2][0][0])*(data_array[i][2][2][2]-data_array[i][2][1][2]);
					var n_cz:Number = (data_array[i][2][1][0]-data_array[i][2][0][0])*(data_array[i][2][2][1]-data_array[i][2][1][1])-(data_array[i][2][1][1]-data_array[i][2][0][1])*(data_array[i][2][2][0]-data_array[i][2][1][0]);
					var n_clxyz:Number = lightpoz_array[0]*n_cx+lightpoz_array[1]*n_cy+lightpoz_array[2]*n_cz;
					var n_cxyz:Number = Math.sqrt(n_cx*n_cx+n_cy*n_cy+n_cz*n_cz);
					var n_lxyz:Number = Math.sqrt(lightpoz_array[0]*lightpoz_array[0]+lightpoz_array[1]*lightpoz_array[1]+lightpoz_array[2]*lightpoz_array[2]);
					data_array[i][1][1] = Math.floor((Math.acos(n_clxyz/(n_cxyz*n_lxyz))/Math.PI)*256);
					
					for (j = 0; j<data_array[i][2].length; j++) {
						data_array[i][0] += data_array[i][2][j][2]/data_array[i][2].length;
					}
					data_array[i][0] -=7000;
				}
				///pertrance
				for (i = 0; i<data_array.length; i++) {
					if(data_array[i][1][0] == "culled"){
						continue;
					}
					for (j = 0; j<data_array[i][2].length; j++) {
						data_array[i][2][j] = Math3D.pertrans(data_array[i][2][j][0], data_array[i][2][j][1], data_array[i][2][j][2]);
					}
				}
				//sort
				var z_array:Array = Math3D.zSort(data_array);
				
				//render
				for (i =0;i < mcnum_num; i++) {
					sprits[i].graphics.clear();
				}
				
				// Spriteインスタンスへの矩形の描画
				mcnum_num = data_array.length
				for (k = 0; k < mcnum_num; k++) {
					i = z_array[k]
					if(data_array[i][1][0] == "culled"){
						continue;
					}
					//trace(data_array[i][1][1]);
					sprits[k].graphics.lineStyle(1,0xFF0000,1);
					//sprits[k].graphics.beginFill(data_array[i][1][1]*65793,0.7);
					sprits[k].graphics.beginFill(data_array[i][1][1]<<16,0.7);
					sprits[k].graphics.moveTo(data_array[i][2][0][0],data_array[i][2][0][1]);
					for (j = 1; j<data_array[i][2].length; j++) {
						sprits[k].graphics.lineTo(data_array[i][2][j][0],data_array[i][2][j][1]);
					}
				}
			}
			
			//addEventListener類
			addEventListener(Event.ENTER_FRAME, ENTER_FRAME);
			function ENTER_FRAME(e:Event):void {
				n_rx += (stage.mouseY - stageHeight / 2) / 10000;
				n_ry += (stage.mouseX - stageWidth / 2) / 10000;
				lightpoz_array[0] = stage.mouseX - stageWidth / 2;
				lightpoz_array[1] = stage.mouseY - stageHeight / 2;
				fc_create(n_dx, n_dy, n_dz, n_rx, n_ry, n_rz);
			}
			
			addEventListener( MouseEvent.MOUSE_WHEEL , MOUSE_WHEEL );
			function MOUSE_WHEEL( event:MouseEvent ):void{
				Math3D.vp += event.delta*3;
				lightpoz_array[2] = Math3D.vp;
			}
			
			stage.addEventListener( KeyboardEvent.KEY_DOWN , KEY_DOWN );
			function KEY_DOWN( event:KeyboardEvent ):void {
				if(event.keyCode == 38){
					n_dz -= 5;
				}else if(event.keyCode == 40){
					n_dz += 5;
				}
			}
			
		}
	}
}

class Math3D {
	static public function zSort(pt_array:Array):Array{
		var len:int = pt_array.length;
		var sorter_array:Array = [];
		for (var i:int = 0; i<len; i++) {
			sorter_array[i] = 10000-pt_array[i][0];
		}
		return sorter_array.sort(Array.NUMERIC | Array.RETURNINDEXEDARRAY);// | Array.DESCENDING
	}
	public static var vp:Number = 300;
	public static function pertrans(arg_x_num:Number, arg_y_num:Number, arg_z_num:Number):Array {
		var _per:Number = vp/(vp+arg_z_num);
		return [arg_x_num*_per, arg_y_num*_per, _per*100];
	}
	public static function affine(x:Number, y:Number, z:Number, arg_array:Array):Array {
		var n_cx:Number = arg_array[0];
		var n_sx:Number = arg_array[1];
		var n_cy:Number = arg_array[2];
		var n_sy:Number = arg_array[3];
		var n_cz:Number = arg_array[4];
		var n_sz:Number = arg_array[5];
		var _array:Array = new Array(3);
		_array[0] = x*(n_cz*n_cy+n_sy*n_sx*n_sz)+y*(-n_sz*n_cy+n_sy*n_sx*n_cz)+z*(n_sy*n_cx);
		_array[1] = x*(n_cx*n_sz)+y*n_cx*n_cz-z*(n_sx);
		_array[2] = x*(-n_sy*n_cz+n_cy*n_sx*n_sz)+y*(n_sy*n_sz+n_cy*n_sx*n_cz)+z*(n_cy*n_cx)+arg_array[6];;
		return _array;
	}
	public static function arraycopy(copy_array:Array):Array {
		var _array:Array = new Array();
		var i_array:Array = new Array();
		var length:int = copy_array.length;
		for(var i:int= 0;i<length;i++){
			i_array[0] = copy_array[i][0];		
			i_array[1] = copy_array[i][1].concat();
			var j_array:Array = new Array();
			for(var j:int= 0;j<copy_array[i][2].length;j++){
				j_array[j] = copy_array[i][2][j].concat();
			}
			i_array[2] = j_array.concat();
			_array[i] = i_array.concat();
		}
		return _array
	}
}