三和Tween.js - 不必要的旋转,是这个万向节锁吗?

时间:2017-01-31 20:37:56

标签: three.js tween.js

我在这里补充一个对象

Position (X:82.22, Y:-8.31, Z:57.75)
Rotation (X:-3.00, Y:-0.95, Z:-3.02)

到这里

Position (X:57.36, Y:-8.31, Z:93.78)
Rotation (X:-3.05, Y:-0.55, Z:-3.10)

使用此补间

            behaviour.tween = new TWEEN.Tween(behaviour.origin).to(behaviour.target,behaviour.offsetTime * 1000)
            .onUpdate(function(){

                hotspot.position.x = behaviour.origin.pX;
                hotspot.position.y = behaviour.origin.pY;
                hotspot.position.z = behaviour.origin.pZ;
                hotspot.rotation.x = behaviour.origin.rX;
                hotspot.rotation.y = behaviour.origin.rY;
                hotspot.rotation.z = behaviour.origin.rZ;
                hotspot.scale.set(behaviour.origin.scale,behaviour.origin.scale,behaviour.origin.scale);
                hotspot.opacity = behaviour.origin.opacity;

            }).

当物体在场景中移动时,物体沿z轴旋转。

这可能是万向节锁吗?如果是这样,那么解决这个问题的方法是什么?

1 个答案:

答案 0 :(得分:1)

使用Quaternion进行转换总是更安全。对我而言,它不使用slerp,但只使用Tween.js。

// excerpt from my code
var q = obj.quaternion.clone().multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0), theta));

new TWEEN.Tween(obj.quaternion)
  .to(q, time)
  .onUpdate(function () { object.quaternion.copy(this); }) // onUpdate isn't really needed in this case
  .start();

所以,对你而言,它应该是这样的:

behaviour.origin.position = new THREE.Vector3(82.22, -8.31, 57.75);
behaviour.origin.quaternion = ew THREE.Quaternion().setFromEuler(new THREE.Euler(-3.00, -0.95, 3.02));

behaviour.target.position = new THREE.Vector(57.36, -8.31, 93.78);
behaviour.target.quaternion = ew THREE.Quaternion().setFromEuler(new THREE.Euler(3.05, -0.55, 3.10));

new TWEEN.Tween(behaviour.origin)
  .to(behaviour.target, behaviour.offsetTime * 1000)
  .onUpdate(function () {
    hotspot.position.copy(behaviour.origin.position);
    hotspot.quaternion.copy(behaviour.origin.quaternion);
  })
  .start();

更新:好的,建议使用slerp(),否则也会导致奇怪的行为。因此,我想,代码应如下所示:

behaviour.origin.position = new THREE.Vector3(82.22, -8.31, 57.75);
behaviour.origin.quaternion = ew THREE.Quaternion().setFromEuler(new THREE.Euler(-3.00, -0.95, 3.02));

behaviour.target.position = new THREE.Vector(57.36, -8.31, 93.78);
behaviour.target.quaternion = ew THREE.Quaternion().setFromEuler(new THREE.Euler(3.05, -0.55, 3.10));

behaviour.origin.t = 0;
behaviour.target.t = 1;

new TWEEN.Tween(behaviour.origin)
  .to(behaviour.target, behaviour.offsetTime * 1000)
  .onUpdate(function () {
    hotspot.position.copy(behaviour.origin.position);
    THREE.Quaternion.slerp(behaviour.origin.quaternion, behaviour.target.quaternion, hotspot.quaternion, behaviour.origin.t);
  })
  .start();