ThreeJS でスキニング/スケルトン アニメーションを使用しています。アニメーションがあり、通常のループ動作ではなく、前後に移動したり、アニメーション内の別の場所にジャンプしたりしたいと考えています。
例のように、アニメーションは次のように作成されます。
var animation = new THREE.Animation( mesh, geometry.animation.name );
animation.currentTime を直接設定するだけでなく、負のデルタでアニメーションを更新しようとしました:
animation.currentTime = animationLocation;
これらは時間を進めた場合にのみ機能するように見えますが、逆方向に移動するとアニメーションが壊れてエラーが発生します:
THREE.Animation.update: Warning! Scale out of bounds: ... on bone ...
エラーなしで実際に動作することの 1 つは、呼び出しstop()
てからplay()
新しい開始時刻を指定することです。
animation.stop();
animation.play( true, animationLocation );
...しかし、これらの関数が実際に何をしているのかを見ると、多くの関数呼び出し、ループ、変換のリセットなどが含まれます。ハックとして機能するとしても、これは恐ろしい方法のように思えます。
この機能はまだ存在しない可能性があります。その場合は、掘り下げて、最小限の作業を行う関数を作成しようとしますが、まだ見つかっていない別の方法があることを願っています。
誰でもこれを手伝ってもらえますか?
[アップデート]
進捗状況の最新情報として、現時点での最善の解決策を投稿します...
stop()
関数と関数の内容を取り出し、play()
「play()」によって特定の値が既に設定されていることを前提として、可能な限りすべてを取り除きました。
stop()
これはおそらく最善の方法ではないように思えますが、 thenを呼び出すよりも作業が少し少なくなりplay()
ます。
これは私がそれを得ることができたものです:
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;
}
有用性に関する関数の主な制限は、ある任意の時間から別の時間に補間できないことです。基本的に、アニメーション内をスクラブするだけです。