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

PV3D StereoScene + Rainbow + clockmaker's Ribon Road

Forked by forresto from clockmaker's "[PV3D] Ribon Road" 
*  for cross-eye Stereo 3D viewing.  Cross your eyes and ride!

=====================================================
Papervison3Dを利用したリボン表現
*
* Tweenerを使って作成したベジェ曲線に
* Planeを位置と角度を調整して並べています。
* 強引なやり方なので、いい方法があったら教えてください!
* 
* @author Yasu (clockmaker.jp)

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

/*
 *  Forked by forresto from clockmaker's "[PV3D] Ribon Road" 
 *  for cross-eye Stereo 3D viewing.  Cross your eyes and ride!
 */

/*=====================================================*//**
* Papervison3Dを利用したリボン表現
*
* Tweenerを使って作成したベジェ曲線に
* Planeを位置と角度を調整して並べています。
* 強引なやり方なので、いい方法があったら教えてください!
* 
* @author Yasu (clockmaker.jp)
*//*======================================================*/
package
{
	import caurina.transitions.Tweener;
	import caurina.transitions.properties.CurveModifiers;
	
	import flash.display.*;
	import flash.events.*;
	
	import org.papervision3d.cameras.*;
	import org.papervision3d.core.geom.*;
	import org.papervision3d.core.geom.renderables.*;
	import org.papervision3d.core.proto.*;
	import org.papervision3d.lights.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.shadematerials.*;
	import org.papervision3d.materials.special.*;
	import org.papervision3d.materials.utils.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.view.*;
	
	[SWF(width="800", height="400", frameRate="60", backgroundColor="0xFFFFFF")]

	public class RibbonRoad3DCross extends Sprite
	{
		
		private var stereoScene:StereoScene;
		
                private var lineMaterial	        :LineMaterial;
                private var _arrLines		        :Array 	= [];
                private var _objArray		        :Array 	= [];
                private var LINES_NUM		:int 	= 1
                private var MAX_RADIUS		:int	= 3000;
                private var POINT_NUM		:uint 	= 5
                private var VERTICES_NUM	:uint 	= 400
                private var CAMERA_POSITION	:uint 	= 3000;
                
        private var color:Rainbow = new Rainbow(Math.round(Math.random()*360), .75, .75);
		
		public function RibbonRoad3DCross()
		{
			super();
			stereoScene = new StereoScene(800, 400, 2, 250, true, false);
			addChild(stereoScene);
			CurveModifiers.init();
			init()
			addEventListener(Event.ENTER_FRAME, render);
		}

		private function init():void
		{
			// 3d
			for (var i:int = 0; i < LINES_NUM; i++)
			{
				_arrPlanes[i] = [];
			}
			
			// 2d
			for (i = 0; i < LINES_NUM; i++)
			{
				var newPos:Object = getRandomPos()
				var o:Object =
				{
					x 		: newPos.x,
					prevX 	: newPos.x,
					y 		: newPos.y,
					prevY 	: newPos.y,
					z 		: newPos.z,
					prevZ 	: newPos.z
				}

				_objArray.push(o)
				randomTween(getRandomData(o))
			}
		}

		private function randomTween(o:Object):void
		{
			Tweener.addTween(o,
			{ 
				x			:	o.x1,
				y			:	o.y1, 
				z			:	o.z1, 
				_bezier		:	o.bezier, 
				time		        :	o.time,
				transition	        :	"linear", 
				onComplete	:	function():void
				{
					randomTween(getRandomData(o));
				}
			});
		}
		
		private function getRandomData(o:Object):Object
		{
			o.time = (POINT_NUM * 0.5) + (POINT_NUM * .75);
			var newPos:Object = getRandomPos();
			o.x1 = newPos.x;
			o.y1 = newPos.y;
			o.z1 = newPos.z;
			o.bezier = [];
			for (var i:int = 0; i < POINT_NUM; i++)
			{
				var newBezierPos:Object = getRandomPos();
				o.bezier.push(
				{
					x : newBezierPos.x,
					y : newBezierPos.y,
					z : newBezierPos.z
				});
			}
			return o;
		}

		private function getRandomPos():Object
		{
			var angleY:Number = Math.random() * 2 * Math.PI;
			var angleXZ:Number = Math.random() * 2 * Math.PI;
			return {
				x : Math.cos(angleY) * Math.sin(angleXZ) * MAX_RADIUS,
				y : Math.sin(angleY) * Math.sin(angleXZ) * MAX_RADIUS,
				z : Math.cos(angleXZ) * MAX_RADIUS
			};
		}
		
		private var _arrPlanes:Array = []
		
		private function render(event:Event = null):void
		{
			for (var i:int = 0; i < LINES_NUM; i++)
			{
				var d1:DisplayObject3D = new DisplayObject3D()
				d1.x = _objArray[i].x
				d1.y = _objArray[i].y
				d1.z = _objArray[i].z
				var d2:DisplayObject3D = new DisplayObject3D()
				d2.x = _objArray[i].prevX
				d2.y = _objArray[i].prevY
				d2.z = _objArray[i].prevZ
				
				d1.lookAt(d2);
			
				// Planes
				var len:Number = Math.sqrt(
					(_objArray[i].x - _objArray[i].prevX) * (_objArray[i].x - _objArray[i].prevX)
					+ (_objArray[i].y - _objArray[i].prevY) * (_objArray[i].y - _objArray[i].prevY)
					+ (_objArray[i].z - _objArray[i].prevZ) * (_objArray[i].z - _objArray[i].prevZ)
				)
				
				var mat:MaterialObject3D = new WireframeMaterial(color.getNext())
				mat.doubleSided = true
				var o:DisplayObject3D = stereoScene.scene.addChild(new Plane(mat, 100, 100))

				o.copyTransform(d1.transform)
				o.pitch(90)
				
				_arrPlanes[i].push(o);
				
				if (_arrPlanes[i].length > 10)
				{
					var tmp:DisplayObject3D = _arrPlanes[i][0]
					
					var cameraTarget :DisplayObject3D = new DisplayObject3D();
					cameraTarget.copyTransform( tmp );
					cameraTarget.moveBackward(100);
					cameraTarget.moveUp(100);
					stereoScene.camera.copyTransform(cameraTarget)
					
					stereoScene.camera.lookAt(_arrPlanes[i][10])
					cameraTarget = null
				}
				
				if (_arrPlanes[i].length > VERTICES_NUM)
				{
					stereoScene.scene.removeChild(_arrPlanes[i].shift())
				}
				
				_objArray[i].prevX = _objArray[i].x;
				_objArray[i].prevY = _objArray[i].y;
				_objArray[i].prevZ = _objArray[i].z;
			}
			
			stereoScene.onRenderTick();
		}
	}	
}



class Rainbow
{
    private var _hue:Number; 
    private var _saturation:Number;
    private var _brightness:Number;

    public function Rainbow(hue:Number=0, saturation:Number=1, brightness:Number=1)
    {
        _hue = hue % 360;
        _saturation = saturation;
        _brightness = brightness;
    }

    public function getNext(hueshift:Number=1):uint
    {
        _hue = (_hue + hueshift) % 360;
        return HSBtoRGB(_hue, _saturation, _brightness);
    }
        
    public static function HSBtoRGB(hue:Number, saturation:Number, brightness:Number):uint
    {
        // Conversion taken from Foley, van Dam, et al
        var r:Number, g:Number, b:Number;
        if (saturation == 0)
        {
            r = g = b = brightness;
        }
        else
        {
            var h:Number = (hue % 360) / 60;
            var i:int = int(h);
            var f:Number = h - i;
            var p:Number = brightness * (1 - saturation);
            var q:Number = brightness * (1 - (saturation * f));
            var t:Number = brightness * (1 - (saturation * (1 - f)));
            switch (i) {
                case 0:
                    r = brightness;
                    g = t;
                    b = p;
                    break; 
                case 1:
                    r = q;                    
                    g = brightness;
                    b = p;
                    break; 
                case 2:
                    r = p;
                    g = brightness;
                    b = t; 
                    break;
                case 3:
                    r = p;
                    g = q;
                    b = brightness;
                    break; 
                case 4:
                    r = t;
                    g = p;
                    b = brightness; 
                    break;
                case 5: 
                    r = brightness;
                    g = p;
                    b = q;
                    break;
            }
        }
        r *= 255;
        g *= 255;
        b *= 255;
        return (r << 16 | g << 8 | b);
    }    
}








/*
 *  These following two classes are adopted from:
 *  http://codejockeyscorner.blogspot.com/2009/04/papervision3d-anaglyph-scene.html
 *  
 *  It will be easy to make the anaglyph again once I find some red/blue glasses.
 */

//package com.codejockey.anaglyph {
	//import flash.display.BlendMode;
	import flash.display.Sprite;
	//import flash.geom.ColorTransform;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.view.stats.StatsView;

	class StereoScene extends Sprite
	{
		private var _width:Number;
		private var _height:Number;
		private var _debug:Boolean = false;
		private var _crosseye:Boolean = true;
		
		private var leftViewport:Viewport3D;
		private var rightViewport:Viewport3D;
		
		public var scene:Scene3D;
		
		public var camera:StereoCamera;
		
		private var renderer:BasicRenderEngine;

		public const SPACING:int = 30;
		
		public function StereoScene(width:Number=800, height:Number=600, zoom:Number=1, focus:Number=250, crosseye:Boolean=true, debug:Boolean=false) {
			_width = width;
			_height = height;
			_crosseye = crosseye;
			_debug = debug;
			
			camera = new StereoCamera(zoom, focus);
			
			init3D();
			
			if (debug) {
				this.addChild(new StatsView(renderer));
			}
		}
		
		private function init3D():void {

			leftViewport = new Viewport3D(_width/2 - SPACING*1.5, _height - SPACING*2);
			//leftViewport.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0x00, 0xFF, 0xFF);
			this.addChild(leftViewport);
			
			rightViewport = new Viewport3D(_width/2 - SPACING*1.5, _height - SPACING*2);
			//rightViewport.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0xFF, 0x00, 0x00);
			//rightViewport.blendMode = BlendMode.MULTIPLY;
			this.addChild(rightViewport);

			leftViewport.y = SPACING;
			rightViewport.y = SPACING;
			if (_crosseye) {
				// crosseye viewing (focus between eyes and screen)
				rightViewport.x = _width/2 + SPACING/2; 
				leftViewport.x = SPACING;
			} else {
				// parallel viewing (focus beyond screen)
				leftViewport.x = _width/2 + SPACING/2;
				rightViewport.x = SPACING; 
			}
			
			leftViewport.containerSprite.cacheAsBitmap = false;
			rightViewport.containerSprite.cacheAsBitmap = false;

			scene = new Scene3D();
			
			camera.rotationX = 15;
			
			renderer = new BasicRenderEngine();
		}
		
		public function onRenderTick(event:Event = null):void {
			renderer.renderScene(scene, camera.leftCamera, leftViewport);
			renderer.renderScene(scene, camera.rightCamera, rightViewport);
		}
						
	}
//}

//package com.codejockey.anaglyph {
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.objects.DisplayObject3D;
	import flash.events.Event;
	import org.papervision3d.core.math.Number3D;

	class StereoCamera extends DisplayObject3D
	{
		public const EYE_DISTANCE:int = 24;
		
		public var leftCamera:Camera3D;
		public var rightCamera:Camera3D;
		
		public function StereoCamera(zoom:Number=1, focus:Number=250)
		{
			super();
			
			leftCamera = new Camera3D();
			leftCamera.moveLeft(this.EYE_DISTANCE);
			
			rightCamera = new Camera3D();
			rightCamera.moveRight(this.EYE_DISTANCE);
			
			leftCamera.zoom = rightCamera.zoom = zoom;
			leftCamera.focus = rightCamera.focus = focus;
		}
		
		public override function moveLeft(distance:Number):void {
			leftCamera.moveLeft(distance);
			rightCamera.moveLeft(distance);
			
			super.moveLeft(distance);
		}
		
		public override function moveRight(distance:Number):void {
			leftCamera.moveRight(distance);
			rightCamera.moveRight(distance);
			
			super.moveRight(distance);
		}
		
		public override function moveUp(distance:Number):void {
			leftCamera.moveUp(distance);
			rightCamera.moveUp(distance);
			
			super.moveUp(distance);
		}
		
		public override function moveDown(distance:Number):void {
			leftCamera.moveDown(distance);
			rightCamera.moveDown(distance);
			
			super.moveDown(distance);
		}

		public override function copyTransform(reference:*):void {
			leftCamera.copyTransform(reference);
			rightCamera.copyTransform(reference);

			leftCamera.moveLeft(this.EYE_DISTANCE);
			rightCamera.moveRight(this.EYE_DISTANCE);
			
			super.copyTransform(reference);
		}

		public override function lookAt(targetObject:DisplayObject3D, upAxis:Number3D=null):void {
			leftCamera.lookAt(targetObject, upAxis);
			rightCamera.lookAt(targetObject, upAxis);
			
			super.lookAt(targetObject, upAxis);
		}

	}
//}