我在 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()
和 play()
函数的内容,并剥离了所有可能的内容,对已经设置的某些值做了一些假设通过“播放()”。
这似乎仍然不是最好的方法,但它比仅调用 stop()
然后调用 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;
}
函数在实用性方面的主要限制是您不能从一个任意时间插值到另一个时间。您基本上可以在动画中四处滑动。
最佳答案
您可以使用 THREE.Clock
并分配 startTime
、oldTime
、elapsedTime
。
关于javascript - 三个JS——如何在Animation中设置当前时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13065018/