TriangleMesh3D 法線試験

by hankuro
TriangleMesh3D 法線試験
「ひとりごと」
  papervision3dがだんだん納得出来てきたぞ!
♥0 | Line 145 | Modified 2009-10-31 17:13:34 | MIT License
play

ActionScript3 source code

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

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.ColorMatrixFilter;
	import org.papervision3d.core.geom.renderables.Triangle3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.geom.TriangleMesh3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.NumberUV;
	import org.papervision3d.core.utils.MeshUtil;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.core.math.Matrix3D;
	
	[SWF(width = 500, height = 500, backgroundColor = 0x000000)]
	/**
	 * 
	 * TriangleMesh3D 法線試験
	 * 「ひとりごと」
	 *   papervision3dがだんだん納得出来てきたぞ!
	 * 
	 */
	public class Main extends BasicView
	{
		public var light:Light = new Light();
		public var point3D:Array;
		public var sphere:Sphere;
		public var mesh:Array;
		public var tria:Triangle3D;
		private var uvA:NumberUV;
		private var uvC:NumberUV;
		private var uvB:NumberUV;
		private var v0:Vertex3D;
		private var v1:Vertex3D;
		private var v2:Vertex3D;
		private var color_m:ColorMaterial;
		public function Main() 
		{
			super (500, 500, false, false);
			camera.z = -400;
			sphere = new Sphere(new ColorMaterial(0xFFFFFF, 0), 150, 20, 20);
			mesh = new Array(sphere.geometry.faces.length);
			for ( var i:Number = 0; i < mesh.length; i++) {
				tria = sphere.geometry.faces[i];
				mesh[i] = new TriangleMesh3D(new ColorMaterial(0xFF0000,0), new Array(), new Array(), null );
				v0 = new Vertex3D( tria.vertices[0].x, tria.vertices[0].y, tria.vertices[0].z );
				v1 = new Vertex3D( tria.vertices[1].x, tria.vertices[1].y, tria.vertices[1].z );
				v2 = new Vertex3D( tria.vertices[2].x, tria.vertices[2].y, tria.vertices[2].z );
				mesh[i].geometry.vertices.push( v0 );
				mesh[i].geometry.vertices.push( v1 );
				mesh[i].geometry.vertices.push( v2 );
				uvA = new NumberUV( 0, 0 );
				uvC = new NumberUV( 1, 0 );
				uvB = new NumberUV( 0, 1 );
				mesh[i].geometry.faces.push( new Triangle3D( mesh[i], new Array(v0,v1,v2), null, new Array(uvA,uvC,uvB) ));
				mesh[i].geometry.ready = true;
				scene.addChild(mesh[i]);
			}
			startRendering();
			addEventListener(Event.ENTER_FRAME, onLoop);
		}
		public function onLoop(evt:Event):void {
			light.set_Light_point(mouseX - stage.stageWidth / 2, (mouseY - stage.stageHeight / 2)*-1,-150);
			var c:uint;
			for (var i:Number = 0; i < mesh.length; i++) {
				mesh[i].rotationY += 1;
				point3D = new Array(3);
				var s:TriangleMesh3D;
				for (var n:Number = 0; n < 3; n++) {
					point3D[n] = new Number3D(mesh[i].geometry.vertices[n].x, mesh[i].geometry.vertices[n].y, mesh[i].geometry.vertices[n].z);
					Matrix3D.multiplyVector3x3(mesh[i].transform, point3D[n]);
				}
				c = light.getAdjustedColor( { p0_x: point3D[0].x, p0_y: point3D[0].y , p0_z: point3D[0].z,
											  p1_x: point3D[1].x, p1_y: point3D[1].y , p1_z: point3D[1].z,
											  p2_x: point3D[2].x, p2_y: point3D[2].y , p2_z: point3D[2].z },
										      0x00FFFF);
			    color_m = new ColorMaterial(c);
				mesh[i].material = color_m;
			}
		}
	}	
}
	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;	
			var red:Number = color >> 16;
			var green:Number = color >> 8 & 0xff;
			var blue:Number =color & 0xff;
			
			var lightFactor:Number = getLightFactor();
			red *= lightFactor;
			green *= lightFactor;
			blue *= lightFactor;
			

			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 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;
		}
	}