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

CannonJS 3D世界向量转模型视图矩阵的转换问题

glMatrix与CannonJS四元数旋转转换异常问题

核心问题

使用glMatrix 3.4.0处理物体位置正常,但在四元数(QUAT)与轴角/旋转矩阵(mat4)的转换上存在异常:

  • 明确glMatrix采用弧度制,能正常获取CannonJS物理体的四元数数据
  • 尝试所有旋转转换方式(四元数转矩阵、轴角转矩阵等)均出现问题:玩家物理体推动立方体时,立方体的旋转不会立即固定,而是随推动次数逐渐趋于固定
  • 经典mat4.rotate调用存在角度误差:90°实际显示为96°,180°、270°也有明显偏差
  • 直接用mat4.fromQuat将CannonJS四元数转为旋转矩阵完全失效

相关代码

渲染逻辑代码

mat4.identity(object.mvMatrix);
this.mvPushMatrix(object.mvMatrix, this.mvMatrixStack);

mat4.translate(object.mvMatrix, object.mvMatrix, object.position.worldLocation);

// 从CannonJS四元数获取旋转轴与角度:local.physics.currentBody.quaternion.toAxisAngle()[0]为轴,[1]为角度

// 【经典旋转方案 - 效果有误差】
// 存在角度偏差:90°显示为96°,180°、270°也有问题
var t = vec3.fromValues(object.rotation.axis.x, object.rotation.axis.z, object.rotation.axis.y);
mat4.rotate(object.mvMatrix, object.mvMatrix, object.rotation.angle, t);

// 【四元数转矩阵方案 - 完全失效】
var QP = object.physics.currentBody.quaternion;
var QUAT = quat.fromValues(QP.x, QP.y, QP.z, QP.w);
mat4.fromQuat(object.mvMatrix, QUAT);

重写的CannonJS四元数转轴角方法

尝试重写CannonJS原生toAxisAngle方法,但不同变体仅能修复特定角度问题,无法兼顾所有情况:

// 测试重写CannonJS四元数转轴角方法
CANNON.Quaternion.prototype.toAxisAngle = function(targetAxis){
  targetAxis = targetAxis || new CANNON.Vec3();
  if (this.w > 1) this.normalize(); 
  // 若w>1,acos和sqrt会出错,归一化可避免该问题

  var angle = 2 * Math.acos(this.w);
  var s = Math.sqrt(1 - this.w * this.w); // 假设四元数已归一化,w<1,因此值恒正
  if (s < 0.001) {
      // 避免除零,此时轴方向理论上不影响结果
      // 变体I:修复90°旋转问题,但180°会出现~30°偏差
      targetAxis.x = 0;
      targetAxis.y = 0;
      targetAxis.z = 1;
   
      // 变体II:修复180°旋转问题,但90°会出错
      // targetAxis.x = 1;
      // targetAxis.y = 0;
      // targetAxis.z = 0;

      // 原逻辑:
      // targetAxis.x = this.x;
      // targetAxis.y = this.y;
      // targetAxis.z = this.z;
  } else {
      targetAxis.x = this.x / s; // 归一化旋转轴
      targetAxis.y = this.y / s;
      targetAxis.z = this.z / s;
  }
  return [targetAxis, angle];
};

问题效果截图

  • 四元数转矩阵失效时的异常效果:完全失效时的异常效果
  • 经典旋转方案的误差效果:角度偏差时的效果

项目背景

项目基于matrix-engine,可通过FPSSHOOTER示例复现问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:13:15