2

I have been experimenting a bit with Aframe and AR.js. For augmented reality applications, a common problem is that the object placed on a marker becomes quite 'jittery' or 'jerky'. I have done some research into the problem already and it appears that a possible way to address this issue is to smooth the rotation and the position over several frames. Unfortunately, tutorials on doing so are virtually nonexistent, and I am just starting to get to grips with Html/Javascript.

Hence my question: Would you know if it is possible to have a function in an aframe entity which extracts the position and rotation, smooths them, and then passes them on to (I imagine) a child entity which uses those smoothed values for placement?

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

I could imagine that the start might look something like this:

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

Would you have any idea how to tackle that issue?

J.Galt
  • 529
  • 3
  • 15

1 Answers1

5

Your description sounds like linear interpolation. Utilizing it here should be simple:

Once the marker is visible, get the previous video position / rotation, and make an approximation using the actual marker position / rotation. Then update the video, with the approximated values.

The approximation should ease the 'jitter'. In this case, i'll be using the THREE lerp function. If you're not familiar with linear interpolation then think of it as a method of approximation using linear functions (this may be highly imprecise, but it's how i think of it).

The code (attached to the marker) looks like this:

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;
   }
  }
})

You can notice im setting the values of the object3D instead of the official API (setAttribute() / getAttribute()). It should be faster, which is desirable when making changes within the tick() function.

Here is a glitch (one box is interpolated, its moving quite smoothly).

Piotr Adam Milewski
  • 14,150
  • 3
  • 21
  • 42
  • Soon there will be an event when the marker is found, or lost, more on it [here](https://stackoverflow.com/questions/44799413/how-to-detect-when-a-marker-is-found-in-ar-js). – Piotr Adam Milewski Nov 19 '18 at 22:33
  • Hey @Piotr Adam Milewski, I really like the code you posted above. While trying to understand and maybe use it, I discovered two problems. I created an issue over at the AR.js repo to discuss this: https://github.com/jeromeetienne/AR.js/issues/467 Maybe you want to jump in. – janpio Feb 08 '19 at 14:33