Fork me on GitHub

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