Eye Look

Fun with 3D ray-casting and math quaternions

Eye Look

src/eyeLook.as


package {
//_________________________________________________________________
//                                                          imports
	import flash.events.*;
	import flash.display.*;	
	import org.papervision3d.view.*;
	import org.papervision3d.cameras.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.core.math.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.objects.primitives.*;
//_________________________________________________________________
//                                                  export settings 
	[SWF(backgroundColor="0x000000")] 
//_________________________________________________________________
//                                                            class	
	public class eyeLook extends Sprite {
//_________________________________________________________________
//                                                             vars
		private var view		:BasicView
		private var eye			:DisplayObject3D;
		private var eyeball		:Sphere;
		
		private var ray			:Number3D;
		private var depth		:Number = 2000;
		private var ease		:Number = 0.25;
//_________________________________________________________________
//                                                           embeds			
		[Embed(source="assets/texture4.jpg")]
		 private var texture:Class;		
 //_________________________________________________________________
 //                                                      constructor		
		public function eyeLook() {
			view = new BasicView(stage.stageWidth, stage.stageHeight, true, true, CameraType.TARGET);
			addChild(view);
			
			eye = new DisplayObject3D();
			var skin:BitmapMaterial= new BitmapMaterial((new texture() as Bitmap).bitmapData);
			eyeball = new Sphere(skin, 450, 36, 32);
			eyeball.rotationY-= 110;
			eye.addChild(eyeball);
			eye.z = 2000;
			view.scene.addChild(eye);
			
			view.camera.focus = 100;
			view.camera.zoom = 11;
			view.camera.target = eye;
			
			addEventListener(Event.ENTER_FRAME, loop3D);
		}
//_________________________________________________________________
//                                                      render loop
		private function loop3D(e:Event):void {
			ray = view.camera.unproject(view.viewport.containerSprite.mouseX, view.viewport.containerSprite.mouseY);
			ray.normalize();
			ray.multiplyEq(depth);
			ray = Number3D.add(ray, new Number3D(view.camera.x, view.camera.y, view.camera.z));
			mouseLook(ray);
			
			view.renderer.renderScene(view.scene, view.camera, view.viewport);
		}
//_________________________________________________________________
//                                                      ray casting
		private function mouseLook(ray:Number3D):void {
			var mainPosition:Number3D = new Number3D(eye.x, eye.y, eye.z);
			var dir:Number3D = Number3D.sub(ray, mainPosition);
			dir.normalize();
			var front:Number3D = new Number3D(eye.transform.n13, eye.transform.n23, eye.transform.n33);
			front.normalize();
			var cross:Number3D = Number3D.cross(dir, front);
			var dot:Number = Number3D.dot(front,dir);
			//--just incase the mouse is out of frame during calculation
			dot = (dot > 1) ? 1 : (dot< -1) ? -1 : dot;
			var angle:Number = Math.acos(dot);
			var targetQuat:Quaternion = Quaternion.createFromAxisAngle(cross.x, cross.y, cross.z, angle*ease); 
			eye.transform.calculateMultiply3x3(eye.transform, targetQuat.matrix);
		}
	}
}

Download

raw zip tar