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

不完全照明

papervision3dのReflectionViewを発見した。
http://sebleedelisle.com/2008/07/real-reflections-in-papervision3d/
このサイトを見て、このCubeに照明をあてたらどうなるだろうと、好奇心からこのプログラムを作ってみました。
でも、結論から言って、このプログラム不完全(Z軸がおかしい)です。私のようなど素人がpapervision3d
を使用し、照明を移動させること自体が無謀だったのかも!
もし、こんどこのようなプログラムを作ろうと思った場合、 papervision3dの照明機能(存在不明)
を使用するか、いっそのことpapervision3dは使用しないかも(汗)
ちなみに、照明は、各面(Cube)の法線を求め、色を変化させて実現しています。
「ActionScript3.0	アニメーション Chapter17」に記載されているクラスを借用しています。

「つぶやき」
(PointLight3Dでは、明暗の色限定されちゃうのかな?)
(Cubeはscene.removeChildして再度scene.addChildが一番簡単な色を変更する処理
なのかな?)
(Cubeの各頂点は、z軸が手前プラスの左手座標になっているようみ見えるけど、私の勘違い?)
Get Adobe Flash player
by hankuro 01 Oct 2009
    Embed
/**
 * Copyright hankuro ( http://wonderfl.net/user/hankuro )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ej0q
 */

package {

	import flash.events.Event;
	import flash.display.*;
	import flash.text.*;
 
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.effects.view.ReflectionView;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.lights.PointLight3D;

 
	[SWF (width = "540", height = "480", backgroundColor = "0x000000", frameRate = "30")]
	/*
	 * papervision3dのReflectionViewを発見した。
	 * http://sebleedelisle.com/2008/07/real-reflections-in-papervision3d/
	 * このサイトを見て、このCubeに照明をあてたらどうなるだろうと、好奇心からこのプログラムを作ってみました。
	 * でも、結論から言って、このプログラム不完全(Z軸がおかしい)です。私のようなど素人がpapervision3d
	 * を使用し、照明を移動させること自体が無謀だったのかも!
	 * もし、こんどこのようなプログラムを作ろうと思った場合、 papervision3dの照明機能(存在不明)
	 * を使用するか、いっそのことpapervision3dは使用しないかも(汗)
	 * ちなみに、照明は、各面(Cube)の法線を求め、色を変化させて実現しています。
	 * 「ActionScript3.0	アニメーション Chapter17」に記載されているクラスを借用しています。
	 * 
	 * 「つぶやき」
	 * (PointLight3Dでは、明暗の色限定されちゃうのかな?)
	 * (Cubeはscene.removeChildして再度scene.addChildが一番簡単な色を変更する処理
	 * なのかな?)
	 * (Cubeの各頂点は、z軸が手前プラスの左手座標になっているようみ見えるけど、私の勘違い?)
	 */
 	public class Main extends ReflectionView
	{
 
		private var cube : Cube;
		private var light:Light = new Light();
		private var sphere:Sphere;
		
		private var ml : MaterialsList;
		private var save_point3D:Array = new Array(8);
		private var point_const:Array = [[[5 , 7 , 1],[5 , 3 , 1]],
										 [[4 , 6 , 0],[4 , 2 , 0]],
										 [[3 , 1 , 0],[3 , 2 , 0]],
										 [[5 , 7 , 6],[5 , 4 , 6]],
										 [[1 , 7 , 6],[1 , 0 , 6]],
										 [[5 , 3 , 2],[5 , 4 , 2]]];
		
		private var cube_const:Array = ["top" , "bottom" , "front" ,"back", "right" ,  "left"];
		private var point3D:Array;

		private var yaw:Number = 0;
		
		public var s_x:Number = 0;
		public var s_y:Number = 0;
		public var s_z:Number = 0;
		public var angle:Number = 0;
		public var light_3D:PointLight3D;
		
		public var slider_x:SimpleSlider = new SimpleSlider(200,-200,200);
		public var slider_y:SimpleSlider = new SimpleSlider(0,150,0);
		public var slider_z:SimpleSlider = new SimpleSlider(100,-100,100);
		
		public var label:TextField = new TextField();
		public var format:TextFormat = new TextFormat();
		public var label2:TextField = new TextField();
		public var format2:TextFormat = new TextFormat();
 
		public function Main()
		{
 
			super(540,480,false, false);
			
			slider_x.x = 48;
			slider_x.y = 200;
			slider_y.x = 80;
			slider_y.y = 200;
			slider_z.x = 112;
			slider_z.y = 200;
			label.text = "light position\nX       Y       Z";
			format.color = 0xFFFFFF;
			label.setTextFormat(format);
			label.x = 50;
			label.y = 170;
			label2.x = 50;
			label2.y = 300;
			addChild(label);
			addChild(label2);
			addChild(slider_x);
			addChild(slider_y);
			addChild(slider_z);
			
 			//the height of the reflection plane
			surfaceHeight = -50;
 
			initCube();
 
			camera.z = -400;
			
			addEventListener(Event.ENTER_FRAME, enterFrame);
 
		}
 
 
		public function initCube() : void
		{
 			// create a materials list for the cube.
			ml = new MaterialsList();
			ml.addMaterial(new ColorMaterial(0xFF0000), "all");
 
			cube = new Cube(ml,100,100,100);
			// add the cube to the scene
			scene.addChild(cube);
			
			sphere = new Sphere(new ColorMaterial(0xFFFF00), 15, 24, 24)
			scene.addChild(sphere);
			
//			light_3D = new PointLight3D(true);
//			scene.addChild(light_3D);
		}
 
		public function enterFrame(e:Event) : void
		{			
			scene.removeChild(cube);
 			cube = new Cube(ml,100,100,100);
 			scene.addChild(cube);	
			
			light.set_Light_point(slider_x.value*-1,slider_y.value,slider_z.value*-1);
			sphere.x = slider_x.value;
			sphere.y = slider_y.value;
			sphere.z = slider_z.value;
			
//			scene.removeChild(light_3D);
//			light_3D = new PointLight3D(true);
//			light_3D.x = slider_x.value;
//			light_3D.y = slider_y.value;
//			light_3D.z = slider_z.value;
//			scene.addChild(light_3D);			
			
			label2.text = "x = "+String(int(slider_x.value))+"\ny = "+String(int(slider_y.value))+"\nz = "+String(int(slider_z.value));
			format2.color = 0xFFFFFF;
			label2.setTextFormat(format2);
			
			yaw += (270-mouseX)*0.05;
			cube.yaw(yaw);
//			cube.y=(120-(mouseY/2));
			cube.y=150;
						
			point3D = new Array(cube.geometry.vertices.length);
			for(var i:Number=0;i<point3D.length;i++){
				point3D[i] = new Number3D(cube.geometry.vertices[i].x,cube.geometry.vertices[i].y,cube.geometry.vertices[i].z);
//				trace("x "+cube.geometry.vertices[i].x+" y "+cube.geometry.vertices[i].y+" z "+cube.geometry.vertices[i].z);
				Matrix3D.multiplyVector3x3(cube.transform, point3D[i]);
                point3D[i].y += 150; 
//				trace("x "+point3D[i].x+" y "+point3D[i].y+" z "+point3D[i].z);			
			}
			
			scene.removeChild(cube);
 			cube = new Cube( get_color(),100,100,100);
 			scene.addChild(cube);	
			
			cube.yaw(yaw);
//			cube.y=(120-(mouseY/2));
			cube.y=150; 
			
			if(cube.y<0) cube.y = 0;
 			singleRender(); 
		}
		public function get_color() : MaterialsList
		{
			var rtn:MaterialsList = new MaterialsList();

			for(var i:Number=0;i<point_const.length;i++){
				var color_save:Array = new Array(2);
				for(var j:Number=0;j<point_const[i].length;j++){
					color_save[j] = light.getAdjustedColor({
										 p0_x: point3D[point_const[i][j][0]].x , p0_y: point3D[point_const[i][j][0]].y , p0_z: point3D[point_const[i][j][0]].z ,
										 p1_x: point3D[point_const[i][j][1]].x , p1_y: point3D[point_const[i][j][1]].y , p1_z: point3D[point_const[i][j][1]].z ,
										 p2_x: point3D[point_const[i][j][2]].x , p2_y: point3D[point_const[i][j][2]].y , p2_z: point3D[point_const[i][j][2]].z}
										 ,0xFF0000);
				}
				if(color_save[0]<color_save[1]){
					rtn.addMaterial(new ColorMaterial(color_save[0]),cube_const[i]);
				}else{
					rtn.addMaterial(new ColorMaterial(color_save[1]),cube_const[i]);
				}
			}
			return rtn;
		}
 	}
}
	class Light
	{
		public var x:Number;
		public var y:Number;
		public var z:Number;
		private var _brightness:Number;
		
		public var triangle_data:Object;
		
		private var color:uint;
		
		public function Light(x:Number = -100, y:Number = -100, z:Number = -100, brightness:Number = 1)
		{
			this.x = x;
			this.y = y;
			this.z = z;
			this.brightness = brightness;
		}
		public function set_Light_point(x:Number , y:Number , z:Number):void{
			this.x = x;
			this.y = y;
			this.z = z;
		}
		
		public function set brightness(b:Number):void
		{
			_brightness = Math.max(b, 0);
			_brightness = Math.min(_brightness, 1);
		}
		
		public function get brightness():Number
		{
			return _brightness;
		}
		public function getAdjustedColor(p:Object,color:uint = 0xFF0000):uint
		{
			triangle_data = p;
			this.color = color;
			
//			for (var key:String in triangle_data)
// 			 	trace("triangle_data : "+key + ":" + triangle_data[key]);
//			trace(x+" "+y+" "+z);
			
			var red:Number = color >> 16;
			var green:Number = color >> 8 & 0xff;
			var blue:Number =color & 0xff;
			
			var lightFactor:Number = getLightFactor();

//			trace("lightFactor "+lightFactor);
			
			red *= lightFactor;
			green *= lightFactor;
			blue *= lightFactor;
			
//			var d:uint = red << 16 | green << 8 | blue;
//			trace("color "+d.toString(16));
			
			return red << 16 | green << 8 | blue;
		}
		
		private function getLightFactor():Number
		{
		
			var ab:Object = new Object();
			ab.x = triangle_data.p0_x - triangle_data.p1_x;
			ab.y = triangle_data.p0_y - triangle_data.p1_y;
			ab.z = triangle_data.p0_z - triangle_data.p1_z;
			
			var bc:Object = new Object();
			bc.x = triangle_data.p1_x - triangle_data.p2_x;
			bc.y = triangle_data.p1_y - triangle_data.p2_y;
			bc.z = triangle_data.p1_z - triangle_data.p2_z;
			
			var norm:Object = new Object();
			norm.x = (ab.y * bc.z) - (ab.z * bc.y);
			norm.y = -((ab.x * bc.z) - (ab.z * bc.x));
			norm.z = (ab.x * bc.y) - (ab.y * bc.x);
			
//			var key:String;
//			for (key in ab)
// 			 	trace("ab : "+key + ":" + ab[key]);
// 			for (key in ab)
// 			 	trace("bc : "+key + ":" + bc[key]);
// 			for (key in norm)
// 			 	trace("norm : "+key + ":" + ab[key]);
			
			var dotProd:Number = norm.x * x + 
								 norm.y * y + 
								 norm.z * z;
			
			var normMag:Number = Math.sqrt(norm.x * norm.x + 
										   norm.y * norm.y +
										   norm.z * norm.z);
			
			var lightMag:Number = Math.sqrt(x * x +
											y * y +
											z * z);
			
			return (Math.acos(dotProd / (normMag * lightMag)) / Math.PI)
					* _brightness;
		}
	}
    
    	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.events.Event;
	
	class SimpleSlider extends Sprite
	{
		private var _width:Number = 16;
		private var _height:Number = 100;
		private var _value:Number;
		private var _max:Number = 100;
		private var _min:Number = 0;
		private var _handle:Sprite;
		private var _back:Sprite;
		private var _backWidth:Number = 4;
		private var _handleHeight:Number = 6;
		private var _backColor:uint = 0xcccccc;
		private var _backBorderColor:uint = 0x999999;
		private var _handleColor:uint = 0xeeeeee;
		private var _handleBorderColor:uint = 0xcccccc;
		private var _handleRadius:Number = 2;
		private var _backRadius:Number = 2;
		
		public function SimpleSlider(min:Number=0, max:Number=100, value:Number=100)
		{
			_min = min;
			_max = max;
			_value = Math.min(Math.max(value, min), max)
			init();
		}
		
		private function init():void
		{
			_back = new Sprite();
			addChild(_back);
			
			_handle = new Sprite();
			addChild(_handle);
			_handle.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			
			draw();
			updatePosition();
		}
		
		private function draw():void
		{
			drawBack();
			drawHandle();
		}
		
		private function drawBack():void
		{
			_back.graphics.clear();
			_back.graphics.beginFill(_backColor);
			_back.graphics.lineStyle(0, _backBorderColor);
			_back.graphics.drawRoundRect(0, 0, _backWidth, _height, _backRadius, _backRadius);
			_back.graphics.endFill();
			_back.x = _width / 2 - _backWidth / 2;
		}
		
		private function drawHandle():void
		{
			_handle.graphics.clear();
			_handle.graphics.beginFill(_handleColor);
			_handle.graphics.lineStyle(0, _handleBorderColor);
			_handle.graphics.drawRoundRect(0, 0, _width, _handleHeight, _handleRadius, _handleRadius);
			_handle.graphics.endFill();
		}
	
		private function updatePosition():void
		{
			var handleRange:Number = _height - _handleHeight;
			var valueRange:Number = _max - _min;
			_handle.y = handleRange - (_value - _min) / valueRange * handleRange;
		}
		
		private function updateValue():void
		{
			var handleRange:Number = _height - _handleHeight;
			var valueRange:Number = _max - _min;
			_value = (handleRange - _handle.y) / handleRange * valueRange + _min;
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		private function onMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			_handle.stopDrag();
		}
		
		private function onMouseDown(event:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			_handle.startDrag(false, new Rectangle(0, 0, 0, _height - _handleHeight));
		}
		
		private function onMouseMove(event:MouseEvent):void
		{
			updateValue();
		}


		
		public function invalidate():void
		{
			draw();
		}
		
		public function move(x:Number, y:Number):void
		{
			this.x = x;
			this.y = y;
		}
		
		public function setSize(w:Number, h:Number):void
		{
			_width = w;
			_height = h;
			draw();
		}
		
		
		
		
		
		
		public function set backBorderColor(n:uint):void
		{
			_backBorderColor = n;
			draw();
		}
		public function get backBorderColor():uint
		{
			return _backBorderColor;
		}
		
		public function set backColor(n:uint):void
		{
			_backColor = n;
			draw();
		}
		public function get backColor():uint
		{
			return _backColor;
		}
		
		public function set backRadius(n:Number):void
		{
			_backRadius = n;
		}
		public function get backRadius():Number
		{
			return _backRadius;
		}
		
		public function set backWidth(n:Number):void
		{
			_backWidth = n;
			draw();
		}
		public function get backWidth():Number
		{
			return _backWidth;
		}
		
		public function set handleBorderColor(n:uint):void
		{
			_handleBorderColor = n;
			draw();
		}
		public function get handleBorderColor():uint
		{
			return _handleBorderColor;
		}
		
		public function set handleColor(n:uint):void
		{
			_handleColor = n;
			draw();
		}
		public function get handleColor():uint
		{
			return _handleColor;
		}
		
		public function set handleRadius(n:Number):void
		{
			_handleRadius = n;
			draw();
		}
		public function get handleRadius():Number
		{
			return _handleRadius;
		}
		
		public function set handleHeight(n:Number):void
		{
			_handleHeight = n;
			draw();
			updatePosition();
		}
		public function get handleHeight():Number
		{
			return _handleHeight;
		}
		
		override public function set height(n:Number):void
		{
			_height = n;
			draw();
		}
		override public function get height():Number
		{
			return _height;
		}
		
		public function set max(n:Number):void
		{
			_max = n;
			updatePosition();
		}
		public function get max():Number
		{
			return _max;
		}
		
		public function set min(n:Number):void
		{
			_min = n;
			updatePosition();
		}
		public function get min():Number
		{
			return _min;
		}
		
		public function set value(n:Number):void
		{
			_value = n;
			_value = Math.min(_max, Math.max(_value, _min));
			updatePosition();
		}
		public function get value():Number
		{
			return _value;
		}
		
		override public function set width(n:Number):void
		{
			_width = n;
			draw();
		}
		override public function get width():Number
		{
			return _width;
		}
	}