我在 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 ...
实际工作没有错误的一件事是调用stop()
,然后play()
使用新的开始时间:
animation.stop();
animation.play( true, animationLocation );
...但是,当我查看这些函数实际上在做什么时,它们涉及许多函数调用、循环、重置转换等。这似乎是一种可怕的方法,即使它可以作为一种 hack。
可能此功能尚不存在,在这种情况下,我将尝试挖掘并创建一个工作量最少的功能,但我希望还有另一种我还没有找到的方法。
有人能帮忙吗?
[更新]
作为我进度的更新,我将发布我目前拥有的最佳解决方案......
我提取了stop()
andplay()
函数的内容,并尽可能地剥离了所有内容,对“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;
}
该函数在实用性方面的主要限制是您不能从一个任意时间插值到另一个时间。您基本上可以在动画中擦洗。