Hammerjs和Threejs的怪异旋转行为

时间:2019-03-14 14:14:01

标签: javascript three.js hammer.js

我想用Hammerjs手势旋转object3D。

基本上是轮换工作,但有两个问题我无法弄清。

  1. 旋转方向随机变化。向左转。我停下来,然后突然又一次在同一方向上移动手指,而不是继续向左旋转而不是向右旋转。有时但并非总是如此。

  2. 开始旋转后,尽管我将手指移动到不同的方向,但旋转方向仅是相同的。

这是我处理轮换的方式:

public rotateObject3D (e: HammerInput): void {

    if (rotationEnabled) {
      const translation = new THREE.Vector3();
      const rotation = new THREE.Quaternion();
      const scale = new THREE.Vector3();
      const rotateMatrix = new THREE.Matrix4();
      const deltaRotationQuaternion = new THREE.Quaternion();

      this._myObject.matrix.decompose(translation, rotation, scale);

      this._deltaRot = (e.rotation * 0.01);
      deltaRotationQuaternion.setFromEuler(new THREE.Euler(
        0,
        this._deltaRot * (Math.PI / 180),
        0,
        'XYZ'
      ));

      deltaRotationQuaternion.multiplyQuaternions(deltaRotationQuaternion, rotation);

      this._myObject.matrix = rotateMatrix.compose(translation, deltaRotationQuaternion, scale);
    }
  }

这就是它的调用:

 this._hammerManager.on('rotate', (e) => {
     this._arTools.rotateObject3D(e);
 });

我有什么想念的吗?

1 个答案:

答案 0 :(得分:1)

您似乎正在使用绝对旋转值,而不是旋转变化。例如,请考虑以下情形:

  • 旋转1:12°
  • 旋转2:10°
  • 旋转3:5°

通过四元数相乘,对象将被旋转到12°,然后旋转22°,然后最终旋转到27°,即使您正转回0。这是因为您要将新旋转添加到每个事件。

您应该做的是保存以前的旋转值,并从新的旋转值中减去它,以获得旋转增量:

var previousRot = 0;
var newRot = 0;

rotateObject3D(e) {
    newRot = e.rotation - previousRot;

    // You could use newRot for your quaternion calculations
    // but modifying .rotation.y is simpler
    myObject.rotation.y += newRot

    // Save value to be used on next event
    previousRot = newRot;
}

使用这种方法,以上情况将轮换您进行更改。您的对象将首先旋转+ 12°,然后旋转-2°,然后旋转-5°,以获得更自然的行为。

只要确保在HammerJS的previousRot = 0事件上重置rotateend,就可以避免在新手势开始时使用先前手势中的值。