Skip to content

Commit 856d185

Browse files
committed
only apply user height if there is no positional tracking (fixes #1856)
1 parent 86d9d6f commit 856d185

File tree

11 files changed

+118
-85
lines changed

11 files changed

+118
-85
lines changed

‎docs/core/utils.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,21 @@ diff({a: 1, b: 2, c: 3}, {b: 2, c: 4})
132132
### `AFRAME.utils.extendDeep(target, source, [source, ...])`
133133

134134
[Deep Assign](https://www.npmjs.com/package/deep-assign)
135+
136+
## `AFRAME.utils.device`
137+
138+
### `AFRAME.utils.device.checkHasPositionalTracking()`
139+
140+
Checks if there is positional tracking available. Returns a `boolean`.
141+
142+
### `AFRAME.utils.device.checkHeadsetConnected()`
143+
144+
Checks if a VR headset is connected by looking for orientation data. Returns a `boolean`.
145+
146+
### `AFRAME.utils.device.isGearVR()`
147+
148+
Checks if device is Gear VR. Returns a `boolean`.
149+
150+
### `AFRAME.utils.device.isMobile()`
151+
152+
Checks if device is a smartphone. Returns a `boolean`.

‎src/components/camera.js‎

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var THREE = require('../lib/three');
33
var utils = require('../utils/');
44
var bind = utils.bind;
55

6-
var checkHeadsetConnected = utils.checkHeadsetConnected;
6+
var checkHasPositionalTracking = utils.device.checkHasPositionalTracking;
77

88
/**
99
* Camera component.
@@ -121,20 +121,18 @@ module.exports.Component = registerComponent('camera', {
121121
/**
122122
* Remove the height offset (called when entering VR) since WebVR API gives absolute
123123
* position.
124-
* Does not apply for mobile.
125124
*/
126125
removeHeightOffset: function () {
127126
var currentPosition;
128127
var el = this.el;
129-
var headsetConnected;
130-
var sceneEl = el.sceneEl;
128+
var hasPositionalTracking;
131129
var userHeightOffset = this.data.userHeight;
132130

133-
// If there's not a headset connected we keep the offset.
131+
// Remove the offset if there is positional tracking when entering VR.
134132
// Necessary for fullscreen mode with no headset.
135-
// Checking this.headsetConnected to make the value injectable for unit tests.
136-
headsetConnected = this.headsetConnected || checkHeadsetConnected();
137-
if (sceneEl.isMobile || !userHeightOffset || !headsetConnected) { return; }
133+
// Checking this.hasPositionalTracking to make the value injectable for unit tests.
134+
hasPositionalTracking = this.hasPositionalTracking || checkHasPositionalTracking();
135+
if (!userHeightOffset || !hasPositionalTracking) { return; }
138136

139137
currentPosition = el.getAttribute('position') || {x: 0, y: 0, z: 0};
140138
el.setAttribute('position', {
@@ -149,9 +147,9 @@ module.exports.Component = registerComponent('camera', {
149147
*/
150148
saveCameraPose: function () {
151149
var el = this.el;
152-
var headsetConnected = this.headsetConnected || checkHeadsetConnected();
150+
var hasPositionalTracking = this.hasPositionalTracking || checkHasPositionalTracking();
153151

154-
if (this.savedPose || !headsetConnected) { return; }
152+
if (this.savedPose || !hasPositionalTracking) { return; }
155153

156154
this.savedPose = {
157155
position: el.getAttribute('position'),
@@ -165,9 +163,9 @@ module.exports.Component = registerComponent('camera', {
165163
restoreCameraPose: function () {
166164
var el = this.el;
167165
var savedPose = this.savedPose;
168-
var headsetConnected = this.headsetConnected || checkHeadsetConnected();
166+
var hasPositionalTracking = this.hasPositionalTracking || checkHasPositionalTracking();
169167

170-
if (!savedPose || !headsetConnected) { return; }
168+
if (!savedPose || !hasPositionalTracking) { return; }
171169

172170
// Reset camera orientation.
173171
el.setAttribute('position', savedPose.position);

‎src/components/cursor.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module.exports.Component = registerComponent('cursor', {
3232
dependencies: ['raycaster'],
3333

3434
schema: {
35-
fuse: {default: utils.isMobile()},
35+
fuse: {default: utils.device.isMobile()},
3636
fuseTimeout: {default: 1500, min: 0}
3737
},
3838

‎src/components/look-controls.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
var registerComponent = require('../core/component').registerComponent;
22
var THREE = require('../lib/three');
3-
var isMobile = require('../utils/').isMobile();
3+
var isMobile = require('../utils/').device.isMobile();
44
var bind = require('../utils/bind');
55

66
// To avoid recalculation at every mouse movement tick

‎src/components/scene/vr-mode-ui.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ module.exports.Component = registerComponent('vr-mode-ui', {
9090
var sceneEl = this.el;
9191
var orientationModalEl = this.orientationModalEl;
9292
if (!orientationModalEl || !sceneEl.isMobile) { return; }
93-
if (!utils.isLandscape() && sceneEl.is('vr-mode')) {
93+
if (!utils.device.isLandscape() && sceneEl.is('vr-mode')) {
9494
// Show if in VR mode on portrait.
9595
orientationModalEl.classList.remove(HIDDEN_CLASS);
9696
} else {

‎src/core/scene/a-scene.js‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ var ANode = require('../a-node');
1212
var initPostMessageAPI = require('./postMessage');
1313

1414
var bind = utils.bind;
15-
var checkHeadsetConnected = utils.checkHeadsetConnected;
15+
var checkHeadsetConnected = utils.device.checkHeadsetConnected;
16+
var isIOS = utils.device.isIOS();
17+
var isMobile = utils.device.isMobile();
1618
var registerElement = re.registerElement;
17-
var isIOS = utils.isIOS();
18-
var isMobile = utils.isMobile();
1919
var warn = utils.debug('core:a-scene:warn');
2020

2121
/**

‎src/utils/checkHeadsetConnected.js‎

Lines changed: 0 additions & 16 deletions
This file was deleted.

‎src/utils/device.js‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
var THREE = require('../lib/three');
2+
var dolly = new THREE.Object3D();
3+
var controls = new THREE.VRControls(dolly);
4+
5+
/**
6+
* Determine if a headset is connected by checking if the
7+
* orientation is available
8+
*/
9+
function checkHeadsetConnected () {
10+
var orientation;
11+
controls.update();
12+
orientation = dolly.quaternion;
13+
if (orientation._x !== 0 || orientation._y !== 0 || orientation._z !== 0) {
14+
return true;
15+
}
16+
return false;
17+
}
18+
module.exports.checkHeadsetConnected = checkHeadsetConnected;
19+
20+
/**
21+
* Check for positional tracking.
22+
*/
23+
function checkHasPositionalTracking () {
24+
var position = new THREE.Vector3();
25+
return (function () {
26+
if (isMobile() || isGearVR()) { return false; }
27+
controls.update();
28+
dolly.updateMatrix();
29+
position.setFromMatrixPosition(dolly.matrix);
30+
if (position.x !== 0 || position.y !== 0 || position.z !== 0) {
31+
return true;
32+
}
33+
return false;
34+
})();
35+
}
36+
module.exports.checkHasPositionalTracking = checkHasPositionalTracking;
37+
38+
/**
39+
* Checks if browser is mobile.
40+
* @return {Boolean} True if mobile browser detected.
41+
*/
42+
var isMobile = (function () {
43+
var _isMobile = false;
44+
(function (a) {
45+
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
46+
_isMobile = true;
47+
}
48+
if (isIOS()) {
49+
_isMobile = true;
50+
}
51+
if (isGearVR()) {
52+
_isMobile = false;
53+
}
54+
})(navigator.userAgent || navigator.vendor || window.opera);
55+
56+
return function () { return _isMobile; };
57+
})();
58+
module.exports.isMobile = isMobile;
59+
60+
function isIOS () {
61+
return /iPad|iPhone|iPod/.test(navigator.platform);
62+
}
63+
module.exports.isIOS = isIOS;
64+
65+
function isGearVR () {
66+
return /SamsungBrowser.+Mobile VR/i.test(navigator.userAgent);
67+
}
68+
module.exports.isGearVR = isGearVR;
69+
70+
/**
71+
* Checks mobile device orientation.
72+
* @return {Boolean} True if landscape orientation.
73+
*/
74+
module.exports.isLandscape = function () {
75+
return window.orientation === 90 || window.orientation === -90;
76+
};

‎src/utils/index.js‎

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ var objectAssign = require('object-assign');
66

77
module.exports.bind = require('./bind');
88
module.exports.coordinates = require('./coordinates');
9-
module.exports.checkHeadsetConnected = require('./checkHeadsetConnected');
109
module.exports.debug = require('./debug');
10+
module.exports.device = require('./device');
1111
module.exports.entity = require('./entity');
1212
module.exports.forceCanvasResizeSafariMobile = require('./forceCanvasResizeSafariMobile');
1313
module.exports.material = require('./material');
@@ -89,42 +89,6 @@ module.exports.diff = function (a, b) {
8989
return diff;
9090
};
9191

92-
/**
93-
* Checks if browser is mobile.
94-
* @return {Boolean} True if mobile browser detected.
95-
*/
96-
module.exports.isMobile = function () {
97-
var check = false;
98-
(function (a) {
99-
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
100-
check = true;
101-
}
102-
if (isIOS()) {
103-
check = true;
104-
}
105-
if (isGearVR()) {
106-
check = false;
107-
}
108-
})(navigator.userAgent || navigator.vendor || window.opera);
109-
return check;
110-
};
111-
112-
var isIOS = module.exports.isIOS = function () {
113-
return /iPad|iPhone|iPod/.test(navigator.platform);
114-
};
115-
116-
var isGearVR = module.exports.isGearVR = function () {
117-
return /SamsungBrowser.+Mobile VR/i.test(navigator.userAgent);
118-
};
119-
120-
/**
121-
* Checks mobile device orientation.
122-
* @return {Boolean} True if landscape orientation.
123-
*/
124-
module.exports.isLandscape = function () {
125-
return window.orientation === 90 || window.orientation === -90;
126-
};
127-
12892
/**
12993
* Returns whether we should capture this keyboard event for keyboard shortcuts.
13094
* @param {Event} event Event object.

‎src/utils/mobile.js‎

Whitespace-only changes.

0 commit comments

Comments
 (0)