threejs: smoothly rotate camera towards an object

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

i have just started to study three.js and i am having some trouble to write a function that takes as arguments an object position (Vector3) and a time in milliseconds, and gradually rotate the camera to face it in that time. Substantially a lerp version of the builtin lookAt method.

First i've tried using tweenjs to get smooth rotate transition. For the start and end parameters i've created a dummy object and set its position, rotation and quaternion the same as the camera, then i have use the lookAt function on it to face towards the object and i've stored its quaternion in a new variable "targetQuaternion". Then i have used this variable as the target parameter in the TWEEN.Tween method to update camera.quaternion. I've tried before with quaternions to avoid gymbal lock and then with rotation, but none works fine.

function rotateCameraToObject(object3D, time) {  var cameraPosition = camera.position.clone();               // camera original position var cameraRotation = camera.rotation.clone();               // camera original rotation var cameraQuaternion = camera.quaternion.clone();           // camera original quaternion  var dummyObject = new THREE.Object3D();                     // dummy object   // set dummyObject's position, rotation and quaternion the same as the camera dummyObject.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z); dummyObject.rotation.set(cameraRotation.x, cameraRotation.y, cameraRotation.z); dummyObject.quaternion.set(cameraQuaternion.x, cameraQuaternion.y, cameraQuaternion.z);   // lookAt object3D dummyObject.lookAt(object3D);  // store its quaternion in a variable var targetQuaternion = dummyObject.quaternion.clone();   // tween start object var tweenStart = {     x: cameraQuaternion.x,     y: cameraQuaternion.y,     z: cameraQuaternion.z,     w: cameraQuaternion.w };  //tween target object var tweenTarget = {     x: targetQuaternion.x,     y: targetQuaternion.y,     z: targetQuaternion.z,     w: targetQuaternion.w };  // tween stuff var tween = new TWEEN.Tween(tweenStart).to(tweenTarget, time);  tween.onUpdate(function() {     camera.quaternion.x = tweenStart.x;     camera.quaternion.y = tweenStart.y;     camera.quaternion.z = tweenStart.z;     camera.quaternion.w = tweenStart.w; });  tween.start();

}

So this does not work.

I've also tried another approach, computing the angle between camera vector and object vector and use that angle as target rotation:

function rotateCameraToObject(object3D, time) {  // camera original position var cameraPosition = camera.position.clone();  // object3D position var objectPosition = object3D.position.clone();  // direction vector from camera towards object3D var direction = objectPosition.sub(cameraPosition);  // compute Euler angle var angle = new THREE.Euler(); angle.setFromVector3(direction);   /*  * tween stuff      */ var start = {     x: camera.rotation.clone().x,     y: camera.rotation.clone().y,     z: camera.rotation.clone().z, }  var end = {     x: angle._x,     y: angle._y,     z: angle._z, }  var tween = new TWEEN.Tween(start).to(end, time);  tween.onUpdate(function() {     camera.rotation.y = start.x;     camera.rotation.y = start.y;     camera.rotation.y = start.z; });  tween.start();    

}

This doesn't work neither, eventually camera rotate towards the object but the rotation is not right.

Any help? What is the correct way to have a lerp rotate function for the camera?

Thanks in advance!

回答1:

Have you updated the tween in your animation loop?

function animate() {     requestAnimationFrame( animate );      TWEEN.update();      render(); }

However it's probably better to use the quaternion and not the rotation to turn objects - prevents gimbal lock. THREE.js provides a handy function to use spherical linear interpolation (slerp) as opposed to using tween (lerp) which can give you undesired results, most notably at a 180 deg turn. Put this in your animation loop.

camera.quaternion.slerp(targetQuaternion,t); //t = normalized value 0 to 1

You could then tween t to give you your desired easing.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!