【问题标题】:Aframe: smoothing position and rotation?Aframe:平滑位置和旋转?
【发布时间】:2019-04-22 03:40:48
【问题描述】:

我一直在尝试使用 Aframe 和 AR.js。对于增强现实应用程序,一个常见问题是放置在标记上的对象变得非常“抖动”或“生涩”。我已经对该问题进行了一些研究,似乎解决此问题的一种可能方法是在几帧上平滑旋转和位置。不幸的是,这方面的教程几乎不存在,我才刚刚开始掌握 Html/Javascript。

因此我的问题是:你知道是否有可能在一个框架实体中有一个函数来提取位置和旋转,平滑它们,然后将它们传递给(我想)一个使用这些平滑值的子实体用于安置?

<a-entity position="0 0 0" rotation="0 0 0" >
   <a-video Mysmoothingfunction src="#video" width="3.5" height="2"></a-video>
</a-entity>

我可以想象开头可能是这样的:

<script type="text/javascript"> 
   AFRAME.registerComponent("listener", {
    schema : 
    {
        stepFactor : {
            type : "number",
            default : 0.05
        }
    },
   tick: function() {
       this.getProperty("position"); // something like this?
      }
</script>

您知道如何解决这个问题吗?

【问题讨论】:

    标签: javascript html aframe ar.js


    【解决方案1】:

    您的描述听起来像linear interpolation。在这里使用它应该很简单:

    标记可见后,获取之前的视频位置/旋转,并使用实际的标记位置/旋转进行近似。然后用近似值更新视频

    近似值应该可以缓解“抖动”。在这种情况下,我将使用THREE lerp 函数。 如果您不熟悉linear interpolation,则可以将其视为使用线性函数进行逼近的一种方法(这可能非常不精确,但我是这么认为的)。

    代码(附加到标记)如下所示:

    AFRAME.registerComponent("listener", {
      init: function() {
        this.target = document.querySelector('#target'); // your video
        this.prevPosition = null; // initially there is no position or rotation
        this.prevRotation = null;
      },
    
      tick: function() {
        if (this.el.object3D.visible) {
          this.target.setAttribute('visible', 'true')
    
          if(!this.prevPosition && !this.prevRotation) { 
            // there are no values to lerp from - set the initial values
            this.target.setAttribute('position', this.el.getAttribute('position'))
            this.target.setAttribute('rotation', this.el.getAttribute('rotation'))
          } else {
            // use the previous values to get an approximation 
            this.target.object3D.position.lerp(this.prevPosition, 0.1)
    
            // this (below) may seem ugly, but the rotation is a euler, not a THREE.Vector3, 
            // so to use the lerp function i'm doing some probably unnecessary conversions
            let rot = this.target.object3D.rotation.toVector3().lerp(this.prevRotation, 0.1)
            this.target.object3D.rotation.setFromVector3(rot)
          }
          // update the values
          this.prevPosition = this.el.object3D.position
          this.prevRotation = this.el.object3D.rotation
        } else {
         // the marker dissapeared - reset the values
         this.target.setAttribute('visible', 'false')
         this.prevPosition = null;
         this.prevRotation = null;
       }
      }
    })
    

    您可以注意到我设置了object3D 的值,而不是官方的API (setAttribute() / getAttribute())。它应该更快,这在tick() 函数中进行更改时是可取的。

    Here 是一个小故障(一个盒子被插值,它的移动很平稳)。

    【讨论】:

    • 很快就会有一个事件,当标记被发现或丢失时,更多关于它here
    • 嘿@Piotr Adam Milewski,我真的很喜欢您在上面发布的代码。在尝试理解并可能使用它时,我发现了两个问题。我在 AR.js 存储库中创建了一个问题来讨论这个问题:github.com/jeromeetienne/AR.js/issues/467 也许你想加入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 2021-05-11
    相关资源
    最近更新 更多