Eye Look
Fun with 3D ray-casting and math quaternions
Fun with 3D ray-casting and math quaternions
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);
}
}
}