API Documentation
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 222 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 222 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 232 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 232 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 232 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 232 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 233 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 234 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_core_glge_animatable.js.html, line: 316 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
1 /* 2 GLGE WebGL Graphics Engine 3 Copyright (c) 2010, Paul Brunt 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in the 12 documentation and/or other materials provided with the distribution. 13 * Neither the name of GLGE nor the 14 names of its contributors may be used to endorse or promote products 15 derived from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @fileOverview 31 * @name glge_animatable.js 32 * @author me@paulbrunt.co.uk 33 */ 34 35 36 (function(GLGE){ 37 38 39 40 /** 41 * @class Animation class to agument animatiable objects 42 * @augments GLGE.Events 43 */ 44 GLGE.Animatable=function(){ 45 } 46 /** 47 * @name GLGE.Animatable#animFinished 48 * @event 49 * @param {object} data 50 */ 51 GLGE.augment(GLGE.Events,GLGE.Animatable); 52 53 GLGE.Animatable.prototype.animationStart=null; 54 GLGE.Animatable.prototype.animation=null; 55 GLGE.Animatable.prototype.blendStart=0; 56 GLGE.Animatable.prototype.blendTime=0; 57 GLGE.Animatable.prototype.lastFrame=null; 58 GLGE.Animatable.prototype.frameRate=30; 59 GLGE.Animatable.prototype.loop=GLGE.TRUE; 60 GLGE.Animatable.prototype.paused=GLGE.FALSE; 61 GLGE.Animatable.prototype.pausedTime=null; 62 GLGE.Animatable.prototype.blendFunction=GLGE.LINEAR_BLEND; 63 64 /** 65 * Creates and sets an animation to blend to the properties. Useful for blending to a specific location for example: 66 * blendto({LocX:10,LocY:5,LocZ:10},2000); 67 * @param {object} properties The properties to blend 68 * @param {number} duration the duration of the blend 69 * @param {function} blendFunction[optional] the function used for blending defaults to GLGE.LINEAR_BLEND 70 */ 71 GLGE.Animatable.prototype.blendTo=function(properties,duration,blendFunction){ 72 if(!blendFunction) blendFunction=GLGE.LINEAR_BLEND; 73 var animation=new GLGE.AnimationVector(); 74 var curve; 75 var point; 76 for(var prop in properties){ 77 curve=new GLGE.AnimationCurve(); 78 curve.setChannel(prop); 79 point=new GLGE.LinearPoint(); 80 point.setX(1); 81 point.setY(properties[prop]); 82 curve.addPoint(point); 83 animation.addAnimationCurve(curve); 84 } 85 this.setBlendFunction(blendFunction); 86 this.setAnimation(animation,duration); 87 return this; 88 } 89 /** 90 * Sets the animation blending function 91 * @param {function} value The blending function 92 */ 93 GLGE.Animatable.prototype.setBlendFunction=function(value){ 94 this.blendFunction=value; 95 return this; 96 } 97 /** 98 * Gets the animation blending function 99 * @returns {function} the blending function 100 */ 101 GLGE.Animatable.prototype.getBlendFunction=function(){ 102 return this.blendFunction; 103 } 104 105 /** 106 * Sets the name of this object used for skinning 107 * @param {String} value The name to set 108 */ 109 GLGE.Animatable.prototype.setName=function(value){ 110 this.name=value; 111 return this; 112 } 113 /** 114 * Gets the name of this object used for skinning 115 * @returns {String} the name 116 */ 117 GLGE.Animatable.prototype.getName=function(){ 118 return this.name; 119 } 120 /** 121 * gets the frame at the specified time 122 * @param {number} now the current time 123 */ 124 GLGE.Animatable.prototype.getFrameNumber=function(now){ 125 if(!this.startFrame) this.startFrame=this.animation.startFrame; 126 if(!this.animFrames) this.animFrames=this.animation.frames; 127 var frame; 128 if(!now) now=parseInt(new Date().getTime()); 129 if(this.animFrames>1){ 130 if(this.loop){ 131 frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)%(this.animFrames-1)+1+this.startFrame; 132 }else{ 133 frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)+1+this.startFrame; 134 if(frame>=(this.animFrames+this.startFrame)){ 135 frame=this.animFrames; 136 } 137 } 138 }else{ 139 140 frame=1; 141 } 142 143 return Math.round(frame); 144 } 145 146 /** 147 * Sets the start frame for the animation overriding the animation default 148 * @param {number} startFrame the start frame 149 */ 150 GLGE.Animatable.prototype.setStartFrame=function(startFrame,blendTime,loop){ 151 this.loop=loop; 152 var starttime=parseInt(new Date().getTime()); 153 if(!blendTime) blendTime=0; 154 if(blendTime>0){ 155 if(this.animation){ 156 this.blendInitValues=this.getInitialValues(this.animation,starttime); 157 this.blendTime=blendTime; 158 } 159 } 160 this.animationStart=starttime; 161 this.lastFrame=null; 162 this.animFinished=false; 163 this.startFrame=startFrame; 164 if(this.children){ 165 for(var i=0;i<this.children.length;i++){ 166 if(this.children[i].setStartFrame){ 167 this.children[i].setStartFrame(startFrame,blendTime,loop); 168 } 169 } 170 } 171 return this; 172 } 173 /** 174 * Sets the number of frames to play overriding the animation default 175 * @param {number} frames the number of frames 176 * @private 177 */ 178 GLGE.Animatable.prototype.setFrames=function(frames){ 179 this.animFrames=frames; 180 if(this.children){ 181 for(var i=0;i<this.children.length;i++){ 182 if(this.children[i].setFrames){ 183 this.children[i].setFrames(frames); 184 } 185 } 186 } 187 return this;l 188 } 189 190 /** 191 * gets the initial values for the animation vector for blending 192 * @param {GLGE.AnimationVector} animation The animation 193 * @private 194 */ 195 GLGE.Animatable.prototype.getInitialValues=function(animation,time){ 196 var initValues={}; 197 198 if(this.animation){ 199 this.lastFrame=null; 200 this.animate(time,true); 201 } 202 203 for(var property in animation.curves){ 204 if(this["get"+property]){ 205 initValues[property]=this["get"+property](); 206 } 207 } 208 209 return initValues; 210 } 211 212 /** 213 * update animated properties on this object 214 */ 215 GLGE.Animatable.prototype.animate=function(now,nocache){ 216 if(!this.paused && this.animation){ 217 if(!now) now=parseInt(new Date().getTime()); 218 var frame=this.getFrameNumber(now); 219 220 if(!this.animation.animationCache) this.animation.animationCache={}; 221 if(frame!=this.lastFrame || this.blendTime!=0){ 222 this.lastFrame=frame; 223 if(this.blendTime==0){ 224 if(!this.animation.animationCache[frame] || nocache){ 225 this.animation.animationCache[frame]=[]; 226 if(this.animation.curves["LocX"] && this.animation.curves["LocY"] && this.animation.curves["LocZ"] 227 && this.animation.curves["ScaleX"] && this.animation.curves["ScaleY"] && this.animation.curves["ScaleZ"] 228 && this.animation.curves["QuatX"] && this.animation.curves["QuatY"] && this.animation.curves["QuatZ"] && this.animation.curves["QuatW"]){ 229 //just set matrix 230 for(var property in this.animation.curves){ 231 if(this["set"+property]){ 232 var value=this.animation.curves[property].getValue(parseFloat(frame)); 233 switch(property){ 234 case "QuatX": 235 case "QuatY": 236 case "QuatZ": 237 case "QuatW": 238 case "LocX": 239 case "LocY": 240 case "LocZ": 241 case "ScaleX": 242 case "ScaleY": 243 case "ScaleZ": 244 break; 245 default: 246 this.animation.animationCache[frame].push({property:property,value:value}); 247 break; 248 } 249 this["set"+property](value); 250 } 251 } 252 this.animation.animationCache[frame].push({property:"StaticMatrix",value:this.getLocalMatrix()}); 253 }else{ 254 for(property in this.animation.curves){ 255 if(this["set"+property]){ 256 var value=this.animation.curves[property].getValue(parseFloat(frame)); 257 switch(property){ 258 case "QuatX": 259 case "QuatY": 260 case "QuatZ": 261 case "QuatW": 262 case "RotX": 263 case "RotY": 264 case "RotZ": 265 var rot=true; 266 break; 267 default: 268 this.animation.animationCache[frame].push({property:property,value:value}); 269 break; 270 } 271 this["set"+property](value); 272 } 273 } 274 if(rot){ 275 value=this.getRotMatrix(); 276 this.animation.animationCache[frame].push({property:"RotMatrix",value:value}); 277 } 278 } 279 }else{ 280 var cache=this.animation.animationCache[frame]; 281 for(var i=0;i<cache.length;i++){ 282 if(this["set"+cache[i].property]) this["set"+cache[i].property](cache[i].value); 283 } 284 } 285 }else{ 286 var time=now-this.animationStart; 287 if(time<this.blendTime){ 288 var blendfactor=time/this.blendTime; 289 blendfactor=this.blendFunction(blendfactor); 290 for(property in this.animation.curves){ 291 if(this["set"+property]){ 292 var value=this.animation.curves[property].getValue(parseFloat(frame)); 293 value=value*blendfactor+this.blendInitValues[property]*(1-blendfactor); 294 this["set"+property](value); 295 } 296 } 297 }else{ 298 this.blendTime=0; 299 } 300 } 301 } 302 } 303 if(this.children){ 304 for(var i=0; i<this.children.length;i++){ 305 if(this.children[i].animate){ 306 this.children[i].animate(now,nocache); 307 } 308 } 309 } 310 if(this.animation && !this.animFinished && this.blendTime==0 && this.animation.frames==frame && !nocache){ 311 this.animFinished=true; 312 this.fireEvent("animFinished",{}); 313 } 314 } 315 /** 316 * Sets the animation vector of this object 317 * @param {GLGE.AnimationVector} animationVector the animation to apply to this object 318 * @param {number} blendDuration [Optional] the time in milliseconds to blend into this animation 319 * @param {number} starttime [Optional] the starting time of the animation 320 */ 321 GLGE.Animatable.prototype.setAnimation=function(animationVector,blendDuration,starttime){ 322 if(starttime==null) starttime=parseInt(new Date().getTime()); 323 if(!blendDuration) blendDuration=0; 324 if(blendDuration>0){ 325 this.blendInitValues=this.getInitialValues(animationVector,starttime); 326 this.blendTime=blendDuration; 327 } 328 this.animFrames=null; 329 this.startFrame=null; 330 this.animationStart=starttime; 331 this.lastFrame=null; 332 this.animation=animationVector; 333 this.animFinished=false; 334 return this; 335 } 336 /** 337 * Gets the animation vector of this object 338 * @returns {AnimationVector} 339 */ 340 GLGE.Animatable.prototype.getAnimation=function(){ 341 return this.animation; 342 } 343 /** 344 * Sets the frame rate of the animation 345 * @param {number} value the frame rate to set 346 */ 347 GLGE.Animatable.prototype.setFrameRate=function(value){ 348 this.frameRate=value; 349 if (this.children) { 350 for (var i = 0; i < this.children.length; i++) { 351 if (this.children[i].setFrameRate) { 352 this.children[i].setFrameRate(value); 353 } 354 } 355 } 356 return this; 357 } 358 /** 359 * Gets the frame rate of the animation 360 * @return {number} the current frame rate 361 */ 362 GLGE.Animatable.prototype.getFrameRate=function(){ 363 return this.frameRate; 364 } 365 /** 366 * Sets the loop flag to GLGE.TRUE or GLGE.FALSE 367 * @param {boolean} value 368 */ 369 GLGE.Animatable.prototype.setLoop=function(value){ 370 this.loop=value; 371 return this; 372 } 373 /** 374 * Gets the loop flag 375 * @return {boolean} 376 */ 377 GLGE.Animatable.prototype.getLoop=function(){ 378 return this.loop; 379 } 380 /** 381 * @function is looping? @see GLGE.Animatable#getLoop 382 */ 383 GLGE.Animatable.prototype.isLooping=GLGE.Animatable.prototype.getLoop; 384 385 /** 386 * Sets the paused flag to GLGE.TRUE or GLGE.FALSE 387 * @param {boolean} value 388 */ 389 GLGE.Animatable.prototype.setPaused=function(value){ 390 if(value) this.pauseTime=parseInt(new Date().getTime()); 391 else this.animationStart=this.animationStart+(parseInt(new Date().getTime())-this.pauseTime); 392 this.paused=value; 393 return this; 394 } 395 /** 396 * Gets the paused flag 397 * @return {boolean} 398 */ 399 GLGE.Animatable.prototype.getPaused=function(){ 400 return this.paused; 401 } 402 /** 403 * Toggles the paused flag 404 * @return {boolean} returns the resulting flag state 405 */ 406 GLGE.Animatable.prototype.togglePaused=function(){ 407 this.setPaused(!this.getPaused()); 408 return this.paused; 409 } 410 411 })(GLGE); 412