【问题标题】:Getting vertical device forward/up vectors from flat device euler angles从平面设备欧拉角获取垂直设备前向/向上向量
【发布时间】:2021-09-05 13:06:08
【问题描述】:

我正在使用 Resonance Audio(空间音频 sdk)并尝试根据设备方向来定位听众。

Resonance 具有采用两个向量的方法 setListenerOrientation(forward.x, forward.y, forward.z, up.x, up.y, up.z)setListenerFromMatrix(matrix4)。当用户垂直握住设备时,我还希望 -z 向前,而当设备平放时,DOM api 将 -z 向前。

以前,我也有一个来自three.js的3d环境,我只是使用了这段代码:

this.cameraMatrix4 = cameraEl.object3D.matrixWorld;
this.resonanceAudioScene.setListenerFromMatrix(this.cameraMatrix4);

但是现在我正在做一个没有 3d 可视化的版本,所以我没有像这样方便的东西。 我尝试了各种使用受three.js DeviceOrientationControls启发的四元数和Matrix4s的东西,但运气不佳。

我还尝试了以下方法:

function updateListener(e: DeviceOrientationEvent) {
  const alpha = e.alpha ? (e.alpha / 180) * Math.PI + alphaOffset : 0; // Z
  const beta = e.beta ? (e.beta / 180) * Math.PI : 0; // X'
  const gamma = e.gamma ? (e.gamma / 180) * Math.PI : 0; // Y''
  euler.set(beta, gamma, alpha, "ZXY");
  forward.set(0, 0, -1).applyEuler(euler);
  up.set(0, 1, 0).applyEuler(euler);
  resonanceAudioScene.setListenerOrientation(forward.x, forward.y, forward.z, up.x, up.y, up.z);
}

但是,它甚至看起来在平面方向上的行为并不正确。我已经尝试了一些欧拉顺序的变体,但我有点摸不着头脑,因为我不懂 3d 数学,所以我很感激任何帮助:)

【问题讨论】:

  • 我创建了一个从deviceorientation 事件设置旋转四元数的万向节实用程序。也许它可以引导您朝着正确的方向前进,它似乎与您在这里尝试执行的操作相同。 github.com/marquizzo/three-gimbal

标签: javascript math three.js resonance-audio


【解决方案1】:

感谢查看@Marquizzo 的万向节实用程序并意识到初始 Z 方向不一致(这使我无法有效调试),我想出了这个(包括将初始方向设置为原点的一点):

  //YZX order so we can apply the Y rotation for initial direction compensation
  //and then the offset for vertical device in the X axis last.
  const eulerOrigin = new Euler(Math.PI / 2, 0, 0, "YZX");

  //...

  const alpha = e.alpha ? e.alpha * degtorad + alphaOffset : 0; // Z
  const beta = e.beta ? e.beta * degtorad : 0; // X'
  const gamma = e.gamma ? e.gamma * degtorad : 0; // Y''
  quaternion.setFromEuler(eulerOrigin);
  q0.setFromAxisAngle(zAxis, alpha);
  quaternion.multiply(q0);
  q0.setFromAxisAngle(xAxis, beta);
  quaternion.multiply(q0);
  q0.setFromAxisAngle(yAxis, gamma);
  quaternion.multiply(q0);

  up.copy(upAxis).applyQuaternion(quaternion);
  forward.copy(forwardAxis).applyQuaternion(quaternion);

  if (!initialDirection) {
    initialDirection = new Vector3().projectOnPlane(upAxis).normalize();
    const angle = initialDirection.angleTo(forwardAxis);
    eulerOrigin.y = angle;
  }

  resonanceAudioScene.setListenerOrientation(forward.x, forward.y, forward.z, up.x, up.y, up.z);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2015-11-24
    相关资源
    最近更新 更多