I'm developing a PoC with ViroReact lib but I'm getting strage values for the camera rotation.
Environment:
- Device: Android 10. Xiaomi Mi 9
- ViroReact 2.20.2
The ViroARScene.getCameraOrientationAsync() returns unexpected values in rotation array when I rotate the device over the y-axis, trying to keep the x and z axis fixed.
Specifically, when the y-axis reaches the -90º the x/z values change to +/180º and from this point the y-axis values are getting close to 0, for instance, instead of -135º the y-axis value is -45 with the x/z values in +/-180. In other words the y-axis values NEVER return an absolute value over 90.
Some examples (values have got an error margin of about 6 degrees):
- Rotation expected: [0, -90, 0]. Returned rotation: [+/-180, -90, +/-180]
- Rotation expected: [0, -135, 0]. Returned rotation: [+/-180, -45, +/-180]
- Rotation expected: [0, -180, 0]. Returned rotation: [+/-180, 0, +/-180]
Questions:
- Why the absolute value of y-axis is never greater than 90 ?
- Why the x/z values change to +/-180º when I reach some point (+/-90º in y-axis) if I'm just rotating the device over the y-axis.
- Is this the expeted behavior ? If so, could anyone explain these values (please).
The code to retrieve the values:
<ViroARScene onTrackingUpdated={this._onInitialized} anchorDetectionTypes={"PlanesVertical"}>
...
</ViroARScene>
_onInitialized(state, reason) {
if (state === ViroConstants.TRACKING_NORMAL && reason === ViroConstants.TRACKING_REASON_NONE) {
console.log('Tracking initiated');
this._scene.getCameraOrientationAsync().then(
(orientation) => {
console.log('Cam rot:', round(orientation.rotation));
});
}
}
I've also created a GitHub issue with some mockups to show the rotation values expected and returned: https://github.com/ViroCommunity/viro/issues/13
I think what you're coming up against might be Gimbal lock, which is the reason that a lot of 3d rotators are expressed in Quaternions, instead of the xyz (aka Euler - pronounced "oiler") system you are using now. It's probably expected behaviour for your system.
I'm not familiar with your platform but it might have built-in helpers or alternative methods you can use in order to work with Quaternions instead, if not then a solution for you might be to install a library (or write some code) that translates between Euler angles and Quaternions so that your calculations make more sense, if you are going to be spending time around the y-0.