【问题标题】:ThreeJS - how to set current time in AnimationThreeJS - 如何在动画中设置当前时间
【发布时间】:2012-10-15 10:13:20
【问题描述】:

我在 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() 函数的内容,并尽可能地删除了所有内容,对'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;

}

该函数在实用性方面的主要限制是您不能从一个任意时间插值到另一个时间。您基本上可以在动画中四处滑动。

【问题讨论】:

  • 非常有趣的问题...我正在处理从 collada 导入的动画,并希望在停止动画后立即将动画重置为第 0 帧。我错误地尝试通过使用 -> animation.update(0) -> animation.stop() 来做到这一点,但在阅读了你的问题后,尝试了 animation.update(0) -> animation.play(false, 0) -> animation .stop()... 而且它似乎始终如一地工作。至于您的问题(想要反向播放动画),我的第一个想法就是为反向帧设置动画,然后从头开始播放......
  • 感谢您的评论。我的目标不是向前和向后播放,而是能够从一个姿势跳到另一个姿势,在它们之间进行插值,而不必经过中间的帧。我认为您已经可以使用变形目标动画来做到这一点。前几天我注意到变形目标动画现在也支持反向播放。我认为剥皮涉及更多,所以我想拥有相同的功能需要更长的时间。

标签: javascript three.js


【解决方案1】:

您可以使用THREE.Clock 并分配startTimeoldTimeelapsedTime

【讨论】:

  • 感谢您的回复。抱歉,直到现在我才注意到。我今晚会检查一下...
  • 你好。据我所知,THREE.Clock 仅用于获取每帧的增量时间。我应该在原始问题中提到我确实尝试使用负增量更新动画,但效果与设置 currentTime 相同(即动画坏了。)如果我没有正确解释您的答案,请告诉我。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多