2012-10-25 12 views
7

Sto usando l'animazione skinning/scheletrica in ThreeJS. Ho un'animazione e voglio essere in grado di spostarmi avanti e indietro attraverso di essa, e saltare in posizioni diverse al suo interno, piuttosto che il solito comportamento ciclico.ThreeJS - come impostare l'ora corrente in Animazione

L'animazione viene creata simili, come nell'esempio:

var animation = new THREE.Animation(mesh, geometry.animation.name); 

Ho provato ad aggiornare l'animazione con delta negativo, così come l'impostazione animation.currentTime direttamente:

animation.currentTime = animationLocation; 

Questi sembra funzionare solo se vado avanti nel tempo, ma se vado indietro l'animazione si interrompe e ottengo un errore:

THREE.Animation.update: Warning! Scale out of bounds: ... on bone ... 

Una cosa che funziona veramente senza errori è quello di chiamare stop() e poi play() con un nuovo orario di inizio:

animation.stop(); 
animation.play(true, animationLocation); 

... però quando guardo a ciò che queste funzioni sono in realtà facendo, coinvolgono molti molti funzione chiama, fa il loop, resetta le trasformazioni, ecc. Questo sembra un modo orribile per farlo, anche se funziona come un hack.

Può darsi che questa funzionalità non esista ancora, nel qual caso cercherò di scavare e creare una funzione che faccia un minimo di lavoro, ma spero che ci sia un altro modo in cui non ho trovato

Qualcuno può aiutare con questo?

[UPDATE]

come un aggiornamento sullo stato di avanzamento, vi posterò la soluzione migliore che ho in questo momento ...

ho tirato fuori il contenuto dei stop() e play() funzioni, e spogliato tutto quello che potevo, facendo alcune supposizioni su certi valori già impostati da 'play()'.

Questo sembra ancora che probabilmente non è il modo migliore per farlo, ma sta facendo un po 'meno lavoro che semplicemente chiamando stop() quindi play().

Questo è quello che ero in grado di farlo fino a:

THREE.Animation.prototype.gotoTime = function(time) { 

    //clamp to duration of the animation: 
    time = THREE.Math.clamp(time, 0, this.length); 

    this.currentTime = time; 

    // reset key cache 
    var h, hl = this.hierarchy.length, 
     object; 

    for (h = 0; h < hl; h ++) { 

     object = this.hierarchy[ h ]; 

     var prevKey = object.animationCache.prevKey; 
     var nextKey = object.animationCache.nextKey; 

     prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ]; 
     prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ]; 
     prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ]; 

     nextKey.pos = this.getNextKeyWith("pos", h, 1); 
     nextKey.rot = this.getNextKeyWith("rot", h, 1); 
     nextKey.scl = this.getNextKeyWith("scl", h, 1); 

    } 

    //isPlaying must be true for update to work due to "early out" 
    //so remember the current play state: 
    var wasPlaying = this.isPlaying; 
    this.isPlaying = true; 

    //update with a delta time of zero: 
    this.update(0); 

    //reset the play state: 
    this.isPlaying = wasPlaying; 

} 

Il limite principale della funzione in termini di utilità è che non si può interpolare da un tempo arbitrario ad un altro. In pratica, puoi semplicemente scorrere l'animazione.

+0

Domanda molto interessante ... Stavo lavorando su un'animazione importata da collada e volevo reimpostare l'animazione sul fotogramma 0 immediatamente dopo averlo interrotto. Ho erroneamente cercato di farlo usando -> animation.update (0) -> animation.stop(), ma dopo aver letto la tua domanda, ho provato animation.update (0) -> animation.play (false, 0) -> animation .stop() ... E sembra funzionare in modo coerente. Per quanto riguarda il tuo problema (volendo riprodurre animazioni al contrario), il primo pensiero che ho avuto è stato quello di animare solo i fotogrammi inversi e la riproduzione dall'inizio di ... – Charlie

+0

Grazie per il tuo commento.Il mio obiettivo non era tanto giocare avanti e indietro, ma essere in grado di saltare da una posizione all'altra, interpolando tra di loro senza dover passare attraverso i fotogrammi in mezzo. Penso che tu possa farlo già con le animazioni del bersaglio morph. Ho notato l'altro giorno che le animazioni del morph target ora supportano anche la riproduzione al contrario. La skin è molto più coinvolta, penso, quindi suppongo che ci vorrà più tempo per avere le stesse caratteristiche. – null

risposta

2

È possibile utilizzare THREE.Clock e assegnare startTime, oldTime, elapsedTime.

+0

Grazie per la risposta. Scusa, non l'ho notato fino ad ora. Lo verificherò stasera ... – null

+0

Ciao di nuovo. Da quello che posso dire, THREE.Clock è appena usato per ottenere i tempi delta per ogni frame. Avrei dovuto menzionare nella domanda originale che ho provato ad aggiornare l'animazione con delta negativi, ma l'effetto era lo stesso dell'impostazione di currentTime (cioè l'animazione si è rotta). Fatemi sapere se non sto interpretando correttamente la vostra risposta. Grazie. – null

+0

Questi 2 URL ti possono aiutare. [collegamento 1] (http://stackoverflow.com/questions/12450716/animating-canvas-billboard-in-three-js) [collegamento 2] (http://catchvar.com/threejs-animating-blender-models) – Valay

Problemi correlati