package example.matrix {
	import flash.geom.Vector3D;

	/**
	 * @author Lee
	 * http://webnoon.net
	 */
	public class CustomMatrix3D {
		
		private var _mat : Vector.<Number> ;
		
		public function CustomMatrix3D(){
			this.idenfy() ;
		}
		
		/*
		 * rotationX
		 */
		public function rotationX($val:Number):void
		{
			 var mat : Vector.<Number> = Vector.<Number>([
		 			1,0,0,0,
		 			0,Math.cos($val),-Math.sin($val),0,
		 			0,Math.sin($val),Math.cos($val),0,
		 			0,0,0,1
		 		]) ;
		 	this.cross(mat) ;
		}
		
		public function rotationY($val:Number):void
		{
			var mat : Vector.<Number> = Vector.<Number>([
		 			Math.cos($val),0,Math.sin($val),0,
		 			0,1,0,0,
		 			-Math.sin($val),0,Math.cos($val),0,
		 			0,0,0,1
		 		]) ;
		 	this.cross(mat) ;
		}
		public function rotationZ($val:Number):void
		{
			var mat : Vector.<Number> = Vector.<Number>([Math.cos($val),-Math.sin($val),0,0,
		 			   Math.sin($val), Math.cos($val),0,0,
		 			   0,0,1,0,
		 			   0,0,0,1]) ;
		 	this.cross(mat) ;
		}
		
		public function translation($x:Number,$y:Number,$z:Number):void
		{
			var mat : Vector.<Number> = Vector.<Number>([
				1,0,0,$x,
				0,1,0,$y,
				0,0,1,$z,
				0,0,0,1
			]) ;
			this.cross(mat) ;
		}
		
		public function idenfy():void
		{
			_mat = Vector.<Number>([1,0,0,0,
					0,1,0,0,
					0,0,1,0,
					0,0,0,1]) ;
		}
		
		public function transformVector($v:Vector3D):void
		{
			var x : Number = $v.x ;
			var y : Number = $v.y ;
			var z : Number = $v.z ;
			
			$v.x = _mat[0]*x + _mat[1]*y + _mat[2]*z + _mat[3] * $v.w ;
			$v.y = _mat[4]*x + _mat[5]*y + _mat[6]*z + _mat[7] * $v.w ;
			$v.z = _mat[8]*x + _mat[9]*y + _mat[10]*z + _mat[11] * $v.w ;
			$v.w = _mat[12]*x + _mat[13]*y + _mat[14]*z + _mat[15] * $v.w ;
		}
		
		/*
		 * private
		 */
		public function cross($mat:Vector.<Number>):void
		{
			var mc : Vector.<Number> = _mat.concat() ;
			
			for (var i : int = 0; i < 13; i+=4) {
				for (var j : int = 0; j < 4; j++) {
					_mat[j+i] = 0 ;
					for (var k : int = 0; k < 4; k++) {
						_mat[j+i] += mc[k+i]*$mat[k*4+j] ;
					}
				}
			}
		}
		
	}
}

