我想用Hammerjs手势旋转object3D。
基本上是轮换工作,但有两个问题我无法弄清。
旋转方向随机变化。向左转。我停下来,然后突然又一次在同一方向上移动手指,而不是继续向左旋转而不是向右旋转。有时但并非总是如此。
开始旋转后,尽管我将手指移动到不同的方向,但旋转方向仅是相同的。
这是我处理轮换的方式:
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);
});
我有什么想念的吗?
答案 0 :(得分:1)
您似乎正在使用绝对旋转值,而不是旋转变化。例如,请考虑以下情形:
通过四元数相乘,对象将被旋转到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
,就可以避免在新手势开始时使用先前手势中的值。