forked from: forked from: flash on 2010-5-26

by hiro_rec forked from forked from: flash on 2010-5-26 (diff: 14)
Castクラスはyd_nikuさんの
* http://wonderfl.net/c/5Nfkらへんを拝借
* Zソートは省略
♥0 | Line 314 | Modified 2010-05-26 05:10:53 | MIT License
play

ActionScript3 source code

/**
 * Copyright hiro_rec ( http://wonderfl.net/user/hiro_rec )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6VTf
 */

/**
 * Castクラスはyd_nikuさんの
 * http://wonderfl.net/c/5Nfkらへんを拝借
 * Zソートは省略
 */

 package
{
	import __AS3__.vec.Vector;
	
	import caurina.transitions.Tweener;
	
	import flash.display.*;
	import flash.events.*;
	import flash.filters.*;
	import flash.geom.*;
	
	[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
	
	public class Study09 extends Sprite
	{
		private var viewport:Sprite = new Sprite();
		private var vertices:Vector.<Number> = new Vector.<Number>();
		private var indices:Vector.<int> = new Vector.<int>();
		private var uvtData:Vector.<Number> = new Vector.<Number>();
		
		private var worldMatrix:Matrix3D = new Matrix3D();
		private var viewMatrix:Matrix3D = new Matrix3D();
		private var projection:PerspectiveProjection = new PerspectiveProjection();
		
		private var cast1:Cast;
		private var cast2:Cast;
		
		private var sp1:Sprite;
		private var sp2:Sprite;
		
		
		public function Study09()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			//stage.quality = StageQuality.LOW;
			
			viewport.x = stage.stageWidth * 0.5;
			viewport.y = stage.stageHeight * 0.5;
			addChild(viewport);
			
			worldMatrix.appendRotation(45, Vector3D.X_AXIS);
			viewMatrix.appendTranslation(0, 0, 300);
			projection.fieldOfView = 40;
			//projection.focalLength = 2000
			
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			
			createCast();
		}
		
		private const DIV:uint = 15;
		
		private function createVertices():void
		{
			vertices = new Vector.<Number>();
			indices = new Vector.<int>();
			uvtData = new Vector.<Number>();
		
			var margin:Number = 10;
			var stepInd:int = 0;
			
			for (var i:int = 0; i < DIV; i++)
			{
				for (var j:int = 0; j < DIV; j++)
				{
					var x1:Number = j * margin - DIV * margin / 2;
					var y1:Number = 0;
					var z1:Number = i * margin - DIV * margin / 2;
					
					var x2:Number = (j+1) * margin - DIV * margin / 2;
					var y2:Number = 0;
					var z2:Number = i * margin - DIV * margin / 2;
					
					var x3:Number = (j+1) * margin - DIV * margin / 2;
					var y3:Number = 0;
					var z3:Number = (i+1) * margin - DIV * margin / 2;
					
					var x4:Number = j * margin - DIV * margin / 2;
					var y4:Number = 0;
					var z4:Number = (i+1) * margin - DIV * margin / 2;
					
					if (v)
					{
						//z1 = v.y;
						
					}
					
					vertices.push(
								  x1,		// 頂点 0(左上)
								  y1,
								  z1,
								  
								  x2, 	// 頂点 1(右上)
								  y2,
								  z2,
								  
								  x3, 	// 頂点 2(右下)
								  y3,
								  z3,
								  
								  x4,		// 頂点 3(左下)
								  y4,
								  z4);
					
					indices.push(stepInd,stepInd+1,stepInd+3, stepInd+1,stepInd+2,stepInd+3);
					stepInd += 4;
					
					uvtData.push(
								  j / DIV,		//頂点 0 U
								  i / DIV,		//		 V
								  
								  (j+1) / DIV,	//頂点 1 U
								  i / DIV,		//		 V
								  
								  (j+1) / DIV,	//頂点 2 U
								  (i+1) / DIV,	//		 V
								  
								  j/DIV,		//頂点 3 U
								  (i+1) / DIV,	//		 V
								  0);
				}
			}
		}
		
		private function createCast():void
		{
			cast1 = new Cast();
			cast1.y = -400;
			
			cast2 = new Cast();
			
			bound();
			
			sp1 = new Sprite();
			sp2 = new Sprite();
			
			viewport.addChild(sp2);
			viewport.addChild(sp1);
			
			sp2.blendMode = BlendMode.MULTIPLY;
		}
		
		private function bound():void
		{
			Tweener.addTween(cast1, {y:-25, time:1, transition:"easeOutBounce", onComplete:
				function():void
				{
					Tweener.addTween(cast1, {y:-400, time:1, transition:"easeInBounce", onComplete:
						function():void
						{
							bound();
						}
					});
				}
			});
		}
		
		private function updateVertices():void
		{
			var _x:int = mouseX / stage.stageWidth * DIV + 1;
			var _y:int = mouseY / stage.stageHeight * DIV + 1;
			var xy:int = _x * _y - 1;
			//trace((_x - 1) + " * " + (_y - 1) + " = " + xy);
		}
		
		private function enterFrameHandler(event:Event):void
		{
			createVertices();
			updateVertices();
			updateRotation();
			
			render();
		}
		
		private function updateRotation():void
		{
			var vx:Number = (stage.stageWidth / 2 - mouseX) * 0.01;
			var vy:Number = (stage.stageHeight / 2 - mouseY) * -0.01;
			
			//worldMatrix.appendRotation(vx, Vector3D.Y_AXIS);
			worldMatrix.appendRotation(vy, Vector3D.X_AXIS);
		}
		
		private var vx:int = -1;
		private var vy:int = -1;
		private var a:int = 5;
		private var lx:int = 240;
		private var ly:int = 240;
		private var tx:int = lx / 2;
		private var ty:int = ly / 2;
		
		private function render():void
		{
			cast1.x += a * 1.5 * vx;
			cast1.z += a * vy;
			
			cast2.x += a * 1.5* vx;
			cast2.z += a * vy;
			
			tx += a * 1.5;
			ty += a;
			
			if (tx > lx)
			{
				vx *= -1;
				tx = 0;
			}
			
			if (ty > ly)
			{
				vy *= -1;
				ty = 0;
			}
			
			//cast1.rotateY += 1;
			//viewMatrix.appendTranslation(0, 0, 10);
			
			var m:Matrix3D = new Matrix3D();
			m.append(worldMatrix);
			m.append(viewMatrix);
			m.append(projection.toMatrix3D());
			
			//
			const r_:int = 100;
			var m_:Matrix = new Matrix;
			m_.createGradientBox(r_ * 2, r_ * 2, Math.PI * 0.25, -r_, -r_);
			sp1.graphics.clear();
			sp1.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x0000FF, 0x3333CC], null, [0x4, 0x60, 0xFF], m_, "pad", "rgb", -0.25);
			//sp1.graphics.beginFill(0x0000FF);
			sp1.graphics.drawCircle(0, 0, 50);
			
			sp2.graphics.clear();
			sp2.graphics.beginFill(0x000000, 0.2);
			sp2.graphics.drawCircle(0, 0, 50);
			
			var mtx1:Matrix3D = cast1.transform;
	        mtx1.appendRotation(cast1.rotateX, Vector3D.X_AXIS);
	        mtx1.appendRotation(cast1.rotateY, Vector3D.Y_AXIS);
	        mtx1.appendRotation(cast1.rotateZ, Vector3D.Z_AXIS);
	        mtx1.appendScale(cast1.scaleX, cast1.scaleY, cast1.scaleZ);
	        mtx1.appendTranslation(cast1.x, cast1.y, cast1.z);
			mtx1.append(worldMatrix);
			mtx1.append(viewMatrix);
			
			var mtx2:Matrix3D = cast2.transform;
	        mtx2.appendRotation(cast2.rotateX, Vector3D.X_AXIS);
	        mtx2.appendRotation(cast2.rotateY, Vector3D.Y_AXIS);
	        mtx2.appendRotation(cast2.rotateZ, Vector3D.Z_AXIS);
	        mtx2.appendScale(cast2.scaleX, cast2.scaleY, cast2.scaleZ);
	        mtx2.appendTranslation(cast2.x, cast2.y, cast2.z);
			mtx2.append(worldMatrix);
			mtx2.append(viewMatrix);
			
			sp1.transform.matrix3D = mtx1;
			sp1.rotationX = 0;
			sp1.rotationY = 0;
			sp1.rotationZ = 0;
			
			sp2.transform.matrix3D = mtx2;
			sp2.rotationX += 90;
			sp2.scaleX = sp2.scaleY = 1 - Math.abs(cast1.y) / 200 * 0.5;
			//trace(cast.transform.matrix3D.toString())
			//m2.append(projection.toMatrix3D());
			//cast.transform.matrix3D.prepend(m2);
			
			

			var projected:Vector.<Number> = new Vector.<Number>();
			Utils3D.projectVectors(m, vertices, projected, uvtData);
			
			var g:Graphics = viewport.graphics;
			g.clear();
			g.lineStyle(0, 0x000000, 0.1);
			g.beginFill(0xEEEEEE, 1);
			g.drawTriangles(projected, indices, null, TriangleCulling.NONE);
			
			//unProject
			
			var invProj:Matrix3D = projection.toMatrix3D().clone();
			var invView:Matrix3D = viewMatrix.clone();
			var invWorld:Matrix3D = worldMatrix.clone();
			
			invProj.invert();
			invView.invert();
			invWorld.invert();
			
			var rawData:Vector.<Number> = new Vector.<Number>();
			
			var mx:Number = (mouseX - stage.stageWidth / 2) / stage.stageWidth;
			var my:Number = (mouseY - stage.stageHeight / 2) / stage.stageHeight;
			
			rawData[0] = mx;
			rawData[1] = my;
			rawData[2] = 0;
			rawData[3] = 1;
			
			rawData[4] = mx;
			rawData[5] = my;
			rawData[6] = 0;
			rawData[7] = 1;
			
			rawData[8] = mx;
			rawData[9] = my;
			rawData[10] = 0;
			rawData[11] = 1;
			
			rawData[12] = mx;
			rawData[13] = my;
			rawData[14] = 0;
			rawData[15] = 1;
			
			m = new Matrix3D();
			m.rawData = rawData;
			
			m.append(invProj);
			m.append(viewMatrix);
			m.append(worldMatrix);
			
			v = new Vector3D();
			v = m.transformVector(v);
			
		}
		
		private var v:Vector3D;
	}
}
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	

internal class Cast {
    // for Calcuration
    public var position:Vector3D;
    public var rotate:Vector3D;
    public var scale:Vector3D;
    
    public function Cast( x:Number = 0, y:Number =0, z:Number =0 )
    {
        position = new Vector3D( x, y, z );
        rotate = new Vector3D();
        scale = new Vector3D( 1, 1, 1 );
    }
    
    // Position
    public function set x( value:Number ):void{
        position.x = value;
    }
    public function get x():Number {
        return position.x;
    }
    public function set y( value:Number ):void{
        position.y = value;
    }
    public function get y():Number {
        return position.y;
    }
    public function set z( value:Number ):void{
        position.z = value;
    }
    public function get z():Number {
        return position.z;
    }
    
    // Rotation
    public function set rotateX( value:Number ):void{
        rotate.x = value;
    }
    public function get rotateX():Number {
        return rotate.x;
    }
    public function set rotateY( value:Number ):void{
        rotate.y = value;
    }
    public function get rotateY():Number {
        return rotate.y;
    }
    public function set rotateZ( value:Number ):void{
        rotate.z = value;
    }
    public function get rotateZ():Number {
        return rotate.z;
    }
    
    // Scale
    public function set scaleX( value:Number ):void{
        scale.x = value;
    }
    public function get scaleX():Number {
        return scale.x;
    }
    public function set scaleY( value:Number ):void{
        scale.y = value;
    }
    public function get scaleY():Number {
        return scale.y;
    }
    public function set scaleZ( value:Number ):void{
        scale.z = value;
    }
    public function get scaleZ():Number {
        return scale.z;
    }
    
    public function get transform():Matrix3D {
        var mat:Matrix3D = new Matrix3D();
        mat.appendRotation( rotate.x, Vector3D.X_AXIS );
        mat.appendRotation( rotate.y, Vector3D.Y_AXIS );
        mat.appendRotation( rotate.z, Vector3D.Z_AXIS );
        mat.appendScale( scale.x, scale.y, scale.z );
        mat.appendTranslation( position.x, position.y, position.z );
        return mat;
    }
}