[클릭: 와이어 , 휠: 큐브 회전]


지돌스타님의 http://blog.jidolstar.com/574 를 참고해서
Flash의 3D API를 이용해 Cube를 만들어 봤습니다.

createCube() 부분의 좌표 포인트 등은 for문 등을 쓰지 않고 쌩으로 했습니다.
저도 공부중인데다가 좌표가 어떻게 나오는지 눈으로 직접 봐야알것 같아 일일히 찍어보면서 만들어봤습니다.ㅎㅎ;

처음엔 Plane 하나 만드는데도 어려웠는데 일일히 변경하며 만들어봤더니 재질 입히는것까지..조금은 공부가 된것 같네요.

createMaterial()을 이용해 만든 이미지는 아래와 같습니다.

swc로 만들어 놓은 이미지 객체들을 잘라내서 만들었습니다.

또, wonderfl을 보면서 알게된것 중 하나가 Tween 클래스를 이용하면
var point:Point = new Point(0,0);
TweenMax.to(point , 2 , {x:300 , y:200});
private function 엔터프레임(evt:Event):void
{
    움직일객체.x = point.x;
}
와 같이 Point 객체의 좌표를 트위닝할 수 있고, 그걸 참조해서 객체를 움직일 수 있다..라는게 있었습니다.

아래 소스도 Cube를 만들고,
마우스휠을 돌렸을때 TweenMax에서 Point 좌표를 트위닝 시키고,
Cube는 그 Point 좌표를 참조해서 방향 회전을 하는겁니다.

BitmapData와 ColorTransform을 사용해 흔적이 남는듯한 이동도 그렇고
http://wonderfl.net/ 을 통해 재밌는걸 많이 알게됐네요.

TweenMax나 BitmpaData,ColorTransform을 이용한게 3D API를 사용해 본다는 요점을 흐리는것 같아 코드를
다시 만들어 올릴까하다가 크게 어렵게 보일만한 부분도 아니라 생각되서 그냥 올립니다.

아래 소스 코드를 그대로 쓸 수는 없을테니까요..-oo-;

Adobe에서 제공하는 Flash용 ActionScript 3.0 프로그래밍도 참고하시고
http://help.adobe.com/ko_KR/ActionScript/3.0_ProgrammingAS3/WS18334A17-3F85-4d5a-ADB4-F5BF6196774C.html



package
{
	import com.greensock.TweenMax;
	import com.greensock.easing.Back;
	import com.molgga.displays.Pattern;
	import com.molgga.utils.FpsOutput;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.GraphicsTrianglePath;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Utils3D;
	import flash.geom.Vector3D;
	
	
	[SWF (width="500" , height="400" , backgroundColor="0x333333" , frameRate="60")]
	public class Example5 extends Sprite
	{		
		private var stageRect:Rectangle;
		private var container:Sprite;
		private var canvasContainer:Bitmap;
		private var canvas:BitmapData;
		private var centerMatrix:Matrix;
		private var colorTrans:ColorTransform;
		
		private var projection:PerspectiveProjection;
		private var viewport:Shape;
		private var vision:Matrix3D;
		private var getPoint:Point = new Point(0,0);
		private var bitData:BitmapData;
		
		private var needLine:Boolean = true;
		private var drowShadow:DropShadowFilter;
		
		public function Example5()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			init();
		}
		private function init():void
		{
			stageRect = new Rectangle(0,0, stage.stageWidth , stage.stageHeight );
			centerMatrix = new Matrix();
			centerMatrix.translate(stageRect.width/2 , stageRect.height/2);
			colorTrans = new ColorTransform(0.8 , 0.999 , 0.999 , 0.9);
			
			container = new Sprite();
			canvas = new BitmapData(stageRect.width , stageRect.height , true, 0);
			canvasContainer = new Bitmap(canvas);
			
			createMaterial();
			
			viewport = new Shape();
			projection = new PerspectiveProjection();
			projection.focalLength = 400;
			vision = new Matrix3D();
			
			addChild(container);
			container.addChild(new Pattern(stageRect.width , stageRect.height , 10 , 0xff555555));
			container.addChild(canvasContainer);
			container.addChild(new FpsOutput());
			
			addEventListener(MouseEvent.MOUSE_WHEEL , wheelHandler);
			addEventListener(MouseEvent.MOUSE_DOWN , mouseHandler);
			addEventListener(MouseEvent.MOUSE_UP , mouseHandler);
			
			viewport.filters = [new DropShadowFilter(10,90,0,0.1,10,10)];
			viewport.addEventListener(Event.ENTER_FRAME , rendering);
		}
		private function createMaterial():void
		{
			var sizeW:uint = 200;
			var sizeH:uint = 200;
			var matrix:Matrix = new Matrix();
			var rect:Rectangle = new Rectangle();
			var smooth:Boolean = true;
			
			rect.width = sizeW;
			rect.height = sizeH;
			
			bitData = new BitmapData(800, 200, true , 0);
			bitData.draw(new SampleImage(), matrix, null , null , rect, smooth);
			
			rect.width = sizeW*2;
			matrix.scale(0.5, 0.5);
			matrix.tx = sizeW;
			bitData.draw(new Cat(), matrix, null , null , rect, smooth);
			
			rect.width = sizeW*3;
			matrix.scale(0.8, 0.8);
			matrix.tx = sizeW*2;
			bitData.draw(new Orange(), matrix, null , null , rect, smooth);
			
			rect.width = sizeW*4;
			matrix.scale(1.15,1.15);
			matrix.tx = sizeW*3;
			bitData.draw(new Cat(), matrix, null , null , rect, smooth);
		}
		private function getSortedIndices(mesh:GraphicsTrianglePath):Vector.
		{
			var triangles:Array = [];
			var length:uint = mesh.indices.length;
			
			for ( var i:uint=0; i < length; i += 3 ){
				var i1:uint = mesh.indices[ i+0 ];
				var i2:uint = mesh.indices[ i+1 ];
				var i3:uint = mesh.indices[ i+2 ];
				var z:Number = Math.min( mesh.uvtData[i1 * 3 + 2], mesh.uvtData[i2 * 3 + 2], mesh.uvtData[i3 * 3 + 2]);
				if (z > 0) triangles.push({i1:i1, i2:i2, i3:i3, z:z}); 
			}
			triangles = triangles.sortOn("z", Array.NUMERIC);
			
			var sortedIndices:Vector. = new Vector.(0, false);
			for each (var triangle:Object in triangles) {
				sortedIndices.push(triangle.i1, triangle.i2, triangle.i3);
			}
			return sortedIndices;
		}
		private function createCube():void
		{
			var vertices:Vector. = new Vector.(0, false);
			var indices:Vector. = new Vector.(0, false);
			var uvtData:Vector. = new Vector.(0, false);
			
			var mesh:GraphicsTrianglePath = new GraphicsTrianglePath(vertices , indices , uvtData);
			
			var usX:int = 100;
			var msX:int = -usX;
			var usY:int = 50;
			var msY:int = -usY;
			var usZ:int = usX;
			var msZ:int = -usZ;
			
			mesh.vertices.push( msX , msY , msZ );
			mesh.vertices.push( usX , msY , msZ );
			mesh.vertices.push( msX , usY , msZ );
			mesh.vertices.push( usX , usY , msZ );
			
			mesh.vertices.push( usX , msY , msZ );
			mesh.vertices.push( usX , msY , usZ );
			mesh.vertices.push( usX , usY , msZ );
			mesh.vertices.push( usX , usY , usZ );
			
			mesh.vertices.push( usX , msY , usZ );
			mesh.vertices.push( msX , msY , usZ );
			mesh.vertices.push( usX , usY , usZ );
			mesh.vertices.push( msX , usY , usZ );
			
			mesh.vertices.push( msX , msY , usZ );
			mesh.vertices.push( msX , msY , msZ );
			mesh.vertices.push( msX , usY , usZ );
			mesh.vertices.push( msX , usY , msZ );
			
			mesh.indices.push(0,1,2 , 1,3,2);
			mesh.indices.push(4,5,6 , 5,7,6);
			mesh.indices.push(8,9,10 , 9,11,10);
			mesh.indices.push(12,13,14 , 13,15,14);
			
			mesh.uvtData.push(0     , 0, 0 ,     0.25, 0, 0 ,    0     , 1, 0 ,     0.25, 1, 0);
			mesh.uvtData.push(0.25, 0, 0 ,     0.5  , 0, 0 ,    0.25, 1, 0 ,     0.5  , 1, 0);
			mesh.uvtData.push(0.5  , 0, 0 ,     0.75, 0, 0 ,    0.5  , 1, 0 ,     0.75, 1, 0);
			mesh.uvtData.push(0.75, 0, 0 ,     1     , 0, 0 ,    0.75, 1, 0 ,     1     , 1, 0);
			
			var projected:Vector. = new Vector.(0, false);;
			Utils3D.projectVectors(vision , mesh.vertices , projected , mesh.uvtData);
			
			viewport.graphics.clear();
			if(needLine) viewport.graphics.lineStyle( 1, 0 , 1 );
			viewport.graphics.beginBitmapFill(bitData, null ,false, true);
			viewport.graphics.drawTriangles(projected , getSortedIndices(mesh) , mesh.uvtData , mesh.culling);     
			viewport.graphics.endFill();
			
			canvas.lock();
			(needLine) ? canvas.fillRect(stageRect , 0) : canvas.colorTransform(stageRect, colorTrans);
			canvas.draw(viewport , centerMatrix);
			canvas.unlock();
		}
		private function rendering(evt:Event):void
		{
			vision.identity();
			vision.appendRotation(getPoint.y , Vector3D.X_AXIS);
			vision.appendRotation(getPoint.x , Vector3D.Y_AXIS);
			vision.appendTranslation(0, 0, 400);
			vision.append(projection.toMatrix3D());
			createCube();
		}
		private function wheelHandler(evt:MouseEvent):void
		{
			var targetX:int;
			switch(evt.delta){
				case 3:
					if(getPoint.x%90 == 0){
						targetX = getPoint.x - 90;
						TweenMax.to(getPoint , 2 , {x:targetX , ease:Back.easeInOut});
					}
					break;
				case -3:
					if(getPoint.x%90 == 0){
						targetX = getPoint.x + 90;
						TweenMax.to(getPoint , 2 , {x:targetX , ease:Back.easeInOut});
					}
					break;
			}
			if(getPoint.y%360 == 0){
				var targetY:int = getPoint.y + 360;
				TweenMax.to(getPoint , 2 , {y:targetY  , ease:Back.easeOut});
			}
		}
		private function mouseHandler(evt:MouseEvent):void
		{
			switch(evt.type){
				case MouseEvent.MOUSE_DOWN:
					needLine = !needLine;
					break;
			}
		}
	}
}
저작자 표시 비영리 변경 금지
신고
Posted by 돼냥이

댓글을 달아 주세요

  1. 거꾸로 그 영향한 이런 좌식의 필수적인 요구를 설명한다

    2013.04.25 00:48 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. 사람이란 자기가 생각하는 만큼 결코행복하지도 불행하지도 않다.Topics related articles:


    http://simmel.tistory.com/114 新建文章 8

    http://capitalgate.tistory.com/170 新建文章 12

    http://neoconan.tistory.com/220 新建文章 12

    http://wintness.tistory.com/75 新建文章 12

    2013.04.29 00:34 신고 [ ADDR : EDIT/ DEL : REPLY ]
  3. 전통음식의 현황에 관한 연구

    2013.05.03 06:04 신고 [ ADDR : EDIT/ DEL : REPLY ]


티스토리 툴바