From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- js/helper-classes/RDGE/src/core/script/camera.js | 251 +++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 js/helper-classes/RDGE/src/core/script/camera.js (limited to 'js/helper-classes/RDGE/src/core/script/camera.js') diff --git a/js/helper-classes/RDGE/src/core/script/camera.js b/js/helper-classes/RDGE/src/core/script/camera.js new file mode 100644 index 00000000..caff232b --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/camera.js @@ -0,0 +1,251 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/* + * camera class + */ +camera = function() { + this.proj = mat4.identity(); + this.view = mat4.identity(); + this.world = mat4.identity(); + this.viewProj = mat4.identity(); + this.invViewProj = mat4.identity(); + this.frustum = []; + this.frustumPts = []; + this.controller = null; + + this.setPerspective = function(fov, aratio, near, far) + { + this.ortho = null; + this.persp = {}; + this.persp.fov = fov; + this.persp.aratio = aratio; + this.persp.near = near; + this.persp.far = far; + this.proj = mat4.perspective(fov, aratio, near, far); + this.recalc(); + } + + this.reset = function() { + this.world = mat4.identity(); + this.recalc(); + } + + this.copy = function(cam) { + mat4.inplace_copy(this.view, cam.view); + mat4.inplace_copy(this.world, cam.world); + mat4.inplace_copy(this.proj, cam.proj); + mat4.inplace_copy(this.viewProj, cam.viewProj); + mat4.inplace_copy(this.invViewProj, cam.invViewProj); + this.frustum = cam.frustum.slice(); + this.frustumPts = cam.frustumPts.slice(); + } + + this.recalc = function() { + // update frustum planes + this.frustum = []; + var vp = this.viewProj; + + normalizePlane = function( p ) { + var len = vec3.length( p ); + if( Math.abs( 1.0 - len ) > 0.001 ) { + p[0] /= len; + p[1] /= len; + p[2] /= len; + p[3] /= len; + } + return p; + } + + /* This is the old way + var t = this.persp.near * Math.tan(0.017453292519943295769236 * this.persp.fov * 0.5); + var r = t * this.persp.aratio; + var u = t; + var l = -r; + var b = -u; + + tview = mat4.transpose(this.view); + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [this.persp.near, 0.0, l, 0.0] ) ) ); // left + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [-this.persp.near, 0.0, -r, 0.0] ) ) ); // right + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, this.persp.near, b, 0.0] ) ) ); // bottom + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, -this.persp.near, -u, 0.0] ) ) ); // top + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, 0.0, -1.0, -this.persp.near] ) ) ); // near + this.frustum.push( normalizePlane( mat4.transformPoint(tview, [0.0, 0.0, 1.0, this.persp.far] ) ) ); // far + */ + var l = normalizePlane( [vp[3] + vp[0], vp[7] + vp[4], vp[11] + vp[8], vp[15]+vp[12]] ); + var r = normalizePlane( [vp[3] - vp[0], vp[7] - vp[4], vp[11] - vp[8], vp[15]-vp[12]] ); + var t = normalizePlane( [vp[3] - vp[1], vp[7] - vp[5], vp[11] - vp[9], vp[15]-vp[13]] ); + var b = normalizePlane( [vp[3] + vp[1], vp[7] + vp[5], vp[11] + vp[9], vp[15]+vp[13]] ); + var n = normalizePlane( [vp[3] + vp[2], vp[7] + vp[6], vp[11] + vp[10], vp[15]+vp[14]] ); + var f = normalizePlane( [vp[3] - vp[2], vp[7] - vp[6], vp[11] - vp[10], vp[15]-vp[14]] ); + + this.frustum.push(l); + this.frustum.push(r); + this.frustum.push(t); + this.frustum.push(b); + this.frustum.push(n); + this.frustum.push(f); + + // update frustum points + this.frustumPts = []; + var invvp = this.viewProj; + this.frustumPts.push( mat4.transformPoint( invvp, [-1,-1,-1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [-1,1,-1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [1,1,-1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [1,-1,-1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [-1,-1,1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [-1,1,1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [1,1,1] ) ); + this.frustumPts.push( mat4.transformPoint( invvp, [1,-1,1] ) ); + }; + + this.setWorld = function(m) { + this.world = m; + this.view = mat4.inverse(m); + this.viewProj = mat4.mul( this.view, this.proj ); + this.invViewProj = mat4.inverse(this.viewProj); + this.recalc(); + } + + this.setView = function(m) { + this.view = m; + this.world = mat4.inverse(m); + this.viewProj = mat4.mul( this.view, this.proj ); + this.invViewProj = mat4.inverse(this.viewProj); + this.recalc(); + } + + this.setLookAt = function(eyePos, targetPos, upVec) { + this.setWorld( mat4.lookAt(eyePos, targetPos, upVec) ); + //this.recalc(); + }; + + this.setPerspective = function(fov, aratio, near, far) { + this.ortho = null; + this.persp = {}; + this.persp.fov = fov; + this.persp.aratio = aratio; + this.persp.near = near; + this.persp.far = far; + this.proj = mat4.perspective(fov, aratio, near, far); + this.recalc(); + } + + this.setOrthographic = function( l, r, t, b, n, f ) { + this.persp = null; + this.ortho = {}; + this.ortho.left = l; + this.ortho.right = r; + this.ortho.top = t; + this.ortho.bottom = b; + this.ortho.near = n; + this.ortho.far = f; + this.proj = mat4.orthographic(l, r, t, b, n, f); + this.recalc(); + } + + this.onResize = function(x, y, width, height) { + if( this.persp ) { + this.setPerspective(this.persp.fov, width / height, this.persp.near, this.persp.far); + } + if( this.ortho ) { + this.setOrthographic(x, x + width, y, y + height, this.ortho.near, this.ortho.far); + } + } + + this.zNear = function() { + if( this.persp ) { + return this.persp.near; + } + + if( this.ortho ) { + return this.ortho.near; + } + + return 0.0; + } + + this.zFar = function() { + if( this.persp ) { + return this.persp.far; + } + + if( this.ortho ) { + return this.ortho.far; + } + + return 0.0; + } + + // this is used by ambient occlusion... + this.getFTR = function() { + var fovyRad = (this.persp.fov * 0.5) * Math.PI / 180.0; + return [ + Math.tan(fovyRad) * this.persp.far, + Math.tan(fovyRad / this.persp.aratio) * this.persp.far, + this.persp.far ]; + } + + this.attachCameraToNode = function( node ) + { + this.controller = node; + } +} + + +/** Camera Manager + * This class is used to manage the active camera. It provides functionality + * for getting and setting the active camera, as well as providing stack operations + * to switch to and from multiple cameras. + */ +cameraManager = function() { + this.stack = []; + + /* Set the active camera. + * This function sets the active camera to the given camera. + */ + this.setActiveCamera = function(c) { + // pop the active camera off the stack. + if( this.stack.length > 0 ) { + this.stack.pop(); + } + // push the given camera onto the stack. + this.stack.push(c); + } + + /* Get the active camera. + * The active camera always resides at the top of the stack. + */ + this.getActiveCamera = function() { + if( this.stack.length > 0 ) { + return this.stack[this.stack.length - 1]; + } else { + return null; + } + } + + /* Push a camera onto the stack. + * The given camera becomes the active camera. + */ + this.pushCamera = function(c) { + this.stack.push(c); + } + + /* Pop a camera off the stack. + * Returns the camera that was popped. + * The next camera on the stack becomes active. + */ + this.popCamera = function() { + return this.stack.pop(); + } + + this.onResize = function(x, y, w, h) { + var i = this.stack.length - 1; + while( i >= 0 ) { + this.stack[i].onResize( x, y, w, h ); + i--; + } + } +} -- cgit v1.2.3