0

我正在使用 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 数学,所以我很感激任何帮助:)

4

1 回答 1

0

感谢查看 @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);
于 2021-06-22T13:12:14.057 回答