2012-10-25 8 views
7

Ich verwende Skinning/Skeleton Animation in ThreeJS. Ich habe eine Animation, und ich möchte in der Lage sein, rückwärts und vorwärts durch sie zu gehen und zu verschiedenen Orten innerhalb derselben zu springen, anstatt das übliche Schleifenverhalten.ThreeJS - wie man die aktuelle Zeit in Animation einstellt

Die Animation wird wie folgt erstellt, wie im Beispiel:

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

Ich habe versucht, die Animation mit negativen Deltas zu aktualisieren, sowie der Einstellung animation.currentTime direkt:

animation.currentTime = animationLocation; 

These scheinen nur zu funktionieren, wenn ich mich zeitlich vorwärts bewege, aber wenn ich rückwärts gehe, bricht die Animation ab und ich bekomme einen Fehler:

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

Eine Sache, die tatsächlich ohne Fehler funktioniert ist stop() und dann play() mit einer neuen Startzeit zu nennen:

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

... aber wenn ich sehe, was diese Funktionen tatsächlich tun, beinhalten sie viele, viele Funktion Aufrufe, Schleifen, Zurücksetzen von Transformationen usw. Das scheint ein schrecklicher Weg zu sein, selbst wenn es als Hack funktioniert.

Es kann sein, dass diese Funktionalität noch nicht existiert, in diesem Fall werde ich versuchen, zu graben und eine Funktion zu erstellen, die eine minimale Menge Arbeit macht, aber ich hoffe, es gibt eine andere Möglichkeit, t gefunden.

Kann mir jemand dabei helfen?

[UPDATE]

als Update auf meine Fortschritte, ich werde die beste Lösung poste ich zu dieser Zeit haben ...

ich den Inhalt der stop() und play() Funktionen herausgezogen wird, und alles, was ich konnte, aussortieren und einige Annahmen über bestimmte Werte machen, die bereits von 'play()' festgelegt wurden.

Dies scheint immer noch wie es ist wahrscheinlich nicht der beste Weg, es zu tun, aber es ist ein bisschen weniger Arbeit als nur stop() dann play() aufrufen.

Dies ist, was ich in der Lage war, es zu bekommen unten:

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; 

} 

Die wichtigste Einschränkung der Funktion in Bezug auf die Nützlichkeit ist, dass man nicht von einem beliebigen Zeitpunkt zu einem anderen interpolieren kann. Sie können im Grunde nur in der Animation herumschrubben.

+0

Sehr interessante Frage ... Ich habe an einer Animation gearbeitet, die aus Collada importiert wurde, und wollte die Animation unmittelbar nach dem Stoppen auf Frame 0 zurücksetzen. Ich habe versehentlich versucht, dies zu tun, indem ich -> animation.update (0) -> animation.stop(), aber nach dem Lesen Ihrer Frage versucht, animation.update (0) -> animation.play (false, 0) -> Animation .stop() ... Und es scheint, als ob es konsequent funktioniert. Was Ihr Problem angeht (ich wollte Animationen in umgekehrter Reihenfolge abspielen), war der erste Gedanke, den ich hatte, nur die umgekehrten Frames zu animieren und von Anfang an zu spielen ... – Charlie

+0

Danke für Ihren Kommentar.Mein Ziel war nicht so sehr, es vorwärts und rückwärts zu spielen, sondern in der Lage zu sein, von Pose zu Pose zu springen, zwischen ihnen zu interpolieren, ohne die Frames dazwischen durchgehen zu müssen. Ich denke du kannst das schon mit Morph Target Animationen machen. Neulich ist mir aufgefallen, dass die Morph-Zielanimationen nun auch das Rückwärtsspielen unterstützen. Skinning ist viel mehr involviert, denke ich, also denke ich, dass es länger dauern wird, die gleichen Features zu haben. – null

Antwort

2

Sie können THREE.Clock verwenden und startTime, oldTime, elapsedTime zuweisen.

+0

Danke für die Antwort. Tut mir leid, ich habe es bis jetzt nicht bemerkt. Ich werde das heute Abend überprüfen ... – null

+0

Hallo nochmal. Von dem, was ich sagen kann, wird THREE.Clock nur verwendet, um Delta-Zeiten für jeden Rahmen zu erhalten. Ich hätte in der ursprünglichen Frage erwähnen sollen, dass ich versucht habe, die Animation mit negativen Deltas zu aktualisieren, aber der Effekt war derselbe wie das Setzen von currentTime (dh die Animation ist kaputt gegangen). Bitte lassen Sie mich wissen, wenn ich Ihre Antwort nicht richtig interpretiere. Vielen Dank. – null

+0

Vielleicht helfen Ihnen diese 2 URLs. [link 1] (http://stackoverflow.com/questions/12450716/animating-canvas-billboard-in-three-js) [link 2] (http://catchvar.com/threejs-animating-blender-models) – Valay

Verwandte Themen