1 /* 2 Copyright (c) 2008 Seneca College 3 Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) 4 */ 5 6 7 /** 8 @class c3dl.Camera is a base class for c3dl.OrbitCamera and c3dl.FreeCamera. 9 */ 10 c3dl.Camera = function() 11 { 12 // Raw Position Values 13 this.left = [1.0, 0.0, 0.0]; // Camera Left vector 14 this.up = [0.0, 1.0, 0.0]; // Camera Up vector 15 this.dir = [0.0, 0.0, 1.0]; // The direction its looking at 16 this.pos = [0.0, 0.0, 0.0]; // Camera eye position 17 18 this.projectionTransform = null; 19 this.projMatrix; 20 this.viewMatrix; 21 22 this.fieldOfView = c3dl.DEFAULT_FIELD_OF_VIEW; 23 this.nearClippingPlane = c3dl.DEFAULT_NEAR_CLIPPING_PLANE; 24 this.farClippingPlane = c3dl.DEFAULT_FAR_CLIPPING_PLANE; 25 } 26 27 28 /** 29 @private 30 31 Create the projection matrix. 32 33 Places the view matrix at the bottom of the matrix stack. 34 */ 35 c3dl.Camera.prototype.applyToWorld = function(aspectRatio) 36 { 37 // set the bottom matrix of the matrix stack to the viewmatrix 38 c3dl.loadMatrix(c3dl.lookAt(this.pos,c3dl.addVectors(this.pos,this.dir), this.up)); 39 c3dl.translate(-this.pos[0], -this.pos[1], -this.pos[2]); 40 this.viewMatrix = c3dl.peekMatrix(); 41 42 // Create a projection matrix and store it inside a globally accessible place. 43 this.projMatrix = c3dl.makePerspective(this.fieldOfView, aspectRatio, this.nearClippingPlane, this.farClippingPlane); 44 c3dl.matrixMode(c3dl.PROJECTION); 45 c3dl.loadMatrix(this.projMatrix); 46 c3dl.matrixMode(c3dl.MODELVIEW); 47 } 48 49 50 /** 51 Get the direction of the camera. 52 53 @returns {Array} vector 54 */ 55 c3dl.Camera.prototype.getDir = function() 56 { 57 return [this.dir[0], this.dir[1], this.dir[2]]; 58 } 59 60 61 /** 62 Get the far clipping plane. 63 64 @returns {float} far clipping plane value. 65 */ 66 c3dl.Camera.prototype.getFarClippingPlane = function() 67 { 68 return this.farClippingPlane; 69 } 70 71 72 /** 73 Get the vertical field of view for this camera in degrees. 74 75 @returns {float} field of view is greater than 0 and less than 180. 76 */ 77 c3dl.Camera.prototype.getFieldOfView = function() 78 { 79 return this.fieldOfView; 80 } 81 82 83 /** 84 Get the left vector of the camera. 85 86 @returns {Array} vector 87 */ 88 c3dl.Camera.prototype.getLeft = function() 89 { 90 return [this.left[0], this.left[1], this.left[2]]; 91 } 92 93 94 /** 95 Get the near clipping plane. 96 97 @returns {float} near clipping plane value. 98 */ 99 c3dl.Camera.prototype.getNearClippingPlane = function() 100 { 101 return this.nearClippingPlane; 102 } 103 104 105 /** 106 Get the position of the camera. 107 108 @returns {Array} A three element array which contains the position of the camera. 109 */ 110 c3dl.Camera.prototype.getPosition = function() 111 { 112 return [this.pos[0], this.pos[1], this.pos[2]]; 113 } 114 115 116 /** 117 @private 118 */ 119 c3dl.Camera.prototype.getProjectionMatrix = function() 120 { 121 return c3dl.copyObj(this.projMatrix); 122 } 123 124 /** 125 @private 126 */ 127 c3dl.Camera.prototype.getViewMatrix = function() 128 { 129 return c3dl.copyObj(this.viewMatrix); 130 } 131 132 /** 133 Get the up vector of the camera. 134 135 @returns {Array} 136 */ 137 c3dl.Camera.prototype.getUp = function() 138 { 139 return [this.up[0], this.up[1], this.up[2]]; 140 } 141 142 143 /** 144 The far clipping plane should not be set to an extremely large value. This 145 can create depth buffer precision problems such as z-fighting. see 146 http://www.opengl.org/resources/faq/technical/depthbuffer.htm for more information. 147 148 @param {float} fcp Must be larger than 0. 149 */ 150 c3dl.Camera.prototype.setFarClippingPlane = function(fcp) 151 { 152 if( fcp > 0 ) 153 { 154 this.farClippingPlane = fcp; 155 } 156 } 157 158 159 /** 160 Set the field of view for this camera in degrees. 161 162 @param {float} fov Specified in degrees. Must be greater than 0 and less than 180. 163 */ 164 c3dl.Camera.prototype.setFieldOfView = function(fov) 165 { 166 if( fov > 0 && fov < 180) 167 { 168 this.fieldOfView = fov; 169 } 170 } 171 172 173 /** 174 The near clipping plane must be set to a positive value. 175 176 @param {float} ncp Must be larger than 0. 177 */ 178 c3dl.Camera.prototype.setNearClippingPlane = function(ncp) 179 { 180 if( ncp > 0) 181 { 182 this.nearClippingPlane = ncp; 183 } 184 } 185 186 /** 187 Get a string representation of this camera. 188 189 @param {String} [delimiter=","] A string used to separate the member 190 variables of the object. 191 192 @returns {String} a string representation of this class. 193 */ 194 c3dl.Camera.prototype.toString = function(delimiter) 195 { 196 // make sure user passed up a string if they actually decided 197 // to specify a delimiter. 198 if(!delimiter || typeof(delimiter) != "string") 199 { 200 delimiter = ","; 201 } 202 203 return "c3dl.Camera: " + delimiter + 204 "left: " + this.getLeft() + delimiter + 205 "up: " + this.getUp() + delimiter + 206 "direction: " + this.getDir() + delimiter + 207 "position: " + this.getPosition() + delimiter + 208 "fied of view: " + this.getFieldOfView() + delimiter + 209 "near clipping plane: " + this.getNearClippingPlane() + delimiter + 210 "far clipping plane: " + this.getFarClippingPlane() + delimiter; 211 } 212 213 /** 214 @private 215 216 Called automatically. 217 218 Update Animation of the camera. 219 220 @param {float} timeStep 221 */ 222 c3dl.Camera.prototype.update = function(timeStep) 223 { 224 225 if (c3dl.isVectorZero(linVel) && c3dl.isVectorZero(angVel)) return false; 226 227 if (c3dl.vectorLengthSq(linVel) > 0.0) 228 { 229 // Add a velocity to the position 230 velVec = c3dl.makeVector(linVel[0], linVel[1], linVel[2]); 231 c3dl.multiplyVector(velVec, timeStep, velVec); 232 233 c3dl.addVectors(pos, velVec, pos); 234 } 235 236 if (c3dl.vectorLengthSq(angVel) > 0.0) 237 { 238 // Apply some rotations to the orientation from the angular velocity 239 this.pitch(angVel[0] * timeStep); 240 this.yaw(angVel[1] * timeStep); 241 this.roll(angVel[2] * timeStep); 242 } 243 244 return true; 245 } 246