You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取相机的世界Y平面并取反?实现按Q/E后修改cameraDir.y的需求

问题解决方案

1. 获取相机世界Y平面并取反

相机的世界空间Y轴向量,可通过将本地Y轴((0,1,0))应用相机的四元数转换得到;取反操作直接对该向量分量乘以-1即可:

// 获取相机世界Y轴向量
const cameraWorldY = new THREE.Vector3(0, 1, 0).applyQuaternion(this._params.camera.quaternion);
// 取反得到反向Y轴向量
const invertedCameraWorldY = cameraWorldY.multiplyScalar(-1);

如果是要让相机绕自身Y轴完成180度翻转(即“取反Y平面”),直接用相机原四元数乘以绕Y轴π弧度的旋转四元数即可,这也是你代码中已用到的逻辑:

_A.set(0, 1, 0);
_Q.setFromAxisAngle(_A, Math.PI);
_R.multiply(_Q); // _R为相机原四元数,相乘后得到翻转后的四元数

2. 实现Q/E按键后的cameraDir Y值设置需求

根据需求,按下Q或E键后,需让cameraDir保持在相机的Y=0平面(即相机局部空间的X-Z平面),替代原代码中世界空间下的cameraDir.y = 0逻辑。修改后的完整代码如下:

if (input._keys.a) {
  _R.copy(this._params.camera.quaternion);
  if (input._keys.q) {
    _A.set(0, 0, 1);
    _Q.setFromAxisAngle(_A, 0.5 * Math.PI * timeInSeconds);
    _R.multiply(_Q);
    this._params.camera.quaternion.copy(_R);
  }
  if (input._keys.e) {
    _A.set(0, 0, -1);
    _Q.setFromAxisAngle(_A, 0.5 * Math.PI * timeInSeconds);
    _R.multiply(_Q);
    this._params.camera.quaternion.copy(_R);
  }

  // 将cameraDir约束到相机的Y=0平面
  const localCameraDir = cameraDir.clone().applyQuaternion(this._params.camera.quaternion.invert());
  localCameraDir.y = 0; // 相机局部空间Y分量置0
  localCameraDir.normalize();
  cameraDir.copy(localCameraDir).applyQuaternion(this._params.camera.quaternion);

  _A.set(0, 1, 0);  // over Y
  _Q.setFromAxisAngle(_A, Math.PI);
  _R.multiply(_Q);
  controlObject.quaternion.copy(_R);
}

if (!input._keys.a) {
  cameraDir.y = 0; 
  cameraDir.normalize();
  controlObject.quaternion.setFromUnitVectors(from, cameraDir);
}

核心逻辑说明

  1. 把世界空间的cameraDir转换到相机局部空间(通过相机四元数的逆运算)
  2. 在局部空间将Y分量设为0,确保方向处于相机的X-Z平面(即相机的Y=0平面)
  3. 将处理后的向量转换回世界空间,重新赋值给cameraDir

内容的提问来源于stack exchange,提问作者cubesareneat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:40:20