2012-10-25 13 views
7

Używam skórki/animacji szkieletowej w ThreeJS. Mam animację i chcę być w stanie poruszać się w tył i w przód i przeskakiwać do różnych miejsc w niej, a nie do zwykłego zachowania w pętli.ThreeJS - jak ustawić bieżący czas w animacji

Animacja jest tworzony tak, jak w przykładzie:

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

Próbowałem aktualizacji animację z negatywnymi delt, jak również ustawienie animation.currentTime bezpośrednio:

animation.currentTime = animationLocation; 

These Wygląda na to, że działa tylko wtedy, gdy poruszam się do przodu w czasie, ale jeśli cofnę się, animacja zostanie przerwana i pojawi się błąd:

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

Jedną rzeczą, która ma rzeczywiście działa bez błędu jest wywołanie stop() a następnie play() z nowym Godzina rozpoczęcia:

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

... Jednak kiedy patrzę na to, co te funkcje są rzeczywiście robi, dotyczą one wiele, wiele funkcji wywoływanie, zapętlanie, resetowanie transformacji itd. Wydaje się, że to straszny sposób, nawet jeśli działa jak włamanie.

Możliwe, że ta funkcjonalność jeszcze nie istnieje, w takim przypadku spróbuję zagłębić się i utworzyć funkcję, która wykonuje minimalną ilość pracy, ale mam nadzieję, że istnieje inny sposób, niż ja nie mam. znaleziono t.

Czy ktoś może w tym pomóc?

[UPDATE]

Jako aktualizacji na moim toku, wyślę najlepsze rozwiązanie mam w tej chwili ...

Wyciągnąłem zawartość funkcji stop() i play() i usunąłem wszystko, co mogłem, przyjmując pewne założenia o pewnych wartościach, które zostały już ustawione przez "play()".

To nadal wygląda na to, że prawdopodobnie nie jest to najlepszy sposób na zrobienie tego, ale robi trochę mniej pracy niż po prostu dzwoniąc pod numer stop(), a następnie play().

To co udało mi się dostać do:

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; 

} 

Głównym ograniczeniem funkcji pod względem przydatności jest to, że nie można interpolować z jednego dowolnego czasu do drugiego. Możesz po prostu po prostu szorować w animacji.

+0

Bardzo interesujące pytanie ... Pracowałem nad animacją importowaną z collada i chciałem zresetować animację do klatki 0 natychmiast po jej zatrzymaniu. Pomyłkowo próbowałam to zrobić używając -> animation.update (0) -> animation.stop(), ale po przeczytaniu twojego pytania wypróbowałem animation.update (0) -> animation.play (false, 0) -> animation .stop() ... Wygląda na to, że działa konsekwentnie. Jeśli chodzi o twój problem (chcąc odtwarzać animacje w odwrotnej kolejności), pierwszą myślą, którą miałem, było jedynie animowanie odwróconych klatek i odtwarzanie od początku tego ... – Charlie

+0

Dzięki za komentarz.Moim celem było nie tyle granie w przód, ani w tył, ale umiejętność przeskakiwania z pozycji do pozowania, interpolowanie między nimi bez konieczności przechodzenia między ramkami. Myślę, że możesz to zrobić już za pomocą animacji celu morfingu. Niedawno zauważyłem, że animacja celu morfingu obsługuje teraz grę również w odwrotnej kolejności. Skórowanie jest o wiele bardziej zaangażowane, więc myślę, że dłużej będzie mieć te same funkcje. – null

Odpowiedz

2

Można użyć THREE.Clock i przypisać startTime, oldTime, elapsedTime.

+0

Dzięki za odpowiedź. Przepraszam, nie zauważyłem tego aż do teraz. Sprawdzę to dziś wieczorem ... – null

+0

Cześć jeszcze raz. Z tego, co wiem, THREE.Clock jest właśnie używany do uzyskania czasów delta dla każdej klatki. Powinienem był wspomnieć w oryginalnym pytaniu, że próbowałem zaktualizować animację za pomocą negatywnych delt, ale efekt był taki sam jak ustawienie currentTime (tzn. Animacja się zepsuła). Daj mi znać, jeśli nie interpretuję poprawnie twojej odpowiedzi. Dzięki. – null

+0

Być może te 2 adresy URL ci pomogą. [link 1] (http://stackoverflow.com/questions/12450716/animating-canvas-billboard-in-three-js) [link 2] (http://catchvar.com/threejs-animating-blender-models) – Valay

Powiązane problemy