使用hammerjs和threejs的奇怪旋转行为

问题描述 投票:0回答:1

我想用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);
 });

有什么我想念的吗?

javascript three.js hammer.js
1个回答
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,这样就不会在新的手势开始时使用之前手势的值。

© www.soinside.com 2019 - 2024. All rights reserved.