0

Im trying to Tween the camera movement from one to another place but i can't seem to work it out. Im using the Globe from Chrome Experiments and added this function on it

  function changeCountry(lat,lng){
var phi = (90 - lat) * Math.PI / 180;
var theta = (180 - lng) * Math.PI / 180;
var from = {
    x : camera.position.x,
    y : camera.position.y,
    z : distance
  };

  var to = {
    posX : 200 * Math.sin(phi) * Math.cos(theta),
    posY : 200 * Math.cos(phi),
    posZ : distance
  };
  var tween = new TWEEN.Tween(from)
  .to(to,2000)
  .easing(TWEEN.Easing.Linear.None)
  .onUpdate(function () {
    camera.position.set(this.x, this.y, this.z);
    camera.lookAt(new THREE.Vector3(0,0,0));
  })
  .onComplete(function () {
    camera.lookAt(new THREE.Vector3(0,0,0));
  })
  .start();
  console.log(to,from,lat,lng);}

I've console printed the values and it all works perfectly with getting the lat&long and converting them to the right values, also the x,y,z values are great but it just don't move the camera at all. In console i get this errors: Uncaught TypeError: n is not a function, 90Tween.js:4 Uncaught TypeError: is not a function& 419Tween.js:4 Uncaught TypeError: is not a function and the last endlessly counts ++.

If anyone can help me sort it out it would be from a lot of help.

edit: I fixed the error with replacing .easing(TWEEN.Easing.Linear.None) with .easing(TWEEN.Easing.Linear.EaseNone) . However the camera does irregular movement - always the same and then goes back to the normal position before the animation. When playing with TWEEN.update() in my render() function i get different results but none of them works as it should. The render() function is like this:

zoom(curZoomSpeed);

rotation.x += (target.x - rotation.x) * 0.1;
rotation.y += (target.y - rotation.y) * 0.1;


distance += (distanceTarget - distance) * 0.3;

camera.position.x = distance * Math.sin(rotation.x) * Math.cos(rotation.y);
camera.position.y = distance * Math.sin(rotation.y);
camera.position.z = distance * Math.cos(rotation.x) * Math.cos(rotation.y);

camera.lookAt(mesh.position);

TWEEN.update();
renderer.render(scene, camera);

1 Answers1

0

It looks a bit odd what you are doing. For me it works quite well and looks much more simple:

var newpos = new THREE.Vector3( /* new values */ );
new TWEEN.Tween(camera.position)
    .to(newpos, 500)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .start();

The update in the render() function is just

TWEEN.update();
camera.lookAt(mesh.position);

The only problem is that if the new position is at the opposite side of the globe, the camera will tween through the globe which doesn't look nice. So, maybe it's better to put the camera into an Object3D and tween the rotation of this object. You are working with lat and lng anyway, so it should be easier to work with angles in general.

camera.position.set(0,0,distance);
camera.lookAt(new THREE.Vector3(0,0,0));
var camObject = new THREE.Object3D();
camObject.add(camera); 

// camera.lookAt shouldn't be needed anymore within render()

...

var phi = (90 - lat) * Math.PI / 180;
var theta = (180 - lng) * Math.PI / 180;

var euler = new THREE.Euler(phi, theta, 0, 'XYZ');
var newq = new THREE.Quaternion().setFromEuler(euler);

new TWEEN.Tween(camObject.quaternion)
    .to(newq, 500)
    .easing(TWEEN.Easing.Quadratic.InOut)
    .start();

I didn't test this idea, there is probably something wrong (e.g. how and in which order to define the new angles). I just want to give some hints.

Brakebein
  • 2,197
  • 1
  • 16
  • 21