1 /**
  2  * Copyright (C) 2009-2012 Klaus Reimer <k@ailis.de>
  3  * See LICENSE.txt for licensing information
  4  * 
  5  * @require threedee.js
  6  * @require threedee/SceneNode.js
  7  * @use threedee/Matrix.js
  8  */
  9 
 10 /**
 11  * Constructs a new camera node.
 12  * 
 13  * @constructor
 14  * @extends {threedee.SceneNode}
 15  * @class 
 16  * A camera node.
 17  */
 18 threedee.CameraNode = function()
 19 {
 20     threedee.SceneNode.call(this);
 21 };
 22 threedee.inherit(threedee.CameraNode, threedee.SceneNode);
 23 
 24 /**
 25  * Transforms the node so it looks at the specified point.
 26  * 
 27  * @param {threedee.Vector} eye
 28  *            The position of the eye
 29  * @param {threedee.Vector} center
 30  *            The point the eye looks at
 31  * @param {threedee.Vector} up
 32  *            The up vector of the eye
 33  *            The transformation matrix
 34  */
 35 threedee.CameraNode.prototype.lookAt = function(eye, center, up)
 36 {
 37     var forwardx, forwardy, forwardz, invMag, upx, upy, upz,
 38         sidex, sidey, sidez, mat;
 39 
 40     forwardx = eye.x - center.x;
 41     forwardy = eye.y - center.y;
 42     forwardz = eye.z - center.z;
 43 
 44     invMag =
 45         1.0 / Math.sqrt(forwardx * forwardx + forwardy * forwardy
 46             + forwardz * forwardz);
 47     forwardx = forwardx * invMag;
 48     forwardy = forwardy * invMag;
 49     forwardz = forwardz * invMag;
 50 
 51     invMag = 1.0 / Math.sqrt(up.x * up.x + up.y * up.y + up.z * up.z);
 52     upx = up.x * invMag;
 53     upy = up.y * invMag;
 54     upz = up.z * invMag;
 55 
 56     // side = Up cross forward
 57     sidex = upy * forwardz - forwardy * upz;
 58     sidey = upz * forwardx - upx * forwardz;
 59     sidez = upx * forwardy - upy * forwardx;
 60 
 61     invMag =
 62         1.0 / Math.sqrt(sidex * sidex + sidey * sidey + sidez * sidez);
 63     sidex *= invMag;
 64     sidey *= invMag;
 65     sidez *= invMag;
 66 
 67     // recompute up = forward cross side
 68 
 69     upx = forwardy * sidez - sidey * forwardz;
 70     upy = forwardz * sidex - forwardx * sidez;
 71     upz = forwardx * sidey - forwardy * sidex;
 72 
 73     mat = [];
 74     
 75     // transpose because we calculated the inverse of what we want
 76     mat[0] = sidex;
 77     mat[1] = sidey;
 78     mat[2] = sidez;
 79 
 80     mat[4] = upx;
 81     mat[5] = upy;
 82     mat[6] = upz;
 83 
 84     mat[8] = forwardx;
 85     mat[9] = forwardy;
 86     mat[10] = forwardz;
 87 
 88     mat[3] = -eye.x * mat[0] + -eye.y * mat[1] + -eye.z * mat[2];
 89     mat[7] = -eye.x * mat[4] + -eye.y * mat[5] + -eye.z * mat[6];
 90     mat[11] = -eye.x * mat[8] + -eye.y * mat[9] + -eye.z * mat[10];
 91 
 92     mat[12] = mat[13] = mat[14] = 0;
 93     mat[15] = 1;
 94    
 95     var m = new threedee.Matrix().set(
 96         mat[0], mat[1], mat[2], mat[3],
 97         mat[4], mat[5], mat[6], mat[7],
 98         mat[8], mat[9], mat[10], mat[11],
 99         mat[12], mat[13], mat[14], mat[15]);
100     this.setTransform(m);
101 };
102