我想用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);
});
有什么我想念的吗?
看起来你正在使用绝对旋转值,而不是旋转的变化。例如,请考虑以下情形:
通过乘以四元数,您的对象将被旋转到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
,这样就不会在新的手势开始时使用之前手势的值。