1 /**
2 * @author mikael emtinger / http://gomo.se/
3 * @author mrdoob / http://mrdoob.com/
4 * @author alteredq / http://alteredqualia.com/
5 */
6
7 /**@constructor*/
8 THREE.Animation = function ( root, name, interpolationType ) {
9
10 this.root = root;
11 this.data = THREE.AnimationHandler.get( name );
12 this.hierarchy = THREE.AnimationHandler.parse( root );
13
14 this.currentTime = 0;
15 this.timeScale = 1;
16
17 this.isPlaying = false;
18 this.isPaused = true;
19 this.loop = true;
20
21 this.interpolationType = interpolationType !== undefined ? interpolationType : THREE.AnimationHandler.LINEAR;
22
23 this.points = [];
24 this.target = new THREE.Vector3();
25
26 };
27
28 THREE.Animation.prototype.play = function ( loop, startTimeMS ) {
29
30 if ( this.isPlaying === false ) {
31
32 this.isPlaying = true;
33 this.loop = loop !== undefined ? loop : true;
34 this.currentTime = startTimeMS !== undefined ? startTimeMS : 0;
35
36 // reset key cache
37
38 var h, hl = this.hierarchy.length,
39 object;
40
41 for ( h = 0; h < hl; h ++ ) {
42
43 object = this.hierarchy[ h ];
44
45 if ( this.interpolationType !== THREE.AnimationHandler.CATMULLROM_FORWARD ) {
46
47 object.useQuaternion = true;
48
49 }
50
51 object.matrixAutoUpdate = true;
52
53 if ( object.animationCache === undefined ) {
54
55 object.animationCache = {};
56 object.animationCache.prevKey = { pos: 0, rot: 0, scl: 0 };
57 object.animationCache.nextKey = { pos: 0, rot: 0, scl: 0 };
58 object.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
59
60 }
61
62 var prevKey = object.animationCache.prevKey;
63 var nextKey = object.animationCache.nextKey;
64
65 prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ];
66 prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ];
67 prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ];
68
69 nextKey.pos = this.getNextKeyWith( "pos", h, 1 );
70 nextKey.rot = this.getNextKeyWith( "rot", h, 1 );
71 nextKey.scl = this.getNextKeyWith( "scl", h, 1 );
72
73 }
74
75 this.update( 0 );
76
77 }
78
79 this.isPaused = false;
80
81 THREE.AnimationHandler.addToUpdate( this );
82
83 };
84
85
86 THREE.Animation.prototype.pause = function() {
87
88 if ( this.isPaused === true ) {
89
90 THREE.AnimationHandler.addToUpdate( this );
91
92 } else {
93
94 THREE.AnimationHandler.removeFromUpdate( this );
95
96 }
97
98 this.isPaused = !this.isPaused;
99
100 };
101
102
103 THREE.Animation.prototype.stop = function() {
104
105 this.isPlaying = false;
106 this.isPaused = false;
107 THREE.AnimationHandler.removeFromUpdate( this );
108
109 };
110
111
112 THREE.Animation.prototype.update = function ( deltaTimeMS ) {
113
114 // early out
115
116 if ( this.isPlaying === false ) return;
117
118
119 // vars
120
121 var types = [ "pos", "rot", "scl" ];
122 var type;
123 var scale;
124 var vector;
125 var prevXYZ, nextXYZ;
126 var prevKey, nextKey;
127 var object;
128 var animationCache;
129 var frame;
130 var JIThierarchy = this.data.JIT.hierarchy;
131 var currentTime, unloopedCurrentTime;
132 var currentPoint, forwardPoint, angle;
133
134
135 this.currentTime += deltaTimeMS * this.timeScale;
136
137 unloopedCurrentTime = this.currentTime;
138 currentTime = this.currentTime = this.currentTime % this.data.length;
139 frame = parseInt( Math.min( currentTime * this.data.fps, this.data.length * this.data.fps ), 10 );
140
141
142 for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
143
144 object = this.hierarchy[ h ];
145 animationCache = object.animationCache;
146
147 // loop through pos/rot/scl
148
149 for ( var t = 0; t < 3; t ++ ) {
150
151 // get keys
152
153 type = types[ t ];
154 prevKey = animationCache.prevKey[ type ];
155 nextKey = animationCache.nextKey[ type ];
156
157 // switch keys?
158
159 if ( nextKey.time <= unloopedCurrentTime ) {
160
161 // did we loop?
162
163 if ( currentTime < unloopedCurrentTime ) {
164
165 if ( this.loop ) {
166
167 prevKey = this.data.hierarchy[ h ].keys[ 0 ];
168 nextKey = this.getNextKeyWith( type, h, 1 );
169
170 while( nextKey.time < currentTime ) {
171
172 prevKey = nextKey;
173 nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
174
175 }
176
177 } else {
178
179 this.stop();
180 return;
181
182 }
183
184 } else {
185
186 do {
187
188 prevKey = nextKey;
189 nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
190
191 } while( nextKey.time < currentTime )
192
193 }
194
195 animationCache.prevKey[ type ] = prevKey;
196 animationCache.nextKey[ type ] = nextKey;
197
198 }
199
200
201 object.matrixAutoUpdate = true;
202 object.matrixWorldNeedsUpdate = true;
203
204 scale = ( currentTime - prevKey.time ) / ( nextKey.time - prevKey.time );
205 prevXYZ = prevKey[ type ];
206 nextXYZ = nextKey[ type ];
207
208
209 // check scale error
210
211 if ( scale < 0 || scale > 1 ) {
212
213 console.log( "THREE.Animation.update: Warning! Scale out of bounds:" + scale + " on bone " + h );
214 scale = scale < 0 ? 0 : 1;
215
216 }
217
218 // interpolate
219
220 if ( type === "pos" ) {
221
222 vector = object.position;
223
224 if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) {
225
226 vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
227 vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
228 vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
229
230 } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
231 this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
232
233 this.points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ];
234 this.points[ 1 ] = prevXYZ;
235 this.points[ 2 ] = nextXYZ;
236 this.points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ];
237
238 scale = scale * 0.33 + 0.33;
239
240 currentPoint = this.interpolateCatmullRom( this.points, scale );
241
242 vector.x = currentPoint[ 0 ];
243 vector.y = currentPoint[ 1 ];
244 vector.z = currentPoint[ 2 ];
245
246 if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
247
248 forwardPoint = this.interpolateCatmullRom( this.points, scale * 1.01 );
249
250 this.target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] );
251 this.target.subSelf( vector );
252 this.target.y = 0;
253 this.target.normalize();
254
255 angle = Math.atan2( this.target.x, this.target.z );
256 object.rotation.set( 0, angle, 0 );
257
258 }
259
260 }
261
262 } else if ( type === "rot" ) {
263
264 THREE.Quaternion.slerp( prevXYZ, nextXYZ, object.quaternion, scale );
265
266 } else if ( type === "scl" ) {
267
268 vector = object.scale;
269
270 vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
271 vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
272 vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
273
274 }
275
276 }
277
278 }
279
280 };
281
282 // Catmull-Rom spline
283
284 THREE.Animation.prototype.interpolateCatmullRom = function ( points, scale ) {
285
286 var c = [], v3 = [],
287 point, intPoint, weight, w2, w3,
288 pa, pb, pc, pd;
289
290 point = ( points.length - 1 ) * scale;
291 intPoint = Math.floor( point );
292 weight = point - intPoint;
293
294 c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
295 c[ 1 ] = intPoint;
296 c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
297 c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
298
299 pa = points[ c[ 0 ] ];
300 pb = points[ c[ 1 ] ];
301 pc = points[ c[ 2 ] ];
302 pd = points[ c[ 3 ] ];
303
304 w2 = weight * weight;
305 w3 = weight * w2;
306
307 v3[ 0 ] = this.interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
308 v3[ 1 ] = this.interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
309 v3[ 2 ] = this.interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );
310
311 return v3;
312
313 };
314
315 THREE.Animation.prototype.interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {
316
317 var v0 = ( p2 - p0 ) * 0.5,
318 v1 = ( p3 - p1 ) * 0.5;
319
320 return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
321
322 };
323
324
325
326 // Get next key with
327
328 THREE.Animation.prototype.getNextKeyWith = function ( type, h, key ) {
329
330 var keys = this.data.hierarchy[ h ].keys;
331
332 if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
333 this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
334
335 key = key < keys.length - 1 ? key : keys.length - 1;
336
337 } else {
338
339 key = key % keys.length;
340
341 }
342
343 for ( ; key < keys.length; key++ ) {
344
345 if ( keys[ key ][ type ] !== undefined ) {
346
347 return keys[ key ];
348
349 }
350
351 }
352
353 return this.data.hierarchy[ h ].keys[ 0 ];
354
355 };
356
357 // Get previous key with
358
359 THREE.Animation.prototype.getPrevKeyWith = function ( type, h, key ) {
360
361 var keys = this.data.hierarchy[ h ].keys;
362
363 if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
364 this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
365
366 key = key > 0 ? key : 0;
367
368 } else {
369
370 key = key >= 0 ? key : key + keys.length;
371
372 }
373
374
375 for ( ; key >= 0; key -- ) {
376
377 if ( keys[ key ][ type ] !== undefined ) {
378
379 return keys[ key ];
380
381 }
382
383 }
384
385 return this.data.hierarchy[ h ].keys[ keys.length - 1 ];
386
387 };
388
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016