Skip to content

Commit 630038e

Browse files
committed
ios fix (#466) applied manually to existing DeviceOrientationControls
1 parent c4f1c0b commit 630038e

9 files changed

+88
-47
lines changed

aframe/build/aframe-ar-new-location-only.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aframe/build/aframe-ar-new-location-only.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

aframe/build/aframe-ar-nft.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aframe/build/aframe-ar-nft.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

aframe/build/aframe-ar.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aframe/build/aframe-ar.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

three.js/build/ar-threex-location-only.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

three.js/build/ar-threex-location-only.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

three.js/src/location-based/js/device-orientation-controls.js

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import { Euler, EventDispatcher, MathUtils, Quaternion, Vector3 } from "three";
55

6+
const isIOS = navigator.userAgent.match(/iPhone|iPad|iPod/i);
7+
68
const _zee = new Vector3(0, 0, 1);
79
const _euler = new Euler();
810
const _q0 = new Quaternion();
@@ -30,7 +32,7 @@ class DeviceOrientationControls extends EventDispatcher {
3032

3133
this.enabled = true;
3234

33-
this.deviceOrientation = {};
35+
this.deviceOrientation = null;
3436
this.screenOrientation = 0;
3537

3638
this.alphaOffset = 0; // radians
@@ -44,8 +46,25 @@ class DeviceOrientationControls extends EventDispatcher {
4446

4547
this.smoothingFactor = 1;
4648

47-
const onDeviceOrientationChangeEvent = function (event) {
48-
scope.deviceOrientation = event;
49+
const onDeviceOrientationChangeEvent = function ({
50+
alpha,
51+
beta,
52+
gamma,
53+
webkitCompassHeading,
54+
}) {
55+
if (isIOS) {
56+
const ccwNorthHeading = 360 - webkitCompassHeading;
57+
scope.alphaOffset = MathUtils.degToRad(ccwNorthHeading - alpha);
58+
scope.deviceOrientation = { alpha, beta, gamma, webkitCompassHeading };
59+
} else {
60+
if (alpha < 0) alpha += 360;
61+
scope.deviceOrientation = { alpha, beta, gamma };
62+
}
63+
window.dispatchEvent(
64+
new CustomEvent("camera-rotation-change", {
65+
detail: { cameraRotation: object.rotation },
66+
}),
67+
);
4968
};
5069

5170
const onScreenOrientationChangeEvent = function () {
@@ -123,9 +142,10 @@ class DeviceOrientationControls extends EventDispatcher {
123142
);
124143

125144
scope.enabled = false;
145+
scope.deviceOrientation = null;
126146
};
127147

128-
this.update = function () {
148+
this.update = function ({ theta = 0 } = { theta: 0 }) {
129149
if (scope.enabled === false) return;
130150

131151
const device = scope.deviceOrientation;
@@ -143,45 +163,63 @@ class DeviceOrientationControls extends EventDispatcher {
143163
? MathUtils.degToRad(scope.screenOrientation)
144164
: 0; // O
145165

146-
if (this.smoothingFactor < 1) {
147-
if (this.lastOrientation) {
148-
const k = this.smoothingFactor;
149-
alpha = this._getSmoothedAngle(
166+
if (isIOS) {
167+
const currentQuaternion = new THREE.Quaternion();
168+
setObjectQuaternion(currentQuaternion, alpha, beta, gamma, orient);
169+
// Extract the Euler angles from the quaternion and add the heading angle to the Y-axis rotation of the Euler angles
170+
// (If we replace only the alpha value of the quaternion without using Euler angles, the camera will rotate unexpectedly. This is because a quaternion does not represent rotation values individually but rather through a combination of rotation axes and weights.)
171+
const currentEuler = new THREE.Euler().setFromQuaternion(
172+
currentQuaternion,
173+
"YXZ",
174+
);
175+
console.log(currentEuler.x, currentEuler.y, currentEuler.z);
176+
// Replace the current alpha value of the Euler angles and reset the quaternion
177+
currentEuler.y = THREE.MathUtils.degToRad(
178+
360 - device.webkitCompassHeading,
179+
);
180+
currentQuaternion.setFromEuler(currentEuler);
181+
scope.object.quaternion.copy(currentQuaternion);
182+
} else {
183+
if (this.smoothingFactor < 1) {
184+
if (this.lastOrientation) {
185+
const k = this.smoothingFactor;
186+
alpha = this._getSmoothedAngle(
187+
alpha,
188+
this.lastOrientation.alpha,
189+
k,
190+
);
191+
beta = this._getSmoothedAngle(
192+
beta + Math.PI,
193+
this.lastOrientation.beta,
194+
k,
195+
);
196+
gamma = this._getSmoothedAngle(
197+
gamma + this.HALF_PI,
198+
this.lastOrientation.gamma,
199+
k,
200+
Math.PI,
201+
);
202+
} else {
203+
beta += Math.PI;
204+
gamma += this.HALF_PI;
205+
}
206+
207+
this.lastOrientation = {
150208
alpha,
151-
this.lastOrientation.alpha,
152-
k,
153-
);
154-
beta = this._getSmoothedAngle(
155-
beta + Math.PI,
156-
this.lastOrientation.beta,
157-
k,
158-
);
159-
gamma = this._getSmoothedAngle(
160-
gamma + this.HALF_PI,
161-
this.lastOrientation.gamma,
162-
k,
163-
Math.PI,
164-
);
165-
} else {
166-
beta += Math.PI;
167-
gamma += this.HALF_PI;
209+
beta,
210+
gamma,
211+
};
168212
}
169-
170-
this.lastOrientation = {
171-
alpha: alpha,
172-
beta: beta,
173-
gamma: gamma,
174-
};
213+
setObjectQuaternion(
214+
scope.object.quaternion,
215+
alpha + theta,
216+
this.smoothingFactor < 1 ? beta - Math.PI : beta,
217+
this.smoothingFactor < 1 ? gamma - this.HALF_PI : gamma,
218+
orient,
219+
);
175220
}
176221

177-
setObjectQuaternion(
178-
scope.object.quaternion,
179-
alpha,
180-
this.smoothingFactor < 1 ? beta - Math.PI : beta,
181-
this.smoothingFactor < 1 ? gamma - this.HALF_PI : gamma,
182-
orient,
183-
);
184-
222+
// NB - NOT present in IOS fixed version
185223
if (8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
186224
lastQuaternion.copy(scope.object.quaternion);
187225
scope.dispatchEvent(_changeEvent);

0 commit comments

Comments
 (0)