aframevr / aframe

:a: Web framework for building virtual reality experiences.
https://aframe.io/
MIT License
16.55k stars 3.93k forks source link

look-controls component generates very shaky moves on older devices #4623

Open ghost opened 4 years ago

ghost commented 4 years ago

Hello, When using older devices, on version 0.9.2, the scene moves very slowly but remains steady when moving the phone, which seems fine to me. On version 1.0.4, the scene reacts well to the phone moving but the display is super shaky, it's impossible to get a steady image even without touching the phone. Is there a way to get the previous behaviour back or to be able to completely deactivate the device motion when the device is unable to follow and just use the dragging to move the scene? What is weird is that the phone has the DeviceMotionEvent and DeviceOrientationEvent but they just don't work properly, and I don't know how to detect this...

I noticed a change between versions so I consider it both an A-Frame issue and a support request so I also posted it on stackoverflow but without success at the moment : https://stackoverflow.com/questions/62347897/a-frame-look-controls-very-unstable-on-older-devices

dmarcos commented 4 years ago

What Android / Chrome version? Does it only happen on WebView? How about on the regular browser?

ghost commented 4 years ago

Sorry, I should have specified it. It's on WebView but also on the regular browser. On the ASUS X008D I have Android 8.0 and Chrome 83.0. The behaviour is exactly the same in the webview and the browser. I don't have the other test phones with me right now but they were on Android 6 and 7, and the behaviour was the same too. Thanks!

dmarcos commented 4 years ago

DeviceMotionEvent.rotationRate switched from degrees per second to radians per second a long time ago and it was addressed in A-Frame. See context in https://github.com/aframevr/aframe/issues/3476 Sorry I don't have access to any old devices to test.

Your devices are on very old Android versions. It's not possible to update Android? It looks they might be still using the old API. That would explain why 0.9.2 works. Make sure that the DeviceMotion API is available and enabled in chrome://flags.

dmarcos commented 4 years ago

You might be able to detect the Android version and disable magic window. You could use master builds

ghost commented 4 years ago

I don't find the DeviceMotion key in chrome://flags so I'm not really sure what to conclude ^^' What I don't understand is that I can fire devicemotion and deviceorientation events, they are available in the window global, is it normal? Is there a way to know the API version?

It's okay for me to disable magic window on versions 7 and below but is 8 that old? I see it's still largely used, there are only 40% devices on versions superior to 8. Mine is on 8.1.0 and I have the issue. The thing is I don't know on which devices it will be used so I want to minimize the risk to have a shaky motion and disable magic window only in these cases.

I'll make some extra tests to try to find something more determining that I can use to activate magic window or not.

Thanks for your help

ghost commented 4 years ago

Okay I did a bit of debugging and I found something weird about the magicWindowControls in look-controls. Line 59 the THREE.DeviceOrientationControls object is initialized, meaning it's enabled. Line 60 there's a test for DeviceOrientationEvent and its requestPermission property. In my case I don't pass this test and then never pass line 61 that puts the enabled property to false. Then line 248 magicWindowControls are enabled and update method is called, leading to the erractic behaviour, when it should actually not be called. Would a fix be as simple as moving line 61 one line higher so it's disabled by default and enabled only if permissions are granted? It fixes my case but I need to confirm it doesn't break the normal behaviour on functioning devices. Edit : it's actually stupid, it seems like only Apple devices have the requestPermission property so it would prevent all Android devices to work, sorry :)

ghost commented 4 years ago

Ok, with a little more debugging, I noticed that I get the "Sensor could not be read" in console, which seems to come from webvr polyfills which uses cardboard-vr-display pose-sensor and gets a NotReadableError. Would there be a way to catch this kind of error maybe?

dmarcos commented 4 years ago

Thanks for investigating. I don’t have any old device to test. Feel free to open a PR. Easier to discuss over working code

ghost commented 4 years ago

Well I don't really have an "universal" fix for that unfortunately. I managed to disable it on devices that did not support the Gyroscope class from Sensor API by using this, but I would consider that a dirty fix that mostly answers to my issue and would probably not be good for other people.

    var gyroscope = null;
    try {
        gyroscope = new Gyroscope();
        gyroscope.addEventListener('error', event => {
            document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
        });
        gyroscope.start();
        // Stop the gyroscope after trying so it does not run in background.
        setTimeout(function() { gyroscope.stop(); }, 500);
    } catch (error) {
        document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
    }

If you think it should be investigated further and integrated somewhere in A-Frame, I guess you'd know better than me where to make the changes, otherwise I'm good with this (devices will support more and more the Sensor API anyway), the issue can be closed and maybe this snippet will be useful to others :)

federico-camonapp commented 3 years ago

Hi there, this is also happening on some iOS devices (iPhone X, iPhone XS Max). I've managed to reproduce it with several AFrame examples. Bad news here, at least from my end, is that this is not happening every time, so it makes kind of difficult to reproduce (AFrame v1.0.3 and 1.0.4)

federico-camonapp commented 3 years ago

Forgot to mention that if the device is "moving", it works ok, however when the device stands still, the camera begins to shake