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

如何将传感器数据应用到Three.js模型实现简易动作捕捉

动作捕捉骨骼旋转映射问题解决方案

你的思路完全正确——Three.js中骨骼的quaternion属性存储的是相对于其父骨骼的局部坐标系旋转,而传感器输出的是世界坐标系下的绝对旋转,直接赋值必然导致运动错位。以下是具体的转换步骤和实现细节:

核心转换逻辑

要将传感器的世界旋转转换为骨骼的局部旋转,需要基于「校准姿态」和「骨骼绑定姿态」的对应关系,计算旋转增量后再转换到局部坐标系:

  1. 初始化阶段记录基准数据

    • 保存每个传感器在校准完成时的世界四元数(记为calibSensorQuat),这是传感器的"初始姿态基准"。
    • 保存对应骨骼在绑定姿态(T-Pose或校准姿态)下的世界四元数(通过bone.getWorldQuaternion(new THREE.Quaternion())获取,记为bindBoneWorldQuat),这是骨骼的"初始姿态基准"。
  2. 每一帧的旋转转换
    对于任意一帧的传感器世界旋转currentSensorQuat:

    • 计算传感器相对于校准姿态的相对旋转增量:
      const sensorRelativeQuat = calibSensorQuat.clone().invert().multiply(currentSensorQuat);
      
      这个增量代表传感器从校准姿态到当前姿态的旋转变化。
    • 计算骨骼当前应该达到的世界旋转目标:
      const targetBoneWorldQuat = bindBoneWorldQuat.clone().multiply(sensorRelativeQuat);
      
      即骨骼初始姿态叠加传感器的旋转增量,得到世界坐标系下的目标姿态。
    • 将世界旋转转换为相对于父骨骼的局部旋转并赋值:
      const parentCurrentWorldQuat = new THREE.Quaternion();
      bone.parent.getWorldQuaternion(parentCurrentWorldQuat);
      bone.quaternion.copy(parentCurrentWorldQuat.invert().multiply(targetBoneWorldQuat));
      

代码示例(以胸部骨骼为例)

// 初始化:记录基准数据
const calibChestSensorQuat = sensorData.chest.calib.clone(); // 校准完成时的胸部传感器世界四元数
const bindChestBoneWorldQuat = new THREE.Quaternion();
chestBone.getWorldQuaternion(bindChestBoneWorldQuat); // 绑定姿态下胸部骨骼的世界四元数

// 每一帧更新骨骼
function updateChestBone(currentSensorQuat) {
    // 1. 计算传感器相对校准姿态的旋转增量
    const sensorRel = calibChestSensorQuat.clone().invert().multiply(currentSensorQuat);
    // 2. 计算骨骼的目标世界旋转
    const targetWorldQuat = bindChestBoneWorldQuat.clone().multiply(sensorRel);
    // 3. 转换为局部旋转赋值
    const parentWorldQuat = new THREE.Quaternion();
    chestBone.parent.getWorldQuaternion(parentWorldQuat);
    chestBone.quaternion.copy(parentWorldQuat.invert().multiply(targetWorldQuat));
}

关键注意事项

  • 四元数乘法顺序:Three.js中a.multiply(b)表示先应用b的旋转,再应用a的旋转,不要搞反顺序,否则旋转方向会完全错误。
  • 坐标系严格对齐:确保Blender导出模型时Y轴向上,且骨骼的初始绑定姿态与传感器校准姿态的轴向完全一致(比如胸部骨骼Y轴向上、X向右、Z向前)。
  • 根骨骼特殊处理:如果骨骼是根骨骼(父对象是场景),父骨骼的世界旋转是单位四元数,此时可以简化为直接将targetBoneWorldQuat赋值给骨骼的quaternion(因为局部旋转等于世界旋转)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:22:33