How to rotate view (cube interior) with mobile device gyroscope? - Issues with interaction

I’ve been working on a demo in P5.js that would display the inside of a cube with rotation followed by the rotation of a mobile device. We could call this poor-mans-AR, as I don’t need a camera feed, just the rotation. To get the angles I’ve used the code:

window.addEventListener('deviceorientation', function(e) 
{
  if (e.alpha) {
    rotZ = radians(e.alpha);
    rotX = radians(e.beta);
    rotY = radians(e.gamma);
  }
});

Then, to display the cube I’ve used the code:

var cam, fov = 0.5, rotX = 0, rotY = 0, rotZ = 0;
var dim = Math.floor(Math.min(window.innerWidth, window.innerHeight));

function setup() {
  canvas = createCanvas(dim, dim, WEBGL);
  canvas.id('p5canvas');
  cam = createCamera();
}

function draw() {
  perspective(PI * fov, 1, 0.01, 10 * dim);
  cam.setPosition(0,0,0);
  
  rotateZ(rotZ);
  rotateX(rotX);
  rotateY(rotY);

  clear();
  fill(255);
  stroke(0);
  strokeWeight(5);
  box(100);
}

And to this point, it works… sort of. Rotating the phone along X-axis (e.beta) works as expected. I can easily see the floor and the ceiling of the cube. However, when the phone is facing forward, the problem appears. When I move my phone left or right, rotating my whole body (so the phone revolves along Y-axis (e.gamma)) the cube rolls. It works more like the rotation along Z-axis (e.alpha).

So far I’ve tried some variations with angle orders, but then the problem appears with a glitch when the phone is facing forward. I guess that’s a gimbal lock issue with Euler angles?

I want the result to be a seamless experience of seeing the interior of a 3D cube, like we were inside it and were looking through a screen.

However, this problem must’ve been solved, as in AR and VR apps you can easily look around. I would appreciate any help or directions where to follow.

Thanks in advance!

UPDATE EDIT
So I’ve managed to come up with a result very close to my expectations. Yet, there’s still a minor glitch, when the phone is vertical and facing forward. The code I’ve used is here:

var cam, fov = 0.5, rotX = 0, rotY = 0, rotZ = 0;
var dim = Math.floor(Math.min(window.innerWidth, window.innerHeight));

function setup() {
  canvas = createCanvas(dim, dim, WEBGL);
  canvas.id('p5canvas');
  cam = createCamera();
}

function draw() {
  perspective(PI * fov, 1, 0.01, 10 * dim);
  cam.setPosition(0,0,0);
  
  // set camera rotation
  rotateX(rotX);
  rotateY(rotY);

  clear();
  fill(255);
  stroke(0);
  strokeWeight(5);
  box(100);
}

window.addEventListener('deviceorientation', function(e) 
{
  if (e.alpha) {
    gyro = true;
    rotY = -radians(parseFloat(e.alpha + e.gamma).toFixed(1));
    rotX = map(parseFloat(e.beta).toFixed(2), 0, 180, -PI/2, PI/2);
  }
});

When I used only X and Y angles in the rotation that was much more intuitive. Yet the glitch appears, which wasn’t there before :frowning:

1 Like