Away3Dで銀河のような渦を描く

f:id:teppei-studio:20091101224325j:image

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" 
	applicationComplete="init()" 
	backgroundColor="#FFFFFF" 
	mouseWheel="mouseWheelHander(event)" 
	mouseDown="mouseDownHandler(event)">
	
	<mx:Script>
		<![CDATA[
			import away3d.primitives.Plane;
			import away3d.core.geom.Plane3D;
			import away3d.lights.PointLight3D;
			import away3d.lights.DirectionalLight3D;
			import away3d.lights.AmbientLight3D;
			import away3d.materials.ColorMaterial;
			import away3d.primitives.WireSphere;
			import away3d.materials.WireColorMaterial;
			import away3d.primitives.WireCircle;
			import away3d.materials.WireframeMaterial;
			import away3d.core.base.Vertex;
			import away3d.primitives.LineSegment;
			import away3d.core.base.Object3D;
			import away3d.events.MouseEvent3D;
			import away3d.primitives.Sphere;
			import mx.core.UIComponent;
			import away3d.containers.View3D;
		
			private var view:View3D;
//			private var sphere:Sphere;

			private var moveBack:Number = 5000;
			
			[Bindable]
			private var camPosiX:Number = -500;

			[Bindable]
			private var camPosiY:Number = 1000;

			[Bindable]
			private var camPosiZ:Number = 2000;

			private var increX:Boolean = false;
			private var increY:Boolean = false;
			private var increZ:Boolean = false;
			private var decreX:Boolean = false;
			private var decreY:Boolean = false;
			private var decreZ:Boolean = false;

			// Planeサイズ
			private const W:int = 20;
			private const H:int = 20;
					
			// らせんの軌道半径
			private const RADIUS:int = 10;
		
			protected function init():void
			{
				view = new View3D({x:this.stage.width/2, y:this.stage.height/2});
				var component:UIComponent = new UIComponent();
				component.addChild(view);
				this.addChild(component);

				var num:int = 300;								// 100個生成
				var yPos:Number = -stage.stageHeight/2;			//yの位置
				var numOfRotations:Number = 5;					// らせんを何巻きにするか
				var anglePer:Number = 360*numOfRotations / num;	//(360度*らせん巻き数)に対して個数が何個あるかで回転角度を求める
				
				var preVertex:Vertex;
	
				for(var i:int=0;i<num;i++)
				{
					var sph:Sphere = new Sphere({material:new ColorMaterial(0x0000ff),radius:10});
					sph.y = 0;
					sph.x = Math.cos(i*anglePer) * RADIUS * (num - i);
					sph.z = Math.sin(i*anglePer) * RADIUS * (num - i);
					view.scene.addChild(sph);
					
					var current:Vertex = new Vertex(sph.x,sph.y,sph.z);
					
					if(Capabilities.isDebugger)
					{
						if(i>0)
						{
							var line:LineSegment = new LineSegment({edge:30, color:0x000000, width:10});
							line.start = preVertex;
							line.end = current;
							view.scene.addChild(line);
						}

						preVertex = current;

						createSpaceBox();
					}
				}
				
				this.addEventListener(Event.ENTER_FRAME, away3Dloop);
			}
			
			private function away3Dloop(event:Event):void
			{
				view.camera.moveTo(camPosiX,camPosiY,camPosiZ);
				view.camera.moveBackward(moveBack);
				
				view.render();
			}
			
			private function mouseWheelHander(event:MouseEvent):void
			{
				moveBack += event.delta * 100; 
			}
			
			private var mouseDownPosition:Point;
			
			private function mouseDownHandler(event:MouseEvent):void
			{
				this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
				this.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
				this.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
				
				mouseDownPosition = new Point(event.stageX, event.stageY);
			}
			
			private function mouseMoveHandler(event:MouseEvent):void
			{
				moveCamPosiByDrag(event.stageX - mouseDownPosition.x, event.stageY - mouseDownPosition.y);
				mouseDownPosition = new Point(event.stageX, event.stageY);
			}
			
			private function mouseUpHandler(event:MouseEvent):void
			{
				this.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
				this.removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
				this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
				
			}
			
			private function mouseOutHandler(event:MouseEvent):void
			{
				this.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
				this.removeEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
				this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			}
			
			private function moveCamPosiByDrag(x:Number, y:Number):void
			{
				camPosiX -= x * 10;
				camPosiY += y * 10;
			}
			
			private function createSpaceBox():void
			{
				addLine(new Vertex(0, 0, 0),new Vertex(0, 0, 1000));
				addLine(new Vertex(0, 0, 0),new Vertex(0, 1000, 0));
				addLine(new Vertex(0, 0, 0),new Vertex(1000, 0, 0));
				addLine(new Vertex(0, 1000, 1000),new Vertex(0, 0, 1000));
				addLine(new Vertex(0, 1000, 1000),new Vertex(0, 1000, 0));
				addLine(new Vertex(0, 1000, 1000),new Vertex(1000, 1000, 1000));
				addLine(new Vertex(1000, 0, 1000),new Vertex(0, 0, 1000));
				addLine(new Vertex(1000, 0, 1000),new Vertex(1000, 0, 0));
				addLine(new Vertex(1000, 0, 1000),new Vertex(1000, 1000, 1000));
				addLine(new Vertex(1000, 1000, 0),new Vertex(1000, 1000, 1000));
				addLine(new Vertex(1000, 1000, 0),new Vertex(1000, 0, 0));
				addLine(new Vertex(1000, 1000, 0),new Vertex(0, 1000, 0));
			}
			
			private function addLine(start:Vertex, end:Vertex):void
			{
				var line:LineSegment = new LineSegment({edge:30, color:0x000000, width:10});
				line.start = start;
				line.end = end;
				view.scene.addChild(line);
			}
			
		]]>
	</mx:Script>
	
</mx:Application>