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

Gödel, Escher, Bach

Get Adobe Flash player
by yuuganisakase 19 Dec 2009
/**
 * Copyright yuuganisakase ( http://wonderfl.net/user/yuuganisakase )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/b0QQ
 */

package
{
	import fl.motion.easing.Cubic;
	import flash.display.*
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;

	import org.papervision3d.core.proto.DisplayObjectContainer3D;
	import org.papervision3d.core.proto.LightObject3D;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;

	import org.papervision3d.materials.shaders.FlatShader;

	import org.papervision3d.materials.shaders.ShadedMaterial;
	import org.papervision3d.materials.special.CompositeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;

	import org.papervision3d.objects.parsers.DAE;

	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
	import flash.filters.BlurFilter;
	import org.papervision3d.materials.MovieMaterial;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.view.layer.util.ViewportLayerSortMode;
	import com.flashdynamix.motion.Tweensy;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.events.FileLoadEvent;
        import flash.system.Security;

	[SWF(width=465, height=465, frameRate=12, backgroundColor=0x000000)]
	public class ShadowLetters extends BasicView
	{
		private const ShadowBlend:String = BlendMode.MULTIPLY;
		private const ShadowAlpha:Number = 0.8;
		private const ShadowBlur:BlurFilter = new BlurFilter(4, 4, 2);
		
		public var shadowCaster1:ShadowCaster = new ShadowCaster("shadow", 0, ShadowBlend, ShadowAlpha, [ShadowBlur]);
		public var shadowCaster2:ShadowCaster = new ShadowCaster("shadow2", 0, ShadowBlend, ShadowAlpha, [ShadowBlur]);
		public var shadowCaster3:ShadowCaster = new ShadowCaster("shadow3", 0, ShadowBlend, ShadowAlpha, [ShadowBlur]);

		private var casterArray:Array = [shadowCaster1, shadowCaster2, shadowCaster3];
		
		private var movieMaterial:MovieMaterial;
		
		private var plane1:Plane;
		private var plane2:Plane;
		private var plane3:Plane;
		private var cameraTarget:DisplayObject3D;
		
		private var light1:PointLight3D;
		private var sun:Sphere = new Sphere(new ColorMaterial(0xccbbaa,0.6),16, 4, 4);
		
		private var clickCount:int = 2;		
		
		private var text1:DAE = new DAE();// = new DAE("untitled.dae");
		
		private var loader:Loader;
		private var loader2:Loader
		
		private var shadowTarget:DisplayObject3D;
		private var mouseOn:Boolean = true;
		
		
		public function ShadowLetters(viewportWidth:Number = 465, viewportHeight:Number = 465, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
		{
                        Wonderfl.capture_delay( 9);
			super(viewportWidth, viewportHeight, scaleToStage, interactive, cameraType);
			addEventListener(Event.ADDED_TO_STAGE, onInit);
			
		}
		
		private function onInit(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onInit);
			viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
			viewport.containerSprite.filters = [new BlurFilter(2, 2, 1)];
			camera.x = -1042;
			camera.y = 1200;
			camera.z = -762;
			
			cameraTarget = new DisplayObject3D();
			cameraTarget.x = 300;
			cameraTarget.y = 620;
			cameraTarget.z =  300;
			
			for each( var c:ShadowCaster in casterArray) {
				c.setType(ShadowCaster.DIRECTIONAL);
			}
						
			Security.loadPolicyFile("http://lucasclaus.sakura.ne.jp/crossdomain.xml"); 
			var context:LoaderContext = new LoaderContext(true);
			loader = new Loader();
			
			loader.load(new URLRequest("http://lucasclaus.sakura.ne.jp/swf/shadowLetters/back.png"),context);
			//loader.load(new URLRequest("back.png"),context);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBackLoad);
			
			loader2 = new Loader();
			loader2.load(new URLRequest("http://lucasclaus.sakura.ne.jp/swf/shadowLetters/back3.png"),context);
			loader2.contentLoaderInfo.addEventListener(Event.COMPLETE, onTexLoad);
			
			light1 = new PointLight3D(true);

			camera.target = cameraTarget;			
		}
		
		private function onTexLoad(e:Event):void
		{
			var bd:BitmapData = new BitmapData(1024, 1024);
			bd.draw(loader2,null, new ColorTransform());
			var sh:ShadedMaterial = new ShadedMaterial(new BitmapMaterial(bd), new FlatShader(light1, 0xccbbaa, 0x221100),0);
			

			var mats:MaterialsList = new MaterialsList();
			mats.addMaterial(sh, "back3_png");
			//mats.addMaterial(shadow,"mat22");
			text1.load("http://lucasclaus.sakura.ne.jp/swf/shadowLetters/gebTest1.dae",mats);
			text1.addEventListener(FileLoadEvent.LOAD_COMPLETE, onLoad);

		}
		private function onBackLoad(e:Event):void
		{
			var bp:BitmapData = new BitmapData(300, 300);
			bp.draw(loader,null, new ColorTransform(1,1,1,1,-90,-110,-130));
			
			var sp1:Sprite = new Sprite();
			sp1.graphics.beginBitmapFill(bp);
			sp1.graphics.drawRect(0, 0, 300, 300);
			
			
			var sp2:Sprite = new Sprite();
			sp2.graphics.beginBitmapFill(bp);
			sp2.graphics.drawRect(0, 0, 300, 300);

			var sp3:Sprite = new Sprite();
			sp3.graphics.beginBitmapFill(bp);
			sp3.graphics.drawRect(0, 0, 300, 300);

			var mm:MovieMaterial = new MovieMaterial(sp1 , false, true, true);
			var mm2:MovieMaterial = new MovieMaterial(sp2,false, true, true);
			var mm3:MovieMaterial = new MovieMaterial(sp3 ,false, true, true);

			var pSize:int = 2000;

			plane1 = new Plane(mm, pSize, pSize, 10, 10);
			plane2 = new Plane(mm2, pSize, pSize, 1, 1);
			plane3 = new Plane(mm3, pSize, pSize, 1, 1);
			scene.addChild(plane1);
			scene.addChild(plane2);
			scene.addChild(plane3);
			
			plane1.pitch(90);
			plane2.yaw(90);
			plane3.roll(90);			

			plane3.y = pSize/2;
			plane3.z = pSize/2;
			plane2.x = pSize/2;
			plane2.y = pSize / 2;
			viewport.getChildLayer(plane1).layerIndex = -100;
			viewport.getChildLayer(plane2).layerIndex = -100;
			viewport.getChildLayer(plane3).layerIndex = -100;

		}
		private function onLoad(e:FileLoadEvent):void 
		{			
			text1.removeEventListener(FileLoadEvent.LOAD_COMPLETE, onLoad);

			stage.addEventListener(MouseEvent.CLICK, onClick);
			stage.addEventListener(Event.ENTER_FRAME, tick);
			stage.addEventListener( Event.MOUSE_LEAVE, function():void { mouseOn = false;} );
			stage.addEventListener(MouseEvent.MOUSE_MOVE, function():void { mouseOn = true; } );
			scene.addChild(text1);
			text1.rotationX = -90;
			text1.rotationY = 90;
			text1.y = 700;
			text1.z = 100;
			text1.x = -100;
			text1.scale =  263;
			shadowTarget = text1;//.rootNode;
			viewport.getChildLayer(text1).layerIndex = 11;
			viewport.getChildLayer(sun).filters = [new GlowFilter(0xE8F471, 0.7, 16,16,8,2)];
			viewport.getChildLayer(sun).blendMode = BlendMode.ADD;

			scene.addChild(sun);
			viewport.getChildLayer(sun).layerIndex = 200;
			
			light1.x = 1400;
			light1.y = 900;
			light1.z = 1500;
			scene.addChild(light1);

			Tweensy.fromTo(light1, { x:1500, y:1000, z:1500 }, { x: -800, y:1120, z: -600 }, 4, null);

		}
		private function onClick(e:MouseEvent):void
		{
			var dur:Number = 2.5;
			clickCount += 1;
			if (clickCount % 3 == 0) {
				Tweensy.to(light1, { x:-188, y:990, z:-700 }, dur);
			}else if(clickCount % 3 == 1) {
				Tweensy.to(light1, { x:-700, y:960, z:-100 }, dur);
			}else {
				Tweensy.to(light1, { x:-205, y:1470, z:-105 }, dur);
			}
		}

		public function tick(e:Event):void
		{
			singleRender();

			var cull:Boolean = true;
			shadowCaster1.castModel(shadowTarget, light1, plane1, true,cull);
			shadowCaster2.castModel(shadowTarget, light1, plane2, true,cull);
			shadowCaster3.castModel(shadowTarget, light1, plane3, true,cull);
			sun.copyPosition(light1);
			
			if(mouseOn) mouseMove();
		}
		public function mouseMove():void
		{
			var mouseMargin:int = 50;
			if (mouseX < mouseMargin && camera.position.x > -1200) {
				
				camera.moveLeft(40);
			}else if (mouseX > 465 - mouseMargin && camera.position.x < -500) {
				
				camera.moveRight(40);
			}
			
		}
		
	}

}



//
// ShadowCaster class
// http://blog.zupko.info/?p=146
//

	import flash.display.Sprite;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	import org.papervision3d.core.geom.TriangleMesh3D;
	import org.papervision3d.core.geom.renderables.Triangle3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.math.BoundingSphere;
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.Plane3D;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.MovieMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	
	class ShadowCaster
	{
		private var vertexRefs:Dictionary;
		private var numberRefs:Dictionary;
		private var lightRay:Number3D = new Number3D()
		private var p3d:Plane3D = new Plane3D();
		public var color:uint = 0;
		public var alpha:Number = 0;
		public var blend:String = "";
		public var filters:Array;
		public var uid:String;
		private var _type:String = "point";
		private var dir:Number3D;
		private var planeBounds:Dictionary;
		private var targetBounds:Dictionary;
		private var models:Dictionary;
		
		
		public static var DIRECTIONAL:String = "dir";
		public static var SPOTLIGHT:String = "spot";
		
		
		public function ShadowCaster(uid:String, color:uint = 0, blend:String = "multiply", alpha:Number = 1, filters:Array=null)
		{
			this.uid = uid;
			this.color = color;
			this.alpha = alpha;
			this.blend = blend;
			this.filters = filters ? filters : [new BlurFilter()];
			numberRefs = new Dictionary(true);
			targetBounds = new Dictionary(true);
			planeBounds = new Dictionary(true);
			models = new Dictionary(true);
		}

		public function castModel(model:DisplayObject3D, light:PointLight3D, plane:Plane, faces:Boolean = true, cull:Boolean = false):void{
			
			var ar:Array;
			if(models[model])
			{
				ar = models[model];
			}else{
				ar = new Array();
				getChildMesh(model, ar);
				models[model] = ar;
			}
			
			var reset:Boolean = true;
			for each(var t:TriangleMesh3D in ar) {
			
				if(faces)
					castFaces(light, t, plane, cull, reset);
				else
					castBoundingSphere(light, t, plane, 0.75, reset);
				reset = false;
			}
		
		}
		
		private function getChildMesh(do3d:DisplayObject3D, ar:Array):void
		{
			 if(do3d)
			{
				if(do3d is TriangleMesh3D)
				{
					ar.push(do3d);
				}

				for each(var d:DisplayObject3D in do3d.children)
				{
					getChildMesh(d, ar);
				}
			}		
		}

		public function setType(type:String="point"):void{
			_type = type;
		}
		public function getType():String{
			return _type;
		}
		
		public function castBoundingSphere(light:PointLight3D, target:TriangleMesh3D, plane:Plane, scaleRadius:Number=0.8, clear:Boolean = true):void{
			var planeVertices:Array = plane.geometry.vertices;
			
			//convert to target space?
			var world:Matrix3D = plane.world;
			var inv:Matrix3D = Matrix3D.inverse(plane.transform);
			
			var lp:Number3D = new Number3D(light.x, light.y, light.z);
			Matrix3D.multiplyVector(inv, lp);
			
			p3d.setNormalAndPoint(plane.geometry.faces[0].faceNormal, new Number3D());
			
			var b:BoundingSphere = target.geometry.boundingSphere;
			
			
			var bounds:Object = planeBounds[plane];
			if(!bounds){
				bounds = plane.boundingBox();
				planeBounds[plane] = bounds;
			}
				
			
			var tbounds:Object = targetBounds[target];
			if(!tbounds){
				tbounds = target.boundingBox();
				targetBounds[target] = tbounds;
			}
				
			
			var planeMovie:Sprite = Sprite(MovieMaterial(plane.material).movie);
			var movieSize:Point = new Point(planeMovie.width, planeMovie.height);
		
			var castClip:Sprite = getCastClip(plane);
				castClip.blendMode = this.blend;
				castClip.filters = this.filters;
				castClip.alpha = this.alpha;
			
			if(clear)
				castClip.graphics.clear();
						
			vertexRefs = new Dictionary(true);
			
			var tlp:Number3D = new Number3D(light.x, light.y, light.z);
			Matrix3D.multiplyVector(Matrix3D.inverse(target.world), tlp);
			
			var center:Number3D = new Number3D(tbounds.min.x+tbounds.size.x*0.5, tbounds.min.y+tbounds.size.y*0.5, tbounds.min.z+tbounds.size.z*0.5);
			
			
			var dif:Number3D = Number3D.sub(lp, center);
			dif.normalize();
			
			var other:Number3D = new Number3D();
			other.x = -dif.y;
			other.y = dif.x;
			other.z = 0;
			
			other.normalize();
			
			
			var cross:Number3D = Number3D.cross(new Number3D(plane.transform.n12, plane.transform.n22, plane.transform.n32), p3d.normal);
			cross.normalize();
			
			//cross = new Number3D(-dif.y, dif.x, 0);
			//cross.normalize();
			
			cross.multiplyEq(b.radius*scaleRadius);
			
			
			if(_type == DIRECTIONAL){
				var oPos:Number3D = new Number3D(target.x, target.y, target.z);
				Matrix3D.multiplyVector(target.world, oPos);
				Matrix3D.multiplyVector(inv, oPos);
				dir = new Number3D(oPos.x-lp.x, oPos.y-lp.y, oPos.z-lp.z);
			}
			
			//numberRefs = new Dictionary(true);
			var pos:Number3D;
			var c2d:Point;
			var r2d:Point;
		
			//_type = SPOTLIGHT;
			pos = projectVertex(new Vertex3D(center.x, center.y, center.z), lp, inv, target.world);
			c2d = get2dPoint(pos, bounds.min, bounds.size, movieSize);
			
			pos = projectVertex(new Vertex3D(center.x+cross.x, center.y+cross.y, center.z+cross.z), lp, inv, target.world);
			r2d = get2dPoint(pos, bounds.min, bounds.size, movieSize);
			
			var dx:Number = r2d.x-c2d.x;
			var dy:Number = r2d.y-c2d.y;
			var rad:Number = Math.sqrt(dx*dx+dy*dy);
			
			castClip.graphics.beginFill(color);
			castClip.graphics.moveTo(c2d.x, c2d.y);
			castClip.graphics.drawCircle(c2d.x, c2d.y, rad);
			castClip.graphics.endFill();

			
		}
		
		public function getCastClip(plane:Plane):Sprite{
			
			var planeMovie:Sprite = Sprite(MovieMaterial(plane.material).movie);
			var movieSize:Point = new Point(planeMovie.width, planeMovie.height);
			var castClip:Sprite;// = new Sprite();
			if(planeMovie.getChildByName("castClip"+uid))
				return Sprite(planeMovie.getChildByName("castClip"+uid));
			else{
				castClip = new Sprite();
				castClip.name = "castClip"+uid;
				castClip.scrollRect = new Rectangle(0, 0, movieSize.x, movieSize.y);
				//castClip.alpha = 0.4;
				planeMovie.addChild(castClip);
				return castClip;
			}
		}
		
		public function castFaces(light:PointLight3D, target:TriangleMesh3D, plane:Plane, cull:Boolean=false, clear:Boolean = true):void{
			
			
			var planeVertices:Array = plane.geometry.vertices;
		
			//convert to target space?
			var world:Matrix3D = plane.world;
			var inv:Matrix3D = Matrix3D.inverse(plane.transform);
			
			var lp:Number3D = new Number3D(light.x, light.y, light.z);
			Matrix3D.multiplyVector(inv, lp);
			
			var tlp:Number3D;
			if(cull){
				tlp = new Number3D(light.x, light.y, light.z);
				Matrix3D.multiplyVector(Matrix3D.inverse(target.world), tlp);
			}
			//Matrix3D.multiplyVector(Matrix3D.inverse(target.transform), tlp);
			
			//p3d.setThreePoints(planeVertices[0].getPosition(), planeVertices[1].getPosition(), planeVertices[2].getPosition());
			p3d.setNormalAndPoint(plane.geometry.faces[0].faceNormal, new Number3D());
			
			if(_type == DIRECTIONAL){
				var oPos:Number3D = new Number3D(target.x, target.y, target.z);
				Matrix3D.multiplyVector(target.world, oPos);
				Matrix3D.multiplyVector(inv, oPos);
				dir = new Number3D(oPos.x-lp.x, oPos.y-lp.y, oPos.z-lp.z);
			}

			var bounds:Object = planeBounds[plane];
			if(!bounds){
				bounds = plane.boundingBox();
				planeBounds[plane] = bounds;
			}
			
			var castClip:Sprite = getCastClip(plane);
				castClip.blendMode = this.blend;
				castClip.filters = this.filters;
				castClip.alpha = this.alpha;
			
			
			var planeMovie:Sprite = Sprite(MovieMaterial(plane.material).movie);
			var movieSize:Point = new Point(planeMovie.width, planeMovie.height);
			
			if(clear)
				castClip.graphics.clear();
						
			vertexRefs = new Dictionary(true);
			//numberRefs = new Dictionary(true);
			var pos:Number3D;
			var p2d:Point;
			var s2d:Point;
			var hitVert:Number3D = new Number3D();
			
			for each(var t:Triangle3D in target.geometry.faces){
				
				if( cull){
					
					hitVert.x = t.v0.x;
					hitVert.y = t.v0.y;
					hitVert.z = t.v0.z;
					
					if(Number3D.dot(t.faceNormal, Number3D.sub(tlp, hitVert)) <= 0)
						continue;
				}
				
				castClip.graphics.beginFill(color);
				pos = projectVertex(t.v0, lp, inv, target.world);
				s2d = get2dPoint(pos, bounds.min, bounds.size, movieSize);
				castClip.graphics.moveTo(s2d.x, s2d.y);
				
				pos = projectVertex(t.v1, lp, inv, target.world);
				p2d = get2dPoint(pos, bounds.min, bounds.size, movieSize);
				castClip.graphics.lineTo(p2d.x, p2d.y);
				
				pos = projectVertex(t.v2, lp, inv, target.world);
				p2d = get2dPoint(pos, bounds.min, bounds.size, movieSize);
				castClip.graphics.lineTo(p2d.x, p2d.y);

				castClip.graphics.lineTo(s2d.x, s2d.y);
				
				castClip.graphics.endFill();
				
				
			}

		}
		
		public function invalidate():void{
			invalidateModels();
			invalidatePlanes();
		}
		
		public function invalidatePlanes():void{
			planeBounds = new Dictionary(true);
		}
		public function invalidateTargets():void{
			numberRefs = new Dictionary(true);
			targetBounds = new Dictionary(true);
		}
		
		public function invalidateModels():void{
			models = new Dictionary(true);
			invalidateTargets();
		}
		
		private function get2dPoint(pos3D:Number3D, min3D:Number3D, size3D:Number3D, movieSize:Point):Point{
			return new Point((pos3D.x-min3D.x)/size3D.x*movieSize.x, ((-pos3D.y-min3D.y)/size3D.y*movieSize.y));
		}
		
		private function projectVertex(v:Vertex3D, light:Number3D, invMat:Matrix3D, world:Matrix3D):Number3D{

			var pos:Number3D = vertexRefs[v];
			if(pos)
				return pos;
			
			var n:Number3D = numberRefs[v];
			
			if(!n){
				n = new Number3D(v.x, v.y, v.z);
				Matrix3D.multiplyVector(world, n);
				Matrix3D.multiplyVector(invMat, n);
				numberRefs[v] = n;
			}
			
			
			if(_type == SPOTLIGHT){
			
				lightRay.x = light.x;
				lightRay.y = light.y;
				lightRay.z = light.z;
				
			}else{
				lightRay.x = n.x-dir.x;
				lightRay.y = n.y-dir.y;
				lightRay.z = n.z-dir.z;
			}
			
			pos = p3d.getIntersectionLineNumbers(lightRay, n);
			vertexRefs[v] = pos;
			return pos;
		}

	}