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

3D text (3D rotation)

sorry for dirty code, and for the coments in portuguese
learning 3D ^^
Get Adobe Flash player
by Thy 18 May 2010
/**
 * Copyright Thy ( http://wonderfl.net/user/Thy )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/lpwg
 */

// sorry for dirty code, and for the coments in portuguese
// learning 3D ^^

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	
	/**
	 * ...
	 * @author Thi
	 */
	public class Main extends Sprite 
	{
		
		// var dos pontos
		private var num:uint = 1000
		private var pontos:Vector.<Ponto>
		
		// perspectiva
		private var perspectiva:Number = 3000
		private var focal:Number // temp
		
		// var da câmera
		private var cam:Cam
		private var w:Number = stage.stageWidth >> 1
		private var h:Number = stage.stageHeight >> 1
		
		// texto e seu desenho
		private var texto:String = "Thi"
		private var T:TextField
		private var format:TextFormat
		private var TDATA:BitmapData // onde será guardado o desenho do texto
		private var tw:Number // a largura do desenho do texto
		private var th:Number // a altura do desenho do texto
		
		// screen
		private var D:BitmapData, screen:Bitmap
		private var col:ColorTransform, rect:Rectangle
		
		// temp uint
		private var i:uint
		// temp ponto
		private var p:Ponto
		// temp posições
		private var X:Number, Y:Number, Z:Number
		private var X2:Number, Y2:Number, Z2:Number
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// arruma coisas do texto e seu desenho
			initText()
			
			// arruma a câmera
			cam = new Cam()
			cam.cx = w
			cam.cy = h
			
			// cria pontos
			initPontos()
			
			// init screen
			D = new BitmapData(w<<1, h<<1, false, 0xFFFFFF)
			screen = new Bitmap(D, "auto", true)
			stage.addChild(screen)
			//
			col = new ColorTransform(.9, .9, .9)
			rect = D.rect
			
			// init bars
			initBars()
			
			// listeners
			stage.addEventListener(KeyboardEvent.KEY_DOWN, down)
			stage.addEventListener(Event.ENTER_FRAME, ef)
			
		}
		
		private function initText():void
		{
			T = new TextField()
			format = new TextFormat("Arial", 100)
			T.defaultTextFormat = format
			T.autoSize = TextFieldAutoSize.LEFT
			T.text = texto
			tw = T.width
			th = T.height
			stage.addChild(T)
			TDATA = new BitmapData(tw, th, false, 0xFFFFFF)
			TDATA.draw(T)
			// lixo
			stage.removeChild(T)
			format = null
			T = null
		}
		
		private function initPontos():void
		{
			pontos = new Vector.<Ponto>(num)
			
			p = new Ponto()
			//while ( TDATA.getPixel ((X = Math.random()*tw), (Y = Math.random()*th)) != 0)
			//{}
			p.x = 0
			p.y = 0
			p.z = 0
			pontos[0] = p
			
			i = 0
			while (++i < num)
			{
				p = new Ponto()
				while ( TDATA.getPixel ((X = Math.random()*tw), (Y = Math.random()*th)) != 0)
				{}
				p.x = X - (tw>>1)
				p.y = Y - (th>>1)
				p.z = Math.random() * 50 + 50
				pontos[i] = p
				pontos[i - 1].next = p
			}
		}
		
		private function down(e:KeyboardEvent):void
		{
			if (e.keyCode == 37)
			{
				// esquerda
				cam.lado-= 1
			} else if (e.keyCode == 39)
			{
				// direta
				cam.lado += 1
			}
			if (e.keyCode == 38)
			{
				// cima
				cam.frente += 1
				
			} else if (e.keyCode == 40)
			{
				// baixo
				cam.frente -= 1
			}
		}
		private var pitch:Sprite = new Sprite()
		private var yaw:Sprite = new Sprite()
		private var roll:Sprite = new Sprite()
		
		private function initBars():void
		{
			w = w << 1
			h = h << 1
			
			with (pitch.graphics)
			{
				lineStyle(1, 0xFF0000)
				beginFill(0xFFFFFF)
				drawRect(0,0,90, 10)
			}
			stage.addChild(pitch)
			
			with (yaw.graphics)
			{
				lineStyle(1, 0x00FF00)
				beginFill(0xFFFFFF)
				drawRect(0,0,10, 90)
			}
			stage.addChild(yaw)
			
			with (roll.graphics)
			{
				lineStyle(1, 0x0000FF)
				beginFill(0xFFFFFF)
				drawRect(0,0,10, 90)
			}
			stage.addChild(roll)
			
			pitch.x = 10
			pitch.y = h- 10
			yaw.x = w - 10
			
			w = w >> 1
			h = h >> 1
			
			pitch.addEventListener(MouseEvent.MOUSE_DOWN, bd)
			yaw.addEventListener(MouseEvent.MOUSE_DOWN, bd)
			roll.addEventListener(MouseEvent.MOUSE_DOWN, bd)
			
			stage.addEventListener(MouseEvent.MOUSE_UP, mu)
			
			stage.addEventListener(MouseEvent.MOUSE_MOVE, bm)
			
		}
		
		private var mx:Number, my:Number
		private var quem:Number = 0
		
		private function bd(e:MouseEvent):void
		{
			if (e.target == pitch)
			{
				mx = mouseX
				quem = 1
			} else if (e.target == yaw)
			{
				mx = mouseY
				quem = 2
			} else if (e.target == roll)
			{
				mx = mouseY
				quem = 3
			}
		}
		
		private function mu(e:MouseEvent = null):void
		{
			quem = 0
		}
		
		private var d:Number = 0
		
		private function bm(e:MouseEvent):void
		{
			
			if (quem == 1)
			{
				d = mouseX - mx
				mx = mouseX
				pitch.x += d
				cam.pitch = Math.PI*2 * mouseX / (w<<1) 
			} else if (quem == 2)
			{
				d = mouseY - mx
				mx = mouseY
				yaw.y += d
				cam.yaw = Math.PI * 2 * mouseY / (h << 1) 
			} else if (quem == 3)
			{
				d = mouseY - mx
				mx = mouseY
				roll.y += d
				cam.roll = Math.PI * 2 * mouseY / (h << 1) 
			}
			
		}
		
		private function ef(e:Event = null):void
		{
			D.lock()
			render()
			filtro()
			D.unlock()
		}
		
		
		// var pras velocidades x, y, z da câmera
		private var vx:Number, vy:Number, vz:Number
		private function andarCam():void
		{
			
		}
		
		
		private function render():void
		{
			p = pontos[0]
			
			// distãncia do ponto com a câmera
			X = p.x - cam.x
			Y = p.y - cam.y
			Z = p.z - cam.z
			// posição certa de um ponto 3D numa tela 2D
			// eixo x
			X2 = X
			Y2 = Y
			Z2 = Z
			Y = Math.cos(cam.pitch) * Y2 - Math.sin (cam.pitch) * Z2
			Z = Math.sin(cam.pitch) * Y2 + Math.cos (cam.pitch) * Z2
			// eixo y
			X2 = X
			Y2 = Y
			Z2 = Z
			Z = Math.cos(cam.yaw) * Z2 - Math.sin (cam.yaw) * X2
			X = Math.sin(cam.yaw) * Z2 + Math.cos (cam.yaw) * X2
			// eixo z
			X2 = X
			Y2 = Y
			Z2 = Z
			X = Math.cos(cam.roll) * X2 - Math.sin (cam.roll) * Y2
			Y = Math.sin(cam.roll) * X2 + Math.cos (cam.roll) * Y2
			//
			focal = perspectiva / (perspectiva + Z)
			X *= focal
			Y *= focal
			//
			D.setPixel(X + cam.cx, Y + cam.cy, 0xFF0000)
			
			while ( (p = p.next) != null)
			{
				// distãncia do ponto com a câmera
				X = p.x - cam.x
				Y = p.y - cam.y
				Z = p.z - cam.z
				// posição certa de um ponto 3D numa tela 2D
				// eixo x
				X2 = X
				Y2 = Y
				Z2 = Z
				Y = Math.cos(cam.pitch) * Y2 - Math.sin (cam.pitch) * Z2
				Z = Math.sin(cam.pitch) * Y2 + Math.cos (cam.pitch) * Z2
				// eixo y
				X2 = X
				Y2 = Y
				Z2 = Z
				Z = Math.cos(cam.yaw) * Z2 - Math.sin (cam.yaw) * X2
				X = Math.sin(cam.yaw) * Z2 + Math.cos (cam.yaw) * X2
				// eixo z
				X2 = X
				Y2 = Y
				Z2 = Z
				X = Math.cos(cam.roll) * X2 - Math.sin (cam.roll) * Y2
				Y = Math.sin(cam.roll) * X2 + Math.cos (cam.roll) * Y2
				//
				focal = perspectiva / (perspectiva + Z)
				X *= focal
				Y *= focal
				//
				D.setPixel(X + cam.cx, Y + cam.cy, 0xFFFFFF)
				
				
			}
			
		}
		
		
		
		private function filtro():void
		{
			D.colorTransform(rect, col)
		}
		
		
		
		
		
	}
}


//package  
//{
	/**
	 * ...
	 * @author Thi
	 */
	/*public*/ class Cam
	{
		// centro da câmera, no espeço
		public var cx:Number, cy:Number
		// posição da camera num espaço 3D
		public var x:Number, y:Number, z:Number;
		
		// velocidades (tem à ver com as setas)
		public var frente:Number = 0, lado:Number = 0
		
		// rotações da câmera
		public var pitch:Number // valor do ângulo na vertical ('empinado') {eixo x}
		public var yaw:Number // valor do ângulo da horizonal ('curva de carro') {eixo y}
		public var roll:Number // valor do ângulo de rotação ('passar por fenda') {eixo z}
		
		
		public function Cam(x:Number = 0, y:Number = 0, z:Number = 0, yaw:Number = 0, pitch:Number = 0, roll:Number = 0) 
		{
			this.x = x;
			this.y = y;
			this.z = z;
			this.yaw = yaw;
			this.pitch = pitch;
			this.roll = roll;
		}
		
	}

//}

//package  
//{
	/**
	 * ...
	 * @author Thi
	 */
	/*public*/ class Ponto
	{
		// posição do ponto num espaço 3D
		public var x:Number, y:Number, z:Number
		// próxima partícula, no loop
		public var next:Ponto
		
		public function Ponto(x:Number = 0, y:Number = 0, z:Number = 0) 
		{
			this.x = x
			this.y = y
			this.z = z
		}
		
	}

//}