Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const deltaT = this.currentGyroMeasurement.timestampS -
this.previousGyroMeasurement.timestampS;
// Convert gyro rotation vector to a quaternion delta.
const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);
this.gyroIntegralQ.multiply(gyroDeltaQ);
// filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.
this.filterQ.copy(this.previousFilterQ);
this.filterQ.multiply(gyroDeltaQ);
// Calculate the delta between the current estimated gravity and the real
// gravity vector from accelerometer.
const invFilterQ = new MathUtil.Quaternion();
invFilterQ.copy(this.filterQ);
invFilterQ.inverse();
this.estimatedGravity.set(0, 0, -1);
this.estimatedGravity.applyQuaternion(invFilterQ);
this.estimatedGravity.normalize();
this.measuredGravity.copy(this.currentAccelMeasurement.sample);
this.measuredGravity.normalize();
// Compare estimated gravity with measured gravity, get the delta quaternion
// between the two.
const deltaQ = new MathUtil.Quaternion();
deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);
getOrientation() {
let orientation;
// Hack around using deviceorientation instead of devicemotion
if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) {
this.deviceOrientationFixQ = this.deviceOrientationFixQ || (function() {
const y =
new MathUtil.Quaternion().setFromAxisAngle(
new MathUtil.Vector3(0, 1, 0), -this._alpha);
return y;
}).bind(this)();
orientation = this._deviceOrientationQ;
const out = new MathUtil.Quaternion();
out.copy(orientation);
out.multiply(this.filterToWorldQ);
out.multiply(this.resetQ);
out.multiply(this.worldToScreenQ);
out.multiplyQuaternions(this.deviceOrientationFixQ, out);
// return quaternion as glmatrix quaternion object
const out_ = quat.fromValues(
out.x,
out.y,
out.z,
out.w
);
return quat.normalize(out_, out_);
_onDeviceMotionChange({inputEvent}) {
const deviceorientation = inputEvent.deviceorientation;
const deviceMotion = inputEvent;
const accGravity = deviceMotion.accelerationIncludingGravity;
const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;
let timestampS = deviceMotion.timeStamp / 1000;
if (deviceorientation) {
if (!this._alpha) {
this._alpha = deviceorientation.alpha;
}
this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();
this._deviceOrientationQ.setFromEulerYXZ(
deviceorientation.beta,
deviceorientation.alpha,
deviceorientation.gamma
);
this._triggerChange();
} else {
// Firefox Android timeStamp returns one thousandth of a millisecond.
if (this.isFirefoxAndroid) {
timestampS /= 1000;
}
this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);
this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);
this.isIOS = Util.isIOS();
// Ref https://github.com/immersive-web/cardboard-vr-display/issues/18
this.isChromeUsingDegrees = agentInfo.browser.name === "chrome" &&
parseInt(agentInfo.browser.version, 10) >= 66;
this._isEnabled = false;
// Set the filter to world transform, depending on OS.
if (this.isIOS) {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);
} else {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);
}
this.inverseWorldToScreenQ = new MathUtil.Quaternion();
this.worldToScreenQ = new MathUtil.Quaternion();
this.originalPoseAdjustQ = new MathUtil.Quaternion();
this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),
-window.orientation * Math.PI / 180);
this._setScreenTransform();
// Adjust this filter for being in landscape mode.
if (Util.isLandscapeMode()) {
this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);
}
// Keep track of a reset transform for resetSensor.
this.resetQ = new MathUtil.Quaternion();
this.deviceMotion.on("devicemotion", this._onDeviceMotionChange);
this.enable();
// gravity vector from accelerometer.
const invFilterQ = new MathUtil.Quaternion();
invFilterQ.copy(this.filterQ);
invFilterQ.inverse();
this.estimatedGravity.set(0, 0, -1);
this.estimatedGravity.applyQuaternion(invFilterQ);
this.estimatedGravity.normalize();
this.measuredGravity.copy(this.currentAccelMeasurement.sample);
this.measuredGravity.normalize();
// Compare estimated gravity with measured gravity, get the delta quaternion
// between the two.
const deltaQ = new MathUtil.Quaternion();
deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);
deltaQ.inverse();
// Calculate the SLERP target: current orientation plus the measured-estimated
// quaternion delta.
const targetQ = new MathUtil.Quaternion();
targetQ.copy(this.filterQ);
targetQ.multiply(deltaQ);
// SLERP factor: 0 is pure gyro, 1 is pure accel.
this.filterQ.slerp(targetQ, 1 - this.kFilter);
this.previousFilterQ.copy(this.filterQ);
_convertFusionToPredicted(orientation) {
// Predict orientation.
this.predictedQ =
this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);
// Convert to THREE coordinate system: -Z forward, Y up, X right.
const out = new MathUtil.Quaternion();
out.copy(this.filterToWorldQ);
out.multiply(this.resetQ);
out.multiply(this.predictedQ);
out.multiply(this.worldToScreenQ);
return out;
}
_onDeviceMotionChange({inputEvent}) {
constructor() {
super();
this.deviceMotion = new DeviceMotion();
this.accelerometer = new MathUtil.Vector3();
this.gyroscope = new MathUtil.Vector3();
this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);
this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);
this.filter = new ComplementaryFilter(K_FILTER);
this.posePredictor = new PosePredictor(PREDICTION_TIME_S);
this.filterToWorldQ = new MathUtil.Quaternion();
this.isFirefoxAndroid = Util.isFirefoxAndroid();
this.isIOS = Util.isIOS();
// Ref https://github.com/immersive-web/cardboard-vr-display/issues/18
this.isChromeUsingDegrees = agentInfo.browser.name === "chrome" &&
parseInt(agentInfo.browser.version, 10) >= 66;
this._isEnabled = false;
// Set the filter to world transform, depending on OS.
if (this.isIOS) {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);
} else {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);
}
this.estimatedGravity.applyQuaternion(invFilterQ);
this.estimatedGravity.normalize();
this.measuredGravity.copy(this.currentAccelMeasurement.sample);
this.measuredGravity.normalize();
// Compare estimated gravity with measured gravity, get the delta quaternion
// between the two.
const deltaQ = new MathUtil.Quaternion();
deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);
deltaQ.inverse();
// Calculate the SLERP target: current orientation plus the measured-estimated
// quaternion delta.
const targetQ = new MathUtil.Quaternion();
targetQ.copy(this.filterQ);
targetQ.multiply(deltaQ);
// SLERP factor: 0 is pure gyro, 1 is pure accel.
this.filterQ.slerp(targetQ, 1 - this.kFilter);
this.previousFilterQ.copy(this.filterQ);
if (!this.isFilterQuaternionInitialized) {
this.isFilterQuaternionInitialized = true;
}
};
// Ref https://github.com/immersive-web/cardboard-vr-display/issues/18
this.isChromeUsingDegrees = agentInfo.browser.name === "chrome" &&
parseInt(agentInfo.browser.version, 10) >= 66;
this._isEnabled = false;
// Set the filter to world transform, depending on OS.
if (this.isIOS) {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);
} else {
this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);
}
this.inverseWorldToScreenQ = new MathUtil.Quaternion();
this.worldToScreenQ = new MathUtil.Quaternion();
this.originalPoseAdjustQ = new MathUtil.Quaternion();
this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),
-window.orientation * Math.PI / 180);
this._setScreenTransform();
// Adjust this filter for being in landscape mode.
if (Util.isLandscapeMode()) {
this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);
}
// Keep track of a reset transform for resetSensor.
this.resetQ = new MathUtil.Quaternion();
this.deviceMotion.on("devicemotion", this._onDeviceMotionChange);
this.enable();
}
enable() {