Aframe: сглаживание положения и вращения? - PullRequest
0 голосов
/ 19 ноября 2018

Я немного экспериментировал с 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>

Не могли бы вы знать, как решить эту проблему?

1 Ответ

0 голосов
/ 20 ноября 2018

Ваше описание звучит как линейная интерполяция . Использовать его здесь должно быть просто:

Как только маркер станет видимым, получите предыдущее видео положение / поворот и сделайте аппроксимацию, используя фактическую маркер положение / поворот. Затем обновите video , указав приблизительные значения.

Аппроксимация должна ослабить «дрожание». В этом случае я буду использовать функцию THREE lerp. Если вы не знакомы с линейной интерполяцией , тогда подумайте об этом как о методе приближения, использующем линейные функции (это может быть очень неточным, но я так думаю об этом).

Код (прикрепленный к маркеру) выглядит так:

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().

Здесь - сбой (одна коробка интерполирована, она движется довольно плавно).

...